[7.x] Make owner attribute required on kibana.json (#108231) (#110215)

* Make owner attribute required on kibana.json (#108231)

* make owner attribute required

* Add owner properties in more places

* add test for owner attribute

* add error check too in the test

* Fix tests

* fix tests and update docs

* wip

* More test fixes

* Fix All The Errorz

* Adding more owner attributes

* Update x-pack/test/saved_object_api_integration/common/fixtures/saved_object_test_plugin/kibana.json

Co-authored-by: Larry Gregory <lgregorydev@gmail.com>

* Update x-pack/test/ui_capabilities/common/fixtures/plugins/foo_plugin/kibana.json

Co-authored-by: Larry Gregory <lgregorydev@gmail.com>

* commeeeooonnnn

* Update docs

* soooo many kibanajsons

* adjust plugin generator to add an owner

* Add owner to the plugin generator scripts

* update snapshot

* Fix snapshot

* review updates

Co-authored-by: Larry Gregory <lgregorydev@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
# Conflicts:
#	dev_docs/tutorials/building_a_plugin.mdx
#	src/dev/code_coverage/ingest_coverage/integration_tests/fixtures/test_plugin/kibana.json
#	test/common/fixtures/plugins/coverage/kibana.json

* Update kibana.json

Add owner attribute

* Remove this json file. It was deleted.

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Stacey Gammon 2021-08-31 16:19:52 -04:00 committed by GitHub
parent 94c727cd66
commit e7dbd91d3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
99 changed files with 512 additions and 110 deletions

View file

@ -83,12 +83,8 @@ plugins/
`optionalPlugins` - [Optional] If your plugin has an optional dependency on other plugins, you must list them here by id. If any of the optional plugins are disabled or not installed, your plugin will still load, however that plugin's API contract will be undefined in the second parameter of the setup and start functions.
# <<<<<<< HEAD:dev_docs/tutorials/building_a_plugin.mdx
`requiredBundles` - [Required in certain situations] Don't worry about getting this right. The build optimizer will complain if any of these values are incorrect.
> > > > > > > b9f398875a0 (Add more information on kibana.json properties, update example plugins (#107600)):dev_docs/key_concepts/anatomy_of_a_plugin.mdx
<DocCallOut>
You don't need to declare a dependency on a plugin if you only wish to access its types.
</DocCallOut>

View file

@ -26,7 +26,7 @@ Should never be used in code outside of Core but is exported for documentation p
| [id](./kibana-plugin-core-server.pluginmanifest.id.md) | <code>PluginName</code> | Identifier of the plugin. Must be a string in camelCase. Part of a plugin public contract. Other plugins leverage it to access plugin API, navigate to the plugin, etc. |
| [kibanaVersion](./kibana-plugin-core-server.pluginmanifest.kibanaversion.md) | <code>string</code> | The version of Kibana the plugin is compatible with, defaults to "version". |
| [optionalPlugins](./kibana-plugin-core-server.pluginmanifest.optionalplugins.md) | <code>readonly PluginName[]</code> | An optional list of the other plugins that if installed and enabled \*\*may be\*\* leveraged by this plugin for some additional functionality but otherwise are not required for this plugin to work properly. |
| [owner](./kibana-plugin-core-server.pluginmanifest.owner.md) | <code>{</code><br/><code> readonly name: string;</code><br/><code> readonly githubTeam?: string;</code><br/><code> }</code> | TODO: make required once all internal plugins have this specified. |
| [owner](./kibana-plugin-core-server.pluginmanifest.owner.md) | <code>{</code><br/><code> readonly name: string;</code><br/><code> readonly githubTeam?: string;</code><br/><code> }</code> | |
| [requiredBundles](./kibana-plugin-core-server.pluginmanifest.requiredbundles.md) | <code>readonly string[]</code> | List of plugin ids that this plugin's UI code imports modules from that are not in <code>requiredPlugins</code>. |
| [requiredPlugins](./kibana-plugin-core-server.pluginmanifest.requiredplugins.md) | <code>readonly PluginName[]</code> | An optional list of the other plugins that \*\*must be\*\* installed and enabled for this plugin to function properly. |
| [server](./kibana-plugin-core-server.pluginmanifest.server.md) | <code>boolean</code> | Specifies whether plugin includes some server-side specific functionality. |

View file

@ -4,12 +4,10 @@
## PluginManifest.owner property
TODO: make required once all internal plugins have this specified.
<b>Signature:</b>
```typescript
readonly owner?: {
readonly owner: {
readonly name: string;
readonly githubTeam?: string;
};

View file

@ -1,5 +1,9 @@
{
"id": "developerExamples",
"owner": {
"name": "Kibana Core",
"githubTeam": "kibana-core"
},
"kibanaVersion": "kibana",
"version": "0.0.1",
"ui": true

View file

@ -29,8 +29,7 @@ interface Manifest {
server: boolean;
kibanaVersion: string;
version: string;
// TODO: make this required.
owner?: {
owner: {
// Internally, this should be a team name.
name: string;
// All internally owned plugins should have a github team specified that can be pinged in issues, or used to look up
@ -64,6 +63,12 @@ export function parseKibanaPlatformPlugin(manifestPath: string): KibanaPlatformP
throw new TypeError('expected new platform plugin manifest to have a string version');
}
if (!manifest.owner || typeof manifest.owner.name !== 'string') {
throw new TypeError(
`Expected plugin ${manifest.id} manifest to have an owner with name specified (${manifestPath})`
);
}
return {
directory: Path.dirname(manifestPath),
manifestPath,

View file

@ -86,8 +86,8 @@ import ${json} from './${fileName}.json';
${plugin.manifest.description ?? ''}
${
plugin.manifest.owner?.githubTeam && name
? `Contact [${name}](https://github.com/orgs/elastic/teams/${plugin.manifest.owner?.githubTeam}) for questions regarding this plugin.`
plugin.manifest.owner.githubTeam && name
? `Contact [${name}](https://github.com/orgs/elastic/teams/${plugin.manifest.owner.githubTeam}) for questions regarding this plugin.`
: name
? `Contact ${name} for questions regarding this plugin.`
: ''

View file

@ -1,7 +1,7 @@
{
"id": "pluginA",
"summary": "This an example plugin for testing the api documentation system",
"version": "kibana",
"serviceFolders": ["foo"]
}
"id": "pluginA",
"owner": { "name": "Kibana Tech Leads" },
"summary": "This an example plugin for testing the api documentation system",
"version": "kibana",
"serviceFolders": ["foo"]
}

View file

@ -1,5 +1,6 @@
{
"id": "pluginB",
"owner": { "name": "Kibana Tech Leads" },
"summary": "This an example plugin for testing the api documentation system",
"version": "kibana"
}

View file

@ -18,6 +18,9 @@ export function getKibanaPlatformPlugin(id: string, dir?: string): KibanaPlatfor
server: true,
kibanaVersion: '1',
version: '1',
owner: {
name: 'Kibana Core',
},
serviceFolders: [],
requiredPlugins: [],
requiredBundles: [],

View file

@ -2,5 +2,8 @@
"id": "bar",
"ui": true,
"requiredBundles": ["foo"],
"version": "8.0.0"
"version": "8.0.0",
"owner": {
"name": "Operations"
}
}

View file

@ -1,5 +1,8 @@
{
"id": "foo",
"owner": {
"name": "Operations"
},
"ui": true,
"version": "8.0.0"
}

View file

@ -1,4 +1,7 @@
{
"id": "baz",
"owner": {
"name": "Operations"
},
"version": "8.0.0"
}

View file

@ -1,4 +1,7 @@
{
"id": "test_baz",
"owner": {
"name": "Operations"
},
"version": "8.0.0"
}

View file

@ -1,5 +1,6 @@
{
"id": "baz",
"owner": { "name": "Operations", "githubTeam": "kibana-operations" },
"ui": true,
"version": "8.0.0"
}

View file

@ -17,6 +17,9 @@ export interface Answers {
internalLocation: string;
ui: boolean;
server: boolean;
githubTeam?: string;
ownerName: string;
description?: string;
}
export const INTERNAL_PLUGIN_LOCATIONS: Array<{ name: string; value: string }> = [
@ -49,6 +52,11 @@ export const QUESTIONS = [
default: undefined,
validate: (name: string) => (!name ? 'name is required' : true),
},
{
name: 'description',
message: 'Provide a description for your plugin.',
default: undefined,
},
{
name: 'internal',
type: 'confirm',
@ -63,6 +71,24 @@ export const QUESTIONS = [
default: INTERNAL_PLUGIN_LOCATIONS[0].value,
when: ({ internal }: Answers) => internal,
},
{
name: 'ownerName',
message: 'Who is developing and maintaining this plugin?',
default: undefined,
when: ({ internal }: Answers) => !internal,
},
{
name: 'ownerName',
message: 'What team will maintain this plugin?',
default: undefined,
when: ({ internal }: Answers) => internal,
},
{
name: 'githubTeam',
message: 'What is your gitHub team alias?',
default: undefined,
when: ({ internal }: Answers) => internal,
},
{
name: 'ui',
type: 'confirm',

View file

@ -64,6 +64,10 @@ export async function renderTemplates({
hasServer: !!answers.server,
hasUi: !!answers.ui,
ownerName: answers.ownerName,
githubTeam: answers.githubTeam,
description: answers.description,
camelCase,
snakeCase,
upperCamelCase,

View file

@ -2,6 +2,11 @@
"id": "<%= camelCase(name) %>",
"version": "1.0.0",
"kibanaVersion": "kibana",
"owner": {
"name": "<%= ownerName %>",
"githubTeam": "<%= githubTeam %>"
},
"description": "<%= description %>",
"server": <%= hasServer %>,
"ui": <%= hasUi %>,
"requiredPlugins": ["navigation"],

View file

@ -101,9 +101,14 @@ it('builds a generated plugin into a viable archive', async () => {
expect(loadJsonFile.sync(Path.resolve(TMP_DIR, 'kibana', 'fooTestPlugin', 'kibana.json')))
.toMatchInlineSnapshot(`
Object {
"description": "",
"id": "fooTestPlugin",
"kibanaVersion": "7.5.0",
"optionalPlugins": Array [],
"owner": Object {
"githubTeam": "",
"name": "",
},
"requiredPlugins": Array [
"navigation",
],

View file

@ -24,6 +24,9 @@ function createManifest(
requiredPlugins: required,
optionalPlugins: optional,
requiredBundles: [],
owner: {
name: 'foo',
},
} as DiscoveredPlugin;
}

View file

@ -64,6 +64,10 @@ function createManifest(
requiredPlugins: required,
optionalPlugins: optional,
requiredBundles: [],
owner: {
name: 'Core',
githubTeam: 'kibana-core',
},
};
}

View file

@ -65,7 +65,7 @@ test('return error when manifest content is not a valid JSON', async () => {
test('return error when plugin id is missing', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ version: 'some-version' })));
cb(null, Buffer.from(JSON.stringify({ version: 'some-version', owner: { name: 'foo' } })));
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -77,7 +77,12 @@ test('return error when plugin id is missing', async () => {
test('return error when plugin id includes `.` characters', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'some.name', version: 'some-version' })));
cb(
null,
Buffer.from(
JSON.stringify({ id: 'some.name', version: 'some-version', owner: { name: 'foo' } })
)
);
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -90,7 +95,12 @@ test('return error when plugin id includes `.` characters', async () => {
test('return error when pluginId is not in camelCase format', async () => {
expect.assertions(1);
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'some_name', version: 'kibana', server: true })));
cb(
null,
Buffer.from(
JSON.stringify({ id: 'some_name', version: 'kibana', server: true, owner: { name: 'foo' } })
)
);
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -102,7 +112,7 @@ test('return error when pluginId is not in camelCase format', async () => {
test('return error when plugin version is missing', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'someId' })));
cb(null, Buffer.from(JSON.stringify({ id: 'someId', owner: { name: 'foo' } })));
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -114,7 +124,10 @@ test('return error when plugin version is missing', async () => {
test('return error when plugin expected Kibana version is lower than actual version', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'someId', version: '6.4.2' })));
cb(
null,
Buffer.from(JSON.stringify({ id: 'someId', version: '6.4.2', owner: { name: 'foo' } }))
);
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -128,7 +141,14 @@ test('return error when plugin expected Kibana version cannot be interpreted as
mockReadFile.mockImplementation((path, cb) => {
cb(
null,
Buffer.from(JSON.stringify({ id: 'someId', version: '1.0.0', kibanaVersion: 'non-sem-ver' }))
Buffer.from(
JSON.stringify({
id: 'someId',
version: '1.0.0',
kibanaVersion: 'non-sem-ver',
owner: { name: 'foo' },
})
)
);
});
@ -141,7 +161,12 @@ test('return error when plugin expected Kibana version cannot be interpreted as
test('return error when plugin config path is not a string', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.0', configPath: 2 })));
cb(
null,
Buffer.from(
JSON.stringify({ id: 'someId', version: '7.0.0', configPath: 2, owner: { name: 'foo' } })
)
);
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -155,7 +180,14 @@ test('return error when plugin config path is an array that contains non-string
mockReadFile.mockImplementation((path, cb) => {
cb(
null,
Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.0', configPath: ['config', 2] }))
Buffer.from(
JSON.stringify({
id: 'someId',
version: '7.0.0',
configPath: ['config', 2],
owner: { name: 'foo' },
})
)
);
});
@ -168,7 +200,10 @@ test('return error when plugin config path is an array that contains non-string
test('return error when plugin expected Kibana version is higher than actual version', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.1' })));
cb(
null,
Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.1', owner: { name: 'foo' } }))
);
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -180,7 +215,10 @@ test('return error when plugin expected Kibana version is higher than actual ver
test('return error when both `server` and `ui` are set to `false` or missing', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.0' })));
cb(
null,
Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.0', owner: { name: 'foo' } }))
);
});
await expect(parseManifest(pluginPath, packageInfo)).rejects.toMatchObject({
@ -192,7 +230,15 @@ test('return error when both `server` and `ui` are set to `false` or missing', a
mockReadFile.mockImplementation((path, cb) => {
cb(
null,
Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.0', server: false, ui: false }))
Buffer.from(
JSON.stringify({
id: 'someId',
version: '7.0.0',
server: false,
ui: false,
owner: { name: 'foo' },
})
)
);
});
@ -214,6 +260,7 @@ test('return error when manifest contains unrecognized properties', async () =>
server: true,
unknownOne: 'one',
unknownTwo: true,
owner: { name: 'foo' },
})
)
);
@ -237,6 +284,7 @@ test('returns error when manifest contains unrecognized `type`', async () => {
kibanaVersion: '7.0.0',
type: 'unknown',
server: true,
owner: { name: 'foo' },
})
)
);
@ -252,7 +300,12 @@ test('returns error when manifest contains unrecognized `type`', async () => {
describe('configPath', () => {
test('falls back to plugin id if not specified', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'plugin', version: '7.0.0', server: true })));
cb(
null,
Buffer.from(
JSON.stringify({ id: 'plugin', version: '7.0.0', server: true, owner: { name: 'foo' } })
)
);
});
const manifest = await parseManifest(pluginPath, packageInfo);
@ -261,7 +314,12 @@ describe('configPath', () => {
test('falls back to plugin id in snakeCase format', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.0', server: true })));
cb(
null,
Buffer.from(
JSON.stringify({ id: 'someId', version: '7.0.0', server: true, owner: { name: 'foo' } })
)
);
});
const manifest = await parseManifest(pluginPath, packageInfo);
@ -273,7 +331,13 @@ describe('configPath', () => {
cb(
null,
Buffer.from(
JSON.stringify({ id: 'someId', configPath: 'somePath', version: '7.0.0', server: true })
JSON.stringify({
id: 'someId',
configPath: 'somePath',
version: '7.0.0',
server: true,
owner: { name: 'foo' },
})
)
);
});
@ -287,7 +351,13 @@ describe('configPath', () => {
cb(
null,
Buffer.from(
JSON.stringify({ id: 'someId', configPath: ['somePath'], version: '7.0.0', server: true })
JSON.stringify({
id: 'someId',
configPath: ['somePath'],
version: '7.0.0',
server: true,
owner: { name: 'foo' },
})
)
);
});
@ -299,7 +369,12 @@ describe('configPath', () => {
test('set defaults for all missing optional fields', async () => {
mockReadFile.mockImplementation((path, cb) => {
cb(null, Buffer.from(JSON.stringify({ id: 'someId', version: '7.0.0', server: true })));
cb(
null,
Buffer.from(
JSON.stringify({ id: 'someId', version: '7.0.0', server: true, owner: { name: 'foo' } })
)
);
});
await expect(parseManifest(pluginPath, packageInfo)).resolves.toEqual({
@ -313,6 +388,7 @@ test('set defaults for all missing optional fields', async () => {
requiredBundles: [],
server: true,
ui: false,
owner: { name: 'foo' },
});
});
@ -330,6 +406,7 @@ test('return all set optional fields as they are in manifest', async () => {
requiredPlugins: ['some-required-plugin', 'some-required-plugin-2'],
optionalPlugins: ['some-optional-plugin'],
ui: true,
owner: { name: 'foo' },
})
)
);
@ -346,6 +423,7 @@ test('return all set optional fields as they are in manifest', async () => {
requiredPlugins: ['some-required-plugin', 'some-required-plugin-2'],
server: false,
ui: true,
owner: { name: 'foo' },
});
});
@ -361,6 +439,7 @@ test('return manifest when plugin expected Kibana version matches actual version
kibanaVersion: '7.0.0-alpha2',
requiredPlugins: ['some-required-plugin'],
server: true,
owner: { name: 'foo' },
})
)
);
@ -377,6 +456,7 @@ test('return manifest when plugin expected Kibana version matches actual version
requiredBundles: [],
server: true,
ui: false,
owner: { name: 'foo' },
});
});
@ -392,6 +472,7 @@ test('return manifest when plugin expected Kibana version is `kibana`', async ()
requiredPlugins: ['some-required-plugin'],
server: true,
ui: true,
owner: { name: 'foo' },
})
)
);
@ -408,5 +489,6 @@ test('return manifest when plugin expected Kibana version is `kibana`', async ()
requiredBundles: [],
server: true,
ui: true,
owner: { name: 'foo' },
});
});

View file

@ -121,6 +121,15 @@ export async function parseManifest(
);
}
if (!manifest.owner || !manifest.owner.name || typeof manifest.owner.name !== 'string') {
throw PluginDiscoveryError.invalidManifest(
manifestPath,
new Error(
`Plugin manifest for "${manifest.id}" must contain an "owner" property, which includes a nested "name" property.`
)
);
}
if (manifest.configPath !== undefined && !isConfigPath(manifest.configPath)) {
throw PluginDiscoveryError.invalidManifest(
manifestPath,
@ -201,7 +210,7 @@ export async function parseManifest(
ui: includesUiPlugin,
server: includesServerPlugin,
extraPublicDirs: manifest.extraPublicDirs,
owner: manifest.owner,
owner: manifest.owner!,
description: manifest.description,
};
}

View file

@ -30,10 +30,23 @@ const Plugins = {
'kibana.json': 'not-json',
}),
incomplete: () => ({
'kibana.json': JSON.stringify({ version: '1' }),
'kibana.json': JSON.stringify({
version: '1',
owner: {
name: 'foo',
githubTeam: 'foo',
},
}),
}),
incompatible: () => ({
'kibana.json': JSON.stringify({ id: 'plugin', version: '1' }),
'kibana.json': JSON.stringify({
id: 'plugin',
version: '1',
owner: {
name: 'foo',
githubTeam: 'foo',
},
}),
}),
incompatibleType: (id: string) => ({
'kibana.json': JSON.stringify({
@ -42,6 +55,10 @@ const Plugins = {
kibanaVersion: '1.2.3',
type: 'evenEarlierThanPreboot',
server: true,
owner: {
name: 'foo',
githubTeam: 'foo',
},
}),
}),
missingManifest: () => ({}),
@ -51,6 +68,17 @@ const Plugins = {
content: JSON.stringify({ id: 'plugin', version: '1' }),
}),
}),
missingOwnerAttribute: () => ({
'kibana.json': JSON.stringify({
id: 'foo',
configPath: ['plugins', 'foo'],
version: '1',
kibanaVersion: '1.2.3',
requiredPlugins: [],
optionalPlugins: [],
server: true,
}),
}),
valid: (id: string) => ({
'kibana.json': JSON.stringify({
id,
@ -60,6 +88,10 @@ const Plugins = {
requiredPlugins: [],
optionalPlugins: [],
server: true,
owner: {
name: 'foo',
githubTeam: 'foo',
},
}),
}),
validPreboot: (id: string) => ({
@ -72,6 +104,10 @@ const Plugins = {
requiredPlugins: [],
optionalPlugins: [],
server: true,
owner: {
name: 'foo',
githubTeam: 'foo',
},
}),
}),
};
@ -182,6 +218,7 @@ describe('plugins discovery system', () => {
[`${KIBANA_ROOT}/src/plugins/plugin_c`]: Plugins.incompatible(),
[`${KIBANA_ROOT}/src/plugins/plugin_d`]: Plugins.incompatibleType('pluginD'),
[`${KIBANA_ROOT}/src/plugins/plugin_ad`]: Plugins.missingManifest(),
[`${KIBANA_ROOT}/src/plugins/plugin_e`]: Plugins.missingOwnerAttribute(),
},
{ createCwd: false }
);
@ -196,21 +233,40 @@ describe('plugins discovery system', () => {
)
.toPromise();
expect(errors).toEqual(
expect.arrayContaining([
`Error: Unexpected token o in JSON at position 1 (invalid-manifest, ${manifestPath(
'plugin_a'
)})`,
`Error: Plugin manifest must contain an "id" property. (invalid-manifest, ${manifestPath(
'plugin_b'
)})`,
`Error: Plugin "plugin" is only compatible with Kibana version "1", but used Kibana version is "1.2.3". (incompatible-version, ${manifestPath(
'plugin_c'
)})`,
`Error: The "type" in manifest for plugin "pluginD" is set to "evenEarlierThanPreboot", but it should either be "standard" or "preboot". (invalid-manifest, ${manifestPath(
'plugin_d'
)})`,
])
expect(errors).toContain(
`Error: Unexpected token o in JSON at position 1 (invalid-manifest, ${manifestPath(
'plugin_a'
)})`
);
expect(errors).toContain(
`Error: Plugin manifest must contain an "id" property. (invalid-manifest, ${manifestPath(
'plugin_b'
)})`
);
expect(errors).toContain(
`Error: Plugin "plugin" is only compatible with Kibana version "1", but used Kibana version is "1.2.3". (incompatible-version, ${manifestPath(
'plugin_c'
)})`
);
expect(errors).toContain(
`Error: The "type" in manifest for plugin "pluginD" is set to "evenEarlierThanPreboot", but it should either be "standard" or "preboot". (invalid-manifest, ${manifestPath(
'plugin_d'
)})`
);
expect(errors).toContain(
`Error: The "type" in manifest for plugin "pluginD" is set to "evenEarlierThanPreboot", but it should either be "standard" or "preboot". (invalid-manifest, ${manifestPath(
'plugin_d'
)})`
);
expect(errors).toContain(
`Error: Plugin manifest for "foo" must contain an "owner" property, which includes a nested "name" property. (invalid-manifest, ${manifestPath(
'plugin_e'
)})`
);
});

View file

@ -42,6 +42,7 @@ describe('PluginsService', () => {
configPath = [path],
server = true,
ui = true,
owner = { name: 'foo' },
}: {
path?: string;
disabled?: boolean;
@ -54,6 +55,7 @@ describe('PluginsService', () => {
configPath?: ConfigPath;
server?: boolean;
ui?: boolean;
owner?: { name: string };
}
): PluginWrapper => {
return new PluginWrapper({
@ -69,6 +71,7 @@ describe('PluginsService', () => {
optionalPlugins,
server,
ui,
owner,
},
opaqueId: Symbol(id),
initializerContext: { logger } as any,

View file

@ -56,6 +56,7 @@ function createPluginManifest(manifestProps: Partial<PluginManifest> = {}): Plug
requiredBundles: [],
server: true,
ui: true,
owner: { name: 'Core' },
...manifestProps,
};
}

View file

@ -38,6 +38,10 @@ function createPluginManifest(manifestProps: Partial<PluginManifest> = {}): Plug
optionalPlugins: ['some-optional-dep'],
server: true,
ui: true,
owner: {
name: 'Core',
githubTeam: 'kibana-core',
},
...manifestProps,
};
}

View file

@ -101,6 +101,10 @@ const createPlugin = (
requiredBundles,
optionalPlugins,
server,
owner: {
name: 'Core',
githubTeam: 'kibana-core',
},
ui,
},
opaqueId: Symbol(id),

View file

@ -55,6 +55,7 @@ function createPlugin(
requiredBundles: [],
server,
ui,
owner: { name: 'foo' },
},
opaqueId: Symbol(id),
initializerContext: { logger } as any,

View file

@ -226,10 +226,7 @@ export interface PluginManifest {
*/
readonly serviceFolders?: readonly string[];
/**
* TODO: make required once all internal plugins have this specified.
*/
readonly owner?: {
readonly owner: {
/**
* The name of the team that currently owns this plugin.
*/

View file

@ -1533,7 +1533,8 @@ export interface PluginManifest {
readonly id: PluginName;
readonly kibanaVersion: string;
readonly optionalPlugins: readonly PluginName[];
readonly owner?: {
// (undocumented)
readonly owner: {
readonly name: string;
readonly githubTeam?: string;
};
@ -2922,9 +2923,9 @@ export const validBodyOutput: readonly ["data", "stream"];
//
// src/core/server/elasticsearch/client/types.ts:94:7 - (ae-forgotten-export) The symbol "Explanation" needs to be exported by the entry point index.d.ts
// src/core/server/http/router/response.ts:301:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:380:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:380:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:383:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:489:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create"
// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:380:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:486:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create"
```

View file

@ -0,0 +1,10 @@
{
"id": "codeCoverageTestPlugin",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "kibana",
"server": true,
"ui": false
}

View file

@ -1,5 +1,9 @@
{
"id": "newsfeedFixtures",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "kibana",
"server": true,
"ui": false

View file

@ -1,16 +1,13 @@
{
"id": "kbnTpRunPipeline",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"requiredPlugins": [
"data",
"savedObjects",
"kibanaUtils",
"expressions"
],
"requiredPlugins": ["data", "savedObjects", "kibanaUtils", "expressions"],
"server": true,
"ui": true,
"requiredBundles": [
"inspector"
]
"requiredBundles": ["inspector"]
}

View file

@ -1,5 +1,9 @@
{
"id": "appLinkTest",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": false,

View file

@ -1,5 +1,9 @@
{
"id": "coreAppStatus",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["core_app_status"],

View file

@ -1,5 +1,9 @@
{
"id": "coreHistoryBlock",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": false,

View file

@ -1,6 +1,10 @@
{
"id": "coreHttp",
"version": "0.0.1",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"kibanaVersion": "kibana",
"configPath": ["core_http"],
"server": true,

View file

@ -2,6 +2,10 @@
"id": "corePluginA",
"version": "0.0.1",
"kibanaVersion": "kibana",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"configPath": ["core_plugin_a"],
"server": true,
"ui": true

View file

@ -1,6 +1,10 @@
{
"id": "corePluginAppleave",
"version": "0.0.1",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"kibanaVersion": "kibana",
"configPath": ["core_plugin_appleave"],
"server": false,

View file

@ -2,6 +2,10 @@
"id": "corePluginB",
"version": "0.0.1",
"kibanaVersion": "kibana",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"configPath": ["core_plugin_b"],
"server": true,
"ui": true,

View file

@ -1,5 +1,9 @@
{
"id": "corePluginChromeless",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["core_plugin_chromeless"],

View file

@ -1,5 +1,9 @@
{
"id": "corePluginDeepLinks",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["core_plugin_deep_links"],

View file

@ -1,6 +1,10 @@
{
"id": "corePluginDeprecations",
"version": "0.0.1",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"kibanaVersion": "kibana",
"configPath": ["corePluginDeprecations"],
"server": true,

View file

@ -1,5 +1,9 @@
{
"id": "corePluginExecutionContext",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["core_plugin_execution_context"],

View file

@ -1,5 +1,9 @@
{
"id": "corePluginHelpmenu",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["core_plugin_helpmenu"],

View file

@ -1,5 +1,9 @@
{
"id": "corePluginRouteTimeouts",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["core_plugin_route_timeouts"],

View file

@ -1,5 +1,9 @@
{
"id": "corePluginStaticAssets",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": false,

View file

@ -1,14 +1,12 @@
{
"id": "coreProviderPlugin",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"optionalPlugins": [
"corePluginA",
"corePluginB",
"coreHttp",
"licensing",
"globalSearchTest"
],
"optionalPlugins": ["corePluginA", "corePluginB", "coreHttp", "licensing", "globalSearchTest"],
"server": false,
"ui": true
}

View file

@ -1,5 +1,9 @@
{
"id": "dataSearchPlugin",
"owner": {
"name": "App Services",
"githubTeam": "kibana-app-services"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["data_search_test_plugin"],

View file

@ -1,5 +1,9 @@
{
"id": "elasticsearchClientPlugin",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,9 @@
{
"id": "kbnSamplePanelAction",
"owner": {
"name": "App Services",
"githubTeam": "kibana-app-services"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["kbn_sample_panel_action"],

View file

@ -1,5 +1,9 @@
{
"id": "kbnTopNav",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["kbn_top_nav"],

View file

@ -6,10 +6,7 @@
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"requiredPlugins": [
"expressions",
"visualizations"
],
"requiredPlugins": ["expressions", "visualizations"],
"server": false,
"ui": true
}

View file

@ -1,5 +1,9 @@
{
"id": "managementTestPlugin",
"owner": {
"name": "App Services",
"githubTeam": "kibana-app-services"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["management_test_plugin"],

View file

@ -1,5 +1,9 @@
{
"id": "renderingPlugin",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["rendering_plugin"],

View file

@ -1,5 +1,9 @@
{
"id": "savedObjectExportTransforms",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["saved_object_export_transforms"],

View file

@ -1,5 +1,9 @@
{
"id": "savedObjectImportWarnings",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["saved_object_import_warnings"],

View file

@ -1,5 +1,9 @@
{
"id": "savedObjectsHiddenType",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["saved_objects_hidden_type"],

View file

@ -1,5 +1,9 @@
{
"id": "sessionNotifications",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["session_notifications"],

View file

@ -1,5 +1,9 @@
{
"id": "telemetryTestPlugin",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["telemetryTestPlugin"],

View file

@ -1,5 +1,9 @@
{
"id": "uiSettingsPlugin",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["ui_settings_plugin"],

View file

@ -1,5 +1,9 @@
{
"id": "usageCollectionTestPlugin",
"owner": {
"name": "Core",
"githubTeam": "kibana-core"
},
"version": "0.0.1",
"kibanaVersion": "kibana",
"configPath": ["usageCollectionTestPlugin"],

View file

@ -1,5 +1,6 @@
{
"id": "statusPluginA",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,6 @@
{
"id": "statusPluginB",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,9 @@
{
"id": "code",
"owner": {
"name": "Kibana Operations",
"githubTeam": "kibana-operations"
},
"version": "8.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "code"],

View file

@ -1,23 +1,13 @@
{
"id": "dashboardEnhanced",
"owner": {
"name": "App Services",
"githubTeam": "kibana-app-services"
},
"version": "kibana",
"server": true,
"ui": true,
"configPath": [
"xpack",
"dashboardEnhanced"
],
"requiredPlugins": [
"dashboard",
"data",
"embeddable",
"share",
"uiActionsEnhanced"
],
"requiredBundles": [
"embeddable",
"embeddableEnhanced",
"kibanaReact",
"kibanaUtils"
]
"configPath": ["xpack", "dashboardEnhanced"],
"requiredPlugins": ["dashboard", "data", "embeddable", "share", "uiActionsEnhanced"],
"requiredBundles": ["embeddable", "embeddableEnhanced", "kibanaReact", "kibanaUtils"]
}

View file

@ -3,7 +3,7 @@
"version": "8.0.0",
"kibanaVersion": "kibana",
"owner": {
"owner": "Stack Monitoring",
"name": "Stack Monitoring",
"githubTeam": "stack-monitoring-ui"
},
"configPath": ["monitoring"],

View file

@ -1,5 +1,9 @@
{
"id": "ruleRegistry",
"owner": {
"name": "RAC",
"githubTeam": "rac"
},
"version": "8.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "ruleRegistry"],

View file

@ -1,5 +1,9 @@
{
"id": "aadFixtures",
"owner": {
"name": "Alerting Services",
"githubTeam": "kibana-alerting-services"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,5 +1,9 @@
{
"id": "actionsSimulators",
"owner": {
"name": "Alerting Services",
"githubTeam": "kibana-alerting-services"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,10 +1,14 @@
{
"id": "alertsFixtures",
"owner": {
"name": "Alerting Services",
"githubTeam": "kibana-alerting-services"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],
"requiredPlugins": ["taskManager", "features", "actions", "alerting", "encryptedSavedObjects"],
"optionalPlugins": ["security", "spaces"],
"optionalPlugins": ["security", "spaces"],
"server": true,
"ui": false
}

View file

@ -1,5 +1,9 @@
{
"id": "alertsRestrictedFixtures",
"owner": {
"name": "Alerting Services",
"githubTeam": "kibana-alerting-services"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,5 +1,9 @@
{
"id": "taskManagerFixture",
"owner": {
"name": "Alerting Services",
"githubTeam": "kibana-alerting-services"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,10 +1,14 @@
{
"id": "casesClientUserFixture",
"owner": {
"githubTeam": "security-threat-hunting",
"name": "Security Solution Threat Hunting"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],
"requiredPlugins": ["features", "cases"],
"optionalPlugins": ["security", "spaces"],
"optionalPlugins": ["security", "spaces"],
"server": true,
"ui": false
}

View file

@ -1,10 +1,14 @@
{
"id": "observabilityFixtures",
"owner": {
"githubTeam": "security-threat-hunting",
"name": "Security Solution Threat Hunting"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],
"requiredPlugins": ["features", "cases"],
"optionalPlugins": ["security", "spaces"],
"optionalPlugins": ["security", "spaces"],
"server": true,
"ui": false
}

View file

@ -1,10 +1,14 @@
{
"id": "securitySolutionFixtures",
"owner": {
"githubTeam": "security-threat-hunting",
"name": "Security Solution Threat Hunting"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],
"requiredPlugins": ["features", "cases"],
"optionalPlugins": ["security", "spaces"],
"optionalPlugins": ["security", "spaces"],
"server": true,
"ui": false
}

View file

@ -1,5 +1,6 @@
{
"id": "samlProviderPlugin",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,6 @@
{
"id": "eso",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "8.0.0",
"kibanaVersion": "kibana",
"requiredPlugins": ["encryptedSavedObjects", "spaces"],

View file

@ -1,5 +1,6 @@
{
"id": "kibanaCorsTest",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["test", "cors"],

View file

@ -1,5 +1,6 @@
{
"id": "iframeEmbedded",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,6 @@
{
"id": "alertingFixture",
"owner": { "name": "Alerting Services", "githubTeam": "kibana-alerting-services" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,5 +1,6 @@
{
"id": "testFeatureUsage",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "kibana",
"server": false,
"ui": true,

View file

@ -1,5 +1,6 @@
{
"id": "elasticsearchClientXpack",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,9 @@
{
"id": "eventLogFixture",
"owner": {
"name": "Kibana Alerting",
"githubTeam": "kibana-alerting-services"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,5 +1,9 @@
{
"id": "featureUsageTest",
"owner": {
"name": "Platform Security",
"githubTeam": "kibana-security"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "feature_usage_test"],

View file

@ -1,5 +1,9 @@
{
"id": "sampleTaskPlugin",
"owner": {
"name": "Alerting Services",
"githubTeam": "kibana-alerting-services"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,5 +1,6 @@
{
"id": "taskManagerPerformance",
"owner": { "name": "Alerting Services", "githubTeam": "kibana-alerting-services" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],

View file

@ -1,5 +1,6 @@
{
"id": "globalSearchTest",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "global_search_test"],

View file

@ -1,14 +1,14 @@
{
"id": "resolverTest",
"owner": {
"githubTeam": "security-threat-hunting",
"name": "Security Solution Threat Hunting"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "resolverTest"],
"requiredPlugins": [
"securitySolution"
],
"requiredBundles": [
"kibanaReact"
],
"requiredPlugins": ["securitySolution"],
"requiredBundles": ["kibanaReact"],
"server": false,
"ui": true
}

View file

@ -1,5 +1,6 @@
{
"id": "timelinesTest",
"owner": { "name": "Security solution", "githubTeam": "security-solution" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "timelinesTest"],

View file

@ -1,5 +1,6 @@
{
"id": "savedObjectTestPlugin",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "kibana",
"server": true,
"ui": false

View file

@ -1,5 +1,6 @@
{
"id": "auditLog",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": [],

View file

@ -1,5 +1,6 @@
{
"id": "oidcProviderPlugin",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,6 @@
{
"id": "samlProviderPlugin",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,6 @@
{
"id": "securityTestEndpoints",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,

View file

@ -1,5 +1,6 @@
{
"id": "spacesTestPlugin",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "kibana",
"server": true,
"ui": false

View file

@ -1,5 +1,6 @@
{
"id": "fooPlugin",
"owner": { "name": "Platform Security", "githubTeam": "kibana-security" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"requiredPlugins": ["features"],

View file

@ -1,5 +1,6 @@
{
"id": "applicationUsageTest",
"owner": { "name": "Core", "githubTeam": "kibana-core" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "applicationUsageTest"],

View file

@ -1,5 +1,6 @@
{
"id": "stackManagementUsageTest",
"owner": { "name": "Kibana Stack Management", "githubTeam": "kibana-stack-management" },
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "stackManagementUsageTest"],