-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Migrate Management views to Kibana Platform plugin #53880
Conversation
Pinging @elastic/kibana-security (Team:Security) |
@@ -1,23 +0,0 @@ | |||
/* |
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.
note: we don't use any common mode in the legacy plugin anymore.
@@ -15,3 +15,6 @@ $secFormWidth: 460px; | |||
// Public views | |||
@import './views/index'; | |||
|
|||
// Styles of Kibana Platform plugin | |||
@import '../../../../plugins/security/public/index'; |
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.
note: looks like it's the only way to import style from platform plugin right now.
x-pack/plugins/security/kibana.json
Outdated
@@ -3,7 +3,7 @@ | |||
"version": "8.0.0", | |||
"kibanaVersion": "kibana", | |||
"configPath": ["xpack", "security"], | |||
"requiredPlugins": ["features", "licensing"], | |||
"requiredPlugins": ["data", "features", "home", "licensing", "management"], |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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 think home can be listed as an optional dependency. We're treating it that way for the Spaces plugin, so it would at least be consistent between our two main plugins.
++, it makes sense, will do (even though Kibana can't start without home
right now since legacy Kibana plugin assumes that home
is always present 🙈 , I don't think it's correct @TinaHeiligers?).
Disabling data will likely cause most of Kibana itself to become unusable in the future...
Yeah, and looking at its name it feels like it's a some sort of a fundamental plugin and I can't think of reason why user would want to disable it.
For management -- a lot of what the Security plugin has to offer is done via its Management screens, but I could see certain customers/users wanting to disable management, but still take advantage of our security features. They could, for example, manage their users and roles via our API, while still allowing users to authenticate and use Kibana normally. I think our ideal answer would be to use Feature Controls to disable management features, but that's not a reality for us yet (#35965)
That's an interesting thought, and management
is clear "domain" that can potentially be disabled. It costs nothing for us to make it optional - let's try (same story here though - Kibana just fails if management
is disabled - that's bad and we should change that all or nothing
behaviour and enforce during review).
1ff6eda
to
792f460
Compare
@@ -1,3 +0,0 @@ | |||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white"> |
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.
note: looks like a legacy we don't need anymore
@@ -1,141 +0,0 @@ | |||
<ng-form name="changePasswordForm"> |
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.
note: looks like a legacy we don't need anymore
@@ -4,6 +4,7 @@ | |||
* you may not use this file except in compliance with the Elastic License. | |||
*/ | |||
|
|||
import _, { get } from 'lodash'; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
http.get('/api/features').then( | ||
fetchedFeatures => setFeatures(fetchedFeatures), | ||
(err: IHttpFetchError) => { | ||
// TODO: This check can be removed once all of these `resolve` entries are moved out of Angular and into the React app. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@@ -66,7 +66,7 @@ export function getEditRoleBreadcrumbs($route: Record<string, any>) { | |||
|
|||
export function getCreateRoleBreadcrumbs() { | |||
return [ | |||
...getUsersBreadcrumbs(), | |||
...getRolesBreadcrumbs(), |
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.
note: looks like it was just a typo....
@@ -0,0 +1,2 @@ | |||
@import './edit_role/index'; | |||
@import './edit_user/index'; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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.
Did a first pass, and this is looking good! I think the generalizations you put in place will suit the role mappings UI as well
return spaces; | ||
} | ||
|
||
function useFeatures(http: HttpStart, fatalErrors: FatalErrorsSetup) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
return; | ||
} | ||
|
||
// `getCurrentUser` will reject if there is no authenticated user, so we prevent them from |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
const apiKeysUrl = '/internal/security/api_key'; | ||
|
||
export class APIKeysAPIClient { | ||
constructor(private readonly http: HttpStart) {} |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
} | ||
} | ||
|
||
private subscribeToLicenseChanges(management: LegacyManagementStart) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
import routes from 'ui/routes'; | ||
import { getApiKeysBreadcrumbs } from './breadcrumbs'; | ||
|
||
if (npStart.plugins.security.__legacyCompat.management) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@@ -4,51 +4,50 @@ | |||
* you may not use this file except in compliance with the Elastic License. | |||
*/ | |||
|
|||
import expect from '@kbn/expect'; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
import React from 'react'; | ||
import { render, unmountComponentAtNode } from 'react-dom'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { npStart } from 'ui/new_platform'; | ||
import routes from 'ui/routes'; | ||
|
||
routes.when('/account', { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
import { PersonalInfo } from './personal_info'; | ||
|
||
interface Props { | ||
securitySetup: SecurityPluginSetup; | ||
authc: AuthenticationServiceSetup; | ||
apiClient: PublicMethodsOf<UserAPIClient>; |
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.
note: we'll get rid of these PublicMethodsOf
approximately at the same time this issue is being handled in the core #54906
euiIconType: 'securityApp', | ||
}); | ||
|
||
securitySection.registerApp(UsersManagementApp.create({ authc, getStartServices })); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
if (enableStatus) { | ||
app.enable(); | ||
} else { | ||
app.disable(); |
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 probably a bug or design choice in the management
plugin, but disabling our apps does not prevent routing to them. It merely hides the link from the management side nav. If you know the link to a disabled app, or if another app links you to a disabled app, it will still render as if it's enabled. @mattkime do you know if this is intentional or not?
@azasypkin If this is intentional, then I think we still need some version of the checkLicense
toast message below that you asked about.
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.
Hmm, good catch! Having disable
that just hides doesn't feel right to me, it must be a bug or the wrong method name...
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'll help with this. This is a case where the solution during and after the transition to the new api is different.
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
jest.mock('./api_keys_grid', () => ({ |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
create({ getStartServices }: CreateParams) { | ||
return { | ||
id: this.id, | ||
order: 40, |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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 job on this! I've made it through most of the PR, and my feedback is really minor. I have some more testing I want to do yet, but so far so good!
setBreadcrumbs([ | ||
...rolesBreadcrumbs, | ||
action === 'edit' && roleName | ||
? { text: roleName, href: `#${basePath}/edit/${roleName}` } |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@@ -579,5 +582,3 @@ class EditUserPageUI extends Component<Props, State> { | |||
); | |||
} | |||
} | |||
|
|||
export const EditUserPage = injectI18n(EditUserPageUI); |
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.
🎉
setBreadcrumbs([ | ||
...usersBreadcrumbs, | ||
username | ||
? { text: username, href: `#${basePath}/edit/${username}` } |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
}); | ||
} | ||
|
||
// Home is an optional plugin, and if it's disabled we shouldn't try to fill feature catalog. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
'Protect your data and easily manage who has access to what with users and roles.', | ||
}), | ||
icon: 'securityApp', | ||
path: '/app/kibana#/management/security', |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
'Protect your data and easily manage who has access to what with users and roles.', | ||
}), | ||
icon: 'securityApp', | ||
path: '/app/kibana#/management/security', |
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 link ultimately navigates to /app/kibana#/management?section=security
, which just places the user at the root of the management application.
I'm not sure where else we'd want to put them, but we can probably just do away with the /security
portion of this URL, unless we're going to have our own landing page within management for our security offerings.
I also assume at some point that management won't live within the kibana
app. I don't think we have a functional test for this catalogue entry, so we'll want to keep track of when this happens so we can update accordingly.
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'm not sure where else we'd want to put them, but we can probably just do away with the /security portion of this URL, unless we're going to have our own landing page within management for our security offerings.
Right, I forgot to mention that we previously could set default app for the section and made users
app as default. It seems we cannot do this anymore with the NP API. I'll switch to users
URL here for now to keep existing behavior.
@mattkime can you please confirm that it's intentional that new Management API doesn't provide a way to specify default application for the section URL (e.g. previously if user navigated to #/management/security
we'd forward them to #/management/security/users
with something like this: uiRoutes.when(SECURITY_PATH, { redirectTo: USERS_PATH });
)?
I also assume at some point that management won't live within the kibana app. I don't think we have a functional test for this catalogue entry, so we'll want to keep track of when this happens so we can update accordingly.
Yeah, I see we have quite a few places in Kibana where app/kibana#/management/
is hard-coded, so I believe it's safe to assume that whoever will be changing this URL will grep for places like this or setup an automatic forwarder with deprecation warning (and announcement).
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.
can you please confirm that it's intentional that new Management API doesn't provide a way to specify default application for the section URL
Its intentional but I'm happy to have a discussion. You can implement the redirect, I don't see the importance of having it at the api level but I might be unfamiliar with your particular challenge.
setBreadcrumbs([ | ||
...roleMappingsBreadcrumbs, | ||
name | ||
? { text: name, href: `#${basePath}/edit/${name}` } |
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.
? { text: name, href: `#${basePath}/edit/${name}` } | |
? { text: name, href: `#${basePath}/edit/${encodeURIComponent(name)}` } |
await this.setCurrentUser(); | ||
} | ||
|
||
public async componentDidUpdate(prevProps: Props) { |
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.
question Is this logic needed as a result of the new routing we have to do?
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.
Yeah, when you open Edit User page and manually change username in the URL or just remove it and hit Enter
, Router logic will be triggered and for example will update breadcrumbs. But since view is already mounted we need to reload user as well.
That made me realize that we need componentDidUpdate
for Edit Role Mappings as well, I'll add it. Edit Role page is based on Hooks so it already should work properly.
title: i18n.translate('xpack.security.management.securityTitle', { | ||
defaultMessage: 'Security', | ||
}), | ||
order: 100, |
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.
note: Just noticed that ML also uses 100 🙈
… appropriate naming format for the management app object names, fix feature catalogue link, properly handle role mapping name change in Edit Role Mapping page, properly encode parameters in breadcrumbs links.
) { | ||
const [indexPatternsTitles, setIndexPatternsTitles] = useState<string[] | null>(null); | ||
useEffect(() => { | ||
indexPatterns.getTitles().then(setIndexPatternsTitles, err => fatalErrors.add(err)); |
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.
Rather than using a fatal error here, we could instead show a toast notification. That would allow us to resolve #51756. When we fail, returning an empty array should allow the app to continue functioning.
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.
Do you think we should make a distinction between 403 and the rest?
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'm torn -- checking for the 403
is more intentional, but on the other hand, this request isn't required for the page to function...
Let's check for the 403
, and use a fatal error for other failure codes. We'll have a better chance of catching a regression this way, instead of silently failing when we expected a successful response.
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.
👍
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 pending green CI and change to check for the 403
error response on index patterns. Nice work!
…en index patterns are not available.
delete kfetchError.response; | ||
return Promise.reject(kfetchError); | ||
}); | ||
return this.http.fetch(path, { method, query, body }); |
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.
note: discussed with @rudolf that's no longer necessary since BWC is maintained within HttpFetchError itself now.
@elasticmachine merge upstream |
#55136 is merged, now everything should be in place :) |
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.
👍 for Platform changes
@elasticmachine merge upstream |
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
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.
Sorry for the delay, most recent changes LGTM!
7.x/7.7.0: d57c7b7 |
In this PR I'm moving all management screens and related code to Kibana Platform plugin. Legacy plugin is only responsible for the routing part (this API will available in Kibana Platform after #52579).
Additionally I removed some legacy and not used code.
Note to reviewers: It'd be easier to review this PR commit by commit (pure move commit and then changes). Also lots of changes are just
import ... from ...
changes. The riskiest change isEdit Role
page.Blocked by:
#53768,#53620,#55136Fixes: #51756