-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[Serverless] Add internal uiSettings routes and expose public routes in self-managed only #160499
[Serverless] Add internal uiSettings routes and expose public routes in self-managed only #160499
Conversation
Pinging @elastic/platform-deployment-management (Team:Deployment Management) |
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.
Approach looks fine to me, but PR still needs changes to be ready to merge.
@@ -51,15 +51,33 @@ export function registerDeleteRoute(router: InternalUiSettingsRouter) { | |||
throw error; | |||
} | |||
}; | |||
if (publicApiEnabled) { |
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.
General comment for all routes:
Either we decide that for now, those two API prefix (/api and /internal) should have the exact same behavior, in which case I would reuse the handlers, instead of duplicating them, e.g
const deleteHandler: HttpRequestHandler<forgotWhichGenerics> = async (context, request, response) => {
const uiSettingsClient = (await context.core).uiSettings.client;
return await deleteFromRequest(uiSettingsClient, context, request, response);
}
if (publicApiEnabled) {
router.delete({ path: '/api/kibana/settings/{key}', validate }, deleteHandler);
}
router.delete({ path: '/internal/kibana/global_settings/{key}', validate, options: { access: 'internal' } }, deleteHandler)
Or we decide that the code may diverge, in which case the registration should be fully dissociated, with an individual file for the public and one for the internal API.
Given we decided to go the "public + internal" way in case we may want to make the APIs diverge, I would go with later.
We can for example have two folders:
packages/core/ui-settings/core-ui-settings-server-internal/src/routes/public
packages/core/ui-settings/core-ui-settings-server-internal/src/routes/internal
Or, what we sometimes do for Core routes:
packages/core/ui-settings/core-ui-settings-server-internal/src/routes/
<- public routespackages/core/ui-settings/core-ui-settings-server-internal/src/routes/internal
<- internal routes
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 agree that separating the public and the internal routes in different files is the better option given what we discussed about potentially evolving the public routes in the future.
I took the Core routes approach for structuring the files (having public routes in /src/routes
and internal ones in /src/routes/internal
).
registerDeleteRoute(router); | ||
registerSetRoute(router); | ||
registerSetManyRoute(router); | ||
export function registerRoutes(router: InternalUiSettingsRouter, publicApiEnabled: boolean = true) { |
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.
publicApiEnabled
being optional is misleading and potentially error-prone. Just make the option mandatory and adapt existing usages (if not done already)
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 argument is no longer needed after separating the public from the internal routes in different files.
packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_config.ts
Show resolved
Hide resolved
if (config.hasOwnProperty('publicApiEnabled')) { | ||
registerRoutes( | ||
http.createRouter<InternalUiSettingsRequestHandlerContext>(''), | ||
config.publicApiEnabled | ||
); | ||
} else { | ||
registerRoutes(http.createRouter<InternalUiSettingsRequestHandlerContext>('')); | ||
} |
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.
NIT: unnecessary duplication
const publicApiEnabled = config.hasOwnProperty('publicApiEnabled') && config.publicApiEnabled === true;
registerRoutes(
http.createRouter<InternalUiSettingsRequestHandlerContext>(''),
publicApiEnabled
);
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.
Sure, I refactored these lines of code, but I don't think the condition config.hasOwnProperty('publicApiEnabled') && config.publicApiEnabled === true
would work for self-managed where this would evaluate to false since we don't have the publicApiEnabled
setting configured, so I changed this logic a bit.
describe('set', () => { | ||
it('validates value', async () => { | ||
const response = await request | ||
.post(root, '/api/kibana/settings/custom') | ||
.post(root, '/internal/kibana/settings/custom') | ||
.send({ value: 100 }) | ||
.expect(400); | ||
|
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.
We gonna need proper test coverage for the public routes too. Those tests needs to be running against the public routes (duplicating them is fine)
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.
Sure, I added a duplicate set of tests for both public and internal routes.
Pinging @elastic/apm-ui (Team:APM) |
Pinging @elastic/fleet (Team:Fleet) |
@elasticmachine merge upstream |
Thanks a lot for the review @pgayvallet! I made the changes that you suggested and left a couple of comments. Let me know if any additional changes are needed. |
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Page load bundle
Unknown metric groupsESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: cc @ElenaStoeva |
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.
LGTM, thanks for the changes!
@elastic/apm-ui and @elastic/security-solution, can you please verify that, with these changes, your plugins work as expected in self-managed and serverless environment? |
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.
apm changes lgtm
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.
packages/kbn-test
LGTM
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.
Changes doesn't impact security_solution functionality. Could you please clarify why do we need to switch to internal APIs for the self-managed tests you've changed in security_solution?
Thanks a lot for the review @YulNaumenko! The internal routes are intended for use by the browser-side clients in both serverless and self-managed (sorry if that wasn't clear from the PR description). This is why I replaced all usages of the public routes across Kibana with the internal ones. The public API is intended for use by the user and will only be available in self-managed. Also, it may be changed or even removed in the future. |
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.
Appex-QA changes LGTM
Partially addresses #159590
Summary
This PR adds an an internal uiSettings API that is a duplicate of the public API and is intended for use by the browser-side uiSettings client.
The PR also adds a config settings that is configured in serverless context only and exposes the public uiSettings routes based on the value of this setting (it defaults to false since we don't want to expose the public routes in serverless).
How to test:
I. Verify that in serverless the internal routes are exposed but the public ones aren't:
yarn es snapshot
and Kibana withyarn serverless-{mode}
where{mode}
can bees
,oblt
, orsecurity
(the public routes should be disabled for all projects).curl --user elastic:changeme 'http://localhost:5601/zhb/api/kibana/settings' -X 'GET'
should return{"statusCode":404,"error":"Not Found","message":"Not Found"}
.curl --user elastic:changeme 'http://localhost:5601/zhb/internal/kibana/settings' -X 'GET'
should return{"settings":{"buildNum":{"userValue":9007199254740991},"isDefaultIndexMigrated":{"userValue":true},"defaultRoute":{"isOverridden":true,"userValue":"/app/elasticsearch"}}}
II. Verify that the both public and internal routes are exposed in self-managed:
yarn es snapshot
and Kibana withyarn start
curl --user elastic:changeme 'http://localhost:5601/zhb/api/kibana/settings' -X 'GET'
should return{"settings":{"buildNum":{"userValue":9007199254740991},"isDefaultIndexMigrated":{"userValue":true}}}
curl --user elastic:changeme 'http://localhost:5601/zhb/internal/kibana/settings' -X 'GET'
should return{"settings":{"buildNum":{"userValue":9007199254740991},"isDefaultIndexMigrated":{"userValue":true}}}
III. Verify that the plugins/services that consume the internal uiSettings endpoints work as expected in both self-managed and serverless environment.
For maintainers