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

Add SavedObject management section registration in core #59291

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented Mar 4, 2020

Summary

Step 1/3 of #50308
Fix #59349

  • Allow plugins to register their types management sections using the registerType API.
    This should be the last part of SO registration, allowing plugins to totally drop legacy regarding SO types.
  • Also remove the code handling the config type as a special one. the config (aka settings aka uiSettings aka advancedSettings) type is now registered from core as any other one.

Checklist

@pgayvallet pgayvallet added the Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc label Mar 4, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@pgayvallet pgayvallet added Feature:New Platform release_note:skip Skip the PR/issue when compiling release notes v7.7.0 v8.0.0 labels Mar 4, 2020
Comment on lines 299 to 302
savedObjects: {
client: SavedObjectsClientContract;
typeRegistry: ISavedObjectTypeRegistry;
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be used for the next step of the migration (migrate the server routes in new plugin). I could retrieve the registry using getStartServices, but I thought it made sense to expose it there. Tell me if I should remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me to have it here 👍

Comment on lines 299 to 304
const getImportableAndExportableTypes = () => {
return this.typeRegistry
.getAllTypes()
.map(type => type.name)
.filter(type => this.typeRegistry.isImportableAndExportable(type));
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same 'issue' than with the migrator, The (NP registered) types are not registered until the end of the setup phase, I now need an accessor to retrieve them instead of raw values.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't these routes use the context.savedObjects.typeRegistry to get this data? If so, we could just add a method to the type registry that does this filtering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I actually did that before adding the typeRegistry to the context. The routes should use the context instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, actually, the types are needed outside of the handler:

  const typeSchema = schema.string({
    validate: (type: string) => {
      if (!getSupportedTypes().includes(type)) {
        return `${type} is not exportable`;
      }
    },
  });

Guess I can move the validation in the handler's body instead.

@pgayvallet pgayvallet marked this pull request as ready for review March 4, 2020 10:49
@pgayvallet pgayvallet requested a review from a team as a code owner March 4, 2020 10:49
@joshdover
Copy link
Contributor

ack: will review today

@pgayvallet
Copy link
Contributor Author

I adapted the so management service to be aware of NP types by using the registry. This causes functional test failures caused by the issue logged here: #59349

I guess I will have to make the changes regarding the config SO type in this PR.

savedObjectsManagement(): SavedObjectsManagement;
getSavedObjectsManagement(): SavedObjectsManagement;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if not used, the d.ts definition was wrong.

Comment on lines 298 to 299
this.typeRegistry.registerType(configSavedObjectType);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm registering the config type from the so service itself. @restrry do you think it make more sense to have the type declaration in src/core/server/ui_settings and having the uiSettings service performs the registration instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I think we should. I was planning to do it on the final cleanup when we move ui settings definitions to NP https://github.com/elastic/kibana/blob/7e087633d26dfebe5cf262bbfde2cd4c29770464/src/legacy/core_plugins/kibana/ui_setting_defaults.js
but it can be done now. do you want me to create an issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do in this PR, moving the type to the ui_settings folder should be trivial

Copy link
Contributor

@mshustov mshustov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some minors. LGTM

* The icon name to display in the management table.
* If not defined, no icon will be displayed.
*/
icon?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it icon name or icon url? Applications configure URL for icon and name(?) for euiIconType

euiIconType?: string;
/**
* A URL to an image file used as an icon. Used as a fallback
* if `euiIconType` is not provided.
*/
icon?: string;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an EUI icon name.

I.E

dashboard: {
icon: 'dashboardApp',

Now is the good time to rename any of the management property. Shall I rename icon to euiIconType ?

(minor) Also my description is wrong. A default apps icon will actually be used if not present

<EuiIcon
aria-label={getSavedObjectLabel(type)}
type={object.meta.icon || 'apps'}
size="s"
/>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now is the good time to rename any of the management property. Shall I rename icon to euiIconType ?

I prefer euiIconType personally to make it explicit that it is not the same as the icon option on the AppBase type.

* Function returning the url to use to redirect to this object from the management section.
* If not defined, redirecting to the object will not be allowed.
*/
getInAppUrl?: (savedObject: SavedObject<any>) => { path: string; uiCapabilitiesPath: string };
Copy link
Contributor

@mshustov mshustov Mar 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add comments what returned values mean? uiCapabilitiesPath doesn't say much


/**
* @internal
* @deprecated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional nit: would be good to provide a reference to SavedObjectsTypeManagementDefinition as recommended substitution

.getImportableAndExportableTypes()
.map(t => t.name);
if (types) {
const invalidTypes = types.filter(t => !supportedTypes.includes(t));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: it would be easier to test if we extract this logic in a separate function out of the route handler.

@@ -144,7 +153,8 @@ describe('SavedObjectsService', () => {
};
setup.registerType(type);

expect(typeRegistryInstanceMock.registerType).toHaveBeenCalledTimes(1);
// the config type is also registered during setup
expect(typeRegistryInstanceMock.registerType).toHaveBeenCalledTimes(internalTypesCount + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this comment related to internalTypesCount and should be placed near https://github.com/elastic/kibana/pull/59291/files#diff-ae6a02eb060bb735014b535756384724R40 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. But as I'm going to move the config registration to ui_settings, this internalTypesCount is going to disappear from this file.

Comment on lines 298 to 299
this.typeRegistry.registerType(configSavedObjectType);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I think we should. I was planning to do it on the final cleanup when we move ui settings definitions to NP https://github.com/elastic/kibana/blob/7e087633d26dfebe5cf262bbfde2cd4c29770464/src/legacy/core_plugins/kibana/ui_setting_defaults.js
but it can be done now. do you want me to create an issue?

return res.badRequest({
body: {
message: `Trying to export object(s) with non-exportable types: ${invalidObjects
.map(obj => `${obj.type}-${obj.id}`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any precedence for the formatting of a list of objects in our API's? I would have expected a : instead of an - like ${obj.type}:${obj.id} but if we're using the dash somewhere else it might be better to stay consintent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No you are right, : is what should be used here. We dont use the dash anywhere.

resolutions[`${type}:${id}`] = overwrite;

hidden: false,
namespaceAgnostic: false,
mappings: {
dynamic: true as any, // TODO: check if can be switched to false, else adapt the type to allow true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we use it, but with dynamic: false we wouldn't be able to do telemetry on configuration objects which might be useful information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm too afraid to touch that value anyway, this will stay true.

Now the question is: do we want to allow plugins to register types with dynamic=true mappings? As josh suggested, we could have our own internal type representation that allow true where it's not allowed in the public SavedObjectType, however this means a lot of changes for something that can be force-casted anyway if plugins really wants to do it, so I'm leaning to just change false | 'strict' to boolean | strict. @joshdover wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we use it, but with dynamic: false we wouldn't be able to do telemetry on configuration objects which might be useful information.

I don't really think this has to be implemented as a ES query even if we did have telemetry like this. We only have one of these objects per space, per release version. I'm not sure how many spaces we support, but I can't imagine a customer ever having so many that doing this calculation in-memory would be a problem.

That said, it may not be worth doing this change right now.

so I'm leaning to just change false | 'strict' to boolean | strict

I lean towards just keeping it the way you have it (force casted) so as to not encourage plugins to use dynamic: true since it is probably never what we want or need. If a legitimate use case comes up, we can change this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, changing back to force-casting with explanatory comment

@@ -246,6 +245,46 @@ export interface SavedObjectsType {
* An optional map of {@link SavedObjectMigrationFn | migrations} to be used to migrate the type.
*/
migrations?: SavedObjectMigrationMap;
/**
* An optional {@link SavedObjectsTypeManagementDefinition | management section} definition for the type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* An optional {@link SavedObjectsTypeManagementDefinition | management section} definition for the type.
* An optional {@link SavedObjectsTypeManagementDefinition | saved objects management section} definition for the type.

Comment on lines 278 to 281
/**
* Function returning the url to use to redirect to the edition page of this object.
* If not defined, edition will not be allowed.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* Function returning the url to use to redirect to the edition page of this object.
* If not defined, edition will not be allowed.
*/
/**
* Function returning the url to use to redirect to the editing page of this object.
* If not defined, editing will not be allowed.
*/

@pgayvallet
Copy link
Contributor Author

retest

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@pgayvallet pgayvallet merged commit f1272b5 into elastic:master Mar 10, 2020
pgayvallet added a commit to pgayvallet/kibana that referenced this pull request Mar 10, 2020
* add management section to SavedObjectsType

* adapt import/export routes to get types accessor

* add documentation

* update generated doc

* update migration guide

* use request context to access exportable types

* update generated doc

* adapt SavedObjectsManagement to use the registry

* stop magical tricks about the config type, register it as any other so type.

* fix FTR assertions

* fix so_mixin tests

* register the `config` type from the uiSettings service

* nits and comments

* update generated doc

* remove true from dynamic property definition, use force-cast back for config type

* remove obsolete test comment
gmmorris added a commit to gmmorris/kibana that referenced this pull request Mar 10, 2020
* master:
  [Logs / Metrics UI] Link handling / stop page reloads (elastic#58478)
  Add SavedObject management section registration in core  (elastic#59291)
pgayvallet added a commit that referenced this pull request Mar 10, 2020
)

* add management section to SavedObjectsType

* adapt import/export routes to get types accessor

* add documentation

* update generated doc

* update migration guide

* use request context to access exportable types

* update generated doc

* adapt SavedObjectsManagement to use the registry

* stop magical tricks about the config type, register it as any other so type.

* fix FTR assertions

* fix so_mixin tests

* register the `config` type from the uiSettings service

* nits and comments

* update generated doc

* remove true from dynamic property definition, use force-cast back for config type

* remove obsolete test comment
gmmorris added a commit to gmmorris/kibana that referenced this pull request Mar 10, 2020
* master:
  Add a retry to dashboard test for a sometimes slow async operation (elastic#59600)
  [Endpoint] Sample data generator for endpoint app (elastic#58936)
  [Vis Editor] Refactoring metrics axes (elastic#59135)
  [DOCS] Changed Discover app to Discover (elastic#59769)
  [Metrics Alerts] Add support for search query and groupBy on alerts (elastic#59388)
  Enhancement - EUICodeEditor for Visualize JSON  (elastic#58679)
  [ML] Transforms: Data grid fixes. (elastic#59538)
  [SIEM] Fix and consolidate handling of error responses in the client (elastic#59438)
  [Maps] convert tooltip classes to typescript (elastic#59589)
  [ML] Functional tests - re-activate date_nanos test (elastic#59649)
  Move canvas to use NP Expressions service (elastic#58387)
  Update misc dependencies (elastic#59542)
  [Unit Testing] Configure react-testing-library queries to use Kibana's data-test-subj instead of default data-testid (elastic#59445)
  [Console] Remove unused code (elastic#59554)
  [Logs / Metrics UI] Link handling / stop page reloads (elastic#58478)
  Add SavedObject management section registration in core  (elastic#59291)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Saved Objects config type export broken on master
6 participants