From cdb59c766263fbdc91c96c02d647bd66ef7df70c Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 15 May 2020 16:05:29 +0200 Subject: [PATCH 01/16] unskip newsfeed tests (#66562) --- test/functional/apps/home/_newsfeed.ts | 3 +-- test/ui_capabilities/newsfeed_err/test.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/test/functional/apps/home/_newsfeed.ts b/test/functional/apps/home/_newsfeed.ts index c5891c704dd6a1..096e237850c72d 100644 --- a/test/functional/apps/home/_newsfeed.ts +++ b/test/functional/apps/home/_newsfeed.ts @@ -60,8 +60,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) { } }); - // TODO currently fails because styles are not correctly applied in the new platform - it.skip('clicking on newsfeed icon should close opened newsfeed', async () => { + it('clicking on newsfeed icon should close opened newsfeed', async () => { await globalNav.clickNewsfeed(); const isOpen = await PageObjects.newsfeed.openNewsfeedPanel(); expect(isOpen).to.be(false); diff --git a/test/ui_capabilities/newsfeed_err/test.ts b/test/ui_capabilities/newsfeed_err/test.ts index 07c829e8b15a08..2aa81f34028a02 100644 --- a/test/ui_capabilities/newsfeed_err/test.ts +++ b/test/ui_capabilities/newsfeed_err/test.ts @@ -51,8 +51,7 @@ export default function uiCapabilitiesTests({ getService, getPageObjects }: FtrP expect(objects).to.eql([]); }); - // TODO currently fails because styles are not correctly applied in the new platform - it.skip('clicking on newsfeed icon should close opened newsfeed', async () => { + it('clicking on newsfeed icon should close opened newsfeed', async () => { await globalNav.clickNewsfeed(); const isOpen = await PageObjects.newsfeed.openNewsfeedPanel(); expect(isOpen).to.be(false); From 4b8eb06a5ab671d308c4c22a9bb33a9e156b8101 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Fri, 15 May 2020 07:34:39 -0700 Subject: [PATCH 02/16] [DOCS] Rename monitoring collection from internal to legacy (#65781) --- docs/user/monitoring/configuring-monitoring.asciidoc | 6 +++--- docs/user/monitoring/monitoring-kibana.asciidoc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/user/monitoring/configuring-monitoring.asciidoc b/docs/user/monitoring/configuring-monitoring.asciidoc index de9e99117fc990..776a76b24c4ec3 100644 --- a/docs/user/monitoring/configuring-monitoring.asciidoc +++ b/docs/user/monitoring/configuring-monitoring.asciidoc @@ -8,8 +8,8 @@ If you enable the {monitor-features} in your cluster, there are two methods to collect metrics about {kib}: -* <> -* <> +* <> +* <> You can also use {kib} to <>. @@ -17,6 +17,6 @@ You can also use {kib} to To learn about monitoring in general, see {ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. -include::monitoring-kibana.asciidoc[] include::monitoring-metricbeat.asciidoc[] include::viewing-metrics.asciidoc[] +include::monitoring-kibana.asciidoc[] diff --git a/docs/user/monitoring/monitoring-kibana.asciidoc b/docs/user/monitoring/monitoring-kibana.asciidoc index 9aa10289d299b3..bb619ac79e143e 100644 --- a/docs/user/monitoring/monitoring-kibana.asciidoc +++ b/docs/user/monitoring/monitoring-kibana.asciidoc @@ -1,15 +1,15 @@ [role="xpack"] [[monitoring-kibana]] -=== Collecting {kib} monitoring data +=== Collecting monitoring data using legacy collectors ++++ -Collecting monitoring data +Legacy collection methods ++++ If you enable the Elastic {monitor-features} in your cluster, you can optionally collect metrics about {kib}. The following method involves sending the metrics to the production cluster, -which ultimately routes them to the monitoring cluster. For an alternative +which ultimately routes them to the monitoring cluster. For the recommended method, see <>. To learn about monitoring in general, see From 7366552a323781404250cbe5c7f1c3e403c773dc Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Fri, 15 May 2020 08:39:28 -0600 Subject: [PATCH 03/16] [docLinks] Add docLinks to CoreSetup. (#66631) * Add docLinks to CoreSetup. * Update generated docs. * Add inline snapshot for expect test error. Co-authored-by: Elastic Machine --- ...a-plugin-core-public.coresetup.doclinks.md | 13 +++++++++ .../kibana-plugin-core-public.coresetup.md | 1 + ...e-public.doclinkssetup.doc_link_version.md | 11 ++++++++ ...ublic.doclinkssetup.elastic_website_url.md | 11 ++++++++ ...plugin-core-public.doclinkssetup.links.md} | 4 +-- ...kibana-plugin-core-public.doclinkssetup.md | 21 +++++++++++++++ ...e-public.doclinksstart.doc_link_version.md | 11 -------- ...ublic.doclinksstart.elastic_website_url.md | 11 -------- ...kibana-plugin-core-public.doclinksstart.md | 13 ++------- .../core/public/kibana-plugin-core-public.md | 3 ++- src/core/public/core_system.test.ts | 5 ++++ src/core/public/core_system.ts | 4 ++- .../doc_links/doc_links_service.mock.ts | 10 ++++--- .../doc_links/doc_links_service.test.ts | 26 +++++++++++++++--- .../public/doc_links/doc_links_service.ts | 27 ++++++++++++++----- src/core/public/doc_links/index.ts | 2 +- src/core/public/index.ts | 5 +++- src/core/public/legacy/legacy_service.test.ts | 2 ++ src/core/public/mocks.ts | 1 + src/core/public/plugins/plugin_context.ts | 1 + .../public/plugins/plugins_service.test.ts | 1 + src/core/public/public.api.md | 7 ++++- 22 files changed, 137 insertions(+), 53 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-core-public.coresetup.doclinks.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.doclinkssetup.doc_link_version.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.doclinkssetup.elastic_website_url.md rename docs/development/core/public/{kibana-plugin-core-public.doclinksstart.links.md => kibana-plugin-core-public.doclinkssetup.links.md} (94%) create mode 100644 docs/development/core/public/kibana-plugin-core-public.doclinkssetup.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.doclinksstart.doc_link_version.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.doclinksstart.elastic_website_url.md diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.doclinks.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.doclinks.md new file mode 100644 index 00000000000000..b239319c427fe4 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.doclinks.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [CoreSetup](./kibana-plugin-core-public.coresetup.md) > [docLinks](./kibana-plugin-core-public.coresetup.doclinks.md) + +## CoreSetup.docLinks property + +[DocLinksSetup](./kibana-plugin-core-public.doclinkssetup.md) + +Signature: + +```typescript +docLinks: DocLinksSetup; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.md index 870fa33dce9000..4f981b5a40139f 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.md @@ -18,6 +18,7 @@ export interface CoreSetupApplicationSetup | [ApplicationSetup](./kibana-plugin-core-public.applicationsetup.md) | | [context](./kibana-plugin-core-public.coresetup.context.md) | ContextSetup | [ContextSetup](./kibana-plugin-core-public.contextsetup.md) | +| [docLinks](./kibana-plugin-core-public.coresetup.doclinks.md) | DocLinksSetup | [DocLinksSetup](./kibana-plugin-core-public.doclinkssetup.md) | | [fatalErrors](./kibana-plugin-core-public.coresetup.fatalerrors.md) | FatalErrorsSetup | [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | | [getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md) | StartServicesAccessor<TPluginsStart, TStart> | [StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) | | [http](./kibana-plugin-core-public.coresetup.http.md) | HttpSetup | [HttpSetup](./kibana-plugin-core-public.httpsetup.md) | diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.doc_link_version.md b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.doc_link_version.md new file mode 100644 index 00000000000000..c8d13bab92b058 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.doc_link_version.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksSetup](./kibana-plugin-core-public.doclinkssetup.md) > [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinkssetup.doc_link_version.md) + +## DocLinksSetup.DOC\_LINK\_VERSION property + +Signature: + +```typescript +readonly DOC_LINK_VERSION: string; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.elastic_website_url.md b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.elastic_website_url.md new file mode 100644 index 00000000000000..d8493148bae107 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.elastic_website_url.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksSetup](./kibana-plugin-core-public.doclinkssetup.md) > [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinkssetup.elastic_website_url.md) + +## DocLinksSetup.ELASTIC\_WEBSITE\_URL property + +Signature: + +```typescript +readonly ELASTIC_WEBSITE_URL: string; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.links.md similarity index 94% rename from docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md rename to docs/development/core/public/kibana-plugin-core-public.doclinkssetup.links.md index b43c484f8de7f9..fd05ae139ba215 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.links.md @@ -1,8 +1,8 @@ -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) > [links](./kibana-plugin-core-public.doclinksstart.links.md) +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksSetup](./kibana-plugin-core-public.doclinkssetup.md) > [links](./kibana-plugin-core-public.doclinkssetup.links.md) -## DocLinksStart.links property +## DocLinksSetup.links property Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.md b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.md new file mode 100644 index 00000000000000..1114e05589c4b7 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.doclinkssetup.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksSetup](./kibana-plugin-core-public.doclinkssetup.md) + +## DocLinksSetup interface + + +Signature: + +```typescript +export interface DocLinksSetup +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinkssetup.doc_link_version.md) | string | | +| [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinkssetup.elastic_website_url.md) | string | | +| [links](./kibana-plugin-core-public.doclinkssetup.links.md) | {
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly date_histogram: string;
readonly date_range: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessSyntax: string;
readonly luceneExpressions: string;
};
readonly indexPatterns: {
readonly loadingData: string;
readonly introduction: string;
};
readonly kibana: string;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly luceneQuerySyntax: string;
readonly queryDsl: string;
readonly kueryQuerySyntax: string;
};
readonly date: {
readonly dateMath: string;
};
readonly management: Record<string, string>;
} | | + diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.doc_link_version.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.doc_link_version.md deleted file mode 100644 index 8140b3fcf380f9..00000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.doc_link_version.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) > [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) - -## DocLinksStart.DOC\_LINK\_VERSION property - -Signature: - -```typescript -readonly DOC_LINK_VERSION: string; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.elastic_website_url.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.elastic_website_url.md deleted file mode 100644 index af770ed3055aad..00000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.elastic_website_url.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) > [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) - -## DocLinksStart.ELASTIC\_WEBSITE\_URL property - -Signature: - -```typescript -readonly ELASTIC_WEBSITE_URL: string; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index 69bc4e473590c8..af2a41b691727d 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -2,20 +2,11 @@ [Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) -## DocLinksStart interface +## DocLinksStart type Signature: ```typescript -export interface DocLinksStart +export declare type DocLinksStart = DocLinksSetup; ``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | -| [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly date_histogram: string;
readonly date_range: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessSyntax: string;
readonly luceneExpressions: string;
};
readonly indexPatterns: {
readonly loadingData: string;
readonly introduction: string;
};
readonly kibana: string;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly luceneQuerySyntax: string;
readonly queryDsl: string;
readonly kueryQuerySyntax: string;
};
readonly date: {
readonly dateMath: string;
};
readonly management: Record<string, string>;
} | | - diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index eafc81447ee03e..b2524ec48c757d 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -65,7 +65,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ContextSetup](./kibana-plugin-core-public.contextsetup.md) | An object that handles registration of context providers and configuring handlers with context. | | [CoreSetup](./kibana-plugin-core-public.coresetup.md) | Core services exposed to the Plugin setup lifecycle | | [CoreStart](./kibana-plugin-core-public.corestart.md) | Core services exposed to the Plugin start lifecycle | -| [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | | +| [DocLinksSetup](./kibana-plugin-core-public.doclinkssetup.md) | | | [EnvironmentMode](./kibana-plugin-core-public.environmentmode.md) | | | [ErrorToastOptions](./kibana-plugin-core-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) error APIs. | | [FatalErrorInfo](./kibana-plugin-core-public.fatalerrorinfo.md) | Represents the message and stack of a fatal Error | @@ -149,6 +149,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ChromeHelpExtensionMenuGitHubLink](./kibana-plugin-core-public.chromehelpextensionmenugithublink.md) | | | [ChromeHelpExtensionMenuLink](./kibana-plugin-core-public.chromehelpextensionmenulink.md) | | | [ChromeNavLinkUpdateableFields](./kibana-plugin-core-public.chromenavlinkupdateablefields.md) | | +| [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | | | [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [Freezable](./kibana-plugin-core-public.freezable.md) | | | [HandlerContextType](./kibana-plugin-core-public.handlercontexttype.md) | Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-core-public.handlerfunction.md) to represent the type of the context. | diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index a42719417a2b17..2979dd7661e593 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -197,6 +197,11 @@ describe('#setup()', () => { expect(MockInjectedMetadataService.setup).toHaveBeenCalledTimes(1); }); + it('calls docLinks#setup()', async () => { + await setupCore(); + expect(MockDocLinksService.setup).toHaveBeenCalledTimes(1); + }); + it('calls http#setup()', async () => { await setupCore(); expect(MockHttpService.setup).toHaveBeenCalledTimes(1); diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index e58114b69dcc1e..46e1ecb83e9e4e 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -160,6 +160,7 @@ export class CoreSystem { i18n: this.i18n.getContext(), }); await this.integrations.setup(); + const docLinks = this.docLinks.setup({ injectedMetadata }); const http = this.http.setup({ injectedMetadata, fatalErrors: this.fatalErrorsSetup }); const uiSettings = this.uiSettings.setup({ http, injectedMetadata }); const notifications = this.notifications.setup({ uiSettings }); @@ -180,6 +181,7 @@ export class CoreSystem { const core: InternalCoreSetup = { application, context, + docLinks, fatalErrors: this.fatalErrorsSetup, http, injectedMetadata, @@ -211,7 +213,7 @@ export class CoreSystem { try { const injectedMetadata = await this.injectedMetadata.start(); const uiSettings = await this.uiSettings.start(); - const docLinks = await this.docLinks.start({ injectedMetadata }); + const docLinks = this.docLinks.start(); const http = await this.http.start(); const savedObjects = await this.savedObjects.start({ http }); const i18n = await this.i18n.start(); diff --git a/src/core/public/doc_links/doc_links_service.mock.ts b/src/core/public/doc_links/doc_links_service.mock.ts index 239249f40fe66d..9edcf2e3c79901 100644 --- a/src/core/public/doc_links/doc_links_service.mock.ts +++ b/src/core/public/doc_links/doc_links_service.mock.ts @@ -18,21 +18,25 @@ */ import { injectedMetadataServiceMock } from '../injected_metadata/injected_metadata_service.mock'; -import { DocLinksService, DocLinksStart } from './doc_links_service'; +import { DocLinksService, DocLinksSetup, DocLinksStart } from './doc_links_service'; -const createStartContractMock = (): DocLinksStart => { +const createSetupContractMock = (): DocLinksSetup => { // This service is so simple that we actually use the real implementation const injectedMetadata = injectedMetadataServiceMock.createStartContract(); injectedMetadata.getKibanaBranch.mockReturnValue('mocked-test-branch'); - return new DocLinksService().start({ injectedMetadata }); + return new DocLinksService().setup({ injectedMetadata }); }; +const createStartContractMock: () => DocLinksStart = createSetupContractMock; + type DocLinksServiceContract = PublicMethodsOf; const createMock = (): jest.Mocked => ({ + setup: jest.fn().mockReturnValue(createSetupContractMock()), start: jest.fn().mockReturnValue(createStartContractMock()), }); export const docLinksServiceMock = { create: createMock, + createSetupContract: createSetupContractMock, createStartContract: createStartContractMock, }; diff --git a/src/core/public/doc_links/doc_links_service.test.ts b/src/core/public/doc_links/doc_links_service.test.ts index 283bfa9e2771a7..4c5d6bcde8b773 100644 --- a/src/core/public/doc_links/doc_links_service.test.ts +++ b/src/core/public/doc_links/doc_links_service.test.ts @@ -20,15 +20,33 @@ import { DocLinksService } from './doc_links_service'; import { injectedMetadataServiceMock } from '../injected_metadata/injected_metadata_service.mock'; -describe('DocLinksService#start()', () => { +describe('DocLinksService#setup()', () => { it('templates the doc links with the branch information from injectedMetadata', () => { const injectedMetadata = injectedMetadataServiceMock.createStartContract(); injectedMetadata.getKibanaBranch.mockReturnValue('test-branch'); const service = new DocLinksService(); - const start = service.start({ injectedMetadata }); - expect(start.DOC_LINK_VERSION).toEqual('test-branch'); - expect(start.links.kibana).toEqual( + const setup = service.setup({ injectedMetadata }); + expect(setup.DOC_LINK_VERSION).toEqual('test-branch'); + expect(setup.links.kibana).toEqual( 'https://www.elastic.co/guide/en/kibana/test-branch/index.html' ); }); }); + +describe('DocLinksService#start()', () => { + it('returns the same data as setup', () => { + const injectedMetadata = injectedMetadataServiceMock.createStartContract(); + injectedMetadata.getKibanaBranch.mockReturnValue('test-branch'); + const service = new DocLinksService(); + const setup = service.setup({ injectedMetadata }); + const start = service.start(); + expect(setup).toEqual(start); + }); + + it('must be called after setup', () => { + const service = new DocLinksService(); + expect(() => { + service.start(); + }).toThrowErrorMatchingInlineSnapshot(`"DocLinksService#setup() must be called first!"`); + }); +}); diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 9b672d40961d8e..aeeb8c3342e462 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -17,21 +17,23 @@ * under the License. */ -import { InjectedMetadataStart } from '../injected_metadata'; +import { InjectedMetadataSetup } from '../injected_metadata'; import { deepFreeze } from '../../utils'; -interface StartDeps { - injectedMetadata: InjectedMetadataStart; +interface SetupDeps { + injectedMetadata: InjectedMetadataSetup; } /** @internal */ export class DocLinksService { - public start({ injectedMetadata }: StartDeps): DocLinksStart { + private service?: DocLinksSetup; + + public setup({ injectedMetadata }: SetupDeps): DocLinksSetup { const DOC_LINK_VERSION = injectedMetadata.getKibanaBranch(); const ELASTIC_WEBSITE_URL = 'https://www.elastic.co/'; const ELASTICSEARCH_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`; - return deepFreeze({ + this.service = deepFreeze({ DOC_LINK_VERSION, ELASTIC_WEBSITE_URL, links: { @@ -124,11 +126,21 @@ export class DocLinksService { }, }, }); + + return this.service; + } + + public start(): DocLinksStart { + if (!this.service) { + throw new Error(`DocLinksService#setup() must be called first!`); + } + + return this.service; } } /** @public */ -export interface DocLinksStart { +export interface DocLinksSetup { readonly DOC_LINK_VERSION: string; readonly ELASTIC_WEBSITE_URL: string; readonly links: { @@ -218,3 +230,6 @@ export interface DocLinksStart { readonly management: Record; }; } + +/** @public */ +export type DocLinksStart = DocLinksSetup; diff --git a/src/core/public/doc_links/index.ts b/src/core/public/doc_links/index.ts index fe49d4a7c6a583..fbfa9db5635ddc 100644 --- a/src/core/public/doc_links/index.ts +++ b/src/core/public/doc_links/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { DocLinksService, DocLinksStart } from './doc_links_service'; +export { DocLinksService, DocLinksSetup, DocLinksStart } from './doc_links_service'; diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 3b2d9ed3c0b022..3698fdcfe95129 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -65,7 +65,7 @@ import { OverlayStart } from './overlays'; import { Plugin, PluginInitializer, PluginInitializerContext, PluginOpaqueId } from './plugins'; import { UiSettingsState, IUiSettingsClient } from './ui_settings'; import { ApplicationSetup, Capabilities, ApplicationStart } from './application'; -import { DocLinksStart } from './doc_links'; +import { DocLinksSetup, DocLinksStart } from './doc_links'; import { SavedObjectsStart } from './saved_objects'; export { PackageInfo, EnvironmentMode } from '../server/types'; import { @@ -208,6 +208,8 @@ export interface CoreSetup, any, any]>, []>(() => Promise.resolve([createCoreStartMock({ basePath }), pluginStartDeps, pluginStartContract]) diff --git a/src/core/public/plugins/plugin_context.ts b/src/core/public/plugins/plugin_context.ts index 19cfadf70be1b8..c4b3c929415ee7 100644 --- a/src/core/public/plugins/plugin_context.ts +++ b/src/core/public/plugins/plugin_context.ts @@ -101,6 +101,7 @@ export function createPluginSetupContext< deps.application.registerMountContext(plugin.opaqueId, contextName, provider), }, context: deps.context, + docLinks: deps.docLinks, fatalErrors: deps.fatalErrors, http: deps.http, notifications: deps.notifications, diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts index 6d71844bc19c84..6c5ab5fcedcfdd 100644 --- a/src/core/public/plugins/plugins_service.test.ts +++ b/src/core/public/plugins/plugins_service.test.ts @@ -89,6 +89,7 @@ describe('PluginsService', () => { mockSetupDeps = { application: applicationServiceMock.createInternalSetupContract(), context: contextServiceMock.createSetupContract(), + docLinks: docLinksServiceMock.createSetupContract(), fatalErrors: fatalErrorsServiceMock.createSetupContract(), http: httpServiceMock.createSetupContract(), injectedMetadata: pick(injectedMetadataServiceMock.createStartContract(), 'getInjectedVar'), diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 225ef611c0298f..fbd8f474151fa7 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -383,6 +383,8 @@ export interface CoreSetup; @@ -471,7 +473,7 @@ export const DEFAULT_APP_CATEGORIES: Readonly<{ }>; // @public (undocumented) -export interface DocLinksStart { +export interface DocLinksSetup { // (undocumented) readonly DOC_LINK_VERSION: string; // (undocumented) @@ -565,6 +567,9 @@ export interface DocLinksStart { }; } +// @public (undocumented) +export type DocLinksStart = DocLinksSetup; + // @public (undocumented) export interface EnvironmentMode { // (undocumented) From 58b77fcb34ab12869ac8bbf8814b1acf2d4f8b96 Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Fri, 15 May 2020 10:39:58 -0400 Subject: [PATCH 04/16] [CI] Add slack alerts to tracked branch jobs, change default channel, change formatting (#66580) --- Jenkinsfile | 6 +++-- vars/slackNotifications.groovy | 43 ++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 958ced8c6195a6..ad5bd23b76b5d0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -53,7 +53,9 @@ kibanaPipeline(timeoutMinutes: 135, checkPrChanges: true) { } } - retryable.printFlakyFailures() - kibanaPipeline.sendMail() + if (params.NOTIFY_ON_FAILURE) { + slackNotifications.onFailure() + kibanaPipeline.sendMail() + } } } diff --git a/vars/slackNotifications.groovy b/vars/slackNotifications.groovy index 8ae37d1c44637c..5092f631e7b397 100644 --- a/vars/slackNotifications.groovy +++ b/vars/slackNotifications.groovy @@ -62,21 +62,32 @@ def getTestFailures() { def messages = [] messages << "*Test Failures*" - def list = failures.collect { "• <${it.url}|${it.fullDisplayName}>" }.join("\n") + def list = failures.collect { "• <${it.url}|${it.fullDisplayName.split('.', 2)[-1]}>" }.join("\n") return "*Test Failures*\n${list}" } -def sendFailedBuild(Map params = [:]) { - def displayName = "${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}" +def getDefaultDisplayName() { + return "${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}" +} +def getDefaultContext() { + def duration = currentBuild.durationString.replace(' and counting', '') + + return contextBlock([ + "${buildUtils.getBuildStatus().toLowerCase().capitalize()} after ${duration}", + "", + ].join(' · ')) +} + +def sendFailedBuild(Map params = [:]) { def config = [ - channel: '#kibana-operations', - title: ":broken_heart: *<${env.BUILD_URL}|${displayName}>*", - message: ":broken_heart: ${displayName}", + channel: '#kibana-operations-alerts', + title: ":broken_heart: *<${env.BUILD_URL}|${getDefaultDisplayName()}>*", + message: ":broken_heart: ${getDefaultDisplayName()}", color: 'danger', icon: ':jenkins:', username: 'Kibana Operations', - context: contextBlock("${displayName} · "), + context: getDefaultContext(), ] + params def blocks = [markdownBlock(config.title)] @@ -94,18 +105,24 @@ def sendFailedBuild(Map params = [:]) { ) } +def onFailure(Map options = [:]) { + catchError { + def status = buildUtils.getBuildStatus() + if (status != "SUCCESS") { + catchErrors { + sendFailedBuild(options) + } + } + } +} + def onFailure(Map options = [:], Closure closure) { // try/finally will NOT work here, because the build status will not have been changed to ERROR when the finally{} block executes catchError { closure() } - def status = buildUtils.getBuildStatus() - if (status != "SUCCESS" && status != "UNSTABLE") { - catchErrors { - sendFailedBuild(options) - } - } + onFailure(options) } return this From 1c004e98d6fe394719a8e942eb2ffb9411151762 Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Fri, 15 May 2020 10:40:30 -0400 Subject: [PATCH 05/16] [CI] Add one retry to setup step (#66638) --- vars/kibanaPipeline.groovy | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/vars/kibanaPipeline.groovy b/vars/kibanaPipeline.groovy index 6252a103d28813..f4c44a8ae2df4e 100644 --- a/vars/kibanaPipeline.groovy +++ b/vars/kibanaPipeline.groovy @@ -178,7 +178,18 @@ def bash(script, label) { } def doSetup() { - runbld("./test/scripts/jenkins_setup.sh", "Setup Build Environment and Dependencies") + retryWithDelay(2, 15) { + try { + runbld("./test/scripts/jenkins_setup.sh", "Setup Build Environment and Dependencies") + } catch (ex) { + try { + // Setup expects this directory to be missing, so we need to remove it before we do a retry + bash("rm -rf ../elasticsearch", "Remove elasticsearch sibling directory, if it exists") + } finally { + throw ex + } + } + } } def buildOss() { From e3f6da0416dbb3436a745f3f5d719dd86f6b8e6d Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Fri, 15 May 2020 10:41:02 -0400 Subject: [PATCH 06/16] Replace agent metrics link with the new one (#66632) --- vars/agentInfo.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/agentInfo.groovy b/vars/agentInfo.groovy index cb20b434ba34cf..166a86c1692616 100644 --- a/vars/agentInfo.groovy +++ b/vars/agentInfo.groovy @@ -5,7 +5,7 @@ def print() { def resourcesUrl = ( - "https://infra-stats.elastic.co/app/visualize#/edit/8bd92360-1b92-11ea-b719-aba04518cc34" + + "https://infra-stats.elastic.co/app/kibana#/visualize/edit/8bd92360-1b92-11ea-b719-aba04518cc34" + "?_g=(time:(from:'${startTime}',to:'${endTime}'))" + "&_a=(query:'host.name:${env.NODE_NAME}')" ) From 976ff056178914c4e89873420e2a03d654acdf3a Mon Sep 17 00:00:00 2001 From: Stacey Gammon Date: Fri, 15 May 2020 10:59:42 -0400 Subject: [PATCH 07/16] KP plugins shouldn't need package.json (#66654) Co-authored-by: Elastic Machine --- examples/alerting_example/package.json | 17 ----------------- examples/bfetch_explorer/package.json | 17 ----------------- examples/demo_search/package.json | 17 ----------------- examples/embeddable_examples/package.json | 17 ----------------- examples/embeddable_explorer/package.json | 17 ----------------- examples/search_explorer/package.json | 17 ----------------- examples/state_containers_examples/package.json | 17 ----------------- examples/ui_action_examples/package.json | 17 ----------------- examples/ui_actions_explorer/package.json | 17 ----------------- examples/url_generators_examples/package.json | 17 ----------------- examples/url_generators_explorer/package.json | 17 ----------------- 11 files changed, 187 deletions(-) delete mode 100644 examples/alerting_example/package.json delete mode 100644 examples/bfetch_explorer/package.json delete mode 100644 examples/demo_search/package.json delete mode 100644 examples/embeddable_examples/package.json delete mode 100644 examples/embeddable_explorer/package.json delete mode 100644 examples/search_explorer/package.json delete mode 100644 examples/state_containers_examples/package.json delete mode 100644 examples/ui_action_examples/package.json delete mode 100644 examples/ui_actions_explorer/package.json delete mode 100644 examples/url_generators_examples/package.json delete mode 100644 examples/url_generators_explorer/package.json diff --git a/examples/alerting_example/package.json b/examples/alerting_example/package.json deleted file mode 100644 index 96187d847c1c41..00000000000000 --- a/examples/alerting_example/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "alerting_example", - "version": "1.0.0", - "main": "target/examples/alerting_example", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/bfetch_explorer/package.json b/examples/bfetch_explorer/package.json deleted file mode 100644 index ea5a1b1848613b..00000000000000 --- a/examples/bfetch_explorer/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "bfetch_explorer", - "version": "1.0.0", - "main": "target/examples/bfetch_explorer", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/demo_search/package.json b/examples/demo_search/package.json deleted file mode 100644 index d29ad55b32db2d..00000000000000 --- a/examples/demo_search/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "demo_data_search", - "version": "1.0.0", - "main": "target/examples/demo_data_search", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/embeddable_examples/package.json b/examples/embeddable_examples/package.json deleted file mode 100644 index 055ee6d7315123..00000000000000 --- a/examples/embeddable_examples/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "embeddable_examples", - "version": "1.0.0", - "main": "target/examples/embeddable_examples", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/embeddable_explorer/package.json b/examples/embeddable_explorer/package.json deleted file mode 100644 index 771c5c9be9c06e..00000000000000 --- a/examples/embeddable_explorer/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "embeddable_explorer", - "version": "1.0.0", - "main": "target/examples/embeddable_explorer", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/search_explorer/package.json b/examples/search_explorer/package.json deleted file mode 100644 index f3c71c5d181f8d..00000000000000 --- a/examples/search_explorer/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "searchExplorer", - "version": "1.0.0", - "main": "target/examples/search_explorer", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/state_containers_examples/package.json b/examples/state_containers_examples/package.json deleted file mode 100644 index b309494a366628..00000000000000 --- a/examples/state_containers_examples/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "state_containers_examples", - "version": "1.0.0", - "main": "target/examples/state_containers_examples", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/ui_action_examples/package.json b/examples/ui_action_examples/package.json deleted file mode 100644 index fbede6b4dbad7d..00000000000000 --- a/examples/ui_action_examples/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "ui_actions_examples", - "version": "1.0.0", - "main": "target/examples/ui_actions_examples", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/ui_actions_explorer/package.json b/examples/ui_actions_explorer/package.json deleted file mode 100644 index 1758471ced483a..00000000000000 --- a/examples/ui_actions_explorer/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "ui_actions_explorer", - "version": "1.0.0", - "main": "target/examples/ui_actions_explorer", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/url_generators_examples/package.json b/examples/url_generators_examples/package.json deleted file mode 100644 index d3e8bd98aebf4c..00000000000000 --- a/examples/url_generators_examples/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "url_generators_examples", - "version": "1.0.0", - "main": "target/examples/url_generators_examples", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/examples/url_generators_explorer/package.json b/examples/url_generators_explorer/package.json deleted file mode 100644 index f472ba1d08506a..00000000000000 --- a/examples/url_generators_explorer/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "url_generators_explorer", - "version": "1.0.0", - "main": "target/examples/url_generators_explorer", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} From 9df3d9faab04dcaf0ab6f4bb5eb3ca9901b2d7a8 Mon Sep 17 00:00:00 2001 From: patrykkopycinski Date: Fri, 15 May 2020 17:15:24 +0200 Subject: [PATCH 08/16] [SIEM][Detection Engine] Add validation for Rule Actions (#63332) --- .../rules/rule_actions_field/index.test.tsx | 2 +- .../rules/rule_actions_field/index.tsx | 99 ++++++++--- .../rules/rule_actions_field/translations.tsx | 14 ++ .../rules/step_rule_actions/index.test.tsx | 13 +- .../rules/step_rule_actions/index.tsx | 82 ++++++--- .../rules/step_rule_actions/schema.test.tsx | 166 ++++++++++++++++++ .../rules/step_rule_actions/schema.tsx | 76 ++++++-- .../rules/step_rule_actions/translations.tsx | 23 ++- .../rules/step_rule_actions/utils.test.ts | 142 +++++++++++++++ .../rules/step_rule_actions/utils.ts | 67 +++++++ .../translations/translations/ja-JP.json | 4 +- .../translations/translations/zh-CN.json | 4 +- .../triggers_actions_ui/public/index.ts | 4 +- 13 files changed, 628 insertions(+), 68 deletions(-) create mode 100644 x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/translations.tsx create mode 100644 x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.test.tsx create mode 100644 x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.test.ts create mode 100644 x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.ts diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.test.tsx b/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.test.tsx index 579f8869c08b17..a9bde76126b6e1 100644 --- a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.test.tsx +++ b/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.test.tsx @@ -13,7 +13,7 @@ import { useFormFieldMock } from '../../../../common/mock'; jest.mock('../../../../common/lib/kibana'); describe('RuleActionsField', () => { - it('should not render ActionForm is no actions are supported', () => { + it('should not render ActionForm if no actions are supported', () => { (useKibana as jest.Mock).mockReturnValue({ services: { triggers_actions_ui: { diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.tsx b/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.tsx index 2e9a793bbdef2a..e503a090fe762a 100644 --- a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.tsx +++ b/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.tsx @@ -4,16 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback, useEffect, useState } from 'react'; +import { isEmpty } from 'lodash/fp'; +import { EuiSpacer, EuiCallOut } from '@elastic/eui'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import deepMerge from 'deepmerge'; +import ReactMarkdown from 'react-markdown'; +import styled from 'styled-components'; import { NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS } from '../../../../../common/constants'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { loadActionTypes } from '../../../../../../triggers_actions_ui/public/application/lib/action_connector_api'; import { SelectField } from '../../../../shared_imports'; -import { ActionForm, ActionType } from '../../../../../../triggers_actions_ui/public'; +import { + ActionForm, + ActionType, + loadActionTypes, +} from '../../../../../../triggers_actions_ui/public'; import { AlertAction } from '../../../../../../alerting/common'; import { useKibana } from '../../../../common/lib/kibana'; +import { FORM_ERRORS_TITLE } from './translations'; type ThrottleSelectField = typeof SelectField; @@ -21,7 +28,14 @@ const DEFAULT_ACTION_GROUP_ID = 'default'; const DEFAULT_ACTION_MESSAGE = 'Rule {{context.rule.name}} generated {{state.signals_count}} signals'; +const FieldErrorsContainer = styled.div` + p { + margin-bottom: 0; + } +`; + export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables }) => { + const [fieldErrors, setFieldErrors] = useState(null); const [supportedActionTypes, setSupportedActionTypes] = useState(); const { http, @@ -31,13 +45,18 @@ export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables application: { capabilities }, } = useKibana().services; + const actions: AlertAction[] = useMemo( + () => (!isEmpty(field.value) ? (field.value as AlertAction[]) : []), + [field.value] + ); + const setActionIdByIndex = useCallback( (id: string, index: number) => { - const updatedActions = [...(field.value as Array>)]; + const updatedActions = [...(actions as Array>)]; updatedActions[index] = deepMerge(updatedActions[index], { id }); field.setValue(updatedActions); }, - [field] + [field.setValue, actions] ); const setAlertProperty = useCallback( @@ -48,11 +67,11 @@ export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables const setActionParamsProperty = useCallback( // eslint-disable-next-line @typescript-eslint/no-explicit-any (key: string, value: any, index: number) => { - const updatedActions = [...(field.value as AlertAction[])]; + const updatedActions = [...actions]; updatedActions[index].params[key] = value; field.setValue(updatedActions); }, - [field] + [field.setValue, actions] ); useEffect(() => { @@ -65,23 +84,57 @@ export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables })(); }, []); + useEffect(() => { + if (field.form.isSubmitting || !field.errors.length) { + return setFieldErrors(null); + } + if ( + field.form.isSubmitted && + !field.form.isSubmitting && + field.form.isValid === false && + field.errors.length + ) { + const errorsString = field.errors.map(({ message }) => message).join('\n'); + return setFieldErrors(errorsString); + } + }, [ + field.form.isSubmitted, + field.form.isSubmitting, + field.isChangingValue, + field.form.isValid, + field.errors, + setFieldErrors, + ]); + if (!supportedActionTypes) return <>; return ( - + <> + {fieldErrors ? ( + <> + + + + + + + + ) : null} + + ); }; diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/translations.tsx b/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/translations.tsx new file mode 100644 index 00000000000000..8bf8e39685dfd2 --- /dev/null +++ b/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/translations.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const FORM_ERRORS_TITLE = i18n.translate( + 'xpack.siem.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle', + { + defaultMessage: 'Please fix issues listed below', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.test.tsx b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.test.tsx index 712aacd3e3e822..165aa5a30b0f03 100644 --- a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.test.tsx +++ b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.test.tsx @@ -9,7 +9,18 @@ import { shallow } from 'enzyme'; import { StepRuleActions } from './index'; -jest.mock('../../../../common/lib/kibana'); +jest.mock('../../../../common/lib/kibana', () => ({ + useKibana: jest.fn().mockReturnValue({ + services: { + application: { + getUrlForApp: jest.fn(), + }, + triggers_actions_ui: { + actionTypeRegistry: jest.fn(), + }, + }, + }), +})); describe('StepRuleActions', () => { it('renders correctly', () => { diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.tsx b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.tsx index 86d2eb557e0749..8f3a13ef94b584 100644 --- a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.tsx +++ b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.tsx @@ -4,7 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiHorizontalRule, EuiFlexGroup, EuiFlexItem, EuiButton, EuiSpacer } from '@elastic/eui'; +import { + EuiHorizontalRule, + EuiForm, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiSpacer, +} from '@elastic/eui'; +import { findIndex } from 'lodash/fp'; import React, { FC, memo, useCallback, useEffect, useMemo, useState } from 'react'; import deepEqual from 'fast-deep-equal'; @@ -24,7 +32,7 @@ import { } from '../throttle_select_field'; import { RuleActionsField } from '../rule_actions_field'; import { useKibana } from '../../../../common/lib/kibana'; -import { schema } from './schema'; +import { getSchema } from './schema'; import * as I18n from './translations'; interface StepRuleActionsProps extends RuleStepProps { @@ -42,6 +50,15 @@ const stepActionsDefaultValue = { const GhostFormField = () => <>; +const getThrottleOptions = (throttle?: string | null) => { + // Add support for throttle options set by the API + if (throttle && findIndex(['value', throttle], THROTTLE_OPTIONS) < 0) { + return [...THROTTLE_OPTIONS, { value: throttle, text: throttle }]; + } + + return THROTTLE_OPTIONS; +}; + const StepRuleActionsComponent: FC = ({ addPadding = false, defaultValues, @@ -54,8 +71,12 @@ const StepRuleActionsComponent: FC = ({ }) => { const [myStepData, setMyStepData] = useState(stepActionsDefaultValue); const { - services: { application }, + services: { + application, + triggers_actions_ui: { actionTypeRegistry }, + }, } = useKibana(); + const schema = useMemo(() => getSchema({ actionTypeRegistry }), [actionTypeRegistry]); const { form } = useForm({ defaultValue: myStepData, @@ -104,6 +125,12 @@ const StepRuleActionsComponent: FC = ({ setMyStepData, ]); + const throttleOptions = useMemo(() => { + const throttle = myStepData.throttle; + + return getThrottleOptions(throttle); + }, [myStepData]); + const throttleFieldComponentProps = useMemo( () => ({ idAria: 'detectionEngineStepRuleActionsThrottle', @@ -112,7 +139,7 @@ const StepRuleActionsComponent: FC = ({ hasNoInitialSelection: false, handleChange: updateThrottle, euiFieldProps: { - options: THROTTLE_OPTIONS, + options: throttleOptions, }, }), [isLoading, updateThrottle] @@ -126,30 +153,39 @@ const StepRuleActionsComponent: FC = ({ <>
- - {myStepData.throttle !== stepActionsDefaultValue.throttle && ( - <> - + + + {myStepData.throttle !== stepActionsDefaultValue.throttle ? ( + <> + + + + + + ) : ( - - - )} - + )} + +
diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.test.tsx b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.test.tsx new file mode 100644 index 00000000000000..d746d42aefe78a --- /dev/null +++ b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.test.tsx @@ -0,0 +1,166 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { validateSingleAction, validateRuleActionsField } from './schema'; +import { isUuidv4, getActionTypeName, validateMustache, validateActionParams } from './utils'; +import { actionTypeRegistryMock } from '../../../../../../triggers_actions_ui/public/application/action_type_registry.mock'; +import { FormHook } from '../../../../shared_imports'; +jest.mock('./utils'); + +describe('stepRuleActions schema', () => { + const actionTypeRegistry = actionTypeRegistryMock.create(); + + describe('validateSingleAction', () => { + it('should validate single action', () => { + (isUuidv4 as jest.Mock).mockReturnValue(true); + (validateActionParams as jest.Mock).mockReturnValue([]); + (validateMustache as jest.Mock).mockReturnValue([]); + + expect( + validateSingleAction( + { + id: '817b8bca-91d1-4729-8ee1-3a83aaafd9d4', + group: 'default', + actionTypeId: '.slack', + params: {}, + }, + actionTypeRegistry + ) + ).toHaveLength(0); + }); + + it('should validate single action with invalid mustache template', () => { + (isUuidv4 as jest.Mock).mockReturnValue(true); + (validateActionParams as jest.Mock).mockReturnValue([]); + (validateMustache as jest.Mock).mockReturnValue(['Message is not valid mustache template']); + + const errors = validateSingleAction( + { + id: '817b8bca-91d1-4729-8ee1-3a83aaafd9d4', + group: 'default', + actionTypeId: '.slack', + params: { + message: '{{{mustache}}', + }, + }, + actionTypeRegistry + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toEqual('Message is not valid mustache template'); + }); + + it('should validate single action with incorrect id', () => { + (isUuidv4 as jest.Mock).mockReturnValue(false); + (validateMustache as jest.Mock).mockReturnValue([]); + (validateActionParams as jest.Mock).mockReturnValue([]); + + const errors = validateSingleAction( + { + id: '823d4', + group: 'default', + actionTypeId: '.slack', + params: {}, + }, + actionTypeRegistry + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toEqual('No connector selected'); + }); + }); + + describe('validateRuleActionsField', () => { + it('should validate rule actions field', () => { + const validator = validateRuleActionsField(actionTypeRegistry); + + const result = validator({ + path: '', + value: [], + form: {} as FormHook, + formData: jest.fn(), + errors: [], + }); + + expect(result).toEqual(undefined); + }); + + it('should validate incorrect rule actions field', () => { + (getActionTypeName as jest.Mock).mockReturnValue('Slack'); + const validator = validateRuleActionsField(actionTypeRegistry); + + const result = validator({ + path: '', + value: [ + { + id: '3', + group: 'default', + actionTypeId: '.slack', + params: {}, + }, + ], + form: {} as FormHook, + formData: jest.fn(), + errors: [], + }); + + expect(result).toEqual({ + code: 'ERR_FIELD_FORMAT', + message: ` +**Slack:** +* No connector selected +`, + path: '', + }); + }); + + it('should validate multiple incorrect rule actions field', () => { + (isUuidv4 as jest.Mock).mockReturnValueOnce(false); + (getActionTypeName as jest.Mock).mockReturnValueOnce('Slack'); + (isUuidv4 as jest.Mock).mockReturnValueOnce(true); + (getActionTypeName as jest.Mock).mockReturnValueOnce('Pagerduty'); + (validateActionParams as jest.Mock).mockReturnValue(['Summary is required']); + (validateMustache as jest.Mock).mockReturnValue(['Component is not valid mustache template']); + const validator = validateRuleActionsField(actionTypeRegistry); + + const result = validator({ + path: '', + value: [ + { + id: '817b8bca-91d1-4729-8ee1-3a83aaafd9d4', + group: 'default', + actionTypeId: '.slack', + params: {}, + }, + { + id: 'a8d1ef21-dcb9-4ac6-9e52-961f938a4c17', + group: 'default', + actionTypeId: '.pagerduty', + params: { + component: '{{{', + }, + }, + ], + form: {} as FormHook, + formData: jest.fn(), + errors: [], + }); + + expect(result).toEqual({ + code: 'ERR_FIELD_FORMAT', + message: ` +**Slack:** +* No connector selected + + +**Pagerduty:** +* Summary is required +* Component is not valid mustache template +`, + path: '', + }); + }); + }); +}); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.tsx b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.tsx index b2f8b79e3f62ce..189b55ae5622cb 100644 --- a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.tsx +++ b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.tsx @@ -8,9 +8,69 @@ import { i18n } from '@kbn/i18n'; -import { FormSchema } from '../../../../shared_imports'; +import { + AlertAction, + ActionTypeRegistryContract, +} from '../../../../../../triggers_actions_ui/public'; +import { FormSchema, FormData, ValidationFunc, ERROR_CODE } from '../../../../shared_imports'; +import * as I18n from './translations'; +import { isUuidv4, getActionTypeName, validateMustache, validateActionParams } from './utils'; -export const schema: FormSchema = { +export const validateSingleAction = ( + actionItem: AlertAction, + actionTypeRegistry: ActionTypeRegistryContract +): string[] => { + if (!isUuidv4(actionItem.id)) { + return [I18n.NO_CONNECTOR_SELECTED]; + } + + const actionParamsErrors = validateActionParams(actionItem, actionTypeRegistry); + const mustacheErrors = validateMustache(actionItem.params); + + return [...actionParamsErrors, ...mustacheErrors]; +}; + +export const validateRuleActionsField = (actionTypeRegistry: ActionTypeRegistryContract) => ( + ...data: Parameters +): ReturnType> | undefined => { + const [{ value, path }] = data as [{ value: AlertAction[]; path: string }]; + + const errors = value.reduce((acc, actionItem) => { + const errorsArray = validateSingleAction(actionItem, actionTypeRegistry); + + if (errorsArray.length) { + const actionTypeName = getActionTypeName(actionItem.actionTypeId); + const errorsListItems = errorsArray.map(error => `* ${error}\n`); + + return [...acc, `\n**${actionTypeName}:**\n${errorsListItems.join('')}`]; + } + + return acc; + }, [] as string[]); + + if (errors.length) { + return { + code: 'ERR_FIELD_FORMAT', + path, + message: `${errors.join('\n')}`, + }; + } +}; + +export const getSchema = ({ + actionTypeRegistry, +}: { + actionTypeRegistry: ActionTypeRegistryContract; +}): FormSchema => ({ + actions: { + validations: [ + { + validator: validateRuleActionsField(actionTypeRegistry), + }, + ], + }, + enabled: {}, + kibanaSiemAppUrl: {}, throttle: { label: i18n.translate( 'xpack.siem.detectionEngine.createRule.stepRuleActions.fieldThrottleLabel', @@ -26,14 +86,4 @@ export const schema: FormSchema = { } ), }, - actions: { - label: i18n.translate( - 'xpack.siem.detectionEngine.createRule.stepRuleActions.fieldActionsLabel', - { - defaultMessage: 'Actions', - } - ), - }, - enabled: {}, - kibanaSiemAppUrl: {}, -}; +}); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/translations.tsx b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/translations.tsx index 67bcc1af8150b9..d0c990df81ffec 100644 --- a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/translations.tsx +++ b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/translations.tsx @@ -5,17 +5,36 @@ */ import { i18n } from '@kbn/i18n'; +import { startCase } from 'lodash/fp'; export const COMPLETE_WITHOUT_ACTIVATING = i18n.translate( - 'xpack.siem.detectionEngine.createRule. stepScheduleRule.completeWithoutActivatingTitle', + 'xpack.siem.detectionEngine.createRule.stepScheduleRule.completeWithoutActivatingTitle', { defaultMessage: 'Create rule without activating it', } ); export const COMPLETE_WITH_ACTIVATING = i18n.translate( - 'xpack.siem.detectionEngine.createRule. stepScheduleRule.completeWithActivatingTitle', + 'xpack.siem.detectionEngine.createRule.stepScheduleRule.completeWithActivatingTitle', { defaultMessage: 'Create & activate rule', } ); + +export const NO_CONNECTOR_SELECTED = i18n.translate( + 'xpack.siem.detectionEngine.createRule.stepRuleActions.noConnectorSelectedErrorMessage', + { + defaultMessage: 'No connector selected', + } +); + +export const INVALID_MUSTACHE_TEMPLATE = (paramKey: string) => + i18n.translate( + 'xpack.siem.detectionEngine.createRule.stepRuleActions.invalidMustacheTemplateErrorMessage', + { + defaultMessage: '{key} is not valid mustache template', + values: { + key: startCase(paramKey), + }, + } + ); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.test.ts b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.test.ts new file mode 100644 index 00000000000000..74c9c35d72494a --- /dev/null +++ b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.test.ts @@ -0,0 +1,142 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { actionTypeRegistryMock } from '../../../../../../triggers_actions_ui/public/application/action_type_registry.mock'; +import { isUuidv4, getActionTypeName, validateMustache, validateActionParams } from './utils'; + +describe('stepRuleActions utils', () => { + describe('isUuidv4', () => { + it('should validate proper uuid v4 value', () => { + expect(isUuidv4('817b8bca-91d1-4729-8ee1-3a83aaafd9d4')).toEqual(true); + }); + + it('should validate incorrect uuid v4 value', () => { + expect(isUuidv4('ad9d4')).toEqual(false); + }); + }); + + describe('getActionTypeName', () => { + it('should return capitalized action type name', () => { + expect(getActionTypeName('.slack')).toEqual('Slack'); + }); + + it('should return empty string actionTypeId had improper format', () => { + expect(getActionTypeName('slack')).toEqual(''); + }); + }); + + describe('validateMustache', () => { + it('should validate mustache template', () => { + expect( + validateMustache({ + message: 'Mustache Template {{variable}}', + }) + ).toHaveLength(0); + }); + + it('should validate incorrect mustache template', () => { + expect( + validateMustache({ + message: 'Mustache Template {{{variable}}', + }) + ).toHaveLength(1); + }); + }); + + describe('validateActionParams', () => { + const validateParamsMock = jest.fn(); + const actionTypeRegistry = actionTypeRegistryMock.create(); + + beforeAll(() => { + const actionMock = { + id: 'id', + iconClass: 'iconClass', + validateParams: validateParamsMock, + selectMessage: 'message', + validateConnector: jest.fn(), + actionConnectorFields: null, + actionParamsFields: null, + }; + actionTypeRegistry.get.mockReturnValue(actionMock); + }); + + it('should validate action params', () => { + validateParamsMock.mockReturnValue({ errors: [] }); + + expect( + validateActionParams( + { + id: '817b8bca-91d1-4729-8ee1-3a83aaafd9d4', + group: 'default', + actionTypeId: '.slack', + params: { + message: 'Message', + }, + }, + actionTypeRegistry + ) + ).toHaveLength(0); + }); + + it('should validate incorrect action params', () => { + validateParamsMock.mockReturnValue({ + errors: ['Message is required'], + }); + + expect( + validateActionParams( + { + id: '817b8bca-91d1-4729-8ee1-3a83aaafd9d4', + group: 'default', + actionTypeId: '.slack', + params: {}, + }, + actionTypeRegistry + ) + ).toHaveLength(1); + }); + + it('should validate incorrect action params and filter error objects', () => { + validateParamsMock.mockReturnValue({ + errors: [ + { + message: 'Message is required', + }, + ], + }); + + expect( + validateActionParams( + { + id: '817b8bca-91d1-4729-8ee1-3a83aaafd9d4', + group: 'default', + actionTypeId: '.slack', + params: {}, + }, + actionTypeRegistry + ) + ).toHaveLength(0); + }); + + it('should validate incorrect action params and filter duplicated errors', () => { + validateParamsMock.mockReturnValue({ + errors: ['Message is required', 'Message is required', 'Message is required'], + }); + + expect( + validateActionParams( + { + id: '817b8bca-91d1-4729-8ee1-3a83aaafd9d4', + group: 'default', + actionTypeId: '.slack', + params: {}, + }, + actionTypeRegistry + ) + ).toHaveLength(1); + }); + }); +}); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.ts b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.ts new file mode 100644 index 00000000000000..ed80926d06ed6c --- /dev/null +++ b/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import mustache from 'mustache'; +import { uniq, startCase, flattenDeep, isArray, isString } from 'lodash/fp'; + +import { + AlertAction, + ActionTypeRegistryContract, +} from '../../../../../../triggers_actions_ui/public'; +import * as I18n from './translations'; + +const UUID_V4_REGEX = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; + +export const isUuidv4 = (id: AlertAction['id']) => !!id.match(UUID_V4_REGEX); + +export const getActionTypeName = (actionTypeId: AlertAction['actionTypeId']) => { + if (!actionTypeId) return ''; + const actionType = actionTypeId.split('.')[1]; + + if (!actionType) return ''; + + return startCase(actionType); +}; + +export const validateMustache = (params: AlertAction['params']) => { + const errors: string[] = []; + Object.entries(params).forEach(([paramKey, paramValue]) => { + if (!isString(paramValue)) return; + try { + mustache.render(paramValue, {}); + } catch (e) { + errors.push(I18n.INVALID_MUSTACHE_TEMPLATE(paramKey)); + } + }); + + return errors; +}; + +export const validateActionParams = ( + actionItem: AlertAction, + actionTypeRegistry: ActionTypeRegistryContract +): string[] => { + const actionErrors = actionTypeRegistry + .get(actionItem.actionTypeId) + ?.validateParams(actionItem.params); + + if (actionErrors) { + const actionErrorsValues = Object.values(actionErrors.errors); + + if (actionErrorsValues.length) { + const filteredObjects: Array = actionErrorsValues.filter( + item => isString(item) || isArray(item) + ) as Array; + const uniqActionErrors = uniq(flattenDeep(filteredObjects)); + + if (uniqActionErrors.length) { + return uniqActionErrors; + } + } + } + + return []; +}; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 60073f8a0583c2..bc4a1ace2967b7 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -13304,8 +13304,8 @@ "xpack.siem.detectionEngine.components.importRuleModal.overwriteDescription": "保存されたオブジェクトを同じルールIDで自動的に上書きします", "xpack.siem.detectionEngine.components.importRuleModal.selectRuleDescription": "インポートする SIEM ルール (検出エンジンビューからエクスポートしたもの) を選択します", "xpack.siem.detectionEngine.components.importRuleModal.successfullyImportedRulesTitle": "{totalRules} {totalRules, plural, =1 {ルール} other {ルール}}を正常にインポートしました", - "xpack.siem.detectionEngine.createRule. stepScheduleRule.completeWithActivatingTitle": "ルールの作成と有効化", - "xpack.siem.detectionEngine.createRule. stepScheduleRule.completeWithoutActivatingTitle": "有効化せずにルールを作成", + "xpack.siem.detectionEngine.createRule.stepScheduleRule.completeWithActivatingTitle": "ルールの作成と有効化", + "xpack.siem.detectionEngine.createRule.stepScheduleRule.completeWithoutActivatingTitle": "有効化せずにルールを作成", "xpack.siem.detectionEngine.createRule.backToRulesDescription": "シグナル検出ルールに戻る", "xpack.siem.detectionEngine.createRule.editRuleButton": "編集", "xpack.siem.detectionEngine.createRule.filtersLabel": "フィルター", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bc95b68082f761..b22b607f63aebc 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -13311,8 +13311,8 @@ "xpack.siem.detectionEngine.components.importRuleModal.overwriteDescription": "自动覆盖具有相同规则 ID 的已保存对象", "xpack.siem.detectionEngine.components.importRuleModal.selectRuleDescription": "选择要导入的 SIEM 规则(如从检测引擎视图导出的)", "xpack.siem.detectionEngine.components.importRuleModal.successfullyImportedRulesTitle": "已成功导入 {totalRules} 个{totalRules, plural, =1 {规则} other {规则}}", - "xpack.siem.detectionEngine.createRule. stepScheduleRule.completeWithActivatingTitle": "创建并激活规则", - "xpack.siem.detectionEngine.createRule. stepScheduleRule.completeWithoutActivatingTitle": "创建规则但不激活", + "xpack.siem.detectionEngine.createRule.stepScheduleRule.completeWithActivatingTitle": "创建并激活规则", + "xpack.siem.detectionEngine.createRule.stepScheduleRule.completeWithoutActivatingTitle": "创建规则但不激活", "xpack.siem.detectionEngine.createRule.backToRulesDescription": "返回到信号检测规则", "xpack.siem.detectionEngine.createRule.editRuleButton": "编辑", "xpack.siem.detectionEngine.createRule.filtersLabel": "筛选", diff --git a/x-pack/plugins/triggers_actions_ui/public/index.ts b/x-pack/plugins/triggers_actions_ui/public/index.ts index a72d8815c95b4d..a0e8f3583ac433 100644 --- a/x-pack/plugins/triggers_actions_ui/public/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/index.ts @@ -15,13 +15,15 @@ export { AlertAction, Alert, AlertTypeModel, - AlertTypeParamsExpressionProps, ActionType, + ActionTypeRegistryContract, + AlertTypeParamsExpressionProps, } from './types'; export { ConnectorAddFlyout, ConnectorEditFlyout, } from './application/sections/action_connector_form'; +export { loadActionTypes } from './application/lib/action_connector_api'; export function plugin(ctx: PluginInitializerContext) { return new Plugin(ctx); From 0cc5d133d99f46f95cc9e0ae5ffcf5591c9ab0b8 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Fri, 15 May 2020 17:21:42 +0200 Subject: [PATCH 09/16] lint import from restricted zones for export exressions (#66588) * line restricted zones for export exressions * more robust rule * fix or mute eslint errors Co-authored-by: Elastic Machine --- .../rules/__tests__/no_restricted_paths.js | 22 +++++++++++++++++++ .../rules/no_restricted_paths.js | 4 ++++ .../core_plugins/kibana/public/index.ts | 2 +- src/legacy/ui/public/private/index.d.ts | 2 +- src/legacy/ui/public/url/index.js | 1 + .../loader/pipeline_helpers/index.ts | 1 + src/plugins/dashboard/public/index.ts | 1 + .../public/index.ts | 2 +- .../public/application/editor/lib/index.ts | 2 +- x-pack/legacy/plugins/maps/public/index.ts | 4 ++-- .../xpack_main/public/components/index.js | 2 ++ x-pack/plugins/case/common/api/cases/case.ts | 1 + .../index_management/public/shared_imports.ts | 2 +- .../ingest_manager/services/index.ts | 2 +- .../ingest_pipelines/public/shared_imports.ts | 2 +- .../public/application/lib/telemetry.ts | 2 +- .../plugins/lists/common/siem_common_deps.ts | 2 ++ .../plugins/lists/server/siem_server_deps.ts | 13 ++++++++++- x-pack/plugins/monitoring/public/types.ts | 1 + x-pack/plugins/reporting/common/types.d.ts | 1 + .../transform/public/shared_imports.ts | 5 +---- .../public/application/shared_imports.ts | 2 +- 22 files changed, 60 insertions(+), 16 deletions(-) diff --git a/packages/kbn-eslint-plugin-eslint/rules/__tests__/no_restricted_paths.js b/packages/kbn-eslint-plugin-eslint/rules/__tests__/no_restricted_paths.js index 577be820ccc7bc..e16ba0d16bb876 100644 --- a/packages/kbn-eslint-plugin-eslint/rules/__tests__/no_restricted_paths.js +++ b/packages/kbn-eslint-plugin-eslint/rules/__tests__/no_restricted_paths.js @@ -196,6 +196,28 @@ ruleTester.run('@kbn/eslint/no-restricted-paths', rule, { ], invalid: [ + { + code: 'export { b } from "../server/b.js"', + filename: path.join(__dirname, './files/no_restricted_paths/client/a.js'), + options: [ + { + basePath: __dirname, + zones: [ + { + target: 'files/no_restricted_paths/client/**/*', + from: 'files/no_restricted_paths/server/**/*', + }, + ], + }, + ], + errors: [ + { + message: 'Unexpected path "../server/b.js" imported in restricted zone.', + line: 1, + column: 19, + }, + ], + }, { code: 'import b from "../server/b.js"', filename: path.join(__dirname, './files/no_restricted_paths/client/a.js'), diff --git a/packages/kbn-eslint-plugin-eslint/rules/no_restricted_paths.js b/packages/kbn-eslint-plugin-eslint/rules/no_restricted_paths.js index bed10e77597b78..40c53c7f28f6fd 100644 --- a/packages/kbn-eslint-plugin-eslint/rules/no_restricted_paths.js +++ b/packages/kbn-eslint-plugin-eslint/rules/no_restricted_paths.js @@ -126,6 +126,10 @@ module.exports = { } return { + ExportNamedDeclaration(node) { + if (!node.source) return; + checkForRestrictedImportPath(node.source.value, node.source); + }, ImportDeclaration(node) { checkForRestrictedImportPath(node.source.value, node.source); }, diff --git a/src/legacy/core_plugins/kibana/public/index.ts b/src/legacy/core_plugins/kibana/public/index.ts index be22652ab2c1c7..6b1b7f0d249ff4 100644 --- a/src/legacy/core_plugins/kibana/public/index.ts +++ b/src/legacy/core_plugins/kibana/public/index.ts @@ -20,4 +20,4 @@ export { ProcessedImportResponse, processImportResponse, -} from '../../../../plugins/saved_objects_management/public/lib'; +} from '../../../../plugins/saved_objects_management/public/lib'; // eslint-disable-line @kbn/eslint/no-restricted-paths diff --git a/src/legacy/ui/public/private/index.d.ts b/src/legacy/ui/public/private/index.d.ts index 895dc639393118..3b692ba58cbe1f 100644 --- a/src/legacy/ui/public/private/index.d.ts +++ b/src/legacy/ui/public/private/index.d.ts @@ -17,4 +17,4 @@ * under the License. */ -export { IPrivate } from '../../../../plugins/kibana_legacy/public/utils/private'; +export { IPrivate } from '../../../../plugins/kibana_legacy/public/'; diff --git a/src/legacy/ui/public/url/index.js b/src/legacy/ui/public/url/index.js index f3beb05e577c1d..8ef267de2890c2 100644 --- a/src/legacy/ui/public/url/index.js +++ b/src/legacy/ui/public/url/index.js @@ -19,4 +19,5 @@ export { KbnUrlProvider } from './url'; export { RedirectWhenMissingProvider } from './redirect_when_missing'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { modifyUrl } from '../../../../core/utils'; diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts index fe7f239fbea3bc..f9a2234d6e5a46 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts @@ -17,4 +17,5 @@ * under the License. */ +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { buildPipeline } from '../../../../../../plugins/visualizations/public/legacy/build_pipeline'; diff --git a/src/plugins/dashboard/public/index.ts b/src/plugins/dashboard/public/index.ts index e093342f957358..a5211fb3b5d7b3 100644 --- a/src/plugins/dashboard/public/index.ts +++ b/src/plugins/dashboard/public/index.ts @@ -33,6 +33,7 @@ export { DashboardConstants, createDashboardEditUrl } from './dashboard_constant export { DashboardStart, DashboardUrlGenerator } from './plugin'; export { DASHBOARD_APP_URL_GENERATOR } from './url_generator'; +export { addEmbeddableToDashboardUrl } from './url_utils/url_helper'; export function plugin(initializerContext: PluginInitializerContext) { return new DashboardPlugin(initializerContext); diff --git a/src/plugins/telemetry_management_section/public/index.ts b/src/plugins/telemetry_management_section/public/index.ts index 6a80cdd98b1a3d..082f68809a67e5 100644 --- a/src/plugins/telemetry_management_section/public/index.ts +++ b/src/plugins/telemetry_management_section/public/index.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ - +export { OptInExampleFlyout } from './components'; import { TelemetryManagementSectionPlugin } from './plugin'; export function plugin() { diff --git a/src/plugins/visualize/public/application/editor/lib/index.ts b/src/plugins/visualize/public/application/editor/lib/index.ts index d2fe028b371c25..78589383925fb9 100644 --- a/src/plugins/visualize/public/application/editor/lib/index.ts +++ b/src/plugins/visualize/public/application/editor/lib/index.ts @@ -19,4 +19,4 @@ export { useVisualizeAppState } from './visualize_app_state'; export { makeStateful } from './make_stateful'; -export { addEmbeddableToDashboardUrl } from '../../../../../dashboard/public/url_utils/url_helper'; +export { addEmbeddableToDashboardUrl } from '../../../../../dashboard/public/'; diff --git a/x-pack/legacy/plugins/maps/public/index.ts b/x-pack/legacy/plugins/maps/public/index.ts index e1532cac858ac0..89ce976de9278d 100644 --- a/x-pack/legacy/plugins/maps/public/index.ts +++ b/x-pack/legacy/plugins/maps/public/index.ts @@ -26,9 +26,9 @@ export const plugin = () => { return new MapsPlugin(); }; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { RenderTooltipContentParams, ITooltipProperty, -} from '../../../../plugins/maps/public/classes/tooltips/tooltip_property'; +} from '../../../../plugins/maps/public/classes/tooltips/tooltip_property'; // eslint-disable-line @kbn/eslint/no-restricted-paths +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { MapEmbeddable, MapEmbeddableInput } from '../../../../plugins/maps/public/embeddable'; diff --git a/x-pack/legacy/plugins/xpack_main/public/components/index.js b/x-pack/legacy/plugins/xpack_main/public/components/index.js index 871d86e642dec1..0fe056ec0d46fd 100644 --- a/x-pack/legacy/plugins/xpack_main/public/components/index.js +++ b/x-pack/legacy/plugins/xpack_main/public/components/index.js @@ -4,8 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { LicenseStatus } from '../../../../../plugins/license_management/public/application/sections/license_dashboard/license_status/license_status'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { AddLicense } from '../../../../../plugins/license_management/public/application/sections/license_dashboard/add_license/add_license'; /* diff --git a/x-pack/plugins/case/common/api/cases/case.ts b/x-pack/plugins/case/common/api/cases/case.ts index 586c2b0c2a2597..283196373fe9f7 100644 --- a/x-pack/plugins/case/common/api/cases/case.ts +++ b/x-pack/plugins/case/common/api/cases/case.ts @@ -11,6 +11,7 @@ import { UserRT } from '../user'; import { CommentResponseRt } from './comment'; import { CasesStatusResponseRt } from './status'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { ActionTypeExecutorResult } from '../../../../actions/server/types'; const StatusRt = rt.union([rt.literal('open'), rt.literal('closed')]); diff --git a/x-pack/plugins/index_management/public/shared_imports.ts b/x-pack/plugins/index_management/public/shared_imports.ts index cd2964df23d9bf..89423672615113 100644 --- a/x-pack/plugins/index_management/public/shared_imports.ts +++ b/x-pack/plugins/index_management/public/shared_imports.ts @@ -10,7 +10,7 @@ export { UseRequestConfig, sendRequest, useRequest, -} from '../../../../src/plugins/es_ui_shared/public/request/np_ready_request'; +} from '../../../../src/plugins/es_ui_shared/public/'; export { FormSchema, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts index 64669b5cd123a5..085bad2d183753 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getFlattenedObject } from '../../../../../../../src/core/utils'; +export { getFlattenedObject } from '../../../../../../../src/core/public'; export { agentConfigRouteService, diff --git a/x-pack/plugins/ingest_pipelines/public/shared_imports.ts b/x-pack/plugins/ingest_pipelines/public/shared_imports.ts index cfa946ff942ecd..a2ee3215260520 100644 --- a/x-pack/plugins/ingest_pipelines/public/shared_imports.ts +++ b/x-pack/plugins/ingest_pipelines/public/shared_imports.ts @@ -12,7 +12,7 @@ export { UseRequestConfig, sendRequest, useRequest, -} from '../../../../src/plugins/es_ui_shared/public/request/np_ready_request'; +} from '../../../../src/plugins/es_ui_shared/public/'; export { FormSchema, diff --git a/x-pack/plugins/license_management/public/application/lib/telemetry.ts b/x-pack/plugins/license_management/public/application/lib/telemetry.ts index 823680a36dccb1..421f0887a14c05 100644 --- a/x-pack/plugins/license_management/public/application/lib/telemetry.ts +++ b/x-pack/plugins/license_management/public/application/lib/telemetry.ts @@ -6,7 +6,7 @@ import { TelemetryPluginSetup } from '../../../../../../src/plugins/telemetry/public'; -export { OptInExampleFlyout } from '../../../../../../src/plugins/telemetry_management_section/public/components'; +export { OptInExampleFlyout } from '../../../../../../src/plugins/telemetry_management_section/public/'; export { PRIVACY_STATEMENT_URL } from '../../../../../../src/plugins/telemetry/common/constants'; export { TelemetryPluginSetup, shouldShowTelemetryOptIn }; diff --git a/x-pack/plugins/lists/common/siem_common_deps.ts b/x-pack/plugins/lists/common/siem_common_deps.ts index 5e74753a6f0bde..c5242843dfbdd0 100644 --- a/x-pack/plugins/lists/common/siem_common_deps.ts +++ b/x-pack/plugins/lists/common/siem_common_deps.ts @@ -4,5 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { getPaths, foldLeftRight } from '../../siem/server/utils/build_validation/__mocks__/utils'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { exactCheck } from '../../siem/server/utils/build_validation/exact_check'; diff --git a/x-pack/plugins/lists/server/siem_server_deps.ts b/x-pack/plugins/lists/server/siem_server_deps.ts index e78debc8e43492..6231b2e014111b 100644 --- a/x-pack/plugins/lists/server/siem_server_deps.ts +++ b/x-pack/plugins/lists/server/siem_server_deps.ts @@ -7,15 +7,26 @@ export { transformError, buildSiemResponse, -} from '../../siem/server/lib/detection_engine/routes/utils'; +} from '../../siem/server/lib/detection_engine/routes/utils'; // eslint-disable-line @kbn/eslint/no-restricted-paths +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { deleteTemplate } from '../../siem/server/lib/detection_engine/index/delete_template'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { deletePolicy } from '../../siem/server/lib/detection_engine/index/delete_policy'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { deleteAllIndex } from '../../siem/server/lib/detection_engine/index/delete_all_index'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { setPolicy } from '../../siem/server/lib/detection_engine/index/set_policy'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { setTemplate } from '../../siem/server/lib/detection_engine/index/set_template'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { getTemplateExists } from '../../siem/server/lib/detection_engine/index/get_template_exists'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { getPolicyExists } from '../../siem/server/lib/detection_engine/index/get_policy_exists'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { createBootstrapIndex } from '../../siem/server/lib/detection_engine/index/create_bootstrap_index'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { getIndexExists } from '../../siem/server/lib/detection_engine/index/get_index_exists'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { buildRouteValidation } from '../../siem/server/utils/build_validation/route_validation'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { validate } from '../../siem/server/lib/detection_engine/routes/rules/validate'; diff --git a/x-pack/plugins/monitoring/public/types.ts b/x-pack/plugins/monitoring/public/types.ts index 5fcb6b50f5d834..b8c854f4e7ee0d 100644 --- a/x-pack/plugins/monitoring/public/types.ts +++ b/x-pack/plugins/monitoring/public/types.ts @@ -8,6 +8,7 @@ import { PluginInitializerContext, CoreStart } from 'kibana/public'; import { NavigationPublicPluginStart as NavigationStart } from '../../../../src/plugins/navigation/public'; import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { MonitoringConfig } from '../server'; export interface MonitoringPluginDependencies { diff --git a/x-pack/plugins/reporting/common/types.d.ts b/x-pack/plugins/reporting/common/types.d.ts index 34f0bc9ac8a366..7ab9a15e1773a5 100644 --- a/x-pack/plugins/reporting/common/types.d.ts +++ b/x-pack/plugins/reporting/common/types.d.ts @@ -4,4 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ +// eslint-disable-next-line @kbn/eslint/no-restricted-paths export { ConfigType } from '../server/config'; diff --git a/x-pack/plugins/transform/public/shared_imports.ts b/x-pack/plugins/transform/public/shared_imports.ts index 3737377de2d5ee..56be8d7bb7de7a 100644 --- a/x-pack/plugins/transform/public/shared_imports.ts +++ b/x-pack/plugins/transform/public/shared_imports.ts @@ -9,12 +9,9 @@ export { XJsonMode, collapseLiteralStrings, expandLiteralStrings, -} from '../../../../src/plugins/es_ui_shared/public'; - -export { UseRequestConfig, useRequest, -} from '../../../../src/plugins/es_ui_shared/public/request/np_ready_request'; +} from '../../../../src/plugins/es_ui_shared/public'; export { getErrorMessage, diff --git a/x-pack/plugins/watcher/public/application/shared_imports.ts b/x-pack/plugins/watcher/public/application/shared_imports.ts index 94ef7af1c28d13..a9e07b80a9b221 100644 --- a/x-pack/plugins/watcher/public/application/shared_imports.ts +++ b/x-pack/plugins/watcher/public/application/shared_imports.ts @@ -10,6 +10,6 @@ export { UseRequestConfig, sendRequest, useRequest, -} from '../../../../../src/plugins/es_ui_shared/public/request/np_ready_request'; +} from '../../../../../src/plugins/es_ui_shared/public/'; export { useXJsonMode } from '../../../../../src/plugins/es_ui_shared/static/ace_x_json/hooks'; From 02f2e80fcee11c4b04adf07568aefc82e0e9a3dc Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Fri, 15 May 2020 12:15:19 -0400 Subject: [PATCH 10/16] [CI] Add 20 minutes to overall build timeout --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index ad5bd23b76b5d0..f435b18c6d824e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -3,7 +3,7 @@ library 'kibana-pipeline-library' kibanaLibrary.load() -kibanaPipeline(timeoutMinutes: 135, checkPrChanges: true) { +kibanaPipeline(timeoutMinutes: 155, checkPrChanges: true) { ciStats.trackBuild { githubPr.withDefaultPrComments { catchError { From 62e8214f903c7250c22f4bc80eaef17300b042d5 Mon Sep 17 00:00:00 2001 From: Josh Dover Date: Fri, 15 May 2020 10:22:12 -0600 Subject: [PATCH 11/16] Migrate Beats Management UI to KP (#65791) --- x-pack/.i18nrc.json | 2 +- .../common/constants/index.ts | 2 +- .../legacy/plugins/beats_management/index.ts | 5 - .../framework/kibana_framework_adapter.ts | 261 ------------------ .../public/lib/compose/memory.ts | 70 ----- .../beats_management/scripts/fake_env.ts | 3 +- .../lib/adapters/events/adapter_types.ts | 3 +- .../elasticsearch_beat_events_adapter.ts | 3 +- .../server/rest_api/beats/tag_assignment.ts | 3 +- .../plugins/beats_management/common/index.ts | 21 ++ x-pack/plugins/beats_management/kibana.json | 15 + .../beats_management/public/application.tsx} | 48 ++-- .../beats_management/public/bootstrap.tsx | 72 +++++ .../components/autocomplete_field/index.tsx | 2 +- .../autocomplete_field/suggestion_item.tsx | 2 +- .../public/components/config_list.tsx | 6 +- .../public/components/enroll_beats.tsx | 2 +- .../public/components/inputs/code_editor.tsx | 0 .../public/components/inputs/index.ts | 0 .../public/components/inputs/input.tsx | 0 .../public/components/inputs/multi_input.tsx | 0 .../components/inputs/password_input.tsx | 0 .../public/components/inputs/select.tsx | 0 .../public/components/layouts/background.tsx | 0 .../public/components/layouts/no_data.tsx | 0 .../public/components/layouts/primary.tsx | 0 .../public/components/layouts/walkthrough.tsx | 0 .../public/components/loading.tsx | 0 .../navigation/breadcrumb/breadcrumb.tsx | 4 +- .../navigation/breadcrumb/consumer.tsx | 0 .../navigation/breadcrumb/context.tsx | 0 .../components/navigation/breadcrumb/index.ts | 0 .../navigation/breadcrumb/provider.tsx | 4 +- .../navigation/breadcrumb/types.d.ts | 0 .../components/navigation/child_routes.tsx | 0 .../components/navigation/connected_link.tsx | 0 .../public/components/table/action_schema.ts | 0 .../table/controls/action_control.tsx | 0 .../public/components/table/controls/index.ts | 0 .../table/controls/option_control.tsx | 0 .../table/controls/tag_badge_list.tsx | 2 +- .../public/components/table/index.ts | 0 .../public/components/table/table.tsx | 4 +- .../components/table/table_type_configs.tsx | 5 +- .../tag/config_view/config_form.tsx | 5 +- .../components/tag/config_view/index.tsx | 6 +- .../public/components/tag/index.ts | 0 .../public/components/tag/tag_badge.tsx | 2 +- .../public/components/tag/tag_edit.tsx | 6 +- .../public/containers/beats.ts | 4 +- .../public/containers/tags.ts | 2 +- .../containers/with_kuery_autocompletion.tsx | 2 +- .../public/containers/with_url_state.tsx | 0 .../public/frontend_types.d.ts | 0 .../plugins/beats_management/public/index.ts | 38 +++ .../beats_management/public/kbn_services.ts | 25 ++ .../lib/__tests__/config_blocks.test.ts | 4 +- .../lib/adapters/beats/adapter_types.ts | 4 +- .../adapters/beats/memory_beats_adapter.ts | 4 +- .../lib/adapters/beats/rest_beats_adapter.ts | 4 +- .../configuration_blocks/adapter_types.ts | 7 +- .../memory_config_blocks_adapter.ts | 7 +- .../rest_config_blocks_adapter.ts | 4 +- .../adapters/elasticsearch/adapter_types.ts | 2 +- .../lib/adapters/elasticsearch/memory.ts | 2 +- .../public/lib/adapters/elasticsearch/rest.ts | 8 +- .../lib/adapters/framework/adapter_types.ts | 33 +-- .../framework/kibana_framework_adapter.ts | 182 ++++++++++++ .../framework/testing_framework_adapter.ts | 17 +- .../lib/adapters/rest_api/adapter_types.ts | 0 .../rest_api/axios_rest_api_adapter.ts | 0 .../rest_api/node_axios_api_adapter.ts | 0 .../public/lib/adapters/tags/adapter_types.ts | 5 +- .../lib/adapters/tags/memory_tags_adapter.ts | 5 +- .../lib/adapters/tags/rest_tags_adapter.ts | 7 +- .../lib/adapters/tokens/adapter_types.ts | 0 .../adapters/tokens/memory_tokens_adapter.ts | 0 .../adapters/tokens/rest_tokens_adapter.ts | 2 +- .../beats_management/public/lib/beats.ts | 4 +- .../public/lib/compose/kibana.ts | 51 ++-- .../public/lib/compose/scripts.ts | 4 +- .../public/lib/configuration_blocks.ts | 5 +- .../public/lib/elasticsearch.ts | 2 +- .../beats_management/public/lib/framework.ts | 6 +- .../beats_management/public/lib/tags.ts | 2 +- .../beats_management/public/lib/types.ts | 0 .../beats_management/public/pages/__404.tsx | 0 .../public/pages/beat/details.tsx | 12 +- .../public/pages/beat/index.tsx | 2 +- .../public/pages/beat/tags.tsx | 5 +- .../public/pages/error/enforce_security.tsx | 0 .../public/pages/error/invalid_license.tsx | 0 .../public/pages/error/no_access.tsx | 0 .../beats_management/public/pages/index.ts | 0 .../pages/overview/configuration_tags.tsx | 0 .../public/pages/overview/enrolled_beats.tsx | 5 +- .../public/pages/overview/index.tsx | 2 +- .../public/pages/tag/create.tsx | 7 +- .../public/pages/tag/edit.tsx | 8 +- .../public/pages/walkthrough/initial/beat.tsx | 0 .../pages/walkthrough/initial/finish.tsx | 2 +- .../pages/walkthrough/initial/index.tsx | 0 .../public/pages/walkthrough/initial/tag.tsx | 5 +- .../beats_management/public/router.tsx | 0 .../public/utils/random_eui_color.ts | 0 .../public/utils/typed_react.ts | 0 .../plugins/beats_management/server/index.ts | 23 ++ 107 files changed, 562 insertions(+), 509 deletions(-) delete mode 100644 x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts delete mode 100644 x-pack/legacy/plugins/beats_management/public/lib/compose/memory.ts create mode 100644 x-pack/plugins/beats_management/common/index.ts create mode 100644 x-pack/plugins/beats_management/kibana.json rename x-pack/{legacy/plugins/beats_management/public/index.tsx => plugins/beats_management/public/application.tsx} (64%) create mode 100644 x-pack/plugins/beats_management/public/bootstrap.tsx rename x-pack/{legacy => }/plugins/beats_management/public/components/autocomplete_field/index.tsx (99%) rename x-pack/{legacy => }/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx (97%) rename x-pack/{legacy => }/plugins/beats_management/public/components/config_list.tsx (91%) rename x-pack/{legacy => }/plugins/beats_management/public/components/enroll_beats.tsx (99%) rename x-pack/{legacy => }/plugins/beats_management/public/components/inputs/code_editor.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/inputs/index.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/inputs/input.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/inputs/multi_input.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/inputs/password_input.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/inputs/select.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/layouts/background.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/layouts/no_data.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/layouts/primary.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/layouts/walkthrough.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/loading.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx (90%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/breadcrumb/consumer.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/breadcrumb/context.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/breadcrumb/index.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx (95%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/breadcrumb/types.d.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/child_routes.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/navigation/connected_link.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/action_schema.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/controls/action_control.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/controls/index.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/controls/option_control.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/controls/tag_badge_list.tsx (96%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/index.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/table.tsx (96%) rename x-pack/{legacy => }/plugins/beats_management/public/components/table/table_type_configs.tsx (98%) rename x-pack/{legacy => }/plugins/beats_management/public/components/tag/config_view/config_form.tsx (98%) rename x-pack/{legacy => }/plugins/beats_management/public/components/tag/config_view/index.tsx (94%) rename x-pack/{legacy => }/plugins/beats_management/public/components/tag/index.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/components/tag/tag_badge.tsx (93%) rename x-pack/{legacy => }/plugins/beats_management/public/components/tag/tag_edit.tsx (98%) rename x-pack/{legacy => }/plugins/beats_management/public/containers/beats.ts (93%) rename x-pack/{legacy => }/plugins/beats_management/public/containers/tags.ts (93%) rename x-pack/{legacy => }/plugins/beats_management/public/containers/with_kuery_autocompletion.tsx (96%) rename x-pack/{legacy => }/plugins/beats_management/public/containers/with_url_state.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/frontend_types.d.ts (100%) create mode 100644 x-pack/plugins/beats_management/public/index.ts create mode 100644 x-pack/plugins/beats_management/public/kbn_services.ts rename x-pack/{legacy => }/plugins/beats_management/public/lib/__tests__/config_blocks.test.ts (95%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/beats/adapter_types.ts (84%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts (94%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts (92%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts (67%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts (84%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts (86%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/elasticsearch/adapter_types.ts (85%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/elasticsearch/memory.ts (91%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/elasticsearch/rest.ts (85%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/framework/adapter_types.ts (69%) create mode 100644 x-pack/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/framework/testing_framework_adapter.ts (79%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/rest_api/adapter_types.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/rest_api/axios_rest_api_adapter.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/rest_api/node_axios_api_adapter.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/tags/adapter_types.ts (82%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/tags/memory_tags_adapter.ts (91%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts (90%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/tokens/adapter_types.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/tokens/memory_tokens_adapter.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts (87%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/beats.ts (92%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/compose/kibana.ts (59%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/compose/scripts.ts (91%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/configuration_blocks.ts (97%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/elasticsearch.ts (96%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/framework.ts (92%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/tags.ts (93%) rename x-pack/{legacy => }/plugins/beats_management/public/lib/types.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/__404.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/beat/details.tsx (93%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/beat/index.tsx (98%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/beat/tags.tsx (94%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/error/enforce_security.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/error/invalid_license.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/error/no_access.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/index.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/overview/configuration_tags.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/overview/enrolled_beats.tsx (99%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/overview/index.tsx (97%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/tag/create.tsx (95%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/tag/edit.tsx (96%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/walkthrough/initial/beat.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/walkthrough/initial/finish.tsx (97%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/walkthrough/initial/index.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx (97%) rename x-pack/{legacy => }/plugins/beats_management/public/router.tsx (100%) rename x-pack/{legacy => }/plugins/beats_management/public/utils/random_eui_color.ts (100%) rename x-pack/{legacy => }/plugins/beats_management/public/utils/typed_react.ts (100%) create mode 100644 x-pack/plugins/beats_management/server/index.ts diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 7c464d44d57610..7ac27dd47ad64e 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -7,7 +7,7 @@ "xpack.alerting": "plugins/alerting", "xpack.alertingBuiltins": "plugins/alerting_builtins", "xpack.apm": ["legacy/plugins/apm", "plugins/apm"], - "xpack.beatsManagement": "legacy/plugins/beats_management", + "xpack.beatsManagement": ["legacy/plugins/beats_management", "plugins/beats_management"], "xpack.canvas": "plugins/canvas", "xpack.dashboard": "plugins/dashboard_enhanced", "xpack.crossClusterReplication": "plugins/cross_cluster_replication", diff --git a/x-pack/legacy/plugins/beats_management/common/constants/index.ts b/x-pack/legacy/plugins/beats_management/common/constants/index.ts index 31fa84906cd38a..5f9ae815e34d44 100644 --- a/x-pack/legacy/plugins/beats_management/common/constants/index.ts +++ b/x-pack/legacy/plugins/beats_management/common/constants/index.ts @@ -9,4 +9,4 @@ export { INDEX_NAMES } from './index_names'; export { PLUGIN } from './plugin'; export { LICENSES, REQUIRED_LICENSES, REQUIRED_ROLES } from './security'; export { TABLE_CONFIG } from './table'; -export const BASE_PATH = '/management/beats_management'; +export const BASE_PATH = '/management/beats/beats_management'; diff --git a/x-pack/legacy/plugins/beats_management/index.ts b/x-pack/legacy/plugins/beats_management/index.ts index 3355bc98818118..b5399595fb7828 100644 --- a/x-pack/legacy/plugins/beats_management/index.ts +++ b/x-pack/legacy/plugins/beats_management/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ import Joi from 'joi'; -import { resolve } from 'path'; import { PLUGIN } from './common/constants'; import { CONFIG_PREFIX } from './common/constants/plugin'; import { initServerWithKibana } from './server/kibana.index'; @@ -29,10 +28,6 @@ export function beats(kibana: any) { return new kibana.Plugin({ id: PLUGIN.ID, require: ['kibana', 'elasticsearch', 'xpack_main'], - publicDir: resolve(__dirname, 'public'), - uiExports: { - managementSections: ['plugins/beats_management'], - }, config: () => config, configPrefix: CONFIG_PREFIX, init(server: KibanaLegacyServer) { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts deleted file mode 100644 index b2cfd826e62079..00000000000000 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/* eslint-disable max-classes-per-file */ -import { IScope } from 'angular'; -import { PathReporter } from 'io-ts/lib/PathReporter'; -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { UIRoutes } from 'ui/routes'; -import { isLeft } from 'fp-ts/lib/Either'; -import { npSetup } from 'ui/new_platform'; -import { SecurityPluginSetup } from '../../../../../../../plugins/security/public'; -import { BufferedKibanaServiceCall, KibanaAdapterServiceRefs, KibanaUIConfig } from '../../types'; -import { - FrameworkAdapter, - FrameworkInfo, - FrameworkUser, - ManagementAPI, - RuntimeFrameworkInfo, - RuntimeFrameworkUser, -} from './adapter_types'; -interface IInjector { - get(injectable: string): any; -} - -export class KibanaFrameworkAdapter implements FrameworkAdapter { - public get info() { - if (this.xpackInfo) { - return this.xpackInfo; - } else { - throw new Error('framework adapter must have init called before anything else'); - } - } - - public get currentUser() { - return this.shieldUser!; - } - private xpackInfo: FrameworkInfo | null = null; - private adapterService: KibanaAdapterServiceProvider; - private shieldUser: FrameworkUser | null = null; - constructor( - private readonly PLUGIN_ID: string, - private readonly management: ManagementAPI, - private readonly routes: UIRoutes, - private readonly getBasePath: () => string, - private readonly onKibanaReady: () => Promise, - private readonly xpackInfoService: any | null, - public readonly version: string - ) { - this.adapterService = new KibanaAdapterServiceProvider(); - } - - public setUISettings = (key: string, value: any) => { - this.adapterService.callOrBuffer(({ config }) => { - config.set(key, value); - }); - }; - - public async waitUntilFrameworkReady(): Promise { - await this.onKibanaReady(); - const xpackInfo: any = this.xpackInfoService; - let xpackInfoUnpacked: FrameworkInfo; - - try { - xpackInfoUnpacked = { - basePath: this.getBasePath(), - license: { - type: xpackInfo ? xpackInfo.getLicense().type : 'oss', - expired: xpackInfo ? !xpackInfo.getLicense().isActive : false, - expiry_date_in_millis: - xpackInfo.getLicense().expiryDateInMillis !== undefined - ? xpackInfo.getLicense().expiryDateInMillis - : -1, - }, - security: { - enabled: xpackInfo - ? xpackInfo.get(`features.${this.PLUGIN_ID}.security.enabled`, false) - : false, - available: xpackInfo - ? xpackInfo.get(`features.${this.PLUGIN_ID}.security.available`, false) - : false, - }, - settings: xpackInfo ? xpackInfo.get(`features.${this.PLUGIN_ID}.settings`) : {}, - }; - } catch (e) { - throw new Error(`Unexpected data structure from xpackInfoService, ${JSON.stringify(e)}`); - } - - const assertData = RuntimeFrameworkInfo.decode(xpackInfoUnpacked); - if (isLeft(assertData)) { - throw new Error( - `Error parsing xpack info in ${this.PLUGIN_ID}, ${PathReporter.report(assertData)[0]}` - ); - } - this.xpackInfo = xpackInfoUnpacked; - - const securitySetup = ((npSetup.plugins as unknown) as { security?: SecurityPluginSetup }) - .security; - try { - this.shieldUser = (await securitySetup?.authc.getCurrentUser()) || null; - const assertUser = RuntimeFrameworkUser.decode(this.shieldUser); - - if (isLeft(assertUser)) { - throw new Error( - `Error parsing user info in ${this.PLUGIN_ID}, ${PathReporter.report(assertUser)[0]}` - ); - } - } catch (e) { - this.shieldUser = null; - } - } - - public renderUIAtPath( - path: string, - component: React.ReactElement, - toController: 'management' | 'self' = 'self' - ) { - const adapter = this; - this.routes.when( - `${path}${[...Array(6)].map((e, n) => `/:arg${n}?`).join('')}`, // Hack because angular 1 does not support wildcards - { - template: - toController === 'self' - ? `<${this.PLUGIN_ID}>
` - : ` -
-
- `, - // eslint-disable-next-line max-classes-per-file - controller: ($scope: any, $route: any) => { - try { - $scope.$$postDigest(() => { - const elem = document.getElementById(`${this.PLUGIN_ID}ReactRoot`); - ReactDOM.render(component, elem); - adapter.manageAngularLifecycle($scope, $route, elem); - }); - $scope.$onInit = () => { - $scope.topNavMenu = []; - }; - } catch (e) { - throw new Error(`Error rendering Beats CM to the dom, ${e.message}`); - } - }, - } - ); - } - - public registerManagementSection(settings: { - id?: string; - name: string; - iconName: string; - order?: number; - }) { - const sectionId = settings.id || this.PLUGIN_ID; - - if (!this.management.hasItem(sectionId)) { - this.management.register(sectionId, { - display: settings.name, - icon: settings.iconName, - order: settings.order || 30, - }); - } - } - - public registerManagementUI(settings: { - sectionId?: string; - name: string; - basePath: string; - visable?: boolean; - order?: number; - }) { - const sectionId = settings.sectionId || this.PLUGIN_ID; - - if (!this.management.hasItem(sectionId)) { - throw new Error( - `registerManagementUI was called with a sectionId of ${sectionId}, and that is is not yet regestered as a section` - ); - } - - const section = this.management.getSection(sectionId); - - section.register(sectionId, { - visible: settings.visable || true, - display: settings.name, - order: settings.order || 30, - url: `#${settings.basePath}`, - }); - } - - private manageAngularLifecycle($scope: any, $route: any, elem: any) { - const lastRoute = $route.current; - const deregister = $scope.$on('$locationChangeSuccess', () => { - const currentRoute = $route.current; - // if templates are the same we are on the same route - if (lastRoute.$$route.template === currentRoute.$$route.template) { - // this prevents angular from destroying scope - $route.current = lastRoute; - } else { - if (elem) { - ReactDOM.unmountComponentAtNode(elem); - elem.remove(); - } - } - }); - $scope.$on('$destroy', () => { - if (deregister) { - deregister(); - } - - // manually unmount component when scope is destroyed - if (elem) { - ReactDOM.unmountComponentAtNode(elem); - elem.remove(); - } - }); - } -} - -class KibanaAdapterServiceProvider { - public serviceRefs: KibanaAdapterServiceRefs | null = null; - public bufferedCalls: Array> = []; - - public $get($rootScope: IScope, config: KibanaUIConfig) { - this.serviceRefs = { - config, - rootScope: $rootScope, - }; - - this.applyBufferedCalls(this.bufferedCalls); - - return this; - } - - public callOrBuffer(serviceCall: (serviceRefs: KibanaAdapterServiceRefs) => void) { - if (this.serviceRefs !== null) { - this.applyBufferedCalls([serviceCall]); - } else { - this.bufferedCalls.push(serviceCall); - } - } - - public applyBufferedCalls( - bufferedCalls: Array> - ) { - if (!this.serviceRefs) { - return; - } - - this.serviceRefs.rootScope.$apply(() => { - bufferedCalls.forEach(serviceCall => { - if (!this.serviceRefs) { - return; - } - return serviceCall(this.serviceRefs); - }); - }); - } -} diff --git a/x-pack/legacy/plugins/beats_management/public/lib/compose/memory.ts b/x-pack/legacy/plugins/beats_management/public/lib/compose/memory.ts deleted file mode 100644 index b8ecb644ff1b07..00000000000000 --- a/x-pack/legacy/plugins/beats_management/public/lib/compose/memory.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import 'ui/autoload/all'; -// @ts-ignore: path dynamic for kibana -import { management } from 'ui/management'; -// @ts-ignore: path dynamic for kibana -import { uiModules } from 'ui/modules'; -// @ts-ignore: path dynamic for kibana -import routes from 'ui/routes'; -import { configBlockSchemas } from '../../../common/config_schemas'; -import { translateConfigSchema } from '../../../common/config_schemas_translations_map'; -// @ts-ignore: path dynamic for kibana -import { MemoryBeatsAdapter } from '../adapters/beats/memory_beats_adapter'; -import { KibanaFrameworkAdapter } from '../adapters/framework/kibana_framework_adapter'; -import { MemoryTagsAdapter } from '../adapters/tags/memory_tags_adapter'; -import { MemoryTokensAdapter } from '../adapters/tokens/memory_tokens_adapter'; -import { BeatsLib } from '../beats'; -import { ConfigBlocksLib } from '../configuration_blocks'; -import { FrameworkLib } from '../framework'; -import { TagsLib } from '../tags'; -import { FrontendLibs } from '../types'; -import { MemoryElasticsearchAdapter } from './../adapters/elasticsearch/memory'; -import { ElasticsearchLib } from './../elasticsearch'; -import { QuerySuggestion } from '../../../../../../../src/plugins/data/public'; - -const onKibanaReady = uiModules.get('kibana').run; - -export function compose( - mockIsKueryValid: (kuery: string) => boolean, - mockKueryToEsQuery: (kuery: string) => string, - suggestions: QuerySuggestion[] -): FrontendLibs { - const esAdapter = new MemoryElasticsearchAdapter( - mockIsKueryValid, - mockKueryToEsQuery, - suggestions - ); - const elasticsearchLib = new ElasticsearchLib(esAdapter); - - const configBlocks = new ConfigBlocksLib({} as any, translateConfigSchema(configBlockSchemas)); - const tags = new TagsLib(new MemoryTagsAdapter([]), elasticsearchLib); - const tokens = new MemoryTokensAdapter(); - const beats = new BeatsLib(new MemoryBeatsAdapter([]), elasticsearchLib); - - const pluginUIModule = uiModules.get('app/beats_management'); - - const framework = new FrameworkLib( - new KibanaFrameworkAdapter( - pluginUIModule, - management, - routes, - () => '', - onKibanaReady, - null, - '7.0.0' - ) - ); - const libs: FrontendLibs = { - framework, - elasticsearch: elasticsearchLib, - tags, - tokens, - beats, - configBlocks, - }; - return libs; -} diff --git a/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts b/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts index e2e31a218943a0..fe8919f48ac106 100644 --- a/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts +++ b/x-pack/legacy/plugins/beats_management/scripts/fake_env.ts @@ -9,7 +9,8 @@ import request from 'request'; import uuidv4 from 'uuid/v4'; import { configBlockSchemas } from '../common/config_schemas'; import { BeatTag } from '../common/domain_types'; -import { compose } from '../public/lib/compose/scripts'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { compose } from '../../../../plugins/beats_management/public/lib/compose/scripts'; const args = process.argv.slice(2); const chance = new Chance(); diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/adapter_types.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/adapter_types.ts index 273584efb239b9..4cb38bb3d057b6 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/adapter_types.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/adapter_types.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { BeatEvent } from '../../../../common/domain_types'; -import { FrameworkUser } from '../../../../public/lib/adapters/framework/adapter_types'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { FrameworkUser } from '../../../../../../../plugins/beats_management/public/lib/adapters/framework/adapter_types'; export interface BeatEventsAdapter { bulkInsert(user: FrameworkUser, beatId: string, events: BeatEvent[]): Promise; diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/elasticsearch_beat_events_adapter.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/elasticsearch_beat_events_adapter.ts index 62759ce0f5215e..b5056140c8b860 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/elasticsearch_beat_events_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/events/elasticsearch_beat_events_adapter.ts @@ -5,7 +5,8 @@ */ import { BeatEvent } from '../../../../common/domain_types'; -import { FrameworkUser } from '../../../../public/lib/adapters/framework/adapter_types'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { FrameworkUser } from '../../../../../../../plugins/beats_management/public/lib/adapters/framework/adapter_types'; import { DatabaseAdapter } from '../database/adapter_types'; import { BeatEventsAdapter } from './adapter_types'; diff --git a/x-pack/legacy/plugins/beats_management/server/rest_api/beats/tag_assignment.ts b/x-pack/legacy/plugins/beats_management/server/rest_api/beats/tag_assignment.ts index 90ba4056d7c984..db19e5b6a7627e 100644 --- a/x-pack/legacy/plugins/beats_management/server/rest_api/beats/tag_assignment.ts +++ b/x-pack/legacy/plugins/beats_management/server/rest_api/beats/tag_assignment.ts @@ -7,7 +7,8 @@ import Joi from 'joi'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; import { ReturnTypeBulkAction } from '../../../common/return_types'; -import { BeatsTagAssignment } from '../../../public/lib/adapters/beats/adapter_types'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { BeatsTagAssignment } from '../../../../../../plugins/beats_management/public/lib/adapters/beats/adapter_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; diff --git a/x-pack/plugins/beats_management/common/index.ts b/x-pack/plugins/beats_management/common/index.ts new file mode 100644 index 00000000000000..92ca870810ce8d --- /dev/null +++ b/x-pack/plugins/beats_management/common/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { schema, TypeOf } from '@kbn/config-schema'; + +const DEFAULT_ENROLLMENT_TOKENS_TTL_S = 10 * 60; // 10 minutes + +export const beatsManagementConfigSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), + defaultUserRoles: schema.arrayOf(schema.string(), { defaultValue: ['superuser'] }), + encryptionKey: schema.string({ defaultValue: 'xpack_beats_default_encryptionKey' }), + enrollmentTokensTtlInSeconds: schema.number({ + min: 1, + max: 10 * 60 * 14, // No more then 2 weeks for security reasons, + defaultValue: DEFAULT_ENROLLMENT_TOKENS_TTL_S, + }), +}); + +export type BeatsManagementConfigType = TypeOf; diff --git a/x-pack/plugins/beats_management/kibana.json b/x-pack/plugins/beats_management/kibana.json new file mode 100644 index 00000000000000..1b431216ef9923 --- /dev/null +++ b/x-pack/plugins/beats_management/kibana.json @@ -0,0 +1,15 @@ +{ + "id": "beats_management", + "configPath": ["xpack", "beats_management"], + "ui": true, + "server": true, + "version": "kibana", + "requiredPlugins": [ + "data", + "licensing", + "management" + ], + "optionalPlugins": [ + "security" + ] +} diff --git a/x-pack/legacy/plugins/beats_management/public/index.tsx b/x-pack/plugins/beats_management/public/application.tsx similarity index 64% rename from x-pack/legacy/plugins/beats_management/public/index.tsx rename to x-pack/plugins/beats_management/public/application.tsx index cebefabe77cdcd..bf450e9c7a5e31 100644 --- a/x-pack/legacy/plugins/beats_management/public/index.tsx +++ b/x-pack/plugins/beats_management/public/application.tsx @@ -7,26 +7,28 @@ import * as euiVars from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import ReactDOM from 'react-dom'; import { HashRouter } from 'react-router-dom'; import { ThemeProvider } from 'styled-components'; -import { I18nContext } from 'ui/i18n'; import { Provider as UnstatedProvider, Subscribe } from 'unstated'; -import { BASE_PATH } from '../common/constants'; import { Background } from './components/layouts/background'; import { BreadcrumbProvider } from './components/navigation/breadcrumb'; import { Breadcrumb } from './components/navigation/breadcrumb/breadcrumb'; import { BeatsContainer } from './containers/beats'; import { TagsContainer } from './containers/tags'; -import { compose } from './lib/compose/kibana'; import { FrontendLibs } from './lib/types'; import { AppRouter } from './router'; +import { services } from './kbn_services'; +import { ManagementAppMountParams } from '../../../../src/plugins/management/public'; -async function startApp(libs: FrontendLibs) { - libs.framework.renderUIAtPath( - BASE_PATH, +export const renderApp = ( + { basePath, element, setBreadcrumbs }: ManagementAppMountParams, + libs: FrontendLibs +) => { + ReactDOM.render( - - + + @@ -44,30 +46,12 @@ async function startApp(libs: FrontendLibs) { - + , - libs.framework.versionGreaterThen('6.7.0') ? 'management' : 'self' + element ); - await libs.framework.waitUntilFrameworkReady(); - - if (libs.framework.licenseIsAtLeast('standard')) { - libs.framework.registerManagementSection({ - id: 'beats', - name: i18n.translate('xpack.beatsManagement.centralManagementSectionLabel', { - defaultMessage: 'Beats', - }), - iconName: 'logoBeats', - }); - - libs.framework.registerManagementUI({ - sectionId: 'beats', - name: i18n.translate('xpack.beatsManagement.centralManagementLinkLabel', { - defaultMessage: 'Central Management', - }), - basePath: BASE_PATH, - }); - } -} - -startApp(compose()); + return () => { + ReactDOM.unmountComponentAtNode(element); + }; +}; diff --git a/x-pack/plugins/beats_management/public/bootstrap.tsx b/x-pack/plugins/beats_management/public/bootstrap.tsx new file mode 100644 index 00000000000000..ecca9da052feaa --- /dev/null +++ b/x-pack/plugins/beats_management/public/bootstrap.tsx @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { FrontendLibs } from './lib/types'; +import { compose } from './lib/compose/kibana'; + +import { setServices } from './kbn_services'; +import { ManagementSetup } from '../../../../src/plugins/management/public'; +import { SecurityPluginSetup } from '../../security/public'; +import { CoreSetup } from '../../../../src/core/public'; +import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +import { LicensingPluginSetup } from '../../licensing/public'; +import { BeatsManagementConfigType } from '../common'; + +async function startApp(libs: FrontendLibs, core: CoreSetup) { + await libs.framework.waitUntilFrameworkReady(); + + if (libs.framework.licenseIsAtLeast('standard')) { + libs.framework.registerManagementSection({ + id: 'beats', + name: i18n.translate('xpack.beatsManagement.centralManagementSectionLabel', { + defaultMessage: 'Beats', + }), + iconName: 'logoBeats', + }); + + libs.framework.registerManagementUI({ + sectionId: 'beats', + appId: 'beats_management', + name: i18n.translate('xpack.beatsManagement.centralManagementLinkLabel', { + defaultMessage: 'Central Management', + }), + async mount(params) { + const [coreStart, pluginsStart] = await core.getStartServices(); + setServices(coreStart, pluginsStart, params); + const { renderApp } = await import('./application'); + return renderApp(params, libs); + }, + }); + } +} + +interface SetupDeps { + management: ManagementSetup; + licensing: LicensingPluginSetup; + security?: SecurityPluginSetup; +} + +interface StartDeps { + data: DataPublicPluginStart; +} + +export const bootstrap = ( + core: CoreSetup, + plugins: SetupDeps, + config: BeatsManagementConfigType, + version: string +) => { + startApp( + compose({ + core, + config, + version, + ...plugins, + }), + core + ); +}; diff --git a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx b/x-pack/plugins/beats_management/public/components/autocomplete_field/index.tsx similarity index 99% rename from x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx rename to x-pack/plugins/beats_management/public/components/autocomplete_field/index.tsx index 70b7bd3df06629..107cb987f21079 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx +++ b/x-pack/plugins/beats_management/public/components/autocomplete_field/index.tsx @@ -13,7 +13,7 @@ import { import React from 'react'; import styled from 'styled-components'; -import { QuerySuggestion } from '../../../../../../../src/plugins/data/public'; +import { QuerySuggestion } from '../../../../../../src/plugins/data/public'; import { composeStateUpdaters } from '../../utils/typed_react'; import { SuggestionItem } from './suggestion_item'; diff --git a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx b/x-pack/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx similarity index 97% rename from x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx rename to x-pack/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx index 690d471b306ab8..38f1f5b0255329 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx +++ b/x-pack/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx @@ -9,7 +9,7 @@ import { tint } from 'polished'; import React from 'react'; import styled from 'styled-components'; -import { QuerySuggestion } from '../../../../../../../src/plugins/data/public'; +import { QuerySuggestion } from '../../../../../../src/plugins/data/public'; interface SuggestionItemProps { isSelected?: boolean; diff --git a/x-pack/legacy/plugins/beats_management/public/components/config_list.tsx b/x-pack/plugins/beats_management/public/components/config_list.tsx similarity index 91% rename from x-pack/legacy/plugins/beats_management/public/components/config_list.tsx rename to x-pack/plugins/beats_management/public/components/config_list.tsx index 3ffd42c5201f93..9116f7a37ce927 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/config_list.tsx +++ b/x-pack/plugins/beats_management/public/components/config_list.tsx @@ -8,9 +8,9 @@ import { EuiBasicTable, EuiLink } from '@elastic/eui'; import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; import React from 'react'; -import { configBlockSchemas } from '../../common/config_schemas'; -import { translateConfigSchema } from '../../common/config_schemas_translations_map'; -import { ConfigurationBlock } from '../../common/domain_types'; +import { configBlockSchemas } from '../../../../legacy/plugins/beats_management/common/config_schemas'; +import { translateConfigSchema } from '../../../../legacy/plugins/beats_management/common/config_schemas_translations_map'; +import { ConfigurationBlock } from '../../../../legacy/plugins/beats_management/common/domain_types'; interface ComponentProps { configs: { diff --git a/x-pack/legacy/plugins/beats_management/public/components/enroll_beats.tsx b/x-pack/plugins/beats_management/public/components/enroll_beats.tsx similarity index 99% rename from x-pack/legacy/plugins/beats_management/public/components/enroll_beats.tsx rename to x-pack/plugins/beats_management/public/components/enroll_beats.tsx index ee97198211b560..f7a8ea413531f6 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/enroll_beats.tsx +++ b/x-pack/plugins/beats_management/public/components/enroll_beats.tsx @@ -20,7 +20,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { capitalize } from 'lodash'; import React from 'react'; -import { CMBeat } from '../../common/domain_types'; +import { CMBeat } from '../../../../legacy/plugins/beats_management/common/domain_types'; interface ComponentProps { /** Such as kibanas basePath, for use to generate command */ diff --git a/x-pack/legacy/plugins/beats_management/public/components/inputs/code_editor.tsx b/x-pack/plugins/beats_management/public/components/inputs/code_editor.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/inputs/code_editor.tsx rename to x-pack/plugins/beats_management/public/components/inputs/code_editor.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/inputs/index.ts b/x-pack/plugins/beats_management/public/components/inputs/index.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/inputs/index.ts rename to x-pack/plugins/beats_management/public/components/inputs/index.ts diff --git a/x-pack/legacy/plugins/beats_management/public/components/inputs/input.tsx b/x-pack/plugins/beats_management/public/components/inputs/input.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/inputs/input.tsx rename to x-pack/plugins/beats_management/public/components/inputs/input.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/inputs/multi_input.tsx b/x-pack/plugins/beats_management/public/components/inputs/multi_input.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/inputs/multi_input.tsx rename to x-pack/plugins/beats_management/public/components/inputs/multi_input.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/inputs/password_input.tsx b/x-pack/plugins/beats_management/public/components/inputs/password_input.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/inputs/password_input.tsx rename to x-pack/plugins/beats_management/public/components/inputs/password_input.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/inputs/select.tsx b/x-pack/plugins/beats_management/public/components/inputs/select.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/inputs/select.tsx rename to x-pack/plugins/beats_management/public/components/inputs/select.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/layouts/background.tsx b/x-pack/plugins/beats_management/public/components/layouts/background.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/layouts/background.tsx rename to x-pack/plugins/beats_management/public/components/layouts/background.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/layouts/no_data.tsx b/x-pack/plugins/beats_management/public/components/layouts/no_data.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/layouts/no_data.tsx rename to x-pack/plugins/beats_management/public/components/layouts/no_data.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/layouts/primary.tsx b/x-pack/plugins/beats_management/public/components/layouts/primary.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/layouts/primary.tsx rename to x-pack/plugins/beats_management/public/components/layouts/primary.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/layouts/walkthrough.tsx b/x-pack/plugins/beats_management/public/components/layouts/walkthrough.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/layouts/walkthrough.tsx rename to x-pack/plugins/beats_management/public/components/layouts/walkthrough.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/loading.tsx b/x-pack/plugins/beats_management/public/components/loading.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/loading.tsx rename to x-pack/plugins/beats_management/public/components/loading.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx similarity index 90% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx rename to x-pack/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx index efe5eb25a0ac1c..13a0003b5ebdf8 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx +++ b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx @@ -5,7 +5,7 @@ */ import React, { Component } from 'react'; import { RouteProps } from 'react-router-dom'; -import { BASE_PATH } from '../../../../common/constants'; +import { BASE_PATH } from '../../../../../../legacy/plugins/beats_management/common/constants'; import { BreadcrumbConsumer } from './consumer'; import { Breadcrumb as BreadcrumbData, BreadcrumbContext } from './types'; @@ -53,7 +53,7 @@ export const Breadcrumb: React.FC = ({ title, path, parentBread {context => ( diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/consumer.tsx b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/consumer.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/consumer.tsx rename to x-pack/plugins/beats_management/public/components/navigation/breadcrumb/consumer.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/context.tsx b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/context.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/context.tsx rename to x-pack/plugins/beats_management/public/components/navigation/breadcrumb/context.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/index.ts b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/index.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/index.ts rename to x-pack/plugins/beats_management/public/components/navigation/breadcrumb/index.ts diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx similarity index 95% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx rename to x-pack/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx index f15e08c2ca230a..1dcceac5c710d8 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx +++ b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { Component, ReactElement } from 'react'; -import chrome from 'ui/chrome'; import { Provider } from './context'; import { Breadcrumb } from './types'; +import { services } from '../../../kbn_services'; interface ComponentProps { useGlobalBreadcrumbs: boolean; @@ -64,7 +64,7 @@ export class BreadcrumbProvider extends Component{this.props.children}; } diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/types.d.ts b/x-pack/plugins/beats_management/public/components/navigation/breadcrumb/types.d.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/types.d.ts rename to x-pack/plugins/beats_management/public/components/navigation/breadcrumb/types.d.ts diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/child_routes.tsx b/x-pack/plugins/beats_management/public/components/navigation/child_routes.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/child_routes.tsx rename to x-pack/plugins/beats_management/public/components/navigation/child_routes.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/connected_link.tsx b/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/navigation/connected_link.tsx rename to x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/action_schema.ts b/x-pack/plugins/beats_management/public/components/table/action_schema.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/table/action_schema.ts rename to x-pack/plugins/beats_management/public/components/table/action_schema.ts diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/controls/action_control.tsx b/x-pack/plugins/beats_management/public/components/table/controls/action_control.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/table/controls/action_control.tsx rename to x-pack/plugins/beats_management/public/components/table/controls/action_control.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/controls/index.ts b/x-pack/plugins/beats_management/public/components/table/controls/index.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/table/controls/index.ts rename to x-pack/plugins/beats_management/public/components/table/controls/index.ts diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/controls/option_control.tsx b/x-pack/plugins/beats_management/public/components/table/controls/option_control.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/table/controls/option_control.tsx rename to x-pack/plugins/beats_management/public/components/table/controls/option_control.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/controls/tag_badge_list.tsx b/x-pack/plugins/beats_management/public/components/table/controls/tag_badge_list.tsx similarity index 96% rename from x-pack/legacy/plugins/beats_management/public/components/table/controls/tag_badge_list.tsx rename to x-pack/plugins/beats_management/public/components/table/controls/tag_badge_list.tsx index cd75f882186c23..19acb1441df4c0 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/table/controls/tag_badge_list.tsx +++ b/x-pack/plugins/beats_management/public/components/table/controls/tag_badge_list.tsx @@ -13,7 +13,7 @@ import { EuiPopover, } from '@elastic/eui'; import React from 'react'; -import { TABLE_CONFIG } from '../../../../common/constants/table'; +import { TABLE_CONFIG } from '../../../../../../legacy/plugins/beats_management/common/constants/table'; import { TagBadge } from '../../tag/tag_badge'; import { AssignmentActionType } from '../index'; diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/index.ts b/x-pack/plugins/beats_management/public/components/table/index.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/table/index.ts rename to x-pack/plugins/beats_management/public/components/table/index.ts diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/table.tsx b/x-pack/plugins/beats_management/public/components/table/table.tsx similarity index 96% rename from x-pack/legacy/plugins/beats_management/public/components/table/table.tsx rename to x-pack/plugins/beats_management/public/components/table/table.tsx index 534da6541b683b..ae158e9d034767 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/table/table.tsx +++ b/x-pack/plugins/beats_management/public/components/table/table.tsx @@ -8,8 +8,8 @@ import { EuiBasicTable, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eu import { i18n } from '@kbn/i18n'; import React from 'react'; import styled from 'styled-components'; -import { QuerySuggestion } from '../../../../../../../src/plugins/data/public'; -import { TABLE_CONFIG } from '../../../common/constants'; +import { QuerySuggestion } from '../../../../../../src/plugins/data/public'; +import { TABLE_CONFIG } from '../../../../../legacy/plugins/beats_management/common/constants'; import { AutocompleteField } from '../autocomplete_field/index'; import { ControlSchema } from './action_schema'; import { OptionControl } from './controls/option_control'; diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx b/x-pack/plugins/beats_management/public/components/table/table_type_configs.tsx similarity index 98% rename from x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx rename to x-pack/plugins/beats_management/public/components/table/table_type_configs.tsx index 6fff7574c39e6e..65e0d19aa47700 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx +++ b/x-pack/plugins/beats_management/public/components/table/table_type_configs.tsx @@ -9,7 +9,10 @@ import { i18n } from '@kbn/i18n'; import { sortBy, uniq } from 'lodash'; import moment from 'moment'; import React from 'react'; -import { BeatTag, CMBeat } from '../../../common/domain_types'; +import { + BeatTag, + CMBeat, +} from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { ConnectedLink } from '../navigation/connected_link'; import { TagBadge } from '../tag'; diff --git a/x-pack/legacy/plugins/beats_management/public/components/tag/config_view/config_form.tsx b/x-pack/plugins/beats_management/public/components/tag/config_view/config_form.tsx similarity index 98% rename from x-pack/legacy/plugins/beats_management/public/components/tag/config_view/config_form.tsx rename to x-pack/plugins/beats_management/public/components/tag/config_view/config_form.tsx index 11336f230c8406..0469a623198134 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/tag/config_view/config_form.tsx +++ b/x-pack/plugins/beats_management/public/components/tag/config_view/config_form.tsx @@ -8,7 +8,10 @@ import { i18n } from '@kbn/i18n'; import Formsy from 'formsy-react'; import { get } from 'lodash'; import React from 'react'; -import { ConfigBlockSchema, ConfigurationBlock } from '../../../../common/domain_types'; +import { + ConfigBlockSchema, + ConfigurationBlock, +} from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { FormsyEuiCodeEditor, FormsyEuiFieldText, diff --git a/x-pack/legacy/plugins/beats_management/public/components/tag/config_view/index.tsx b/x-pack/plugins/beats_management/public/components/tag/config_view/index.tsx similarity index 94% rename from x-pack/legacy/plugins/beats_management/public/components/tag/config_view/index.tsx rename to x-pack/plugins/beats_management/public/components/tag/config_view/index.tsx index 20eb2b9c3fd0d9..4390e73b6fc063 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/tag/config_view/index.tsx +++ b/x-pack/plugins/beats_management/public/components/tag/config_view/index.tsx @@ -22,9 +22,9 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { configBlockSchemas } from '../../../../common/config_schemas'; -import { translateConfigSchema } from '../../../../common/config_schemas_translations_map'; -import { ConfigurationBlock } from '../../../../common/domain_types'; +import { configBlockSchemas } from '../../../../../../legacy/plugins/beats_management/common/config_schemas'; +import { translateConfigSchema } from '../../../../../../legacy/plugins/beats_management/common/config_schemas_translations_map'; +import { ConfigurationBlock } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { ConfigForm } from './config_form'; interface ComponentProps { diff --git a/x-pack/legacy/plugins/beats_management/public/components/tag/index.ts b/x-pack/plugins/beats_management/public/components/tag/index.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/components/tag/index.ts rename to x-pack/plugins/beats_management/public/components/tag/index.ts diff --git a/x-pack/legacy/plugins/beats_management/public/components/tag/tag_badge.tsx b/x-pack/plugins/beats_management/public/components/tag/tag_badge.tsx similarity index 93% rename from x-pack/legacy/plugins/beats_management/public/components/tag/tag_badge.tsx rename to x-pack/plugins/beats_management/public/components/tag/tag_badge.tsx index 7fa0231cf34095..5880871da9f135 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/tag/tag_badge.tsx +++ b/x-pack/plugins/beats_management/public/components/tag/tag_badge.tsx @@ -6,7 +6,7 @@ import { EuiBadge, EuiBadgeProps } from '@elastic/eui'; import React from 'react'; -import { TABLE_CONFIG } from '../../../common/constants'; +import { TABLE_CONFIG } from '../../../../../legacy/plugins/beats_management/common/constants'; type TagBadgeProps = EuiBadgeProps & { maxIdRenderSize?: number; diff --git a/x-pack/legacy/plugins/beats_management/public/components/tag/tag_edit.tsx b/x-pack/plugins/beats_management/public/components/tag/tag_edit.tsx similarity index 98% rename from x-pack/legacy/plugins/beats_management/public/components/tag/tag_edit.tsx rename to x-pack/plugins/beats_management/public/components/tag/tag_edit.tsx index 4912abec90682d..5ea4b643fb5a2a 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/tag/tag_edit.tsx +++ b/x-pack/plugins/beats_management/public/components/tag/tag_edit.tsx @@ -24,7 +24,11 @@ import { FormattedMessage } from '@kbn/i18n/react'; import 'brace/mode/yaml'; import 'brace/theme/github'; import React from 'react'; -import { BeatTag, CMBeat, ConfigurationBlock } from '../../../common/domain_types'; +import { + BeatTag, + CMBeat, + ConfigurationBlock, +} from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { ConfigList } from '../config_list'; import { AssignmentActionType, BeatsTableType, Table, tagConfigActions } from '../table'; import { ConfigView } from './config_view'; diff --git a/x-pack/legacy/plugins/beats_management/public/containers/beats.ts b/x-pack/plugins/beats_management/public/containers/beats.ts similarity index 93% rename from x-pack/legacy/plugins/beats_management/public/containers/beats.ts rename to x-pack/plugins/beats_management/public/containers/beats.ts index 7340f6b56d6f65..1c2a337798b252 100644 --- a/x-pack/legacy/plugins/beats_management/public/containers/beats.ts +++ b/x-pack/plugins/beats_management/public/containers/beats.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { Container } from 'unstated'; -import { CMBeat } from './../../common/domain_types'; -import { BeatsTagAssignment } from './../../server/lib/adapters/beats/adapter_types'; +import { CMBeat } from '../../../../legacy/plugins/beats_management/common/domain_types'; +import { BeatsTagAssignment } from '../../../../legacy/plugins/beats_management/server/lib/adapters/beats/adapter_types'; import { FrontendLibs } from './../lib/types'; interface ContainerState { diff --git a/x-pack/legacy/plugins/beats_management/public/containers/tags.ts b/x-pack/plugins/beats_management/public/containers/tags.ts similarity index 93% rename from x-pack/legacy/plugins/beats_management/public/containers/tags.ts rename to x-pack/plugins/beats_management/public/containers/tags.ts index 08af22f7cf4cc3..345d264878503b 100644 --- a/x-pack/legacy/plugins/beats_management/public/containers/tags.ts +++ b/x-pack/plugins/beats_management/public/containers/tags.ts @@ -5,7 +5,7 @@ */ import { Container } from 'unstated'; -import { BeatTag } from '../../common/domain_types'; +import { BeatTag } from '../../../../legacy/plugins/beats_management/common/domain_types'; import { FrontendLibs } from '../lib/types'; interface ContainerState { diff --git a/x-pack/legacy/plugins/beats_management/public/containers/with_kuery_autocompletion.tsx b/x-pack/plugins/beats_management/public/containers/with_kuery_autocompletion.tsx similarity index 96% rename from x-pack/legacy/plugins/beats_management/public/containers/with_kuery_autocompletion.tsx rename to x-pack/plugins/beats_management/public/containers/with_kuery_autocompletion.tsx index 66d52b8dcc5dcb..007f1f9535bc45 100644 --- a/x-pack/legacy/plugins/beats_management/public/containers/with_kuery_autocompletion.tsx +++ b/x-pack/plugins/beats_management/public/containers/with_kuery_autocompletion.tsx @@ -6,7 +6,7 @@ import React from 'react'; -import { QuerySuggestion } from '../../../../../../src/plugins/data/public'; +import { QuerySuggestion } from '../../../../../src/plugins/data/public'; import { FrontendLibs } from '../lib/types'; import { RendererFunction } from '../utils/typed_react'; diff --git a/x-pack/legacy/plugins/beats_management/public/containers/with_url_state.tsx b/x-pack/plugins/beats_management/public/containers/with_url_state.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/containers/with_url_state.tsx rename to x-pack/plugins/beats_management/public/containers/with_url_state.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/frontend_types.d.ts b/x-pack/plugins/beats_management/public/frontend_types.d.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/frontend_types.d.ts rename to x-pack/plugins/beats_management/public/frontend_types.d.ts diff --git a/x-pack/plugins/beats_management/public/index.ts b/x-pack/plugins/beats_management/public/index.ts new file mode 100644 index 00000000000000..9a3d1a9dc0f53d --- /dev/null +++ b/x-pack/plugins/beats_management/public/index.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { CoreSetup, Plugin, PluginInitializerContext } from '../../../../src/core/public'; + +import { ManagementSetup } from '../../../../src/plugins/management/public'; +import { SecurityPluginSetup } from '../../security/public'; +import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +import { LicensingPluginSetup } from '../../licensing/public'; + +import { bootstrap } from './bootstrap'; +import { BeatsManagementConfigType } from '../common'; + +interface SetupDeps { + management: ManagementSetup; + licensing: LicensingPluginSetup; + security?: SecurityPluginSetup; +} + +interface StartDeps { + data: DataPublicPluginStart; +} + +class BeatsManagementPlugin implements Plugin { + constructor(private readonly initContext: PluginInitializerContext) {} + + public setup(core: CoreSetup, plugins: SetupDeps) { + const config = this.initContext.config.get(); + bootstrap(core, plugins, config, this.initContext.env.packageInfo.version); + } + + public start() {} + public stop() {} +} + +export const plugin = (init: PluginInitializerContext) => new BeatsManagementPlugin(init); diff --git a/x-pack/plugins/beats_management/public/kbn_services.ts b/x-pack/plugins/beats_management/public/kbn_services.ts new file mode 100644 index 00000000000000..ca5c63802aac5f --- /dev/null +++ b/x-pack/plugins/beats_management/public/kbn_services.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreStart } from '../../../../src/core/public'; +import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +import { ManagementAppMountParams } from '../../../../src/plugins/management/public'; + +export const services = { + I18nContext: (null as any) as CoreStart['i18n']['Context'], + setBreadcrumbs: (null as any) as ManagementAppMountParams['setBreadcrumbs'], + dataStart: (null as any) as DataPublicPluginStart, +}; + +export const setServices = ( + core: CoreStart, + plugins: { data: DataPublicPluginStart }, + params: ManagementAppMountParams +) => { + services.I18nContext = core.i18n.Context; + services.setBreadcrumbs = params.setBreadcrumbs; + services.dataStart = plugins.data; +}; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/__tests__/config_blocks.test.ts b/x-pack/plugins/beats_management/public/lib/__tests__/config_blocks.test.ts similarity index 95% rename from x-pack/legacy/plugins/beats_management/public/lib/__tests__/config_blocks.test.ts rename to x-pack/plugins/beats_management/public/lib/__tests__/config_blocks.test.ts index 6776fb0b6f5add..6851020cdf97e8 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/__tests__/config_blocks.test.ts +++ b/x-pack/plugins/beats_management/public/lib/__tests__/config_blocks.test.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { configBlockSchemas } from '../../../common/config_schemas'; -import { translateConfigSchema } from '../../../common/config_schemas_translations_map'; +import { configBlockSchemas } from '../../../../../legacy/plugins/beats_management/common/config_schemas'; +import { translateConfigSchema } from '../../../../../legacy/plugins/beats_management/common/config_schemas_translations_map'; import { ConfigBlocksLib } from '../configuration_blocks'; import { MemoryConfigBlocksAdapter } from './../adapters/configuration_blocks/memory_config_blocks_adapter'; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/beats/adapter_types.ts similarity index 84% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/adapter_types.ts rename to x-pack/plugins/beats_management/public/lib/adapters/beats/adapter_types.ts index 815b80e55fa116..1366894f78ddbb 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/adapter_types.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/beats/adapter_types.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CMBeat } from '../../../../common/domain_types'; -import { ReturnTypeBulkAction } from '../../../../common/return_types'; +import { CMBeat } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; +import { ReturnTypeBulkAction } from '../../../../../../legacy/plugins/beats_management/common/return_types'; export interface CMBeatsAdapter { get(id: string): Promise; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts similarity index 94% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts index 319e37e226c9e5..74fd07d5d3dff0 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts @@ -5,8 +5,8 @@ */ import { omit } from 'lodash'; -import { CMBeat } from '../../../../common/domain_types'; -import { ReturnTypeBulkAction } from '../../../../common/return_types'; +import { CMBeat } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; +import { ReturnTypeBulkAction } from '../../../../../../legacy/plugins/beats_management/common/return_types'; import { BeatsTagAssignment, CMBeatsAdapter } from './adapter_types'; export class MemoryBeatsAdapter implements CMBeatsAdapter { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts similarity index 92% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts index b2e11461007fd2..880af83bfb3f21 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CMBeat } from '../../../../common/domain_types'; +import { CMBeat } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { ReturnTypeBulkAction, ReturnTypeGet, ReturnTypeList, ReturnTypeUpdate, -} from '../../../../common/return_types'; +} from '../../../../../../legacy/plugins/beats_management/common/return_types'; import { RestAPIAdapter } from '../rest_api/adapter_types'; import { BeatsTagAssignment, CMBeatsAdapter } from './adapter_types'; export class RestBeatsAdapter implements CMBeatsAdapter { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts similarity index 67% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts rename to x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts index e8e2d5cd6b430d..413cf32529b2f5 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts @@ -3,8 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { ConfigurationBlock } from '../../../../common/domain_types'; -import { ReturnTypeBulkUpsert, ReturnTypeList } from '../../../../common/return_types'; +import { ConfigurationBlock } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; +import { + ReturnTypeBulkUpsert, + ReturnTypeList, +} from '../../../../../../legacy/plugins/beats_management/common/return_types'; export interface FrontendConfigBlocksAdapter { upsert(blocks: ConfigurationBlock[]): Promise; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts similarity index 84% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts index b1405cfbf2e60d..ab36c7fbbae0e7 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts @@ -4,8 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ConfigurationBlock } from '../../../../common/domain_types'; -import { ReturnTypeBulkUpsert, ReturnTypeList } from '../../../../common/return_types'; +import { ConfigurationBlock } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; +import { + ReturnTypeBulkUpsert, + ReturnTypeList, +} from '../../../../../../legacy/plugins/beats_management/common/return_types'; import { FrontendConfigBlocksAdapter } from './adapter_types'; export class MemoryConfigBlocksAdapter implements FrontendConfigBlocksAdapter { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts similarity index 86% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts index be501a5e951ba0..640da59ea572dc 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ConfigurationBlock } from '../../../../common/domain_types'; +import { ConfigurationBlock } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { ReturnTypeBulkDelete, ReturnTypeBulkUpsert, ReturnTypeList, -} from '../../../../common/return_types'; +} from '../../../../../../legacy/plugins/beats_management/common/return_types'; import { RestAPIAdapter } from '../rest_api/adapter_types'; import { FrontendConfigBlocksAdapter } from './adapter_types'; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/adapter_types.ts similarity index 85% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/adapter_types.ts rename to x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/adapter_types.ts index 6e4665fb130de1..16339c8eac0038 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/adapter_types.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/adapter_types.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { QuerySuggestion } from '../../../../../../../../src/plugins/data/public'; +import { QuerySuggestion } from '../../../../../../../src/plugins/data/public'; export interface ElasticsearchAdapter { convertKueryToEsQuery: (kuery: string) => Promise; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/memory.ts b/x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/memory.ts similarity index 91% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/memory.ts rename to x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/memory.ts index fc4daf3df60b2e..bda157cd7f12e2 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/memory.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/memory.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { QuerySuggestion } from '../../../../../../../../src/plugins/data/public'; +import { QuerySuggestion } from '../../../../../../../src/plugins/data/public'; import { ElasticsearchAdapter } from './adapter_types'; export class MemoryElasticsearchAdapter implements ElasticsearchAdapter { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/rest.ts b/x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/rest.ts similarity index 85% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/rest.ts rename to x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/rest.ts index 06e6fac0d75c41..4473e015d9d742 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/elasticsearch/rest.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/elasticsearch/rest.ts @@ -5,9 +5,9 @@ */ import { isEmpty } from 'lodash'; -import { npStart } from 'ui/new_platform'; import { ElasticsearchAdapter } from './adapter_types'; -import { QuerySuggestion, esKuery } from '../../../../../../../../src/plugins/data/public'; +import { QuerySuggestion, esKuery } from '../../../../../../../src/plugins/data/public'; +import { services } from '../../../kbn_services'; export class RestElasticsearchAdapter implements ElasticsearchAdapter { private cachedIndexPattern: any = null; @@ -35,7 +35,7 @@ export class RestElasticsearchAdapter implements ElasticsearchAdapter { const indexPattern = await this.getIndexPattern(); return ( - (await npStart.plugins.data.autocomplete.getQuerySuggestions({ + (await services.dataStart.autocomplete.getQuerySuggestions({ language: 'kuery', indexPatterns: [indexPattern], boolFilter: [], @@ -50,7 +50,7 @@ export class RestElasticsearchAdapter implements ElasticsearchAdapter { if (this.cachedIndexPattern) { return this.cachedIndexPattern; } - const res = await npStart.plugins.data.indexPatterns.getFieldsForWildcard({ + const res = await services.dataStart.indexPatterns.getFieldsForWildcard({ pattern: this.indexPatternName, }); if (isEmpty(res.fields)) { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/framework/adapter_types.ts similarity index 69% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/adapter_types.ts rename to x-pack/plugins/beats_management/public/lib/adapters/framework/adapter_types.ts index 96b64e8171af50..3c0c724d3d87b5 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/framework/adapter_types.ts @@ -7,7 +7,8 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ import * as t from 'io-ts'; -import { LICENSES } from './../../../../common/constants/security'; +import { LICENSES } from '../../../../../../legacy/plugins/beats_management/common/constants/security'; +import { RegisterManagementAppArgs } from '../../../../../../../src/plugins/management/public'; export interface FrameworkAdapter { // Instance vars @@ -16,23 +17,18 @@ export interface FrameworkAdapter { currentUser: FrameworkUser; // Methods waitUntilFrameworkReady(): Promise; - renderUIAtPath( - path: string, - component: React.ReactElement, - toController: 'management' | 'self' - ): void; registerManagementSection(settings: { - id?: string; + id: string; name: string; iconName: string; order?: number; }): void; registerManagementUI(settings: { - sectionId?: string; + sectionId: string; + appId: string; name: string; - basePath: string; - visable?: boolean; order?: number; + mount: RegisterManagementAppArgs['mount']; }): void; } @@ -56,23 +52,6 @@ export const RuntimeFrameworkInfo = t.type({ export interface FrameworkInfo extends t.TypeOf {} -interface ManagementSection { - register( - sectionId: string, - options: { - visible: boolean; - display: string; - order: number; - url: string; - } - ): void; -} -export interface ManagementAPI { - getSection(sectionId: string): ManagementSection; - hasItem(sectionId: string): boolean; - register(sectionId: string, options: { display: string; icon: string; order: number }): void; -} - export const RuntimeFrameworkUser = t.interface( { username: t.string, diff --git a/x-pack/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts new file mode 100644 index 00000000000000..d061e2f35809b9 --- /dev/null +++ b/x-pack/plugins/beats_management/public/lib/adapters/framework/kibana_framework_adapter.ts @@ -0,0 +1,182 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint-disable max-classes-per-file */ +import { IScope } from 'angular'; +import { PathReporter } from 'io-ts/lib/PathReporter'; +import { isLeft } from 'fp-ts/lib/Either'; +import { first } from 'rxjs/operators'; +import { SecurityPluginSetup } from '../../../../../security/public'; +import { BufferedKibanaServiceCall, KibanaAdapterServiceRefs, KibanaUIConfig } from '../../types'; +import { + FrameworkAdapter, + FrameworkInfo, + FrameworkUser, + RuntimeFrameworkInfo, + RuntimeFrameworkUser, +} from './adapter_types'; +import { + ManagementSetup, + RegisterManagementAppArgs, +} from '../../../../../../../src/plugins/management/public'; +import { LicensingPluginSetup } from '../../../../../licensing/public'; +import { BeatsManagementConfigType } from '../../../../common'; + +export class KibanaFrameworkAdapter implements FrameworkAdapter { + public get info() { + if (this.xpackInfo) { + return this.xpackInfo; + } else { + throw new Error('framework adapter must have init called before anything else'); + } + } + + public get currentUser() { + return this.shieldUser!; + } + private xpackInfo: FrameworkInfo | null = null; + private adapterService: KibanaAdapterServiceProvider; + private shieldUser: FrameworkUser | null = null; + constructor( + private readonly PLUGIN_ID: string, + private readonly management: ManagementSetup, + private readonly getBasePath: () => string, + private readonly licensing: LicensingPluginSetup, + private readonly securitySetup: SecurityPluginSetup | undefined, + private readonly config: BeatsManagementConfigType, + public readonly version: string + ) { + this.adapterService = new KibanaAdapterServiceProvider(); + } + + public setUISettings = (key: string, value: any) => { + this.adapterService.callOrBuffer(({ config }) => { + config.set(key, value); + }); + }; + + public async waitUntilFrameworkReady(): Promise { + const license = await this.licensing.license$.pipe(first()).toPromise(); + let xpackInfoUnpacked: FrameworkInfo; + + try { + xpackInfoUnpacked = { + basePath: this.getBasePath(), + license: { + type: license.type ?? 'oss', + expired: !license.isActive, + expiry_date_in_millis: license.expiryDateInMillis ?? -1, + }, + security: { + enabled: license.getFeature('security').isEnabled, + available: license.getFeature('security').isAvailable, + }, + settings: this.config, + }; + } catch (e) { + throw new Error(`Unexpected data structure from xpackInfoService, ${JSON.stringify(e)}`); + } + + const assertData = RuntimeFrameworkInfo.decode(xpackInfoUnpacked); + if (isLeft(assertData)) { + throw new Error( + `Error parsing xpack info in ${this.PLUGIN_ID}, ${PathReporter.report(assertData)[0]}` + ); + } + this.xpackInfo = xpackInfoUnpacked; + + try { + this.shieldUser = (await this.securitySetup?.authc.getCurrentUser()) || null; + const assertUser = RuntimeFrameworkUser.decode(this.shieldUser); + + if (isLeft(assertUser)) { + throw new Error( + `Error parsing user info in ${this.PLUGIN_ID}, ${PathReporter.report(assertUser)[0]}` + ); + } + } catch (e) { + this.shieldUser = null; + } + } + + public registerManagementSection(settings: { + id: string; + name: string; + iconName: string; + order?: number; + }) { + this.management.sections.register({ + id: settings.id, + title: settings.name, + euiIconType: settings.iconName, + order: settings.order || 30, + }); + } + + public registerManagementUI(settings: { + sectionId: string; + appId: string; + name: string; + order?: number; + mount: RegisterManagementAppArgs['mount']; + }) { + const section = this.management.sections.getSection(settings.sectionId); + + if (!section) { + throw new Error( + `registerManagementUI was called with a sectionId of ${settings.sectionId}, and that is is not yet regestered as a section` + ); + } + + section.registerApp({ + id: settings.appId, + title: settings.name, + order: settings.order || 30, + mount: settings.mount, + }); + } +} + +class KibanaAdapterServiceProvider { + public serviceRefs: KibanaAdapterServiceRefs | null = null; + public bufferedCalls: Array> = []; + + public $get($rootScope: IScope, config: KibanaUIConfig) { + this.serviceRefs = { + config, + rootScope: $rootScope, + }; + + this.applyBufferedCalls(this.bufferedCalls); + + return this; + } + + public callOrBuffer(serviceCall: (serviceRefs: KibanaAdapterServiceRefs) => void) { + if (this.serviceRefs !== null) { + this.applyBufferedCalls([serviceCall]); + } else { + this.bufferedCalls.push(serviceCall); + } + } + + public applyBufferedCalls( + bufferedCalls: Array> + ) { + if (!this.serviceRefs) { + return; + } + + this.serviceRefs.rootScope.$apply(() => { + bufferedCalls.forEach(serviceCall => { + if (!this.serviceRefs) { + return; + } + return serviceCall(this.serviceRefs); + }); + }); + } +} diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/testing_framework_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/framework/testing_framework_adapter.ts similarity index 79% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/testing_framework_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/framework/testing_framework_adapter.ts index 9045c7ded2adaa..56f428ff0b927c 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/framework/testing_framework_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/framework/testing_framework_adapter.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as React from 'react'; import { FrameworkAdapter, FrameworkInfo, FrameworkUser } from './adapter_types'; export class TestingFrameworkAdapter implements FrameworkAdapter { @@ -40,14 +39,6 @@ export class TestingFrameworkAdapter implements FrameworkAdapter { return; } - public renderUIAtPath( - path: string, - component: React.ReactElement, - toController: 'management' | 'self' = 'self' - ) { - throw new Error('not yet implamented'); - } - public registerManagementSection(settings: { id?: string; name: string; @@ -57,13 +48,7 @@ export class TestingFrameworkAdapter implements FrameworkAdapter { throw new Error('not yet implamented'); } - public registerManagementUI(settings: { - sectionId?: string; - name: string; - basePath: string; - visable?: boolean; - order?: number; - }) { + public registerManagementUI(settings: { sectionId?: string; name: string; order?: number }) { throw new Error('not yet implamented'); } } diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/rest_api/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/rest_api/adapter_types.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/rest_api/adapter_types.ts rename to x-pack/plugins/beats_management/public/lib/adapters/rest_api/adapter_types.ts diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/rest_api/axios_rest_api_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/rest_api/axios_rest_api_adapter.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/rest_api/axios_rest_api_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/rest_api/axios_rest_api_adapter.ts diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/rest_api/node_axios_api_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/rest_api/node_axios_api_adapter.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/rest_api/node_axios_api_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/rest_api/node_axios_api_adapter.ts diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/tags/adapter_types.ts similarity index 82% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/adapter_types.ts rename to x-pack/plugins/beats_management/public/lib/adapters/tags/adapter_types.ts index 5030b1704b1d7a..b0ddf0309232ab 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/adapter_types.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/tags/adapter_types.ts @@ -3,7 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { BeatTag, CMBeat } from '../../../../common/domain_types'; +import { + BeatTag, + CMBeat, +} from '../../../../../../legacy/plugins/beats_management/common/domain_types'; export interface CMTagsAdapter { getTagsWithIds(tagIds: string[]): Promise; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/memory_tags_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/tags/memory_tags_adapter.ts similarity index 91% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/memory_tags_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/tags/memory_tags_adapter.ts index e26c6c9eb8099e..357790c34ee587 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/memory_tags_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/tags/memory_tags_adapter.ts @@ -4,7 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { BeatTag, CMBeat } from '../../../../common/domain_types'; +import { + BeatTag, + CMBeat, +} from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { CMTagsAdapter } from './adapter_types'; export class MemoryTagsAdapter implements CMTagsAdapter { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts similarity index 90% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts index 190c9e265463dc..4f6852cb6a007a 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts @@ -5,13 +5,16 @@ */ import { uniq } from 'lodash'; -import { BeatTag, CMBeat } from '../../../../common/domain_types'; +import { + BeatTag, + CMBeat, +} from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { ReturnTypeBulkDelete, ReturnTypeBulkGet, ReturnTypeList, ReturnTypeUpsert, -} from '../../../../common/return_types'; +} from '../../../../../../legacy/plugins/beats_management/common/return_types'; import { RestAPIAdapter } from '../rest_api/adapter_types'; import { CMTagsAdapter } from './adapter_types'; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/tokens/adapter_types.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/adapter_types.ts rename to x-pack/plugins/beats_management/public/lib/adapters/tokens/adapter_types.ts diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/memory_tokens_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/tokens/memory_tokens_adapter.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/memory_tokens_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/tokens/memory_tokens_adapter.ts diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts similarity index 87% rename from x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts rename to x-pack/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts index 92cfcc935ad9b0..7bdea96db0f2f0 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ReturnTypeBulkCreate } from '../../../../common/return_types'; +import { ReturnTypeBulkCreate } from '../../../../../../legacy/plugins/beats_management/common/return_types'; import { RestAPIAdapter } from '../rest_api/adapter_types'; import { CMTokensAdapter } from './adapter_types'; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/beats.ts b/x-pack/plugins/beats_management/public/lib/beats.ts similarity index 92% rename from x-pack/legacy/plugins/beats_management/public/lib/beats.ts rename to x-pack/plugins/beats_management/public/lib/beats.ts index 5432a39953b84c..a6cfe0b88dcf8f 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/beats.ts +++ b/x-pack/plugins/beats_management/public/lib/beats.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ReturnTypeBulkAction } from '../../common/return_types'; -import { CMBeat } from './../../common/domain_types'; +import { ReturnTypeBulkAction } from '../../../../legacy/plugins/beats_management/common/return_types'; +import { CMBeat } from '../../../../legacy/plugins/beats_management/common/domain_types'; import { BeatsTagAssignment, CMBeatsAdapter } from './adapters/beats/adapter_types'; import { ElasticsearchLib } from './elasticsearch'; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/compose/kibana.ts b/x-pack/plugins/beats_management/public/lib/compose/kibana.ts similarity index 59% rename from x-pack/legacy/plugins/beats_management/public/lib/compose/kibana.ts rename to x-pack/plugins/beats_management/public/lib/compose/kibana.ts index 2ebda89ba13fd6..d750417640f8c7 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/compose/kibana.ts +++ b/x-pack/plugins/beats_management/public/lib/compose/kibana.ts @@ -5,16 +5,9 @@ */ import { camelCase } from 'lodash'; -// @ts-ignore not typed yet -import { xpackInfo } from 'plugins/xpack_main/services/xpack_info'; -import 'ui/autoload/all'; -import chrome from 'ui/chrome'; -// @ts-ignore not typed yet -import { management } from 'ui/management'; -import routes from 'ui/routes'; -import { configBlockSchemas } from '../../../common/config_schemas'; -import { translateConfigSchema } from '../../../common/config_schemas_translations_map'; -import { INDEX_NAMES } from '../../../common/constants/index_names'; +import { configBlockSchemas } from '../../../../../legacy/plugins/beats_management/common/config_schemas'; +import { translateConfigSchema } from '../../../../../legacy/plugins/beats_management/common/config_schemas_translations_map'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/beats_management/common/constants/index_names'; import { RestBeatsAdapter } from '../adapters/beats/rest_beats_adapter'; import { RestConfigBlocksAdapter } from '../adapters/configuration_blocks/rest_config_blocks_adapter'; import { RestElasticsearchAdapter } from '../adapters/elasticsearch/rest'; @@ -27,14 +20,32 @@ import { ConfigBlocksLib } from '../configuration_blocks'; import { ElasticsearchLib } from '../elasticsearch'; import { TagsLib } from '../tags'; import { FrontendLibs } from '../types'; -import { PLUGIN } from './../../../common/constants/plugin'; +import { PLUGIN } from '../../../../../legacy/plugins/beats_management/common/constants/plugin'; import { FrameworkLib } from './../framework'; +import { ManagementSetup } from '../../../../../../src/plugins/management/public'; +import { SecurityPluginSetup } from '../../../../security/public'; +import { CoreSetup } from '../../../../../../src/core/public'; +import { LicensingPluginSetup } from '../../../../licensing/public'; +import { BeatsManagementConfigType } from '../../../common'; -// A super early spot in kibana loading that we can use to hook before most other things -const onKibanaReady = chrome.dangerouslyGetActiveInjector; +interface ComposeDeps { + core: CoreSetup; + management: ManagementSetup; + licensing: LicensingPluginSetup; + config: BeatsManagementConfigType; + version: string; + security?: SecurityPluginSetup; +} -export function compose(): FrontendLibs { - const api = new AxiosRestAPIAdapter(chrome.getXsrfToken(), chrome.getBasePath()); +export function compose({ + core, + management, + licensing, + config, + version, + security, +}: ComposeDeps): FrontendLibs { + const api = new AxiosRestAPIAdapter(version, core.http.basePath.get()); const esAdapter = new RestElasticsearchAdapter(INDEX_NAMES.BEATS); const elasticsearchLib = new ElasticsearchLib(esAdapter); const configBlocks = new ConfigBlocksLib( @@ -49,11 +60,11 @@ export function compose(): FrontendLibs { new KibanaFrameworkAdapter( camelCase(PLUGIN.ID), management, - routes, - chrome.getBasePath, - onKibanaReady, - xpackInfo, - chrome.getKibanaVersion() + core.http.basePath.get, + licensing, + security, + config, + version ) ); diff --git a/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts b/x-pack/plugins/beats_management/public/lib/compose/scripts.ts similarity index 91% rename from x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts rename to x-pack/plugins/beats_management/public/lib/compose/scripts.ts index 83129384a77dfa..093d618ba8d8b1 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts +++ b/x-pack/plugins/beats_management/public/lib/compose/scripts.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { configBlockSchemas } from '../../../common/config_schemas'; -import { translateConfigSchema } from '../../../common/config_schemas_translations_map'; +import { configBlockSchemas } from '../../../../../legacy/plugins/beats_management/common/config_schemas'; +import { translateConfigSchema } from '../../../../../legacy/plugins/beats_management/common/config_schemas_translations_map'; import { RestBeatsAdapter } from '../adapters/beats/rest_beats_adapter'; import { RestConfigBlocksAdapter } from '../adapters/configuration_blocks/rest_config_blocks_adapter'; import { MemoryElasticsearchAdapter } from '../adapters/elasticsearch/memory'; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/configuration_blocks.ts b/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts similarity index 97% rename from x-pack/legacy/plugins/beats_management/public/lib/configuration_blocks.ts rename to x-pack/plugins/beats_management/public/lib/configuration_blocks.ts index c3b21b5df5175e..ffb431da1f43e3 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/configuration_blocks.ts +++ b/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts @@ -6,7 +6,10 @@ import yaml from 'js-yaml'; import { get, has, omit, set } from 'lodash'; -import { ConfigBlockSchema, ConfigurationBlock } from '../../common/domain_types'; +import { + ConfigBlockSchema, + ConfigurationBlock, +} from '../../../../legacy/plugins/beats_management/common/domain_types'; import { FrontendConfigBlocksAdapter } from './adapters/configuration_blocks/adapter_types'; export class ConfigBlocksLib { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/elasticsearch.ts b/x-pack/plugins/beats_management/public/lib/elasticsearch.ts similarity index 96% rename from x-pack/legacy/plugins/beats_management/public/lib/elasticsearch.ts rename to x-pack/plugins/beats_management/public/lib/elasticsearch.ts index 82576bff2cbfdc..a9ca69c44c97d4 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/elasticsearch.ts +++ b/x-pack/plugins/beats_management/public/lib/elasticsearch.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { QuerySuggestion } from '../../../../../../src/plugins/data/public'; +import { QuerySuggestion } from '../../../../../src/plugins/data/public'; import { ElasticsearchAdapter } from './adapters/elasticsearch/adapter_types'; interface HiddenFields { diff --git a/x-pack/legacy/plugins/beats_management/public/lib/framework.ts b/x-pack/plugins/beats_management/public/lib/framework.ts similarity index 92% rename from x-pack/legacy/plugins/beats_management/public/lib/framework.ts rename to x-pack/plugins/beats_management/public/lib/framework.ts index 141aa7168083d1..c850bdd8bc0ee3 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/framework.ts +++ b/x-pack/plugins/beats_management/public/lib/framework.ts @@ -5,12 +5,14 @@ */ import { difference, get } from 'lodash'; -import { LICENSES, LicenseType } from '../../common/constants/security'; +import { + LICENSES, + LicenseType, +} from '../../../../legacy/plugins/beats_management/common/constants/security'; import { FrameworkAdapter } from './adapters/framework/adapter_types'; export class FrameworkLib { public waitUntilFrameworkReady = this.adapter.waitUntilFrameworkReady.bind(this.adapter); - public renderUIAtPath = this.adapter.renderUIAtPath.bind(this.adapter); public registerManagementSection = this.adapter.registerManagementSection.bind(this.adapter); public registerManagementUI = this.adapter.registerManagementUI.bind(this.adapter); diff --git a/x-pack/legacy/plugins/beats_management/public/lib/tags.ts b/x-pack/plugins/beats_management/public/lib/tags.ts similarity index 93% rename from x-pack/legacy/plugins/beats_management/public/lib/tags.ts rename to x-pack/plugins/beats_management/public/lib/tags.ts index 86562be3ff989e..2d67edf7e347e7 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/tags.ts +++ b/x-pack/plugins/beats_management/public/lib/tags.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import uuidv4 from 'uuid/v4'; -import { BeatTag, CMBeat } from '../../common/domain_types'; +import { BeatTag, CMBeat } from '../../../../legacy/plugins/beats_management/common/domain_types'; import { CMTagsAdapter } from './adapters/tags/adapter_types'; import { ElasticsearchLib } from './elasticsearch'; diff --git a/x-pack/legacy/plugins/beats_management/public/lib/types.ts b/x-pack/plugins/beats_management/public/lib/types.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/lib/types.ts rename to x-pack/plugins/beats_management/public/lib/types.ts diff --git a/x-pack/legacy/plugins/beats_management/public/pages/__404.tsx b/x-pack/plugins/beats_management/public/pages/__404.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/__404.tsx rename to x-pack/plugins/beats_management/public/pages/__404.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/pages/beat/details.tsx b/x-pack/plugins/beats_management/public/pages/beat/details.tsx similarity index 93% rename from x-pack/legacy/plugins/beats_management/public/pages/beat/details.tsx rename to x-pack/plugins/beats_management/public/pages/beat/details.tsx index 3952b44f82561d..6fae3a5efc71fa 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/beat/details.tsx +++ b/x-pack/plugins/beats_management/public/pages/beat/details.tsx @@ -19,10 +19,14 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import { get } from 'lodash'; import React from 'react'; -import { configBlockSchemas } from '../../../common/config_schemas'; -import { translateConfigSchema } from '../../../common/config_schemas_translations_map'; -import { TABLE_CONFIG } from '../../../common/constants'; -import { BeatTag, CMBeat, ConfigurationBlock } from '../../../common/domain_types'; +import { configBlockSchemas } from '../../../../../legacy/plugins/beats_management/common/config_schemas'; +import { translateConfigSchema } from '../../../../../legacy/plugins/beats_management/common/config_schemas_translations_map'; +import { TABLE_CONFIG } from '../../../../../legacy/plugins/beats_management/common/constants'; +import { + BeatTag, + CMBeat, + ConfigurationBlock, +} from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { Breadcrumb } from '../../components/navigation/breadcrumb'; import { ConnectedLink } from '../../components/navigation/connected_link'; import { TagBadge } from '../../components/tag'; diff --git a/x-pack/legacy/plugins/beats_management/public/pages/beat/index.tsx b/x-pack/plugins/beats_management/public/pages/beat/index.tsx similarity index 98% rename from x-pack/legacy/plugins/beats_management/public/pages/beat/index.tsx rename to x-pack/plugins/beats_management/public/pages/beat/index.tsx index 80590febc95be2..bea84377d2ab85 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/beat/index.tsx +++ b/x-pack/plugins/beats_management/public/pages/beat/index.tsx @@ -17,7 +17,7 @@ import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import moment from 'moment'; import React from 'react'; import { Redirect, Route, Switch } from 'react-router-dom'; -import { CMBeat } from '../../../common/domain_types'; +import { CMBeat } from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { PrimaryLayout } from '../../components/layouts/primary'; import { Breadcrumb } from '../../components/navigation/breadcrumb'; import { ChildRoutes } from '../../components/navigation/child_routes'; diff --git a/x-pack/legacy/plugins/beats_management/public/pages/beat/tags.tsx b/x-pack/plugins/beats_management/public/pages/beat/tags.tsx similarity index 94% rename from x-pack/legacy/plugins/beats_management/public/pages/beat/tags.tsx rename to x-pack/plugins/beats_management/public/pages/beat/tags.tsx index 672c0d89bb0028..5a65473b25a24b 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/beat/tags.tsx +++ b/x-pack/plugins/beats_management/public/pages/beat/tags.tsx @@ -7,7 +7,10 @@ import { EuiGlobalToastList } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { BeatTag, CMBeat } from '../../../common/domain_types'; +import { + BeatTag, + CMBeat, +} from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { Breadcrumb } from '../../components/navigation/breadcrumb'; import { BeatDetailTagsTable, Table } from '../../components/table'; import { FrontendLibs } from '../../lib/types'; diff --git a/x-pack/legacy/plugins/beats_management/public/pages/error/enforce_security.tsx b/x-pack/plugins/beats_management/public/pages/error/enforce_security.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/error/enforce_security.tsx rename to x-pack/plugins/beats_management/public/pages/error/enforce_security.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/pages/error/invalid_license.tsx b/x-pack/plugins/beats_management/public/pages/error/invalid_license.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/error/invalid_license.tsx rename to x-pack/plugins/beats_management/public/pages/error/invalid_license.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/pages/error/no_access.tsx b/x-pack/plugins/beats_management/public/pages/error/no_access.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/error/no_access.tsx rename to x-pack/plugins/beats_management/public/pages/error/no_access.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/pages/index.ts b/x-pack/plugins/beats_management/public/pages/index.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/index.ts rename to x-pack/plugins/beats_management/public/pages/index.ts diff --git a/x-pack/legacy/plugins/beats_management/public/pages/overview/configuration_tags.tsx b/x-pack/plugins/beats_management/public/pages/overview/configuration_tags.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/overview/configuration_tags.tsx rename to x-pack/plugins/beats_management/public/pages/overview/configuration_tags.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/pages/overview/enrolled_beats.tsx b/x-pack/plugins/beats_management/public/pages/overview/enrolled_beats.tsx similarity index 99% rename from x-pack/legacy/plugins/beats_management/public/pages/overview/enrolled_beats.tsx rename to x-pack/plugins/beats_management/public/pages/overview/enrolled_beats.tsx index 635b9f03e8b388..5151f501ddba1f 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/overview/enrolled_beats.tsx +++ b/x-pack/plugins/beats_management/public/pages/overview/enrolled_beats.tsx @@ -19,7 +19,10 @@ import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import { flatten, sortBy } from 'lodash'; import moment from 'moment'; import React from 'react'; -import { BeatTag, CMBeat } from '../../../common/domain_types'; +import { + BeatTag, + CMBeat, +} from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { EnrollBeat } from '../../components/enroll_beats'; import { Breadcrumb } from '../../components/navigation/breadcrumb'; import { BeatsTableType, Table } from '../../components/table'; diff --git a/x-pack/legacy/plugins/beats_management/public/pages/overview/index.tsx b/x-pack/plugins/beats_management/public/pages/overview/index.tsx similarity index 97% rename from x-pack/legacy/plugins/beats_management/public/pages/overview/index.tsx rename to x-pack/plugins/beats_management/public/pages/overview/index.tsx index 57b007753491ce..4df1a7d0654696 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/overview/index.tsx +++ b/x-pack/plugins/beats_management/public/pages/overview/index.tsx @@ -16,7 +16,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; import { Subscribe } from 'unstated'; -import { CMBeat } from '../../../common/domain_types'; +import { CMBeat } from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { PrimaryLayout } from '../../components/layouts/primary'; import { ChildRoutes } from '../../components/navigation/child_routes'; import { BeatsContainer } from '../../containers/beats'; diff --git a/x-pack/legacy/plugins/beats_management/public/pages/tag/create.tsx b/x-pack/plugins/beats_management/public/pages/tag/create.tsx similarity index 95% rename from x-pack/legacy/plugins/beats_management/public/pages/tag/create.tsx rename to x-pack/plugins/beats_management/public/pages/tag/create.tsx index 326c529af3c616..65fe8bf5d52c15 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/tag/create.tsx +++ b/x-pack/plugins/beats_management/public/pages/tag/create.tsx @@ -12,8 +12,11 @@ import 'brace/mode/yaml'; import 'brace/theme/github'; import { isEqual } from 'lodash'; import React from 'react'; -import { UNIQUENESS_ENFORCING_TYPES } from '../../../common/constants/configuration_blocks'; -import { BeatTag, ConfigurationBlock } from '../../../common/domain_types'; +import { UNIQUENESS_ENFORCING_TYPES } from '../../../../../legacy/plugins/beats_management/common/constants/configuration_blocks'; +import { + BeatTag, + ConfigurationBlock, +} from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { PrimaryLayout } from '../../components/layouts/primary'; import { TagEdit } from '../../components/tag'; import { AppPageProps } from '../../frontend_types'; diff --git a/x-pack/legacy/plugins/beats_management/public/pages/tag/edit.tsx b/x-pack/plugins/beats_management/public/pages/tag/edit.tsx similarity index 96% rename from x-pack/legacy/plugins/beats_management/public/pages/tag/edit.tsx rename to x-pack/plugins/beats_management/public/pages/tag/edit.tsx index 553128df76baa3..918ae0bb6fcb2d 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/tag/edit.tsx +++ b/x-pack/plugins/beats_management/public/pages/tag/edit.tsx @@ -10,8 +10,12 @@ import 'brace/mode/yaml'; import 'brace/theme/github'; import { flatten } from 'lodash'; import React from 'react'; -import { UNIQUENESS_ENFORCING_TYPES } from '../../../common/constants'; -import { BeatTag, CMBeat, ConfigurationBlock } from '../../../common/domain_types'; +import { UNIQUENESS_ENFORCING_TYPES } from '../../../../../legacy/plugins/beats_management/common/constants'; +import { + BeatTag, + CMBeat, + ConfigurationBlock, +} from '../../../../../legacy/plugins/beats_management/common/domain_types'; import { PrimaryLayout } from '../../components/layouts/primary'; import { TagEdit } from '../../components/tag'; import { AppPageProps } from '../../frontend_types'; diff --git a/x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/beat.tsx b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/beat.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/beat.tsx rename to x-pack/plugins/beats_management/public/pages/walkthrough/initial/beat.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/finish.tsx b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/finish.tsx similarity index 97% rename from x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/finish.tsx rename to x-pack/plugins/beats_management/public/pages/walkthrough/initial/finish.tsx index 93489f5223ef8e..71f0b8161131f1 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/finish.tsx +++ b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/finish.tsx @@ -6,7 +6,7 @@ import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, EuiPageContent } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import React from 'react'; -import { CMBeat } from '../../../../common/domain_types'; +import { CMBeat } from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { AppPageProps } from '../../../frontend_types'; interface PageState { diff --git a/x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/index.tsx b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/index.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/index.tsx rename to x-pack/plugins/beats_management/public/pages/walkthrough/initial/index.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx similarity index 97% rename from x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx rename to x-pack/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx index 8dc3afeb06c6bf..525873e1dd64bd 100644 --- a/x-pack/legacy/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx +++ b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx @@ -9,7 +9,10 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { isEqual } from 'lodash'; import React, { Component } from 'react'; import uuidv4 from 'uuid/v4'; -import { BeatTag, ConfigurationBlock } from '../../../../common/domain_types'; +import { + BeatTag, + ConfigurationBlock, +} from '../../../../../../legacy/plugins/beats_management/common/domain_types'; import { TagEdit } from '../../../components/tag/tag_edit'; import { AppPageProps } from '../../../frontend_types'; interface PageState { diff --git a/x-pack/legacy/plugins/beats_management/public/router.tsx b/x-pack/plugins/beats_management/public/router.tsx similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/router.tsx rename to x-pack/plugins/beats_management/public/router.tsx diff --git a/x-pack/legacy/plugins/beats_management/public/utils/random_eui_color.ts b/x-pack/plugins/beats_management/public/utils/random_eui_color.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/utils/random_eui_color.ts rename to x-pack/plugins/beats_management/public/utils/random_eui_color.ts diff --git a/x-pack/legacy/plugins/beats_management/public/utils/typed_react.ts b/x-pack/plugins/beats_management/public/utils/typed_react.ts similarity index 100% rename from x-pack/legacy/plugins/beats_management/public/utils/typed_react.ts rename to x-pack/plugins/beats_management/public/utils/typed_react.ts diff --git a/x-pack/plugins/beats_management/server/index.ts b/x-pack/plugins/beats_management/server/index.ts new file mode 100644 index 00000000000000..607fb0ab2725d3 --- /dev/null +++ b/x-pack/plugins/beats_management/server/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { beatsManagementConfigSchema } from '../common'; + +export const config = { + schema: beatsManagementConfigSchema, + + exposeToBrowser: { + defaultUserRoles: true, + encryptionKey: true, + enrollmentTokensTtlInSeconds: true, + }, +}; + +export const plugin = () => ({ + setup() {}, + start() {}, + stop() {}, +}); From f5759138507fbb00504bcc6760653a47de026570 Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Fri, 15 May 2020 18:28:28 +0200 Subject: [PATCH 12/16] FTR: move basic services under common folder (#66563) * [CODEOWNERS] set kibana-qa to own test/functional/services * [functional/services] move low-level services to common folder * update codeowners * update imports Co-authored-by: Elastic Machine --- .github/CODEOWNERS | 3 +++ test/common/services/security/test_user.ts | 4 +-- .../services/{ => common}/browser.ts | 8 +++--- .../{ => common}/failure_debugging.ts | 2 +- test/functional/services/{ => common}/find.ts | 4 +-- test/functional/services/common/index.ts | 25 +++++++++++++++++++ .../services/{ => common}/screenshots.ts | 6 ++--- .../services/{ => common}/snapshots.ts | 2 +- .../services/{ => common}/test_subjects.ts | 4 +-- test/functional/services/index.ts | 14 ++++++----- 10 files changed, 51 insertions(+), 21 deletions(-) rename test/functional/services/{ => common}/browser.ts (98%) rename test/functional/services/{ => common}/failure_debugging.ts (97%) rename test/functional/services/{ => common}/find.ts (99%) create mode 100644 test/functional/services/common/index.ts rename test/functional/services/{ => common}/screenshots.ts (95%) rename test/functional/services/{ => common}/snapshots.ts (97%) rename test/functional/services/{ => common}/test_subjects.ts (99%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 19116977756f48..0000fc6f56af33 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -130,6 +130,9 @@ # Quality Assurance /src/dev/code_coverage @elastic/kibana-qa +/test/functional/services/common @elastic/kibana-qa +/test/functional/services/lib @elastic/kibana-qa +/test/functional/services/remote @elastic/kibana-qa # Platform /src/core/ @elastic/kibana-platform diff --git a/test/common/services/security/test_user.ts b/test/common/services/security/test_user.ts index 7f01c64d291a53..e72ded3a6f2fd7 100644 --- a/test/common/services/security/test_user.ts +++ b/test/common/services/security/test_user.ts @@ -19,8 +19,8 @@ import { Role } from './role'; import { User } from './user'; import { FtrProviderContext } from '../../ftr_provider_context'; -import { Browser } from '../../../functional/services/browser'; -import { TestSubjects } from '../../../functional/services/test_subjects'; +import { Browser } from '../../../functional/services/common'; +import { TestSubjects } from '../../../functional/services/common'; export async function createTestUserService( role: Role, diff --git a/test/functional/services/browser.ts b/test/functional/services/common/browser.ts similarity index 98% rename from test/functional/services/browser.ts rename to test/functional/services/common/browser.ts index 13d2365c07191b..4b5a3c101b51ce 100644 --- a/test/functional/services/browser.ts +++ b/test/functional/services/common/browser.ts @@ -24,10 +24,10 @@ import { LegacyActionSequence } from 'selenium-webdriver/lib/actions'; import { ProvidedType } from '@kbn/test/types/ftr'; import Jimp from 'jimp'; -import { modifyUrl } from '../../../src/core/utils'; -import { WebElementWrapper } from './lib/web_element_wrapper'; -import { FtrProviderContext } from '../ftr_provider_context'; -import { Browsers } from './remote/browsers'; +import { modifyUrl } from '../../../../src/core/utils'; +import { WebElementWrapper } from '../lib/web_element_wrapper'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { Browsers } from '../remote/browsers'; export type Browser = ProvidedType; export async function BrowserProvider({ getService }: FtrProviderContext) { diff --git a/test/functional/services/failure_debugging.ts b/test/functional/services/common/failure_debugging.ts similarity index 97% rename from test/functional/services/failure_debugging.ts rename to test/functional/services/common/failure_debugging.ts index cd12f1b75c8281..aa67c455e0100a 100644 --- a/test/functional/services/failure_debugging.ts +++ b/test/functional/services/common/failure_debugging.ts @@ -22,7 +22,7 @@ import { writeFile, mkdir } from 'fs'; import { promisify } from 'util'; import del from 'del'; -import { FtrProviderContext } from '../ftr_provider_context'; +import { FtrProviderContext } from '../../ftr_provider_context'; interface Test { fullTitle(): string; diff --git a/test/functional/services/find.ts b/test/functional/services/common/find.ts similarity index 99% rename from test/functional/services/find.ts rename to test/functional/services/common/find.ts index 3697e944610743..727d81377b1416 100644 --- a/test/functional/services/find.ts +++ b/test/functional/services/common/find.ts @@ -18,8 +18,8 @@ */ import { WebDriver, WebElement, By, until } from 'selenium-webdriver'; -import { FtrProviderContext } from '../ftr_provider_context'; -import { WebElementWrapper } from './lib/web_element_wrapper'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { WebElementWrapper } from '../lib/web_element_wrapper'; export async function FindProvider({ getService }: FtrProviderContext) { const log = getService('log'); diff --git a/test/functional/services/common/index.ts b/test/functional/services/common/index.ts new file mode 100644 index 00000000000000..fc483ca512679a --- /dev/null +++ b/test/functional/services/common/index.ts @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { BrowserProvider, Browser } from './browser'; +export { FailureDebuggingProvider } from './failure_debugging'; +export { FindProvider } from './find'; +export { ScreenshotsProvider } from './screenshots'; +export { SnapshotsProvider } from './snapshots'; +export { TestSubjectsProvider, TestSubjects } from './test_subjects'; diff --git a/test/functional/services/screenshots.ts b/test/functional/services/common/screenshots.ts similarity index 95% rename from test/functional/services/screenshots.ts rename to test/functional/services/common/screenshots.ts index 4c5728174cf992..daa55240f3eb77 100644 --- a/test/functional/services/screenshots.ts +++ b/test/functional/services/common/screenshots.ts @@ -23,9 +23,9 @@ import { promisify } from 'util'; import del from 'del'; -import { comparePngs } from './lib/compare_pngs'; -import { FtrProviderContext } from '../ftr_provider_context'; -import { WebElementWrapper } from './lib/web_element_wrapper'; +import { comparePngs } from '../lib/compare_pngs'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { WebElementWrapper } from '../lib/web_element_wrapper'; const mkdirAsync = promisify(mkdir); const writeFileAsync = promisify(writeFile); diff --git a/test/functional/services/snapshots.ts b/test/functional/services/common/snapshots.ts similarity index 97% rename from test/functional/services/snapshots.ts rename to test/functional/services/common/snapshots.ts index 84526878a7bb45..2e0b360e594e53 100644 --- a/test/functional/services/snapshots.ts +++ b/test/functional/services/common/snapshots.ts @@ -23,7 +23,7 @@ import { promisify } from 'util'; import expect from '@kbn/expect'; import del from 'del'; -import { FtrProviderContext } from '../ftr_provider_context'; +import { FtrProviderContext } from '../../ftr_provider_context'; const mkdirAsync = promisify(mkdir); const writeFileAsync = promisify(writeFile); diff --git a/test/functional/services/test_subjects.ts b/test/functional/services/common/test_subjects.ts similarity index 99% rename from test/functional/services/test_subjects.ts rename to test/functional/services/common/test_subjects.ts index 090dc995ddc112..e4e0e7ce70bc40 100644 --- a/test/functional/services/test_subjects.ts +++ b/test/functional/services/common/test_subjects.ts @@ -20,8 +20,8 @@ import testSubjSelector from '@kbn/test-subj-selector'; import { map as mapAsync } from 'bluebird'; import { ProvidedType } from '@kbn/test/types/ftr'; -import { WebElementWrapper } from './lib/web_element_wrapper'; -import { FtrProviderContext } from '../ftr_provider_context'; +import { WebElementWrapper } from '../lib/web_element_wrapper'; +import { FtrProviderContext } from '../../ftr_provider_context'; interface ExistsOptions { timeout?: number; diff --git a/test/functional/services/index.ts b/test/functional/services/index.ts index 02ed9e9865d9a3..cbb0c6790dbe94 100644 --- a/test/functional/services/index.ts +++ b/test/functional/services/index.ts @@ -20,7 +20,14 @@ import { services as commonServiceProviders } from '../../common/services'; import { AppsMenuProvider } from './apps_menu'; -import { BrowserProvider } from './browser'; +import { + BrowserProvider, + FailureDebuggingProvider, + FindProvider, + ScreenshotsProvider, + SnapshotsProvider, + TestSubjectsProvider, +} from './common'; import { ComboBoxProvider } from './combo_box'; import { DashboardAddPanelProvider, @@ -33,19 +40,14 @@ import { import { DocTableProvider } from './doc_table'; import { ElasticChartProvider } from './elastic_chart'; import { EmbeddingProvider } from './embedding'; -import { FailureDebuggingProvider } from './failure_debugging'; import { FilterBarProvider } from './filter_bar'; -import { FindProvider } from './find'; import { FlyoutProvider } from './flyout'; import { GlobalNavProvider } from './global_nav'; import { InspectorProvider } from './inspector'; import { QueryBarProvider } from './query_bar'; import { RemoteProvider } from './remote'; import { RenderableProvider } from './renderable'; -import { ScreenshotsProvider } from './screenshots'; -import { SnapshotsProvider } from './snapshots'; import { TableProvider } from './table'; -import { TestSubjectsProvider } from './test_subjects'; import { ToastsProvider } from './toasts'; // @ts-ignore not TS yet import { PieChartProvider } from './visualizations'; From aca45a7fac01e83647adc797eecc610985b71f44 Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Fri, 15 May 2020 13:09:39 -0400 Subject: [PATCH 13/16] Add kibana-operations as codeowners for .ci/es-snapshots and vars/ (#66746) --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0000fc6f56af33..85f490bc366b9e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -127,6 +127,8 @@ /src/legacy/server/sass/ @elastic/kibana-operations /src/legacy/server/utils/ @elastic/kibana-operations /src/legacy/server/warnings/ @elastic/kibana-operations +/.ci/es-snapshots/ @elastic/kibana-operations +/vars/ @elastic/kibana-operations # Quality Assurance /src/dev/code_coverage @elastic/kibana-qa From 4e0921d41edad38a9d109242fade5087c2fc607d Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 15 May 2020 10:35:44 -0700 Subject: [PATCH 14/16] [kbn/plugin-helpers] typescript-ify (#66513) --- .eslintrc.js | 1 - .../kbn-plugin-helpers/bin/plugin-helpers.js | 2 +- packages/kbn-plugin-helpers/lib/index.d.ts | 26 --- packages/kbn-plugin-helpers/lib/index.js | 32 --- packages/kbn-plugin-helpers/lib/run.test.js | 58 ----- packages/kbn-plugin-helpers/lib/win_cmd.js | 24 -- packages/kbn-plugin-helpers/package.json | 27 ++- .../kbn-plugin-helpers/{cli.js => src/cli.ts} | 17 +- .../commander_action.test.js.snap | 0 .../{ => src}/lib/commander_action.test.js | 8 +- .../lib/commander_action.ts} | 11 +- .../config_file.js => src/lib/config_file.ts} | 37 ++-- .../{lib/docs.js => src/lib/docs.ts} | 18 +- .../lib/enable_collecting_unknown_options.ts} | 8 +- packages/kbn-plugin-helpers/src/lib/index.ts | 24 ++ .../kbn-plugin-helpers/src/lib/pipeline.ts | 23 ++ .../lib/plugin_config.ts} | 51 +++-- .../{lib/run.js => src/lib/run.ts} | 16 +- .../{lib/tasks.js => src/lib/tasks.ts} | 21 +- .../{lib/utils.js => src/lib/utils.ts} | 19 +- .../kbn-plugin-helpers/src/lib/win_cmd.ts | 24 ++ .../{ => src}/tasks/build/README.md | 0 .../tasks/build/build_task.ts} | 54 ++--- .../src/tasks/build/create_build.ts | 196 +++++++++++++++++ .../tasks/build/create_package.ts} | 40 ++-- .../tasks/build/git_info.ts} | 8 +- .../index.js => src/tasks/build/index.ts} | 2 +- .../build_action_test_plugin/index.js | 0 .../build_action_test_plugin/package.json | 0 .../build_action_test_plugin/public/hack.js | 0 .../translations/es.json | 0 .../create_build_test_plugin/index.js | 0 .../create_build_test_plugin/package.json | 0 .../create_build_test_plugin/public/hack.js | 0 .../public/styles.scss | 0 .../translations/es.json | 0 .../create_package_test_plugin/index.js | 0 .../create_package_test_plugin/package.json | 0 .../create_package_test_plugin/public/hack.js | 0 .../translations/es.json | 0 .../__snapshots__/build_action.test.js.snap | 0 .../integration_tests/build_action.test.js | 38 ++-- .../integration_tests/create_build.test.js | 11 +- .../integration_tests/create_package.test.js | 13 +- .../tasks/build/rewrite_package_json.ts} | 17 +- .../{ => src}/tasks/start/README.md | 0 .../index.js => src/tasks/start/index.ts} | 2 +- .../tasks/start/start_task.ts} | 14 +- .../{ => src}/tasks/test/all/README.md | 0 .../index.js => src/tasks/test/all/index.ts} | 2 +- .../tasks/test/all/test_all_task.ts} | 6 +- .../{ => src}/tasks/test/karma/README.md | 0 .../tasks/test/karma/index.ts} | 2 +- .../tasks/test/karma/test_karma_task.ts} | 10 +- .../{ => src}/tasks/test/mocha/README.md | 0 .../src/tasks/test/mocha/index.ts | 20 ++ .../tasks/test/mocha/test_mocha_task.ts} | 10 +- .../tasks/build/create_build.js | 205 ------------------ .../tasks/test/mocha/index.js | 20 -- packages/kbn-plugin-helpers/tsconfig.json | 9 +- packages/kbn-test/src/index.ts | 2 - renovate.json5 | 40 ++++ x-pack/tasks/build.ts | 2 +- x-pack/tasks/dev.ts | 2 +- x-pack/tasks/test.ts | 2 +- .../common/config.ts | 1 - .../spaces_api_integration/common/config.ts | 1 - yarn.lock | 66 +++++- 68 files changed, 658 insertions(+), 584 deletions(-) delete mode 100644 packages/kbn-plugin-helpers/lib/index.d.ts delete mode 100644 packages/kbn-plugin-helpers/lib/index.js delete mode 100644 packages/kbn-plugin-helpers/lib/run.test.js delete mode 100644 packages/kbn-plugin-helpers/lib/win_cmd.js rename packages/kbn-plugin-helpers/{cli.js => src/cli.ts} (87%) rename packages/kbn-plugin-helpers/{ => src}/lib/__snapshots__/commander_action.test.js.snap (100%) rename packages/kbn-plugin-helpers/{ => src}/lib/commander_action.test.js (94%) rename packages/kbn-plugin-helpers/{lib/commander_action.js => src/lib/commander_action.ts} (81%) rename packages/kbn-plugin-helpers/{lib/config_file.js => src/lib/config_file.ts} (70%) rename packages/kbn-plugin-helpers/{lib/docs.js => src/lib/docs.ts} (72%) rename packages/kbn-plugin-helpers/{lib/enable_collecting_unknown_options.js => src/lib/enable_collecting_unknown_options.ts} (86%) create mode 100644 packages/kbn-plugin-helpers/src/lib/index.ts create mode 100644 packages/kbn-plugin-helpers/src/lib/pipeline.ts rename packages/kbn-plugin-helpers/{lib/plugin_config.js => src/lib/plugin_config.ts} (64%) rename packages/kbn-plugin-helpers/{lib/run.js => src/lib/run.ts} (75%) rename packages/kbn-plugin-helpers/{lib/tasks.js => src/lib/tasks.ts} (64%) rename packages/kbn-plugin-helpers/{lib/utils.js => src/lib/utils.ts} (74%) create mode 100644 packages/kbn-plugin-helpers/src/lib/win_cmd.ts rename packages/kbn-plugin-helpers/{ => src}/tasks/build/README.md (100%) rename packages/kbn-plugin-helpers/{tasks/build/build_action.js => src/tasks/build/build_task.ts} (57%) create mode 100644 packages/kbn-plugin-helpers/src/tasks/build/create_build.ts rename packages/kbn-plugin-helpers/{tasks/build/create_package.js => src/tasks/build/create_package.ts} (58%) rename packages/kbn-plugin-helpers/{tasks/build/git_info.js => src/tasks/build/git_info.ts} (92%) rename packages/kbn-plugin-helpers/{tasks/start/index.js => src/tasks/build/index.ts} (94%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/index.js (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/package.json (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/public/hack.js (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/translations/es.json (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/index.js (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/package.json (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/hack.js (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/styles.scss (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/translations/es.json (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/index.js (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/package.json (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/public/hack.js (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/translations/es.json (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/__snapshots__/build_action.test.js.snap (100%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/build_action.test.js (74%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/create_build.test.js (94%) rename packages/kbn-plugin-helpers/{ => src}/tasks/build/integration_tests/create_package.test.js (85%) rename packages/kbn-plugin-helpers/{tasks/build/rewrite_package_json.js => src/tasks/build/rewrite_package_json.ts} (81%) rename packages/kbn-plugin-helpers/{ => src}/tasks/start/README.md (100%) rename packages/kbn-plugin-helpers/{tasks/build/index.js => src/tasks/start/index.ts} (94%) rename packages/kbn-plugin-helpers/{tasks/start/start_action.js => src/tasks/start/start_task.ts} (85%) rename packages/kbn-plugin-helpers/{ => src}/tasks/test/all/README.md (100%) rename packages/kbn-plugin-helpers/{tasks/test/all/index.js => src/tasks/test/all/index.ts} (94%) rename packages/kbn-plugin-helpers/{tasks/test/all/test_all_action.js => src/tasks/test/all/test_all_task.ts} (89%) rename packages/kbn-plugin-helpers/{ => src}/tasks/test/karma/README.md (100%) rename packages/kbn-plugin-helpers/{tasks/test/karma/index.js => src/tasks/test/karma/index.ts} (94%) rename packages/kbn-plugin-helpers/{tasks/test/karma/test_karma_action.js => src/tasks/test/karma/test_karma_task.ts} (86%) rename packages/kbn-plugin-helpers/{ => src}/tasks/test/mocha/README.md (100%) create mode 100644 packages/kbn-plugin-helpers/src/tasks/test/mocha/index.ts rename packages/kbn-plugin-helpers/{tasks/test/mocha/test_mocha_action.js => src/tasks/test/mocha/test_mocha_task.ts} (86%) delete mode 100644 packages/kbn-plugin-helpers/tasks/build/create_build.js delete mode 100644 packages/kbn-plugin-helpers/tasks/test/mocha/index.js diff --git a/.eslintrc.js b/.eslintrc.js index 529bc68537aa16..6b3378d44cb81b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -493,7 +493,6 @@ module.exports = { '.eslintrc.js', '**/webpackShims/**/*.js', 'packages/kbn-plugin-generator/**/*.js', - 'packages/kbn-plugin-helpers/**/*.js', 'packages/kbn-eslint-import-resolver-kibana/**/*.js', 'packages/kbn-eslint-plugin-eslint/**/*', 'x-pack/gulpfile.js', diff --git a/packages/kbn-plugin-helpers/bin/plugin-helpers.js b/packages/kbn-plugin-helpers/bin/plugin-helpers.js index 18a08332605ea5..175ff1019fa2dc 100755 --- a/packages/kbn-plugin-helpers/bin/plugin-helpers.js +++ b/packages/kbn-plugin-helpers/bin/plugin-helpers.js @@ -25,4 +25,4 @@ if (nodeMajorVersion < 6) { process.exit(1); } -require('../cli'); +require('../target/cli'); diff --git a/packages/kbn-plugin-helpers/lib/index.d.ts b/packages/kbn-plugin-helpers/lib/index.d.ts deleted file mode 100644 index 6f1eb73505b05e..00000000000000 --- a/packages/kbn-plugin-helpers/lib/index.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export function babelRegister(): void; -export function resolveKibanaPath(path: string): string; -export function readFtrConfigFile(path: string): any; -export function run( - task: 'build' | 'start' | 'testAll' | 'testKarma' | 'testMocha' | 'postinstall', - options: any -): Promise; diff --git a/packages/kbn-plugin-helpers/lib/index.js b/packages/kbn-plugin-helpers/lib/index.js deleted file mode 100644 index 836d9de7849dc4..00000000000000 --- a/packages/kbn-plugin-helpers/lib/index.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const run = require('./run'); -const utils = require('./utils'); - -module.exports = function() { - console.error( - 'running tasks with the default export of @kbn/plugin-helpers is deprecated.' + - "use `require('@kbn/plugin-helpers').run()` instead" - ); - - return run.apply(this, arguments); -}; - -Object.assign(module.exports, { run: run }, utils); diff --git a/packages/kbn-plugin-helpers/lib/run.test.js b/packages/kbn-plugin-helpers/lib/run.test.js deleted file mode 100644 index 4c87399319b3bb..00000000000000 --- a/packages/kbn-plugin-helpers/lib/run.test.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/*eslint-env jest*/ - -jest.mock('./plugin_config', () => () => ({ id: 'testPlugin' })); - -jest.mock('./tasks', () => { - return { testTask: jest.fn() }; -}); - -const run = require('./run'); - -describe('lib/run', () => { - beforeEach(() => jest.resetAllMocks()); - - it('throw given an invalid task', function() { - const invalidTaskName = 'thisisnotavalidtasknameandneverwillbe'; - const runner = () => run(invalidTaskName); - - expect(runner).toThrow(/invalid task/i); - }); - - it('runs specified task with plugin and runner', function() { - run('testTask'); - - const { testTask } = require('./tasks'); - const plugin = require('./plugin_config')(); - const args = testTask.mock.calls[0]; - expect(testTask.mock.calls).toHaveLength(1); - expect(args[0]).toEqual(plugin); - expect(args[1]).toBe(run); - }); - - it('returns value returned by task', function() { - const { testTask } = require('./tasks'); - - const symbol = Symbol('foo'); - testTask.mockReturnValue(symbol); - expect(run('testTask')).toBe(symbol); - }); -}); diff --git a/packages/kbn-plugin-helpers/lib/win_cmd.js b/packages/kbn-plugin-helpers/lib/win_cmd.js deleted file mode 100644 index 0bc672bed67c6b..00000000000000 --- a/packages/kbn-plugin-helpers/lib/win_cmd.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const platform = require('os').platform(); - -module.exports = function winCmd(cmd) { - return /^win/.test(platform) ? cmd + '.cmd' : cmd; -}; diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index 53c998ddfaac24..040b779a699519 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -1,17 +1,16 @@ { "name": "@kbn/plugin-helpers", - "private": true, "version": "9.0.2", + "private": true, "description": "Just some helpers for kibana plugin devs.", - "main": "lib/index.js", + "license": "Apache-2.0", + "main": "target/lib/index.js", + "scripts": { + "kbn:bootstrap": "tsc" + }, "bin": { "plugin-helpers": "bin/plugin-helpers.js" }, - "author": "Spencer Alger ", - "license": "Apache-2.0", - "peerDependencies": { - "@kbn/babel-preset": "1.0.0" - }, "dependencies": { "@babel/core": "^7.9.0", "argv-split": "^2.0.1", @@ -27,6 +26,20 @@ "node-sass": "^4.13.1", "through2": "^2.0.3", "through2-map": "^3.0.0", + "vinyl": "^2.2.0", "vinyl-fs": "^3.0.3" + }, + "devDependencies": { + "@types/gulp-rename": "^0.0.33", + "@types/gulp-zip": "^4.0.1", + "@types/inquirer": "^6.5.0", + "@types/node-sass": "^4.11.0", + "@types/through2": "^2.0.35", + "@types/through2-map": "^3.0.0", + "@types/vinyl": "^2.0.4", + "typescript": "3.7.2" + }, + "peerDependencies": { + "@kbn/babel-preset": "1.0.0" } } diff --git a/packages/kbn-plugin-helpers/cli.js b/packages/kbn-plugin-helpers/src/cli.ts similarity index 87% rename from packages/kbn-plugin-helpers/cli.js rename to packages/kbn-plugin-helpers/src/cli.ts index 48b70535272fe8..ee1bca0fe3ac23 100644 --- a/packages/kbn-plugin-helpers/cli.js +++ b/packages/kbn-plugin-helpers/src/cli.ts @@ -17,13 +17,16 @@ * under the License. */ -const program = require('commander'); +import Fs from 'fs'; +import Path from 'path'; -const pkg = require('./package.json'); -const createCommanderAction = require('./lib/commander_action'); -const docs = require('./lib/docs'); -const enableCollectingUnknownOptions = require('./lib/enable_collecting_unknown_options'); +import program from 'commander'; +import { createCommanderAction } from './lib/commander_action'; +import { docs } from './lib/docs'; +import { enableCollectingUnknownOptions } from './lib/enable_collecting_unknown_options'; + +const pkg = JSON.parse(Fs.readFileSync(Path.resolve(__dirname, '../package.json'), 'utf8')); program.version(pkg.version); enableCollectingUnknownOptions( @@ -55,7 +58,7 @@ program buildVersion: command.buildVersion, kibanaVersion: command.kibanaVersion, skipArchive: Boolean(command.skipArchive), - files: files, + files, })) ); @@ -84,7 +87,7 @@ program .on('--help', docs('test/mocha')) .action( createCommanderAction('testMocha', (command, files) => ({ - files: files, + files, })) ); diff --git a/packages/kbn-plugin-helpers/lib/__snapshots__/commander_action.test.js.snap b/packages/kbn-plugin-helpers/src/lib/__snapshots__/commander_action.test.js.snap similarity index 100% rename from packages/kbn-plugin-helpers/lib/__snapshots__/commander_action.test.js.snap rename to packages/kbn-plugin-helpers/src/lib/__snapshots__/commander_action.test.js.snap diff --git a/packages/kbn-plugin-helpers/lib/commander_action.test.js b/packages/kbn-plugin-helpers/src/lib/commander_action.test.js similarity index 94% rename from packages/kbn-plugin-helpers/lib/commander_action.test.js rename to packages/kbn-plugin-helpers/src/lib/commander_action.test.js index 40ac6755f02e54..501c0bd0619130 100644 --- a/packages/kbn-plugin-helpers/lib/commander_action.test.js +++ b/packages/kbn-plugin-helpers/src/lib/commander_action.test.js @@ -17,12 +17,10 @@ * under the License. */ -/*eslint-env jest*/ +import { createCommanderAction } from './commander_action'; +import { run } from './run'; -const createCommanderAction = require('./commander_action'); -const run = require('./run'); - -jest.mock('./run', () => jest.fn()); +jest.mock('./run'); const STACK_TRACE_RE = /\n(?:\s+at .+(?:\n|$))+/g; expect.addSnapshotSerializer({ diff --git a/packages/kbn-plugin-helpers/lib/commander_action.js b/packages/kbn-plugin-helpers/src/lib/commander_action.ts similarity index 81% rename from packages/kbn-plugin-helpers/lib/commander_action.js rename to packages/kbn-plugin-helpers/src/lib/commander_action.ts index 497dee8edf740d..ce585dd0a02c88 100644 --- a/packages/kbn-plugin-helpers/lib/commander_action.js +++ b/packages/kbn-plugin-helpers/src/lib/commander_action.ts @@ -17,10 +17,13 @@ * under the License. */ -const run = require('./run'); +import { run } from './run'; +import { Tasks } from './tasks'; -module.exports = function createCommanderAction(taskName, getOptions = () => {}) { - return async (...args) => { +type GetOptions = (command: any, ...args: string[]) => any; + +export function createCommanderAction(taskName: keyof Tasks, getOptions: GetOptions = () => {}) { + return async (...args: string[]) => { try { // command is the last arg passed by commander, but we move it to the front of the list const command = args.pop(); @@ -30,4 +33,4 @@ module.exports = function createCommanderAction(taskName, getOptions = () => {}) process.exit(1); } }; -}; +} diff --git a/packages/kbn-plugin-helpers/lib/config_file.js b/packages/kbn-plugin-helpers/src/lib/config_file.ts similarity index 70% rename from packages/kbn-plugin-helpers/lib/config_file.js rename to packages/kbn-plugin-helpers/src/lib/config_file.ts index 5b8be836998e44..1566932b658722 100644 --- a/packages/kbn-plugin-helpers/lib/config_file.js +++ b/packages/kbn-plugin-helpers/src/lib/config_file.ts @@ -17,33 +17,34 @@ * under the License. */ -const resolve = require('path').resolve; -const readFileSync = require('fs').readFileSync; +import { resolve } from 'path'; +import { readFileSync } from 'fs'; -const configFiles = ['.kibana-plugin-helpers.json', '.kibana-plugin-helpers.dev.json']; -const configCache = {}; +const configFileNames = ['.kibana-plugin-helpers.json', '.kibana-plugin-helpers.dev.json']; -module.exports = function(root) { - if (!root) root = process.cwd(); +interface Config { + [key: string]: unknown; +} - if (configCache[root]) { - return configCache[root]; +const configCache = new Map(); + +export function configFile(root: string = process.cwd()) { + if (configCache.has(root)) { + return configCache.get(root)!; } // config files to read from, in the order they are merged together - let config = (configCache[root] = {}); - - configFiles.forEach(function(configFile) { + let config: Config = {}; + for (const name of configFileNames) { try { - const content = JSON.parse(readFileSync(resolve(root, configFile))); - config = Object.assign(config, content); + config = JSON.parse(readFileSync(resolve(root, name), 'utf8')); } catch (e) { // rethrow error unless it's complaining about file not existing if (e.code !== 'ENOENT') { throw e; } } - }); + } const deprecationMsg = 'has been removed from `@kbn/plugin-helpers`. ' + @@ -59,8 +60,10 @@ module.exports = function(root) { } // use resolve to ensure correct resolution of paths - const { includePlugins } = config; - if (includePlugins) config.includePlugins = includePlugins.map(path => resolve(root, path)); + if (Array.isArray(config.includePlugins)) { + config.includePlugins = config.includePlugins.map((path: string) => resolve(root, path)); + } + configCache.set(root, config); return config; -}; +} diff --git a/packages/kbn-plugin-helpers/lib/docs.js b/packages/kbn-plugin-helpers/src/lib/docs.ts similarity index 72% rename from packages/kbn-plugin-helpers/lib/docs.js rename to packages/kbn-plugin-helpers/src/lib/docs.ts index f1b288c68c390e..68c095209e8170 100644 --- a/packages/kbn-plugin-helpers/lib/docs.js +++ b/packages/kbn-plugin-helpers/src/lib/docs.ts @@ -17,21 +17,19 @@ * under the License. */ -const resolve = require('path').resolve; -const readFileSync = require('fs').readFileSync; +import { resolve } from 'path'; +import { readFileSync } from 'fs'; -function indent(txt, n) { +function indent(txt: string, n: number) { const space = new Array(n + 1).join(' '); return space + txt.split('\n').join('\n' + space); } -module.exports = function docs(name) { - const md = readFileSync(resolve(__dirname, '../tasks', name, 'README.md'), 'utf8'); +export function docs(name: string) { + const md = readFileSync(resolve(__dirname, '../../src/tasks', name, 'README.md'), 'utf8'); return function() { - console.log('\n Docs:'); - console.log(''); - console.log(indent(md, 4)); - console.log(''); + /* eslint-disable-next-line no-console */ + console.log(`\n Docs:\n\n${indent(md, 4)}\n\n`); }; -}; +} diff --git a/packages/kbn-plugin-helpers/lib/enable_collecting_unknown_options.js b/packages/kbn-plugin-helpers/src/lib/enable_collecting_unknown_options.ts similarity index 86% rename from packages/kbn-plugin-helpers/lib/enable_collecting_unknown_options.js rename to packages/kbn-plugin-helpers/src/lib/enable_collecting_unknown_options.ts index 8b855a8b8769d2..77fa7f2fcae846 100644 --- a/packages/kbn-plugin-helpers/lib/enable_collecting_unknown_options.js +++ b/packages/kbn-plugin-helpers/src/lib/enable_collecting_unknown_options.ts @@ -17,12 +17,14 @@ * under the License. */ -module.exports = function enableCollectingUnknownOptions(command) { +import { Command } from 'commander'; + +export function enableCollectingUnknownOptions(command: Command) { const origParse = command.parseOptions; command.allowUnknownOption(); - command.parseOptions = function(argv) { + command.parseOptions = function(argv: string[]) { const opts = origParse.call(this, argv); this.unknownOptions = opts.unknown; return opts; }; -}; +} diff --git a/packages/kbn-plugin-helpers/src/lib/index.ts b/packages/kbn-plugin-helpers/src/lib/index.ts new file mode 100644 index 00000000000000..acc7134308bec3 --- /dev/null +++ b/packages/kbn-plugin-helpers/src/lib/index.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './run'; +export * from './utils'; +export * from './win_cmd'; +export * from './plugin_config'; +export * from './pipeline'; diff --git a/packages/kbn-plugin-helpers/src/lib/pipeline.ts b/packages/kbn-plugin-helpers/src/lib/pipeline.ts new file mode 100644 index 00000000000000..d66e18f5239a90 --- /dev/null +++ b/packages/kbn-plugin-helpers/src/lib/pipeline.ts @@ -0,0 +1,23 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Stream from 'stream'; +import Util from 'util'; + +export const pipeline = Util.promisify(Stream.pipeline); diff --git a/packages/kbn-plugin-helpers/lib/plugin_config.js b/packages/kbn-plugin-helpers/src/lib/plugin_config.ts similarity index 64% rename from packages/kbn-plugin-helpers/lib/plugin_config.js rename to packages/kbn-plugin-helpers/src/lib/plugin_config.ts index 60baa7fc976607..dc3ef936e2164e 100644 --- a/packages/kbn-plugin-helpers/lib/plugin_config.js +++ b/packages/kbn-plugin-helpers/src/lib/plugin_config.ts @@ -17,16 +17,26 @@ * under the License. */ -const resolve = require('path').resolve; -const readFileSync = require('fs').readFileSync; -const configFile = require('./config_file'); +import { resolve } from 'path'; +import { readFileSync } from 'fs'; -module.exports = function(root) { - if (!root) root = process.cwd(); +import { configFile } from './config_file'; +export interface PluginConfig { + root: string; + kibanaRoot: string; + serverTestPatterns: string[]; + buildSourcePatterns: string[]; + skipInstallDependencies: boolean; + id: string; + version: string; + pkg: any; + [k: string]: unknown; +} + +export function pluginConfig(root: string = process.cwd()): PluginConfig { const pluginPackageJsonPath = resolve(root, 'package.json'); - const pkg = JSON.parse(readFileSync(pluginPackageJsonPath)); - const config = configFile(root); + const pkg = JSON.parse(readFileSync(pluginPackageJsonPath, 'utf8')); const buildSourcePatterns = [ 'yarn.lock', @@ -42,6 +52,7 @@ module.exports = function(root) { const isPluginXpack = pkg.name === 'x-pack'; if (isPluginOnKibanaExtra && !isPluginXpack) { + // eslint-disable-next-line no-console console.warn( `In the future we will disable ../kibana-extra/{pluginName}. You should move your plugin ${pkg.name} as soon as possible to ./plugins/{pluginName}` ); @@ -49,17 +60,15 @@ module.exports = function(root) { const kibanaRootWhenNotXpackPlugin = isPluginOnKibanaExtra ? kibanaExtraDir : kibanaPluginsDir; - return Object.assign( - { - root: root, - kibanaRoot: isPluginXpack ? resolve(root, '..') : kibanaRootWhenNotXpackPlugin, - serverTestPatterns: ['server/**/__tests__/**/*.js'], - buildSourcePatterns: buildSourcePatterns, - skipInstallDependencies: false, - id: pkg.name, - pkg: pkg, - version: pkg.version, - }, - config - ); -}; + return { + root, + kibanaRoot: isPluginXpack ? resolve(root, '..') : kibanaRootWhenNotXpackPlugin, + serverTestPatterns: ['server/**/__tests__/**/*.js'], + buildSourcePatterns, + skipInstallDependencies: false, + id: pkg.name as string, + version: pkg.version as string, + pkg, + ...configFile(root), + }; +} diff --git a/packages/kbn-plugin-helpers/lib/run.js b/packages/kbn-plugin-helpers/src/lib/run.ts similarity index 75% rename from packages/kbn-plugin-helpers/lib/run.js rename to packages/kbn-plugin-helpers/src/lib/run.ts index 119b64f71e2f95..2b1a2a63c1074e 100644 --- a/packages/kbn-plugin-helpers/lib/run.js +++ b/packages/kbn-plugin-helpers/src/lib/run.ts @@ -17,15 +17,21 @@ * under the License. */ -const pluginConfig = require('./plugin_config'); -const tasks = require('./tasks'); +import { pluginConfig, PluginConfig } from './plugin_config'; +import { tasks, Tasks } from './tasks'; -module.exports = function run(name, options) { +export interface TaskContext { + plugin: PluginConfig; + run: typeof run; + options?: any; +} + +export function run(name: keyof Tasks, options?: any) { const action = tasks[name]; if (!action) { throw new Error('Invalid task: "' + name + '"'); } const plugin = pluginConfig(); - return action(plugin, run, options); -}; + return action({ plugin, run, options }); +} diff --git a/packages/kbn-plugin-helpers/lib/tasks.js b/packages/kbn-plugin-helpers/src/lib/tasks.ts similarity index 64% rename from packages/kbn-plugin-helpers/lib/tasks.js rename to packages/kbn-plugin-helpers/src/lib/tasks.ts index afc9c056d51d70..7817838760a2e1 100644 --- a/packages/kbn-plugin-helpers/lib/tasks.js +++ b/packages/kbn-plugin-helpers/src/lib/tasks.ts @@ -17,13 +17,22 @@ * under the License. */ -const buildTask = require('../tasks/build'); -const startTask = require('../tasks/start'); -const testAllTask = require('../tasks/test/all'); -const testKarmaTask = require('../tasks/test/karma'); -const testMochaTask = require('../tasks/test/mocha'); +import { buildTask } from '../tasks/build'; +import { startTask } from '../tasks/start'; +import { testAllTask } from '../tasks/test/all'; +import { testKarmaTask } from '../tasks/test/karma'; +import { testMochaTask } from '../tasks/test/mocha'; -module.exports = { +// define a tasks interface that we can extend in the tests +export interface Tasks { + build: typeof buildTask; + start: typeof startTask; + testAll: typeof testAllTask; + testKarma: typeof testKarmaTask; + testMocha: typeof testMochaTask; +} + +export const tasks: Tasks = { build: buildTask, start: startTask, testAll: testAllTask, diff --git a/packages/kbn-plugin-helpers/lib/utils.js b/packages/kbn-plugin-helpers/src/lib/utils.ts similarity index 74% rename from packages/kbn-plugin-helpers/lib/utils.js rename to packages/kbn-plugin-helpers/src/lib/utils.ts index 6e3d8969802a45..0348f9f8deda98 100644 --- a/packages/kbn-plugin-helpers/lib/utils.js +++ b/packages/kbn-plugin-helpers/src/lib/utils.ts @@ -17,11 +17,11 @@ * under the License. */ -const resolve = require('path').resolve; +import { resolve } from 'path'; -const pluginConfig = require('./plugin_config'); +import { pluginConfig } from './plugin_config'; -function babelRegister() { +export function babelRegister() { const plugin = pluginConfig(); try { @@ -36,18 +36,7 @@ function babelRegister() { } } -function resolveKibanaPath(path) { +export function resolveKibanaPath(path: string) { const plugin = pluginConfig(); return resolve(plugin.kibanaRoot, path); } - -function readFtrConfigFile(log, path, settingOverrides) { - return require('@kbn/test') // eslint-disable-line import/no-dynamic-require - .readConfigFile(log, path, settingOverrides); -} - -module.exports = { - babelRegister: babelRegister, - resolveKibanaPath: resolveKibanaPath, - readFtrConfigFile: readFtrConfigFile, -}; diff --git a/packages/kbn-plugin-helpers/src/lib/win_cmd.ts b/packages/kbn-plugin-helpers/src/lib/win_cmd.ts new file mode 100644 index 00000000000000..a3f5d144602ed5 --- /dev/null +++ b/packages/kbn-plugin-helpers/src/lib/win_cmd.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Os from 'os'; + +export function winCmd(cmd: string) { + return /^win/.test(Os.platform()) ? cmd + '.cmd' : cmd; +} diff --git a/packages/kbn-plugin-helpers/tasks/build/README.md b/packages/kbn-plugin-helpers/src/tasks/build/README.md similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/README.md rename to packages/kbn-plugin-helpers/src/tasks/build/README.md diff --git a/packages/kbn-plugin-helpers/tasks/build/build_action.js b/packages/kbn-plugin-helpers/src/tasks/build/build_task.ts similarity index 57% rename from packages/kbn-plugin-helpers/tasks/build/build_action.js rename to packages/kbn-plugin-helpers/src/tasks/build/build_task.ts index 32513958f66abb..16207f323ff71b 100644 --- a/packages/kbn-plugin-helpers/tasks/build/build_action.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/build_task.ts @@ -17,15 +17,14 @@ * under the License. */ -const join = require('path').join; -const resolve = require('path').resolve; -const inquirer = require('inquirer'); +import { join, resolve } from 'path'; +import inquirer from 'inquirer'; -const createBuild = require('./create_build'); -const createPackage = require('./create_package'); +import { TaskContext } from '../../lib'; +import { createBuild } from './create_build'; +import { createPackage } from './create_package'; -module.exports = function(plugin, run, options) { - options = options || {}; +export async function buildTask({ plugin, options = {} }: TaskContext) { let buildVersion = plugin.version; let kibanaVersion = (plugin.pkg.kibana && plugin.pkg.kibana.version) || plugin.pkg.version; let buildFiles = plugin.buildSourcePatterns; @@ -41,31 +40,24 @@ module.exports = function(plugin, run, options) { if (options.buildVersion) buildVersion = options.buildVersion; if (options.kibanaVersion) kibanaVersion = options.kibanaVersion; - let buildStep; - if (kibanaVersion === 'kibana') { - buildStep = askForKibanaVersion().then(function(customKibanaVersion) { - return createBuild(plugin, buildTarget, buildVersion, customKibanaVersion, buildFiles); - }); - } else { - buildStep = createBuild(plugin, buildTarget, buildVersion, kibanaVersion, buildFiles); + const chosenKibanaVersion = + kibanaVersion === 'kibana' ? await askForKibanaVersion() : kibanaVersion; + + await createBuild(plugin, buildTarget, buildVersion, chosenKibanaVersion, buildFiles); + + if (!options.skipArchive) { + await createPackage(plugin, buildTarget, buildVersion); } +} - return buildStep.then(function() { - if (options.skipArchive) return; - return createPackage(plugin, buildTarget, buildVersion); - }); -}; +async function askForKibanaVersion() { + const answers = await inquirer.prompt([ + { + type: 'input', + name: 'kibanaVersion', + message: 'What version of Kibana are you building for?', + }, + ]); -function askForKibanaVersion() { - return inquirer - .prompt([ - { - type: 'input', - name: 'kibanaVersion', - message: 'What version of Kibana are you building for?', - }, - ]) - .then(function(answers) { - return answers.kibanaVersion; - }); + return answers.kibanaVersion; } diff --git a/packages/kbn-plugin-helpers/src/tasks/build/create_build.ts b/packages/kbn-plugin-helpers/src/tasks/build/create_build.ts new file mode 100644 index 00000000000000..a469e4fe673908 --- /dev/null +++ b/packages/kbn-plugin-helpers/src/tasks/build/create_build.ts @@ -0,0 +1,196 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { relative } from 'path'; +import path from 'path'; + +import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'fs'; +import execa from 'execa'; +import sass from 'node-sass'; +import del from 'del'; +import File from 'vinyl'; +import vfs from 'vinyl-fs'; +import rename from 'gulp-rename'; +import through from 'through2'; +import minimatch from 'minimatch'; +// @ts-ignore +import gulpBabel from 'gulp-babel'; + +import { PluginConfig, winCmd, pipeline } from '../../lib'; +import { rewritePackageJson } from './rewrite_package_json'; + +// `link:` dependencies create symlinks, but we don't want to include symlinks +// in the built zip file. Therefore we remove all symlinked dependencies, so we +// can re-create them when installing the plugin. +function removeSymlinkDependencies(root: string) { + const nodeModulesPattern = path.join(root, '**', 'node_modules', '**'); + + return through.obj((file: File, _, cb) => { + const isSymlink = file.symlink != null; + const isDependency = minimatch(file.path, nodeModulesPattern); + + if (isSymlink && isDependency) { + unlinkSync(file.path); + } + + cb(); + }); +} + +// parse a ts config file +function parseTsconfig(pluginSourcePath: string, configPath: string) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const ts = require(path.join(pluginSourcePath, 'node_modules', 'typescript')); + + const { error, config } = ts.parseConfigFileTextToJson( + configPath, + readFileSync(configPath, 'utf8') + ); + + if (error) { + throw error; + } + + return config; +} + +// transpile with babel +async function transpileWithBabel(srcGlobs: string[], buildRoot: string, presets: string[]) { + await pipeline( + vfs.src( + srcGlobs.concat([ + '!**/*.d.ts', + '!**/*.{test,test.mocks,mock,mocks}.{ts,tsx}', + '!**/node_modules/**', + '!**/bower_components/**', + '!**/__tests__/**', + ]), + { + cwd: buildRoot, + } + ), + + gulpBabel({ + babelrc: false, + presets, + }), + + vfs.dest(buildRoot) + ); +} + +export async function createBuild( + plugin: PluginConfig, + buildTarget: string, + buildVersion: string, + kibanaVersion: string, + files: string[] +) { + const buildSource = plugin.root; + const buildRoot = path.join(buildTarget, 'kibana', plugin.id); + + await del(buildTarget); + + // copy source files and apply some transformations in the process + await pipeline( + vfs.src(files, { + cwd: buildSource, + base: buildSource, + allowEmpty: true, + }), + + // modify the package.json file + rewritePackageJson(buildSource, buildVersion, kibanaVersion), + + // put all files inside the correct directories + rename(function nestFileInDir(filePath) { + const nonRelativeDirname = filePath.dirname!.replace(/^(\.\.\/?)+/g, ''); + filePath.dirname = path.join(relative(buildTarget, buildRoot), nonRelativeDirname); + }), + + // write files back to disk + vfs.dest(buildTarget) + ); + + // install packages in build + if (!plugin.skipInstallDependencies) { + execa.sync(winCmd('yarn'), ['install', '--production', '--pure-lockfile'], { + cwd: buildRoot, + }); + } + + // compile stylesheet + if (typeof plugin.styleSheetToCompile === 'string') { + const file = path.resolve(plugin.root, plugin.styleSheetToCompile); + if (!existsSync(file)) { + throw new Error(`Path provided for styleSheetToCompile does not exist: ${file}`); + } + + const outputFileName = path.basename(file, path.extname(file)) + '.css'; + const output = path.join(buildRoot, path.dirname(plugin.styleSheetToCompile), outputFileName); + + const rendered = sass.renderSync({ file, output }); + writeFileSync(output, rendered.css); + + del.sync([path.join(buildRoot, '**', '*.s{a,c}ss')]); + } + + // transform typescript to js and clean out typescript + const tsConfigPath = path.join(buildRoot, 'tsconfig.json'); + if (existsSync(tsConfigPath)) { + // attempt to patch the extends path in the tsconfig file + const buildConfig = parseTsconfig(buildSource, tsConfigPath); + + if (buildConfig.extends) { + buildConfig.extends = path.join(relative(buildRoot, buildSource), buildConfig.extends); + + writeFileSync(tsConfigPath, JSON.stringify(buildConfig)); + } + + // Transpile ts server code + // + // Include everything except content from public folders + await transpileWithBabel(['**/*.{ts,tsx}', '!**/public/**'], buildRoot, [ + require.resolve('@kbn/babel-preset/node_preset'), + ]); + + // Transpile ts client code + // + // Include everything inside a public directory + await transpileWithBabel(['**/public/**/*.{ts,tsx}'], buildRoot, [ + require.resolve('@kbn/babel-preset/webpack_preset'), + ]); + + del.sync([ + path.join(buildRoot, '**', '*.{ts,tsx,d.ts}'), + path.join(buildRoot, 'tsconfig.json'), + ]); + } + + // remove symlinked dependencies + await pipeline( + vfs.src([relative(buildTarget, buildRoot) + '/**/*'], { + cwd: buildTarget, + base: buildTarget, + resolveSymlinks: false, + }), + + removeSymlinkDependencies(buildRoot) + ); +} diff --git a/packages/kbn-plugin-helpers/tasks/build/create_package.js b/packages/kbn-plugin-helpers/src/tasks/build/create_package.ts similarity index 58% rename from packages/kbn-plugin-helpers/tasks/build/create_package.js rename to packages/kbn-plugin-helpers/src/tasks/build/create_package.ts index 6df55fda902b04..9fa2305a94eabc 100644 --- a/packages/kbn-plugin-helpers/tasks/build/create_package.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/create_package.ts @@ -17,28 +17,30 @@ * under the License. */ -const join = require('path').join; -const relative = require('path').relative; -const del = require('del'); -const vfs = require('vinyl-fs'); -const zip = require('gulp-zip'); +import { relative, join } from 'path'; -module.exports = function createPackage(plugin, buildTarget, buildVersion) { +import del from 'del'; +import vfs from 'vinyl-fs'; +import zip from 'gulp-zip'; + +import { pipeline, PluginConfig } from '../../lib'; + +export async function createPackage( + plugin: PluginConfig, + buildTarget: string, + buildVersion: string +) { const buildId = `${plugin.id}-${buildVersion}`; const buildRoot = join(buildTarget, 'kibana', plugin.id); + const buildFiles = [relative(buildTarget, buildRoot) + '/**/*']; // zip up the package - return new Promise(function(resolve, reject) { - const buildFiles = [relative(buildTarget, buildRoot) + '/**/*']; + await pipeline( + vfs.src(buildFiles, { cwd: buildTarget, base: buildTarget }), + zip(`${buildId}.zip`), + vfs.dest(buildTarget) + ); - vfs - .src(buildFiles, { cwd: buildTarget, base: buildTarget }) - .pipe(zip(`${buildId}.zip`)) - .pipe(vfs.dest(buildTarget)) - .on('end', resolve) - .on('error', reject); - }).then(function() { - // clean up the build path - return del(join(buildTarget, 'kibana')); - }); -}; + // clean up the build path + await del(join(buildTarget, 'kibana')); +} diff --git a/packages/kbn-plugin-helpers/tasks/build/git_info.js b/packages/kbn-plugin-helpers/src/tasks/build/git_info.ts similarity index 92% rename from packages/kbn-plugin-helpers/tasks/build/git_info.js rename to packages/kbn-plugin-helpers/src/tasks/build/git_info.ts index 655b5c95a01025..e3a68f82e48b29 100644 --- a/packages/kbn-plugin-helpers/tasks/build/git_info.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/git_info.ts @@ -17,16 +17,18 @@ * under the License. */ -const execFileSync = require('child_process').execFileSync; +import { execFileSync } from 'child_process'; -module.exports = function gitInfo(rootPath) { +export function gitInfo(rootPath: string) { try { const LOG_SEPARATOR = '||'; + const commitCount = execFileSync('git', ['rev-list', '--count', 'HEAD'], { cwd: rootPath, stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8', }); + const logLine = execFileSync('git', ['log', '--pretty=%h' + LOG_SEPARATOR + '%cD', '-n', '1'], { cwd: rootPath, stdio: ['ignore', 'pipe', 'ignore'], @@ -41,4 +43,4 @@ module.exports = function gitInfo(rootPath) { } catch (e) { return {}; } -}; +} diff --git a/packages/kbn-plugin-helpers/tasks/start/index.js b/packages/kbn-plugin-helpers/src/tasks/build/index.ts similarity index 94% rename from packages/kbn-plugin-helpers/tasks/start/index.js rename to packages/kbn-plugin-helpers/src/tasks/build/index.ts index b76e91fd5f2898..d22d544a954915 100644 --- a/packages/kbn-plugin-helpers/tasks/start/index.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/index.ts @@ -17,4 +17,4 @@ * under the License. */ -module.exports = require('./start_action'); +export * from './build_task'; diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/index.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/index.js similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/index.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/index.js diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/package.json b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/package.json similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/package.json rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/package.json diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/public/hack.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/public/hack.js similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/public/hack.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/public/hack.js diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/translations/es.json b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/translations/es.json similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/translations/es.json rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/build_action_test_plugin/translations/es.json diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/index.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/index.js similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/index.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/index.js diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/package.json b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/package.json similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/package.json rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/package.json diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/hack.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/hack.js similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/hack.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/hack.js diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/styles.scss b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/styles.scss similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/styles.scss rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/public/styles.scss diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/translations/es.json b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/translations/es.json similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/translations/es.json rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_build_test_plugin/translations/es.json diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/index.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/index.js similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/index.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/index.js diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/package.json b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/package.json similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/package.json rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/package.json diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/public/hack.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/public/hack.js similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/public/hack.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/public/hack.js diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/translations/es.json b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/translations/es.json similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/translations/es.json rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__fixtures__/create_package_test_plugin/translations/es.json diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/__snapshots__/build_action.test.js.snap b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__snapshots__/build_action.test.js.snap similarity index 100% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/__snapshots__/build_action.test.js.snap rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/__snapshots__/build_action.test.js.snap diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/build_action.test.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/build_action.test.js similarity index 74% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/build_action.test.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/build_action.test.js index 90deb0c4ac4a86..f596576fe74669 100644 --- a/packages/kbn-plugin-helpers/tasks/build/integration_tests/build_action.test.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/build_action.test.js @@ -17,34 +17,34 @@ * under the License. */ -const resolve = require('path').resolve; -const fs = require('fs'); -const del = require('del'); +import { resolve } from 'path'; +import fs from 'fs'; +import del from 'del'; +import { pluginConfig } from '../../../lib'; const PLUGIN_FIXTURE = resolve(__dirname, '__fixtures__/build_action_test_plugin'); const PLUGIN_BUILD_DIR = resolve(PLUGIN_FIXTURE, 'build'); -const PLUGIN = require('../../../lib/plugin_config')(PLUGIN_FIXTURE); -const noop = () => {}; +const plugin = pluginConfig(PLUGIN_FIXTURE); describe('creating build zip', () => { - const buildAction = require('../build_action'); + const { buildTask } = require('../build_task'); beforeEach(() => del(PLUGIN_BUILD_DIR)); afterEach(() => del(PLUGIN_BUILD_DIR)); it('creates a zip in the build directory', async () => { - await buildAction(PLUGIN); + await buildTask({ plugin }); - const buildFile = resolve(PLUGIN_BUILD_DIR, PLUGIN.id + '-' + PLUGIN.version + '.zip'); + const buildFile = resolve(PLUGIN_BUILD_DIR, plugin.id + '-' + plugin.version + '.zip'); if (!fs.existsSync(buildFile)) { throw new Error('Build file not found: ' + buildFile); } }); it('skips zip creation based on flag', async () => { - await buildAction(PLUGIN, noop, { skipArchive: true }); + await buildTask({ plugin, options: { skipArchive: true } }); - const buildFile = resolve(PLUGIN_BUILD_DIR, PLUGIN.id + '-' + PLUGIN.version + '.zip'); + const buildFile = resolve(PLUGIN_BUILD_DIR, plugin.id + '-' + plugin.version + '.zip'); if (fs.existsSync(buildFile)) { throw new Error('Build file not found: ' + buildFile); } @@ -53,13 +53,13 @@ describe('creating build zip', () => { describe('calling create_build', () => { let mockBuild; - let buildAction; + let buildTask; beforeEach(() => { jest.resetModules(); - mockBuild = jest.fn(() => Promise.resolve()); - jest.mock('../create_build', () => mockBuild); - buildAction = require('../build_action'); + jest.mock('../create_build'); + ({ createBuild: mockBuild } = require('../create_build')); + ({ buildTask } = require('../build_task')); }); const nameArgs = ([plugin, buildTarget, buildVersion, kibanaVersion, files]) => ({ @@ -76,7 +76,7 @@ describe('calling create_build', () => { kibanaVersion: '4.5.6', }; - await buildAction(PLUGIN, noop, options); + await buildTask({ plugin, options }); expect(mockBuild.mock.calls).toHaveLength(1); @@ -86,12 +86,12 @@ describe('calling create_build', () => { }); it('uses default file list without files option', async () => { - await buildAction(PLUGIN); + await buildTask({ plugin }); expect(mockBuild.mock.calls).toHaveLength(1); const { files } = nameArgs(mockBuild.mock.calls[0]); - PLUGIN.buildSourcePatterns.forEach(file => expect(files).toContain(file)); + plugin.buildSourcePatterns.forEach(file => expect(files).toContain(file)); }); it('uses only files passed in', async () => { @@ -99,7 +99,7 @@ describe('calling create_build', () => { files: ['index.js', 'LICENSE.txt', 'plugins/**/*', '{server,public}/**/*'], }; - await buildAction(PLUGIN, noop, options); + await buildTask({ plugin, options }); expect(mockBuild.mock.calls).toHaveLength(1); @@ -112,6 +112,6 @@ describe('calling create_build', () => { throw new Error('foo bar'); }); - await expect(buildAction(PLUGIN, noop)).rejects.toThrowErrorMatchingSnapshot(); + await expect(buildTask({ plugin })).rejects.toThrowErrorMatchingSnapshot(); }); }); diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/create_build.test.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/create_build.test.js similarity index 94% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/create_build.test.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/create_build.test.js index 42ad1c5ae0cfce..8a4a5a55ce237a 100644 --- a/packages/kbn-plugin-helpers/tasks/build/integration_tests/create_build.test.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/create_build.test.js @@ -17,13 +17,14 @@ * under the License. */ -const { resolve } = require('path'); -const { readdirSync, existsSync, unlinkSync } = require('fs'); -const del = require('del'); -const createBuild = require('../create_build'); +import { resolve } from 'path'; +import { readdirSync, existsSync, unlinkSync } from 'fs'; +import del from 'del'; +import { createBuild } from '../create_build'; +import { pluginConfig } from '../../../lib'; const PLUGIN_FIXTURE = resolve(__dirname, '__fixtures__/create_build_test_plugin'); -const PLUGIN = require('../../../lib/plugin_config')(PLUGIN_FIXTURE); +const PLUGIN = pluginConfig(PLUGIN_FIXTURE); const PLUGIN_BUILD_DIR = resolve(PLUGIN_FIXTURE, 'build'); const PLUGIN_BUILD_TARGET = resolve(PLUGIN_BUILD_DIR, 'kibana', PLUGIN.id); diff --git a/packages/kbn-plugin-helpers/tasks/build/integration_tests/create_package.test.js b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/create_package.test.js similarity index 85% rename from packages/kbn-plugin-helpers/tasks/build/integration_tests/create_package.test.js rename to packages/kbn-plugin-helpers/src/tasks/build/integration_tests/create_package.test.js index 9659cfbaa2a304..13de8fa165c291 100644 --- a/packages/kbn-plugin-helpers/tasks/build/integration_tests/create_package.test.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/integration_tests/create_package.test.js @@ -17,14 +17,15 @@ * under the License. */ -const { resolve } = require('path'); -const { statSync } = require('fs'); -const del = require('del'); -const createBuild = require('../create_build'); -const createPackage = require('../create_package'); +import { resolve } from 'path'; +import { statSync } from 'fs'; +import del from 'del'; +import { createBuild } from '../create_build'; +import { createPackage } from '../create_package'; +import { pluginConfig } from '../../../lib'; const PLUGIN_FIXTURE = resolve(__dirname, '__fixtures__/create_package_test_plugin'); -const PLUGIN = require('../../../lib/plugin_config')(PLUGIN_FIXTURE); +const PLUGIN = pluginConfig(PLUGIN_FIXTURE); const PLUGIN_BUILD_DIR = resolve(PLUGIN_FIXTURE, 'build-custom'); const buildVersion = PLUGIN.version; diff --git a/packages/kbn-plugin-helpers/tasks/build/rewrite_package_json.js b/packages/kbn-plugin-helpers/src/tasks/build/rewrite_package_json.ts similarity index 81% rename from packages/kbn-plugin-helpers/tasks/build/rewrite_package_json.js rename to packages/kbn-plugin-helpers/src/tasks/build/rewrite_package_json.ts index 64656baee6fd2b..255b2e6ef99922 100644 --- a/packages/kbn-plugin-helpers/tasks/build/rewrite_package_json.js +++ b/packages/kbn-plugin-helpers/src/tasks/build/rewrite_package_json.ts @@ -17,13 +17,18 @@ * under the License. */ -const map = require('through2-map').obj; -const gitInfo = require('./git_info'); +import Through2Map from 'through2-map'; +import File from 'vinyl'; +import { gitInfo } from './git_info'; -module.exports = function rewritePackage(buildSource, buildVersion, kibanaVersion) { - return map(function(file) { +export function rewritePackageJson( + buildSource: string, + buildVersion: string, + kibanaVersion: string +) { + return Through2Map.obj(function(file: File) { if (file.basename === 'package.json' && file.dirname === buildSource) { - const pkg = JSON.parse(file.contents.toString('utf8')); + const pkg = JSON.parse(file.contents!.toString('utf8')); // rewrite the target kibana version while the // file is on it's way to the archive @@ -46,4 +51,4 @@ module.exports = function rewritePackage(buildSource, buildVersion, kibanaVersio return file; }); -}; +} diff --git a/packages/kbn-plugin-helpers/tasks/start/README.md b/packages/kbn-plugin-helpers/src/tasks/start/README.md similarity index 100% rename from packages/kbn-plugin-helpers/tasks/start/README.md rename to packages/kbn-plugin-helpers/src/tasks/start/README.md diff --git a/packages/kbn-plugin-helpers/tasks/build/index.js b/packages/kbn-plugin-helpers/src/tasks/start/index.ts similarity index 94% rename from packages/kbn-plugin-helpers/tasks/build/index.js rename to packages/kbn-plugin-helpers/src/tasks/start/index.ts index b01a64c7f9be24..cf34bdbadf4166 100644 --- a/packages/kbn-plugin-helpers/tasks/build/index.js +++ b/packages/kbn-plugin-helpers/src/tasks/start/index.ts @@ -17,4 +17,4 @@ * under the License. */ -module.exports = require('./build_action'); +export * from './start_task'; diff --git a/packages/kbn-plugin-helpers/tasks/start/start_action.js b/packages/kbn-plugin-helpers/src/tasks/start/start_task.ts similarity index 85% rename from packages/kbn-plugin-helpers/tasks/start/start_action.js rename to packages/kbn-plugin-helpers/src/tasks/start/start_task.ts index 08ef0914311f83..75affb6da8c6f1 100644 --- a/packages/kbn-plugin-helpers/tasks/start/start_action.js +++ b/packages/kbn-plugin-helpers/src/tasks/start/start_task.ts @@ -17,11 +17,15 @@ * under the License. */ -const execFileSync = require('child_process').execFileSync; -const { join } = require('path'); -const split = require('argv-split'); +import { execFileSync } from 'child_process'; +import { join } from 'path'; -module.exports = function(plugin, run, options) { +// @ts-ignore +import split from 'argv-split'; + +import { TaskContext } from '../../lib'; + +export function startTask({ plugin, options }: TaskContext) { options = options || {}; const cmd = 'node'; @@ -44,4 +48,4 @@ module.exports = function(plugin, run, options) { cwd: plugin.kibanaRoot, stdio: ['ignore', 1, 2], }); -}; +} diff --git a/packages/kbn-plugin-helpers/tasks/test/all/README.md b/packages/kbn-plugin-helpers/src/tasks/test/all/README.md similarity index 100% rename from packages/kbn-plugin-helpers/tasks/test/all/README.md rename to packages/kbn-plugin-helpers/src/tasks/test/all/README.md diff --git a/packages/kbn-plugin-helpers/tasks/test/all/index.js b/packages/kbn-plugin-helpers/src/tasks/test/all/index.ts similarity index 94% rename from packages/kbn-plugin-helpers/tasks/test/all/index.js rename to packages/kbn-plugin-helpers/src/tasks/test/all/index.ts index 0cdc615ee867fd..be8db50825fc96 100644 --- a/packages/kbn-plugin-helpers/tasks/test/all/index.js +++ b/packages/kbn-plugin-helpers/src/tasks/test/all/index.ts @@ -17,4 +17,4 @@ * under the License. */ -module.exports = require('./test_all_action'); +export * from './test_all_task'; diff --git a/packages/kbn-plugin-helpers/tasks/test/all/test_all_action.js b/packages/kbn-plugin-helpers/src/tasks/test/all/test_all_task.ts similarity index 89% rename from packages/kbn-plugin-helpers/tasks/test/all/test_all_action.js rename to packages/kbn-plugin-helpers/src/tasks/test/all/test_all_task.ts index f16e391b2b2113..d07c19291d2cbd 100644 --- a/packages/kbn-plugin-helpers/tasks/test/all/test_all_action.js +++ b/packages/kbn-plugin-helpers/src/tasks/test/all/test_all_task.ts @@ -17,7 +17,9 @@ * under the License. */ -module.exports = function testAllAction(plugin, run) { +import { TaskContext } from '../../../lib'; + +export function testAllTask({ run }: TaskContext) { run('testMocha'); run('testKarma'); -}; +} diff --git a/packages/kbn-plugin-helpers/tasks/test/karma/README.md b/packages/kbn-plugin-helpers/src/tasks/test/karma/README.md similarity index 100% rename from packages/kbn-plugin-helpers/tasks/test/karma/README.md rename to packages/kbn-plugin-helpers/src/tasks/test/karma/README.md diff --git a/packages/kbn-plugin-helpers/tasks/test/karma/index.js b/packages/kbn-plugin-helpers/src/tasks/test/karma/index.ts similarity index 94% rename from packages/kbn-plugin-helpers/tasks/test/karma/index.js rename to packages/kbn-plugin-helpers/src/tasks/test/karma/index.ts index 0472207948c3d7..3089357b499910 100644 --- a/packages/kbn-plugin-helpers/tasks/test/karma/index.js +++ b/packages/kbn-plugin-helpers/src/tasks/test/karma/index.ts @@ -17,4 +17,4 @@ * under the License. */ -module.exports = require('./test_karma_action'); +export * from './test_karma_task'; diff --git a/packages/kbn-plugin-helpers/tasks/test/karma/test_karma_action.js b/packages/kbn-plugin-helpers/src/tasks/test/karma/test_karma_task.ts similarity index 86% rename from packages/kbn-plugin-helpers/tasks/test/karma/test_karma_action.js rename to packages/kbn-plugin-helpers/src/tasks/test/karma/test_karma_task.ts index e1ba8caee7f9a1..2fe8134209894f 100644 --- a/packages/kbn-plugin-helpers/tasks/test/karma/test_karma_action.js +++ b/packages/kbn-plugin-helpers/src/tasks/test/karma/test_karma_task.ts @@ -17,10 +17,12 @@ * under the License. */ -const execFileSync = require('child_process').execFileSync; -const winCmd = require('../../../lib/win_cmd'); +import { execFileSync } from 'child_process'; -module.exports = function testKarmaAction(plugin, run, options) { +import { TaskContext } from '../../../lib'; +import { winCmd } from '../../../lib/win_cmd'; + +export function testKarmaTask({ plugin, options }: TaskContext) { options = options || {}; const kbnServerArgs = ['--kbnServer.plugin-path=' + plugin.root]; @@ -37,4 +39,4 @@ module.exports = function testKarmaAction(plugin, run, options) { cwd: plugin.kibanaRoot, stdio: ['ignore', 1, 2], }); -}; +} diff --git a/packages/kbn-plugin-helpers/tasks/test/mocha/README.md b/packages/kbn-plugin-helpers/src/tasks/test/mocha/README.md similarity index 100% rename from packages/kbn-plugin-helpers/tasks/test/mocha/README.md rename to packages/kbn-plugin-helpers/src/tasks/test/mocha/README.md diff --git a/packages/kbn-plugin-helpers/src/tasks/test/mocha/index.ts b/packages/kbn-plugin-helpers/src/tasks/test/mocha/index.ts new file mode 100644 index 00000000000000..74e53062d4f01a --- /dev/null +++ b/packages/kbn-plugin-helpers/src/tasks/test/mocha/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './test_mocha_task'; diff --git a/packages/kbn-plugin-helpers/tasks/test/mocha/test_mocha_action.js b/packages/kbn-plugin-helpers/src/tasks/test/mocha/test_mocha_task.ts similarity index 86% rename from packages/kbn-plugin-helpers/tasks/test/mocha/test_mocha_action.js rename to packages/kbn-plugin-helpers/src/tasks/test/mocha/test_mocha_task.ts index 7cc9864baa9756..a79ef0a59d19a9 100644 --- a/packages/kbn-plugin-helpers/tasks/test/mocha/test_mocha_action.js +++ b/packages/kbn-plugin-helpers/src/tasks/test/mocha/test_mocha_task.ts @@ -17,10 +17,12 @@ * under the License. */ -const execFileSync = require('child_process').execFileSync; -const globby = require('globby'); +import { execFileSync } from 'child_process'; +import globby from 'globby'; -module.exports = function(plugin, run, options) { +import { TaskContext } from '../../../lib'; + +export function testMochaTask({ plugin, options }: TaskContext) { options = options || {}; let testPatterns = plugin.serverTestPatterns; @@ -43,4 +45,4 @@ module.exports = function(plugin, run, options) { stdio: ['ignore', 1, 2], } ); -}; +} diff --git a/packages/kbn-plugin-helpers/tasks/build/create_build.js b/packages/kbn-plugin-helpers/tasks/build/create_build.js deleted file mode 100644 index 7d42dc13ef278d..00000000000000 --- a/packages/kbn-plugin-helpers/tasks/build/create_build.js +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const path = require('path'); -const relative = require('path').relative; -const { readFileSync, writeFileSync, unlinkSync, existsSync } = require('fs'); -const execa = require('execa'); -const sass = require('node-sass'); -const del = require('del'); -const vfs = require('vinyl-fs'); -const rename = require('gulp-rename'); -const through = require('through2'); -const minimatch = require('minimatch'); -const gulpBabel = require('gulp-babel'); -const { promisify } = require('util'); -const { pipeline } = require('stream'); - -const rewritePackageJson = require('./rewrite_package_json'); -const winCmd = require('../../lib/win_cmd'); - -const asyncPipeline = promisify(pipeline); - -// `link:` dependencies create symlinks, but we don't want to include symlinks -// in the built zip file. Therefore we remove all symlinked dependencies, so we -// can re-create them when installing the plugin. -function removeSymlinkDependencies(root) { - const nodeModulesPattern = path.join(root, '**', 'node_modules', '**'); - - return through.obj((file, enc, cb) => { - const isSymlink = file.symlink != null; - const isDependency = minimatch(file.path, nodeModulesPattern); - - if (isSymlink && isDependency) { - unlinkSync(file.path); - } - - cb(); - }); -} - -// parse a ts config file -function parseTsconfig(pluginSourcePath, configPath) { - const ts = require(path.join(pluginSourcePath, 'node_modules', 'typescript')); // eslint-disable-line import/no-dynamic-require - - const { error, config } = ts.parseConfigFileTextToJson( - configPath, - readFileSync(configPath, 'utf8') - ); - - if (error) { - throw error; - } - - return config; -} - -// transpile with babel -async function transpileWithBabel(srcGlobs, buildRoot, presets) { - await asyncPipeline( - vfs.src( - srcGlobs.concat([ - '!**/*.d.ts', - '!**/*.{test,test.mocks,mock,mocks}.{ts,tsx}', - '!**/node_modules/**', - '!**/bower_components/**', - '!**/__tests__/**', - ]), - { - cwd: buildRoot, - } - ), - - gulpBabel({ - babelrc: false, - presets, - }), - - vfs.dest(buildRoot) - ); -} - -module.exports = function createBuild(plugin, buildTarget, buildVersion, kibanaVersion, files) { - const buildSource = plugin.root; - const buildRoot = path.join(buildTarget, 'kibana', plugin.id); - - return del(buildTarget) - .then(function() { - return new Promise(function(resolve, reject) { - vfs - .src(files, { - cwd: buildSource, - base: buildSource, - allowEmpty: true, - }) - // modify the package.json file - .pipe(rewritePackageJson(buildSource, buildVersion, kibanaVersion)) - - // put all files inside the correct directories - .pipe( - rename(function nestFileInDir(filePath) { - const nonRelativeDirname = filePath.dirname.replace(/^(\.\.\/?)+/g, ''); - filePath.dirname = path.join(relative(buildTarget, buildRoot), nonRelativeDirname); - }) - ) - - .pipe(vfs.dest(buildTarget)) - .on('end', resolve) - .on('error', reject); - }); - }) - .then(function() { - if (plugin.skipInstallDependencies) { - return; - } - - // install packages in build - execa.sync(winCmd('yarn'), ['install', '--production', '--pure-lockfile'], { - cwd: buildRoot, - }); - }) - .then(function() { - if (!plugin.styleSheetToCompile) { - return; - } - - const file = path.resolve(plugin.root, plugin.styleSheetToCompile); - if (!existsSync(file)) { - throw new Error(`Path provided for styleSheetToCompile does not exist: ${file}`); - } - - const outputFileName = path.basename(file, path.extname(file)) + '.css'; - const output = path.join(buildRoot, path.dirname(plugin.styleSheetToCompile), outputFileName); - - const rendered = sass.renderSync({ file, output }); - writeFileSync(output, rendered.css); - - del.sync([path.join(buildRoot, '**', '*.s{a,c}ss')]); - }) - .then(async function() { - const buildConfigPath = path.join(buildRoot, 'tsconfig.json'); - - if (!existsSync(buildConfigPath)) { - return; - } - - // attempt to patch the extends path in the tsconfig file - const buildConfig = parseTsconfig(buildSource, buildConfigPath); - - if (buildConfig.extends) { - buildConfig.extends = path.join(relative(buildRoot, buildSource), buildConfig.extends); - - writeFileSync(buildConfigPath, JSON.stringify(buildConfig)); - } - - // Transpile ts server code - // - // Include everything except content from public folders - await transpileWithBabel(['**/*.{ts,tsx}', '!**/public/**'], buildRoot, [ - require.resolve('@kbn/babel-preset/node_preset'), - ]); - - // Transpile ts client code - // - // Include everything inside a public directory - await transpileWithBabel(['**/public/**/*.{ts,tsx}'], buildRoot, [ - require.resolve('@kbn/babel-preset/webpack_preset'), - ]); - - del.sync([ - path.join(buildRoot, '**', '*.{ts,tsx,d.ts}'), - path.join(buildRoot, 'tsconfig.json'), - ]); - }) - .then(function() { - const buildFiles = [relative(buildTarget, buildRoot) + '/**/*']; - - return new Promise((resolve, reject) => { - vfs - .src(buildFiles, { - cwd: buildTarget, - base: buildTarget, - resolveSymlinks: false, - }) - .pipe(removeSymlinkDependencies(buildRoot)) - .on('finish', resolve) - .on('error', reject); - }); - }); -}; diff --git a/packages/kbn-plugin-helpers/tasks/test/mocha/index.js b/packages/kbn-plugin-helpers/tasks/test/mocha/index.js deleted file mode 100644 index 1ab022db588f92..00000000000000 --- a/packages/kbn-plugin-helpers/tasks/test/mocha/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -module.exports = require('./test_mocha_action'); diff --git a/packages/kbn-plugin-helpers/tsconfig.json b/packages/kbn-plugin-helpers/tsconfig.json index f5559aa7290c5d..d0dbe1e44f0fa5 100644 --- a/packages/kbn-plugin-helpers/tsconfig.json +++ b/packages/kbn-plugin-helpers/tsconfig.json @@ -1,4 +1,11 @@ { "extends": "../../tsconfig.json", - "include": ["lib/index.d.ts"] + "compilerOptions": { + "outDir": "target", + "declaration": true, + "sourceMap": true + }, + "include": [ + "src/**/*.ts" + ] } diff --git a/packages/kbn-test/src/index.ts b/packages/kbn-test/src/index.ts index 57cdc8ffd494f3..585ce8181df5f4 100644 --- a/packages/kbn-test/src/index.ts +++ b/packages/kbn-test/src/index.ts @@ -42,10 +42,8 @@ export { kbnTestConfig, kibanaServerTestUser, kibanaTestUser, adminTestUser } fr // @ts-ignore not typed yet export { setupUsers, DEFAULT_SUPERUSER_PASS } from './functional_tests/lib/auth'; -// @ts-ignore not typed yet export { readConfigFile } from './functional_test_runner/lib/config/read_config_file'; -// @ts-ignore not typed yet export { runFtrCli } from './functional_test_runner/cli'; export { diff --git a/renovate.json5 b/renovate.json5 index c4efa86366bf40..f5bb39a16fe465 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -426,6 +426,14 @@ '@types/indent-string', ], }, + { + groupSlug: 'inquirer', + groupName: 'inquirer related packages', + packageNames: [ + 'inquirer', + '@types/inquirer', + ], + }, { groupSlug: 'intl-relativeformat', groupName: 'intl-relativeformat related packages', @@ -683,6 +691,14 @@ '@types/node-forge', ], }, + { + groupSlug: 'node-sass', + groupName: 'node-sass related packages', + packageNames: [ + 'node-sass', + '@types/node-sass', + ], + }, { groupSlug: 'nodemailer', groupName: 'nodemailer related packages', @@ -951,6 +967,22 @@ '@types/tempy', ], }, + { + groupSlug: 'through2', + groupName: 'through2 related packages', + packageNames: [ + 'through2', + '@types/through2', + ], + }, + { + groupSlug: 'through2-map', + groupName: 'through2-map related packages', + packageNames: [ + 'through2-map', + '@types/through2-map', + ], + }, { groupSlug: 'tinycolor2', groupName: 'tinycolor2 related packages', @@ -1003,6 +1035,14 @@ ], enabled: false, }, + { + groupSlug: 'vinyl', + groupName: 'vinyl related packages', + packageNames: [ + 'vinyl', + '@types/vinyl', + ], + }, { groupSlug: 'vinyl-fs', groupName: 'vinyl-fs related packages', diff --git a/x-pack/tasks/build.ts b/x-pack/tasks/build.ts index 38ebb0bad4bdc7..8dbf6d212d5d29 100644 --- a/x-pack/tasks/build.ts +++ b/x-pack/tasks/build.ts @@ -8,7 +8,7 @@ import execa from 'execa'; import { resolve } from 'path'; import { writeFileSync } from 'fs'; -import pluginHelpers from '@kbn/plugin-helpers'; +import * as pluginHelpers from '@kbn/plugin-helpers'; import { ToolingLog, REPO_ROOT } from '@kbn/dev-utils'; import gulp from 'gulp'; import del from 'del'; diff --git a/x-pack/tasks/dev.ts b/x-pack/tasks/dev.ts index 6e398f231a27c4..f43b67e2885612 100644 --- a/x-pack/tasks/dev.ts +++ b/x-pack/tasks/dev.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import pluginHelpers from '@kbn/plugin-helpers'; +import * as pluginHelpers from '@kbn/plugin-helpers'; import gulp from 'gulp'; import { prepareTask } from './prepare'; diff --git a/x-pack/tasks/test.ts b/x-pack/tasks/test.ts index 78a04413daae74..0d990bff9f44e4 100644 --- a/x-pack/tasks/test.ts +++ b/x-pack/tasks/test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import pluginHelpers from '@kbn/plugin-helpers'; +import * as pluginHelpers from '@kbn/plugin-helpers'; import gulp from 'gulp'; import { getEnabledPlugins } from './helpers/flags'; diff --git a/x-pack/test/saved_object_api_integration/common/config.ts b/x-pack/test/saved_object_api_integration/common/config.ts index c6a8599b1797f9..f933cb30ffd043 100644 --- a/x-pack/test/saved_object_api_integration/common/config.ts +++ b/x-pack/test/saved_object_api_integration/common/config.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore import { resolveKibanaPath } from '@kbn/plugin-helpers'; import { FtrConfigProviderContext } from '@kbn/test/types/ftr'; import path from 'path'; diff --git a/x-pack/test/spaces_api_integration/common/config.ts b/x-pack/test/spaces_api_integration/common/config.ts index 66bf3cf7b683ba..275d80786e43c2 100644 --- a/x-pack/test/spaces_api_integration/common/config.ts +++ b/x-pack/test/spaces_api_integration/common/config.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore import { resolveKibanaPath } from '@kbn/plugin-helpers'; import path from 'path'; import { TestInvoker } from './lib/types'; diff --git a/yarn.lock b/yarn.lock index 044d259d5804ec..245e0de1526585 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3980,6 +3980,11 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== +"@types/expect@^1.20.4": + version "1.20.4" + resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" + integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== + "@types/fancy-log@^1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.1.tgz#dd94fbc8c2e2ab8ab402ca8d04bb8c34965f0696" @@ -4075,6 +4080,20 @@ resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.13.4.tgz#55ae9c29f0fd6b85ee536f5c72b4769d5c5e06b1" integrity sha512-B4yel4ro2nTb3v0pYO8vO6SjgvFJSrwUY+IO6TUSLdOSB+gQFslylrhRCHxvXMIhxB71mv5PEE9dAX+24S8sew== +"@types/gulp-rename@^0.0.33": + version "0.0.33" + resolved "https://registry.yarnpkg.com/@types/gulp-rename/-/gulp-rename-0.0.33.tgz#38d146e97786569f74f5391a1b1f9b5198674b6c" + integrity sha512-FIZQvbZJj6V1gHPTzO+g/BCWpDur7fJrroae4gwV3LaoHBQ+MrR9sB+2HssK8fHv4WdY6hVNxkcft9bYatuPIA== + dependencies: + "@types/node" "*" + +"@types/gulp-zip@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/gulp-zip/-/gulp-zip-4.0.1.tgz#96cd0b994219f9ae3bbbec7ec3baa043fba9d9ef" + integrity sha512-dYwGsHmwv4pnMD+jtyuIdZchJ0CIivnl8PIApHC+rYN7FMj01tJSAiQb+YN4T/pOn10pmmucBLEB9wXEhQX2Ug== + dependencies: + "@types/node" "*" + "@types/gulp@^4.0.6": version "4.0.6" resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-4.0.6.tgz#68fe0e1f0ff3657cfca46fb564806b744a1bf899" @@ -4172,6 +4191,14 @@ dependencies: "@types/hapi" "*" +"@types/inquirer@^6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be" + integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw== + dependencies: + "@types/through" "*" + rxjs "^6.4.0" + "@types/intl-relativeformat@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@types/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#3a2b0043380388f39c666665ec517e11412f1358" @@ -4478,6 +4505,13 @@ dependencies: "@types/node" "*" +"@types/node-sass@^4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@types/node-sass/-/node-sass-4.11.0.tgz#b0372075546e83f39df52bd37359eab00165a04d" + integrity sha512-uNpVWhwVmbB5luE7b8vxcJwu5np75YkVTBJS0O3ar+hrxqLfyhOKXg9NYBwJ6mMQX/V6/8d6mMZTB7x2r5x9Bw== + dependencies: + "@types/node" "*" + "@types/node@*", "@types/node@8.10.54", "@types/node@>=10.17.17 <10.20.0", "@types/node@>=8.9.0", "@types/node@^12.0.2": version "10.17.17" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" @@ -4983,6 +5017,28 @@ "@types/react-dom" "*" "@types/testing-library__dom" "*" +"@types/through2-map@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/through2-map/-/through2-map-3.0.0.tgz#2fda6049bf0ec16fd75394fc64536d73024d3189" + integrity sha512-r2m4v3Lggg30dCt7nG9uDl93LhImYRsAutECYNU7JenHTM3MdwMHudcC3sOqk/rEUEpN9CDNOIuOxRGzJUP1pg== + dependencies: + "@types/node" "*" + "@types/through2" "*" + +"@types/through2@*", "@types/through2@^2.0.35": + version "2.0.35" + resolved "https://registry.yarnpkg.com/@types/through2/-/through2-2.0.35.tgz#9add1643da9f936ecf0622311759b33e881047e8" + integrity sha512-5puhsegK8DdiZkVL71+iL67KxKd92l7kzzzeclc+idlp5L6PbjxDDQX9JCIA6jOUS9aNHgcmONyW5CRtZUvKFw== + dependencies: + "@types/node" "*" + +"@types/through@*": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895" + integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg== + dependencies: + "@types/node" "*" + "@types/tinycolor2@^1.4.0": version "1.4.2" resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf" @@ -5079,6 +5135,14 @@ dependencies: "@types/node" "*" +"@types/vinyl@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.4.tgz#9a7a8071c8d14d3a95d41ebe7135babe4ad5995a" + integrity sha512-2o6a2ixaVI2EbwBPg1QYLGQoHK56p/8X/sGfKbFC8N6sY9lfjsMf/GprtkQkSya0D4uRiutRZ2BWj7k3JvLsAQ== + dependencies: + "@types/expect" "^1.20.4" + "@types/node" "*" + "@types/watchpack@^1.1.5": version "1.1.5" resolved "https://registry.yarnpkg.com/@types/watchpack/-/watchpack-1.1.5.tgz#e5622eb2a49e2239d94d8882275fbc7893147e97" @@ -31231,7 +31295,7 @@ vinyl@^1.1.0: clone-stats "^0.0.1" replace-ext "0.0.1" -vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0: +vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0, vinyl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== From 915ff5db50ca22fe4e881756ecb694de242e57ec Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Fri, 15 May 2020 20:01:33 +0200 Subject: [PATCH 15/16] move oss features registration to KP (#66524) * register OSS features with KP SO types only * use Licensing plugin API in features plugin * add plugin tests * filter hidden types out * cleanup tests * rename * add degug logging * add warning for setup contract * fix typo --- .../saved_objects_service.mock.ts | 1 + x-pack/legacy/plugins/xpack_main/index.js | 5 +- x-pack/plugins/endpoint/server/plugin.test.ts | 1 - x-pack/plugins/features/kibana.json | 1 + x-pack/plugins/features/server/mocks.ts | 1 - x-pack/plugins/features/server/plugin.test.ts | 97 +++++++++++++++++++ x-pack/plugins/features/server/plugin.ts | 72 +++++++------- .../features/server/routes/index.test.ts | 46 ++++----- .../plugins/features/server/routes/index.ts | 7 +- 9 files changed, 161 insertions(+), 70 deletions(-) create mode 100644 x-pack/plugins/features/server/plugin.test.ts diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts index 4e1f5981d6a410..6f5ecb1eb464b0 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -107,4 +107,5 @@ export const savedObjectsServiceMock = { createInternalStartContract: createInternalStartContractMock, createStartContract: createStartContractMock, createMigrationContext: migrationMocks.createContext, + createTypeRegistryMock: typeRegistryMock.create, }; diff --git a/x-pack/legacy/plugins/xpack_main/index.js b/x-pack/legacy/plugins/xpack_main/index.js index 6ce457ffbec05d..1f8a4a62ea1567 100644 --- a/x-pack/legacy/plugins/xpack_main/index.js +++ b/x-pack/legacy/plugins/xpack_main/index.js @@ -64,10 +64,7 @@ export const xpackMain = kibana => { mirrorPluginStatus(server.plugins.elasticsearch, this, 'yellow', 'red'); - featuresPlugin.registerLegacyAPI({ - xpackInfo: setupXPackMain(server), - savedObjectTypes: server.savedObjects.types, - }); + setupXPackMain(server); // register routes xpackInfoRoute(server); diff --git a/x-pack/plugins/endpoint/server/plugin.test.ts b/x-pack/plugins/endpoint/server/plugin.test.ts index 45e9591a149750..215b26942bcdb5 100644 --- a/x-pack/plugins/endpoint/server/plugin.test.ts +++ b/x-pack/plugins/endpoint/server/plugin.test.ts @@ -34,7 +34,6 @@ describe('test endpoint plugin', () => { registerFeature: jest.fn(), getFeatures: jest.fn(), getFeaturesUICapabilities: jest.fn(), - registerLegacyAPI: jest.fn(), }; }); diff --git a/x-pack/plugins/features/kibana.json b/x-pack/plugins/features/kibana.json index 6e51f3b6507106..1cab1821b1bf59 100644 --- a/x-pack/plugins/features/kibana.json +++ b/x-pack/plugins/features/kibana.json @@ -2,6 +2,7 @@ "id": "features", "version": "8.0.0", "kibanaVersion": "kibana", + "requiredPlugins": ["licensing"], "optionalPlugins": ["visTypeTimelion"], "configPath": ["xpack", "features"], "server": true, diff --git a/x-pack/plugins/features/server/mocks.ts b/x-pack/plugins/features/server/mocks.ts index ebaa5f1a504ca9..d9437169a7453b 100644 --- a/x-pack/plugins/features/server/mocks.ts +++ b/x-pack/plugins/features/server/mocks.ts @@ -11,7 +11,6 @@ const createSetup = (): jest.Mocked => { getFeatures: jest.fn(), getFeaturesUICapabilities: jest.fn(), registerFeature: jest.fn(), - registerLegacyAPI: jest.fn(), }; }; diff --git a/x-pack/plugins/features/server/plugin.test.ts b/x-pack/plugins/features/server/plugin.test.ts new file mode 100644 index 00000000000000..3d7cf19e58b0ea --- /dev/null +++ b/x-pack/plugins/features/server/plugin.test.ts @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { coreMock, savedObjectsServiceMock } from 'src/core/server/mocks'; + +import { Plugin } from './plugin'; +const initContext = coreMock.createPluginInitializerContext(); +const coreSetup = coreMock.createSetup(); +const coreStart = coreMock.createStart(); +const typeRegistry = savedObjectsServiceMock.createTypeRegistryMock(); +typeRegistry.getAllTypes.mockReturnValue([ + { + name: 'foo', + hidden: false, + mappings: { properties: {} }, + namespaceType: 'single' as 'single', + }, + { + name: 'bar', + hidden: true, + mappings: { properties: {} }, + namespaceType: 'agnostic' as 'agnostic', + }, +]); +coreStart.savedObjects.getTypeRegistry.mockReturnValue(typeRegistry); + +describe('Features Plugin', () => { + it('returns OSS + registered features', async () => { + const plugin = new Plugin(initContext); + const { registerFeature } = await plugin.setup(coreSetup, {}); + registerFeature({ + id: 'baz', + name: 'baz', + app: [], + privileges: null, + }); + + const { getFeatures } = await plugin.start(coreStart); + + expect(getFeatures().map(f => f.id)).toMatchInlineSnapshot(` + Array [ + "baz", + "discover", + "visualize", + "dashboard", + "dev_tools", + "advancedSettings", + "indexPatterns", + "savedObjectsManagement", + ] + `); + }); + + it('returns OSS + registered features with timelion when available', async () => { + const plugin = new Plugin(initContext); + const { registerFeature } = await plugin.setup(coreSetup, { + visTypeTimelion: { uiEnabled: true }, + }); + registerFeature({ + id: 'baz', + name: 'baz', + app: [], + privileges: null, + }); + + const { getFeatures } = await plugin.start(coreStart); + + expect(getFeatures().map(f => f.id)).toMatchInlineSnapshot(` + Array [ + "baz", + "discover", + "visualize", + "dashboard", + "dev_tools", + "advancedSettings", + "indexPatterns", + "savedObjectsManagement", + "timelion", + ] + `); + }); + + it('registers not hidden saved objects types', async () => { + const plugin = new Plugin(initContext); + await plugin.setup(coreSetup, {}); + const { getFeatures } = await plugin.start(coreStart); + + const soTypes = + getFeatures().find(f => f.id === 'savedObjectsManagement')?.privileges?.all.savedObject.all || + []; + + expect(soTypes.includes('foo')).toBe(true); + expect(soTypes.includes('bar')).toBe(false); + }); +}); diff --git a/x-pack/plugins/features/server/plugin.ts b/x-pack/plugins/features/server/plugin.ts index 2405f05768a2f0..e3480eda9fe7db 100644 --- a/x-pack/plugins/features/server/plugin.ts +++ b/x-pack/plugins/features/server/plugin.ts @@ -6,13 +6,14 @@ import { CoreSetup, + CoreStart, + SavedObjectsServiceStart, Logger, PluginInitializerContext, RecursiveReadonly, } from '../../../../src/core/server'; import { Capabilities as UICapabilities } from '../../../../src/core/server'; import { deepFreeze } from '../../../../src/core/server'; -import { XPackInfo } from '../../../legacy/plugins/xpack_main/server/lib/xpack_info'; import { PluginSetupContract as TimelionSetupContract } from '../../../../src/plugins/vis_type_timelion/server'; import { FeatureRegistry } from './feature_registry'; import { Feature, FeatureConfig } from '../common/feature'; @@ -25,39 +26,26 @@ import { defineRoutes } from './routes'; */ export interface PluginSetupContract { registerFeature(feature: FeatureConfig): void; + /* + * Calling this function during setup will crash Kibana. + * Use start contract instead. + * @deprecated + * */ getFeatures(): Feature[]; getFeaturesUICapabilities(): UICapabilities; - registerLegacyAPI: (legacyAPI: LegacyAPI) => void; } export interface PluginStartContract { getFeatures(): Feature[]; } -/** - * Describes a set of APIs that are available in the legacy platform only and required by this plugin - * to function properly. - */ -export interface LegacyAPI { - xpackInfo: Pick; - savedObjectTypes: string[]; -} - /** * Represents Features Plugin instance that will be managed by the Kibana plugin system. */ export class Plugin { private readonly logger: Logger; - private readonly featureRegistry: FeatureRegistry = new FeatureRegistry(); - - private legacyAPI?: LegacyAPI; - private readonly getLegacyAPI = () => { - if (!this.legacyAPI) { - throw new Error('Legacy API is not registered!'); - } - return this.legacyAPI; - }; + private isTimelionEnabled: boolean = false; constructor(private readonly initializerContext: PluginInitializerContext) { this.logger = this.initializerContext.logger.get(); @@ -67,39 +55,49 @@ export class Plugin { core: CoreSetup, { visTypeTimelion }: { visTypeTimelion?: TimelionSetupContract } ): Promise> { + this.isTimelionEnabled = visTypeTimelion !== undefined && visTypeTimelion.uiEnabled; + defineRoutes({ router: core.http.createRouter(), featureRegistry: this.featureRegistry, - getLegacyAPI: this.getLegacyAPI, }); return deepFreeze({ registerFeature: this.featureRegistry.register.bind(this.featureRegistry), getFeatures: this.featureRegistry.getAll.bind(this.featureRegistry), getFeaturesUICapabilities: () => uiCapabilitiesForFeatures(this.featureRegistry.getAll()), - - registerLegacyAPI: (legacyAPI: LegacyAPI) => { - this.legacyAPI = legacyAPI; - - // Register OSS features. - for (const feature of buildOSSFeatures({ - savedObjectTypes: this.legacyAPI.savedObjectTypes, - includeTimelion: visTypeTimelion !== undefined && visTypeTimelion.uiEnabled, - })) { - this.featureRegistry.register(feature); - } - }, }); } - public start(): RecursiveReadonly { - this.logger.debug('Starting plugin'); + public start(core: CoreStart): RecursiveReadonly { + this.registerOssFeatures(core.savedObjects); + return deepFreeze({ getFeatures: this.featureRegistry.getAll.bind(this.featureRegistry), }); } - public stop() { - this.logger.debug('Stopping plugin'); + public stop() {} + + private registerOssFeatures(savedObjects: SavedObjectsServiceStart) { + const registry = savedObjects.getTypeRegistry(); + const savedObjectTypes = registry + .getAllTypes() + .filter(t => !t.hidden) + .map(t => t.name); + + this.logger.debug( + `Registering OSS features with SO types: ${savedObjectTypes.join(', ')}. "includeTimelion": ${ + this.isTimelionEnabled + }.` + ); + const features = buildOSSFeatures({ + savedObjectTypes, + includeTimelion: this.isTimelionEnabled, + }); + + for (const feature of features) { + this.featureRegistry.register(feature); + } } } diff --git a/x-pack/plugins/features/server/routes/index.test.ts b/x-pack/plugins/features/server/routes/index.test.ts index c43e2a5195fe72..67b28b27f931fb 100644 --- a/x-pack/plugins/features/server/routes/index.test.ts +++ b/x-pack/plugins/features/server/routes/index.test.ts @@ -7,12 +7,20 @@ import { FeatureRegistry } from '../feature_registry'; import { defineRoutes } from './index'; -import { httpServerMock, httpServiceMock } from '../../../../../src/core/server/mocks'; -import { XPackInfoLicense } from '../../../../legacy/plugins/xpack_main/server/lib/xpack_info_license'; +import { httpServerMock, httpServiceMock, coreMock } from '../../../../../src/core/server/mocks'; +import { LicenseType } from '../../../licensing/server/'; +import { licensingMock } from '../../../licensing/server/mocks'; import { RequestHandler } from '../../../../../src/core/server'; import { FeatureConfig } from '../../common'; -let currentLicenseLevel: string = 'gold'; +function createContextMock(licenseType: LicenseType = 'gold') { + return { + core: coreMock.createRequestHandlerContext(), + licensing: { + license: licensingMock.createLicense({ license: { type: licenseType } }), + }, + }; +} describe('GET /api/features', () => { let routeHandler: RequestHandler; @@ -53,16 +61,6 @@ describe('GET /api/features', () => { defineRoutes({ router: routerMock, featureRegistry, - getLegacyAPI: () => ({ - xpackInfo: { - license: { - isOneOf(candidateLicenses: string[]) { - return candidateLicenses.includes(currentLicenseLevel); - }, - } as XPackInfoLicense, - }, - savedObjectTypes: [], - }), }); routeHandler = routerMock.get.mock.calls[0][1]; @@ -70,7 +68,7 @@ describe('GET /api/features', () => { it('returns a list of available features, sorted by their configured order', async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(undefined as any, { query: {} } as any, mockResponse); + routeHandler(createContextMock(), { query: {} } as any, mockResponse); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; @@ -98,10 +96,8 @@ describe('GET /api/features', () => { }); it(`by default does not return features that arent allowed by current license`, async () => { - currentLicenseLevel = 'basic'; - const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(undefined as any, { query: {} } as any, mockResponse); + routeHandler(createContextMock('basic'), { query: {} } as any, mockResponse); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; @@ -126,10 +122,12 @@ describe('GET /api/features', () => { }); it(`ignoreValidLicenses=false does not return features that arent allowed by current license`, async () => { - currentLicenseLevel = 'basic'; - const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(undefined as any, { query: { ignoreValidLicenses: false } } as any, mockResponse); + routeHandler( + createContextMock('basic'), + { query: { ignoreValidLicenses: false } } as any, + mockResponse + ); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; @@ -154,10 +152,12 @@ describe('GET /api/features', () => { }); it(`ignoreValidLicenses=true returns features that arent allowed by current license`, async () => { - currentLicenseLevel = 'basic'; - const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(undefined as any, { query: { ignoreValidLicenses: true } } as any, mockResponse); + routeHandler( + createContextMock('basic'), + { query: { ignoreValidLicenses: true } } as any, + mockResponse + ); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; diff --git a/x-pack/plugins/features/server/routes/index.ts b/x-pack/plugins/features/server/routes/index.ts index 428500c3daa88d..d07b4886930910 100644 --- a/x-pack/plugins/features/server/routes/index.ts +++ b/x-pack/plugins/features/server/routes/index.ts @@ -6,7 +6,6 @@ import { schema } from '@kbn/config-schema'; import { IRouter } from '../../../../../src/core/server'; -import { LegacyAPI } from '../plugin'; import { FeatureRegistry } from '../feature_registry'; /** @@ -15,10 +14,9 @@ import { FeatureRegistry } from '../feature_registry'; export interface RouteDefinitionParams { router: IRouter; featureRegistry: FeatureRegistry; - getLegacyAPI: () => LegacyAPI; } -export function defineRoutes({ router, featureRegistry, getLegacyAPI }: RouteDefinitionParams) { +export function defineRoutes({ router, featureRegistry }: RouteDefinitionParams) { router.get( { path: '/api/features', @@ -37,7 +35,8 @@ export function defineRoutes({ router, featureRegistry, getLegacyAPI }: RouteDef request.query.ignoreValidLicenses || !feature.validLicenses || !feature.validLicenses.length || - getLegacyAPI().xpackInfo.license.isOneOf(feature.validLicenses) + (context.licensing!.license.type && + feature.validLicenses.includes(context.licensing!.license.type)) ) .sort( (f1, f2) => From b2df0529522935c20c03187b0ccb0ce26d165b7f Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 15 May 2020 14:06:06 -0400 Subject: [PATCH 16/16] [Maps] Get number of categories from palette (#66454) --- .../descriptor_types/descriptor_types.d.ts | 1 + .../maps/public/classes/fields/field.ts | 1 + .../dynamic_icon_property.test.tsx.snap | 78 +++++++++++++++++++ .../vector/properties/__tests__/test_util.ts | 75 ++++++++++++++++++ .../properties/dynamic_color_property.test.js | 61 +-------------- .../properties/dynamic_icon_property.js | 5 ++ .../properties/dynamic_icon_property.test.tsx | 61 +++++++++++++++ .../properties/dynamic_style_property.js | 3 +- 8 files changed, 225 insertions(+), 60 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_icon_property.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts create mode 100644 x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.test.tsx diff --git a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts b/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts index 80e417f9dfa62b..4bdafcabaad06f 100644 --- a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts +++ b/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts @@ -115,6 +115,7 @@ export type JoinDescriptor = { // todo : this union type is incompatible with dynamic extensibility of sources. // Reconsider using SourceDescriptor in type signatures for top-level classes export type SourceDescriptor = + | AbstractSourceDescriptor | XYZTMSSourceDescriptor | WMSSourceDescriptor | KibanaTilemapSourceDescriptor diff --git a/x-pack/plugins/maps/public/classes/fields/field.ts b/x-pack/plugins/maps/public/classes/fields/field.ts index 539d0ab4d6ade1..04daedc59c0324 100644 --- a/x-pack/plugins/maps/public/classes/fields/field.ts +++ b/x-pack/plugins/maps/public/classes/fields/field.ts @@ -20,6 +20,7 @@ export interface IField { isValid(): boolean; getOrdinalFieldMetaRequest(): Promise; getCategoricalFieldMetaRequest(size: number): Promise; + supportsFieldMeta(): boolean; } export class AbstractField implements IField { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_icon_property.test.tsx.snap b/x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_icon_property.test.tsx.snap new file mode 100644 index 00000000000000..057907353d68ab --- /dev/null +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_icon_property.test.tsx.snap @@ -0,0 +1,78 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Should render categorical legend with breaks 1`] = ` +
+ + + + + + Other + + } + styleName="icon" + symbolId="square" + /> + + + + + + + + foobar_label + + + + + + +
+`; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts b/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts new file mode 100644 index 00000000000000..1c478bb85ccc7e --- /dev/null +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// eslint-disable-next-line max-classes-per-file +import { FIELD_ORIGIN } from '../../../../../../common/constants'; +import { StyleMeta } from '../../style_meta'; +import { + CategoryFieldMeta, + GeometryTypes, + RangeFieldMeta, + StyleMetaDescriptor, +} from '../../../../../../common/descriptor_types'; +import { AbstractField, IField } from '../../../../fields/field'; + +class MockField extends AbstractField { + async getLabel(): Promise { + return this.getName() + '_label'; + } + supportsFieldMeta(): boolean { + return true; + } +} + +export const mockField: IField = new MockField({ + fieldName: 'foobar', + origin: FIELD_ORIGIN.SOURCE, +}); + +class MockStyle { + getStyleMeta(): StyleMeta { + const geomTypes: GeometryTypes = { + isPointsOnly: false, + isLinesOnly: false, + isPolygonsOnly: false, + }; + const rangeFieldMeta: RangeFieldMeta = { min: 0, max: 100, delta: 100 }; + const catFieldMeta: CategoryFieldMeta = { + categories: [ + { + key: 'US', + count: 10, + }, + { + key: 'CN', + count: 8, + }, + ], + }; + + const styleMetaDescriptor: StyleMetaDescriptor = { + geometryTypes: geomTypes, + fieldMeta: { + foobar: { + range: rangeFieldMeta, + categories: catFieldMeta, + }, + }, + }; + + return new StyleMeta(styleMetaDescriptor); + } +} + +export class MockLayer { + getStyle() { + return new MockStyle(); + } + + getDataRequest() { + return null; + } +} diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.test.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.test.js index b19c25b369848c..f4c2b8d9260755 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.test.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.test.js @@ -15,65 +15,8 @@ import React from 'react'; import { shallow } from 'enzyme'; import { DynamicColorProperty } from './dynamic_color_property'; -import { StyleMeta } from '../style_meta'; -import { COLOR_MAP_TYPE, FIELD_ORIGIN, VECTOR_STYLES } from '../../../../../common/constants'; - -const mockField = { - async getLabel() { - return 'foobar_label'; - }, - getName() { - return 'foobar'; - }, - getRootName() { - return 'foobar'; - }, - getOrigin() { - return FIELD_ORIGIN.SOURCE; - }, - supportsFieldMeta() { - return true; - }, -}; - -class MockStyle { - getStyleMeta() { - return new StyleMeta({ - geometryTypes: { - isPointsOnly: false, - isLinesOnly: false, - isPolygonsOnly: false, - }, - fieldMeta: { - foobar: { - range: { min: 0, max: 100 }, - categories: { - categories: [ - { - key: 'US', - count: 10, - }, - { - key: 'CN', - count: 8, - }, - ], - }, - }, - }, - }); - } -} - -class MockLayer { - getStyle() { - return new MockStyle(); - } - - getDataRequest() { - return null; - } -} +import { COLOR_MAP_TYPE, VECTOR_STYLES } from '../../../../../common/constants'; +import { mockField, MockLayer } from './__tests__/test_util'; const makeProperty = (options, field = mockField) => { return new DynamicColorProperty(options, VECTOR_STYLES.LINE_COLOR, field, new MockLayer(), () => { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js index 05e2ad06842cea..27c4fca7d701d5 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js @@ -29,6 +29,11 @@ export class DynamicIconProperty extends DynamicStyleProperty { return true; } + getNumberOfCategories() { + const palette = getIconPalette(this._options.iconPaletteId); + return palette ? palette.length : 0; + } + syncIconWithMb(symbolLayerId, mbMap, iconPixelSize) { if (this._isIconDynamicConfigComplete()) { mbMap.setLayoutProperty( diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.test.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.test.tsx new file mode 100644 index 00000000000000..c2719432130278 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.test.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// eslint-disable-next-line max-classes-per-file +import { shallow } from 'enzyme'; + +jest.mock('ui/new_platform'); +jest.mock('../components/vector_style_editor', () => ({ + VectorStyleEditor: () => { + return
mockVectorStyleEditor
; + }, +})); + +import React from 'react'; +import { VECTOR_STYLES } from '../../../../../common/constants'; +// @ts-ignore +import { DynamicIconProperty } from './dynamic_icon_property'; +import { mockField, MockLayer } from './__tests__/test_util'; +import { IconDynamicOptions } from '../../../../../common/descriptor_types'; +import { IField } from '../../../fields/field'; + +const makeProperty = (options: Partial, field: IField = mockField) => { + return new DynamicIconProperty( + { ...options, fieldMetaOptions: { isEnabled: false } }, + VECTOR_STYLES.ICON, + field, + new MockLayer(), + () => { + return (x: string) => x + '_format'; + } + ); +}; + +describe('DynamicIconProperty', () => { + it('should derive category number from palettes', async () => { + const filled = makeProperty({ + iconPaletteId: 'filledShapes', + }); + expect(filled.getNumberOfCategories()).toEqual(6); + const hollow = makeProperty({ + iconPaletteId: 'hollowShapes', + }); + expect(hollow.getNumberOfCategories()).toEqual(5); + }); +}); + +test('Should render categorical legend with breaks', async () => { + const iconStyle = makeProperty({ + iconPaletteId: 'filledShapes', + }); + + const legendRow = iconStyle.renderLegendDetailRow({ isPointsOnly: true, isLinesOnly: false }); + const component = shallow(legendRow); + await new Promise(resolve => process.nextTick(resolve)); + component.update(); + + expect(component).toMatchSnapshot(); +}); diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.js index 451a79dd3864aa..56a461a3bb147c 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.js @@ -148,7 +148,8 @@ export class DynamicStyleProperty extends AbstractStyleProperty { if (this.isOrdinal()) { return this._field.getOrdinalFieldMetaRequest(); } else if (this.isCategorical()) { - return this._field.getCategoricalFieldMetaRequest(this.getNumberOfCategories()); + const numberOfCategories = this.getNumberOfCategories(); + return this._field.getCategoricalFieldMetaRequest(numberOfCategories); } else { return null; }