-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[Config Service] Use stripUnknownKeys when checking enabled flags
#201579
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
[Config Service] Use stripUnknownKeys when checking enabled flags
#201579
Conversation
3e45864 to
b852da7
Compare
b852da7 to
e7c0bd7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
proving that stripUnknownKeys works as intended
|
|
||
| const validatedConfig = hasSchema | ||
| ? await this.atPath<{ enabled?: boolean }>(path).pipe(first()).toPromise() | ||
| ? await firstValueFrom( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took the opportunity to change the deprecated usage of .toPromise()
| // Special use case: when the provided config includes `enabled` and the validated config doesn't, | ||
| // it's quite likely that's not an allowed config and it should fail. | ||
| // Applying "normal" validation (not stripping unknowns) in that case. | ||
| if ( | ||
| hasSchema && | ||
| typeof config.get(path)?.enabled !== 'undefined' && | ||
| typeof validatedConfig?.enabled === 'undefined' | ||
| ) { | ||
| validatedConfig = await firstValueFrom( | ||
| this.getValidatedConfigAtPath$(path) as Observable<{ enabled?: boolean }>, | ||
| { defaultValue: undefined } | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to add this special use case since stripUnknownKeys effectively breaks it 😿
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense, although it's possible that the validation error may contain more than just "enabled"... perhaps we can catch and throw a more specific message here about the special "enabled" setting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point! I created #202490 for us to discuss the new potential message.
|
Pinging @elastic/kibana-core (Team:Core) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall lgtm, left a comment about a test and an error message. Let me know what you think! Non blockers.
| ) | ||
| : undefined; | ||
|
|
||
| // Special use case: when the provided config includes `enabled` and the validated config doesn't, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only at the top level of the object?
Also could we add a test case for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the existing test that reminded me that I would introduce a regression with simply using stripUnknownKeys: true above:
kibana/packages/kbn-config/src/config_service.test.ts
Lines 352 to 374 in 3daaaa5
| test('throws if reading "enabled" when it is not present in the schema', async () => { | |
| const initialConfig = { | |
| foo: { | |
| enabled: false, | |
| }, | |
| }; | |
| const rawConfigProvider = createRawConfigServiceMock({ rawConfig: initialConfig }); | |
| const configService = new ConfigService(rawConfigProvider, defaultEnv, logger); | |
| configService.setSchema( | |
| 'foo', | |
| schema.object({ | |
| bar: schema.maybe(schema.string()), | |
| }) | |
| ); | |
| await expect( | |
| async () => await configService.isEnabledAtPath('foo') | |
| ).rejects.toThrowErrorMatchingInlineSnapshot( | |
| `"[config validation of [foo].enabled]: definition for this key is missing"` | |
| ); | |
| }); |
| // Special use case: when the provided config includes `enabled` and the validated config doesn't, | ||
| // it's quite likely that's not an allowed config and it should fail. | ||
| // Applying "normal" validation (not stripping unknowns) in that case. | ||
| if ( | ||
| hasSchema && | ||
| typeof config.get(path)?.enabled !== 'undefined' && | ||
| typeof validatedConfig?.enabled === 'undefined' | ||
| ) { | ||
| validatedConfig = await firstValueFrom( | ||
| this.getValidatedConfigAtPath$(path) as Observable<{ enabled?: boolean }>, | ||
| { defaultValue: undefined } | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense, although it's possible that the validation error may contain more than just "enabled"... perhaps we can catch and throw a more specific message here about the special "enabled" setting?
|
This feature is Serverless-only. However, I chose to backport to |
💚 Build Succeeded
Metrics [docs]
History
cc @afharo |
|
Starting backport for target branches: 8.x |
…lastic#201579) ## Summary Resolves elastic#201442. The underlying issue is that `isEnabledAtPath` validates the entire config object when it only cares about `.enabled`. This PR performs that check using `stripUnknownKeys: true`, as we'll perform the actual validation later on. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios (cherry picked from commit 3e1d62e)
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
…ed` flags (#201579) (#202531) # Backport This will backport the following commits from `main` to `8.x`: - [[Config Service] Use stripUnknownKeys when checking `enabled` flags (#201579)](#201579) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Alejandro Fernández Haro","email":"afharo@gmail.com"},"sourceCommit":{"committedDate":"2024-12-02T16:30:09Z","message":"[Config Service] Use stripUnknownKeys when checking `enabled` flags (#201579)\n\n## Summary\n\nResolves #201442.\n\nThe underlying issue is that `isEnabledAtPath` validates the entire\nconfig object when it only cares about `.enabled`. This PR performs that\ncheck using `stripUnknownKeys: true`, as we'll perform the actual\nvalidation later on.\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"3e1d62ebc4530a1f9ebc05d9cbff858aa46ce438","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Core","release_note:skip","Feature:Configuration","v9.0.0","backport:prev-minor"],"title":"[Config Service] Use stripUnknownKeys when checking `enabled` flags","number":201579,"url":"https://github.com/elastic/kibana/pull/201579","mergeCommit":{"message":"[Config Service] Use stripUnknownKeys when checking `enabled` flags (#201579)\n\n## Summary\n\nResolves #201442.\n\nThe underlying issue is that `isEnabledAtPath` validates the entire\nconfig object when it only cares about `.enabled`. This PR performs that\ncheck using `stripUnknownKeys: true`, as we'll perform the actual\nvalidation later on.\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"3e1d62ebc4530a1f9ebc05d9cbff858aa46ce438"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201579","number":201579,"mergeCommit":{"message":"[Config Service] Use stripUnknownKeys when checking `enabled` flags (#201579)\n\n## Summary\n\nResolves #201442.\n\nThe underlying issue is that `isEnabledAtPath` validates the entire\nconfig object when it only cares about `.enabled`. This PR performs that\ncheck using `stripUnknownKeys: true`, as we'll perform the actual\nvalidation later on.\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"3e1d62ebc4530a1f9ebc05d9cbff858aa46ce438"}}]}] BACKPORT--> Co-authored-by: Alejandro Fernández Haro <afharo@gmail.com>
…lastic#201579) ## Summary Resolves elastic#201442. The underlying issue is that `isEnabledAtPath` validates the entire config object when it only cares about `.enabled`. This PR performs that check using `stripUnknownKeys: true`, as we'll perform the actual validation later on. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
Summary
Resolves #201442.
The underlying issue is that
isEnabledAtPathvalidates the entire config object when it only cares about.enabled. This PR performs that check usingstripUnknownKeys: true, as we'll perform the actual validation later on.Checklist