Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] feat(security): extend `Feature` definition to support explicit feature replacements (#206660) #206925

Merged
merged 1 commit into from
Jan 16, 2025

Conversation

kibanamachine
Copy link
Contributor

Backport

This will backport the following commits from main to 8.x:

Questions ?

Please refer to the Backport tool documentation

replacedBy: ['feature_id_v2'], <--\n },\n id: 'feature_id'\n name: `Case #4 feature ${suffix} (DEPRECATED)`,\n …\n});\n```\n\n## How to test\n\n1. Run test server\n```bash\nnode scripts/functional_tests_server.js --config x-pack/test/security_api_integration/features.config.ts\n```\n\n2. Execute the following request from the Dev Tools (`case_4_feature_a`\nis a deprecated feature that is replaced by multiple features and\n**doesn't use** `deprecated.replacedBy`)\n```http\nPUT kbn:/api/spaces/space/default?overwrite=true\n{\n \"id\":\"default\",\n \"name\":\"Default\",\n \"description\":\"This is your default space!\",\n \"color\":\"#00bfb3\",\n \"disabledFeatures\":[\"case_4_feature_a\"],\n \"_reserved\":true,\n \"imageUrl\":\"\",\n \"initials\":\"D\"\n}\n```\n\n3. Observe that in response deprecated `case_4_feature_a` is replaced by\ntwo features (you can also check\nhttp://localhost:5620/app/management/kibana/spaces/edit/default to see\nhow it's reflected in UI)\n```http\n{\n \"id\": \"default\",\n \"name\": \"Default\",\n \"description\": \"This is your default space!\",\n \"color\": \"#00bfb3\",\n \"initials\": \"D\",\n \"imageUrl\": \"\",\n \"disabledFeatures\": [\n \"case_4_feature_a_v2\",\n \"case_4_feature_c\"\n ],\n \"_reserved\": true\n}\n```\n\n4. Execute the following request from the Dev Tools (`case_4_feature_b`\nis a deprecated feature that is replaced by multiple features, but\n**uses** `deprecated.replacedBy` to set the conceptual\nfeature-successor)\n```http\nPUT kbn:/api/spaces/space/default?overwrite=true\n{\n \"id\":\"default\",\n \"name\":\"Default\",\n \"description\":\"This is your default space!\",\n \"color\":\"#00bfb3\",\n \"disabledFeatures\":[\"case_4_feature_b\"],\n \"_reserved\":true,\n \"imageUrl\":\"\",\n \"initials\":\"D\"\n}\n```\n\n5. Observe that in response deprecated `case_4_feature_b` is replaced by\na single feature (you can also check\nhttp://localhost:5620/app/management/kibana/spaces/edit/default to see\nhow it's reflected in UI)\n```http\n{\n \"id\": \"default\",\n \"name\": \"Default\",\n \"description\": \"This is your default space!\",\n \"color\": \"#00bfb3\",\n \"initials\": \"D\",\n \"imageUrl\": \"\",\n \"disabledFeatures\": [\n \"case_4_feature_b_v2\"\n ],\n \"_reserved\": true\n}\n```\n\n__Required by:__\nhttps://github.com//pull/202863#discussion_r1892672114\n\n//cc @davismcphee","sha":"dd3ce0e7f534279f48be8c125853c89aa92969e2","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Feature:Security/Spaces","release_note:skip","Feature:Security/Authorization","v9.0.0","backport:prev-minor"],"title":"feat(security): extend `Feature` definition to support explicit feature replacements","number":206660,"url":"https://github.com//pull/206660","mergeCommit":{"message":"feat(security): extend `Feature` definition to support explicit feature replacements (#206660)\n\n## Summary\n\nToday, when a developer deprecates a feature and replaces its privileges\nwith those of another feature, we reasonably assume that the new feature\nfully replaces the old one in all possible contexts - whether in role\nmanagement UIs or in the Spaces feature toggles visibility UI. However,\nwhen deprecated privileges are replaced by the privileges of multiple\nfeatures, such as in [this\ncase](https://github.com//pull/202863#discussion_r1892672114)\nwhere the Discover/Dashboard/Maps feature privileges are replaced by the\nprivileges of Discover_v2/Dashboard_v2/Maps_v2, respectively, **and**\nthe privileges of the Saved Query Management feature, the choice is\nambiguous.\n\nWhich of these features should be treated as the replacement for the\ndeprecated feature in contexts that deal with entire features (like the\nSpaces feature toggles visibility UI) rather than individual privileges\n(like in role management UIs)? Should all referenced features be\nconsidered replacements? Or just a subset - or even a single feature? If\nso, which one? Currently, we treat all referenced features as\nreplacements for the deprecated feature, which creates problems, as\ndescribed in detail in [this\ndiscussion](https://github.com//pull/202863#discussion_r1892672114).\n\nThis PR allows developers to customize this behavior by specifying which\nfeatures Kibana should treat as direct successors to deprecated features\nin contexts that deal with whole features rather than individual\nprivileges:\n\n```ts\ndeps.features.registerKibanaFeature({\n deprecated: {\n notice: 'The feature is deprecated because … well, there’s a reason.',\n --> replacedBy: ['feature_id_v2'], <--\n },\n id: 'feature_id'\n name: `Case #4 feature ${suffix} (DEPRECATED)`,\n …\n});\n```\n\n## How to test\n\n1. Run test server\n```bash\nnode scripts/functional_tests_server.js --config x-pack/test/security_api_integration/features.config.ts\n```\n\n2. Execute the following request from the Dev Tools (`case_4_feature_a`\nis a deprecated feature that is replaced by multiple features and\n**doesn't use** `deprecated.replacedBy`)\n```http\nPUT kbn:/api/spaces/space/default?overwrite=true\n{\n \"id\":\"default\",\n \"name\":\"Default\",\n \"description\":\"This is your default space!\",\n \"color\":\"#00bfb3\",\n \"disabledFeatures\":[\"case_4_feature_a\"],\n \"_reserved\":true,\n \"imageUrl\":\"\",\n \"initials\":\"D\"\n}\n```\n\n3. Observe that in response deprecated `case_4_feature_a` is replaced by\ntwo features (you can also check\nhttp://localhost:5620/app/management/kibana/spaces/edit/default to see\nhow it's reflected in UI)\n```http\n{\n \"id\": \"default\",\n \"name\": \"Default\",\n \"description\": \"This is your default space!\",\n \"color\": \"#00bfb3\",\n \"initials\": \"D\",\n \"imageUrl\": \"\",\n \"disabledFeatures\": [\n \"case_4_feature_a_v2\",\n \"case_4_feature_c\"\n ],\n \"_reserved\": true\n}\n```\n\n4. Execute the following request from the Dev Tools (`case_4_feature_b`\nis a deprecated feature that is replaced by multiple features, but\n**uses** `deprecated.replacedBy` to set the conceptual\nfeature-successor)\n```http\nPUT kbn:/api/spaces/space/default?overwrite=true\n{\n \"id\":\"default\",\n \"name\":\"Default\",\n \"description\":\"This is your default space!\",\n \"color\":\"#00bfb3\",\n \"disabledFeatures\":[\"case_4_feature_b\"],\n \"_reserved\":true,\n \"imageUrl\":\"\",\n \"initials\":\"D\"\n}\n```\n\n5. Observe that in response deprecated `case_4_feature_b` is replaced by\na single feature (you can also check\nhttp://localhost:5620/app/management/kibana/spaces/edit/default to see\nhow it's reflected in UI)\n```http\n{\n \"id\": \"default\",\n \"name\": \"Default\",\n \"description\": \"This is your default space!\",\n \"color\": \"#00bfb3\",\n \"initials\": \"D\",\n \"imageUrl\": \"\",\n \"disabledFeatures\": [\n \"case_4_feature_b_v2\"\n ],\n \"_reserved\": true\n}\n```\n\n__Required by:__\nhttps://github.com//pull/202863#discussion_r1892672114\n\n//cc @davismcphee","sha":"dd3ce0e7f534279f48be8c125853c89aa92969e2"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com//pull/206660","number":206660,"mergeCommit":{"message":"feat(security): extend `Feature` definition to support explicit feature replacements (#206660)\n\n## Summary\n\nToday, when a developer deprecates a feature and replaces its privileges\nwith those of another feature, we reasonably assume that the new feature\nfully replaces the old one in all possible contexts - whether in role\nmanagement UIs or in the Spaces feature toggles visibility UI. However,\nwhen deprecated privileges are replaced by the privileges of multiple\nfeatures, such as in [this\ncase](https://github.com//pull/202863#discussion_r1892672114)\nwhere the Discover/Dashboard/Maps feature privileges are replaced by the\nprivileges of Discover_v2/Dashboard_v2/Maps_v2, respectively, **and**\nthe privileges of the Saved Query Management feature, the choice is\nambiguous.\n\nWhich of these features should be treated as the replacement for the\ndeprecated feature in contexts that deal with entire features (like the\nSpaces feature toggles visibility UI) rather than individual privileges\n(like in role management UIs)? Should all referenced features be\nconsidered replacements? Or just a subset - or even a single feature? If\nso, which one? Currently, we treat all referenced features as\nreplacements for the deprecated feature, which creates problems, as\ndescribed in detail in [this\ndiscussion](https://github.com//pull/202863#discussion_r1892672114).\n\nThis PR allows developers to customize this behavior by specifying which\nfeatures Kibana should treat as direct successors to deprecated features\nin contexts that deal with whole features rather than individual\nprivileges:\n\n```ts\ndeps.features.registerKibanaFeature({\n deprecated: {\n notice: 'The feature is deprecated because … well, there’s a reason.',\n --> replacedBy: ['feature_id_v2'], <--\n },\n id: 'feature_id'\n name: `Case #4 feature ${suffix} (DEPRECATED)`,\n …\n});\n```\n\n## How to test\n\n1. Run test server\n```bash\nnode scripts/functional_tests_server.js --config x-pack/test/security_api_integration/features.config.ts\n```\n\n2. Execute the following request from the Dev Tools (`case_4_feature_a`\nis a deprecated feature that is replaced by multiple features and\n**doesn't use** `deprecated.replacedBy`)\n```http\nPUT kbn:/api/spaces/space/default?overwrite=true\n{\n \"id\":\"default\",\n \"name\":\"Default\",\n \"description\":\"This is your default space!\",\n \"color\":\"#00bfb3\",\n \"disabledFeatures\":[\"case_4_feature_a\"],\n \"_reserved\":true,\n \"imageUrl\":\"\",\n \"initials\":\"D\"\n}\n```\n\n3. Observe that in response deprecated `case_4_feature_a` is replaced by\ntwo features (you can also check\nhttp://localhost:5620/app/management/kibana/spaces/edit/default to see\nhow it's reflected in UI)\n```http\n{\n \"id\": \"default\",\n \"name\": \"Default\",\n \"description\": \"This is your default space!\",\n \"color\": \"#00bfb3\",\n \"initials\": \"D\",\n \"imageUrl\": \"\",\n \"disabledFeatures\": [\n \"case_4_feature_a_v2\",\n \"case_4_feature_c\"\n ],\n \"_reserved\": true\n}\n```\n\n4. Execute the following request from the Dev Tools (`case_4_feature_b`\nis a deprecated feature that is replaced by multiple features, but\n**uses** `deprecated.replacedBy` to set the conceptual\nfeature-successor)\n```http\nPUT kbn:/api/spaces/space/default?overwrite=true\n{\n \"id\":\"default\",\n \"name\":\"Default\",\n \"description\":\"This is your default space!\",\n \"color\":\"#00bfb3\",\n \"disabledFeatures\":[\"case_4_feature_b\"],\n \"_reserved\":true,\n \"imageUrl\":\"\",\n \"initials\":\"D\"\n}\n```\n\n5. Observe that in response deprecated `case_4_feature_b` is replaced by\na single feature (you can also check\nhttp://localhost:5620/app/management/kibana/spaces/edit/default to see\nhow it's reflected in UI)\n```http\n{\n \"id\": \"default\",\n \"name\": \"Default\",\n \"description\": \"This is your default space!\",\n \"color\": \"#00bfb3\",\n \"initials\": \"D\",\n \"imageUrl\": \"\",\n \"disabledFeatures\": [\n \"case_4_feature_b_v2\"\n ],\n \"_reserved\": true\n}\n```\n\n__Required by:__\nhttps://github.com//pull/202863#discussion_r1892672114\n\n//cc @davismcphee","sha":"dd3ce0e7f534279f48be8c125853c89aa92969e2"}}]}] BACKPORT-->

…re replacements (elastic#206660)

## Summary

Today, when a developer deprecates a feature and replaces its privileges
with those of another feature, we reasonably assume that the new feature
fully replaces the old one in all possible contexts - whether in role
management UIs or in the Spaces feature toggles visibility UI. However,
when deprecated privileges are replaced by the privileges of multiple
features, such as in [this
case](elastic#202863 (comment))
where the Discover/Dashboard/Maps feature privileges are replaced by the
privileges of Discover_v2/Dashboard_v2/Maps_v2, respectively, **and**
the privileges of the Saved Query Management feature, the choice is
ambiguous.

Which of these features should be treated as the replacement for the
deprecated feature in contexts that deal with entire features (like the
Spaces feature toggles visibility UI) rather than individual privileges
(like in role management UIs)? Should all referenced features be
considered replacements? Or just a subset - or even a single feature? If
so, which one? Currently, we treat all referenced features as
replacements for the deprecated feature, which creates problems, as
described in detail in [this
discussion](elastic#202863 (comment)).

This PR allows developers to customize this behavior by specifying which
features Kibana should treat as direct successors to deprecated features
in contexts that deal with whole features rather than individual
privileges:

```ts
deps.features.registerKibanaFeature({
  deprecated: {
    notice: 'The feature is deprecated because … well, there’s a reason.',
    --> replacedBy: ['feature_id_v2'], <--
  },
  id: 'feature_id'
  name: `Case elastic#4 feature ${suffix} (DEPRECATED)`,
  …
});
```

## How to test

1. Run test server
```bash
node scripts/functional_tests_server.js --config x-pack/test/security_api_integration/features.config.ts
```

2. Execute the following request from the Dev Tools (`case_4_feature_a`
is a deprecated feature that is replaced by multiple features and
**doesn't use** `deprecated.replacedBy`)
```http
PUT kbn:/api/spaces/space/default?overwrite=true
{
  "id":"default",
  "name":"Default",
  "description":"This is your default space!",
  "color":"#00bfb3",
  "disabledFeatures":["case_4_feature_a"],
  "_reserved":true,
  "imageUrl":"",
  "initials":"D"
}
```

3. Observe that in response deprecated `case_4_feature_a` is replaced by
two features (you can also check
http://localhost:5620/app/management/kibana/spaces/edit/default to see
how it's reflected in UI)
```http
{
  "id": "default",
  "name": "Default",
  "description": "This is your default space!",
  "color": "#00bfb3",
  "initials": "D",
  "imageUrl": "",
  "disabledFeatures": [
    "case_4_feature_a_v2",
    "case_4_feature_c"
  ],
  "_reserved": true
}
```

4. Execute the following request from the Dev Tools (`case_4_feature_b`
is a deprecated feature that is replaced by multiple features, but
**uses** `deprecated.replacedBy` to set the conceptual
feature-successor)
```http
PUT kbn:/api/spaces/space/default?overwrite=true
{
  "id":"default",
  "name":"Default",
  "description":"This is your default space!",
  "color":"#00bfb3",
  "disabledFeatures":["case_4_feature_b"],
  "_reserved":true,
  "imageUrl":"",
  "initials":"D"
}
```

5. Observe that in response deprecated `case_4_feature_b` is replaced by
a single feature (you can also check
http://localhost:5620/app/management/kibana/spaces/edit/default to see
how it's reflected in UI)
```http
{
  "id": "default",
  "name": "Default",
  "description": "This is your default space!",
  "color": "#00bfb3",
  "initials": "D",
  "imageUrl": "",
  "disabledFeatures": [
    "case_4_feature_b_v2"
  ],
  "_reserved": true
}
```

__Required by:__
elastic#202863 (comment)

//cc @davismcphee

(cherry picked from commit dd3ce0e)
@kibanamachine kibanamachine merged commit db491db into elastic:8.x Jan 16, 2025
11 checks passed
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
features 110 109 -1
Unknown metric groups

API count

id before after diff
features 270 273 +3

References to deprecated APIs

id before after diff
spaces 14 12 -2

cc @azasypkin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants