From 5686010b46daa5c0acc48b3b3ade3f0ea246dd6c Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 5 Feb 2020 13:19:37 -0700 Subject: [PATCH 01/41] force yarn 1.21.1 until we can handle invalid output of 1.22.0 (#56914) --- package.json | 2 +- src/dev/ci_setup/setup_env.sh | 3 +-- x-pack/package.json | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index c9376e974492a..4aae657d74483 100644 --- a/package.json +++ b/package.json @@ -486,6 +486,6 @@ }, "engines": { "node": "10.18.0", - "yarn": "^1.21.1" + "yarn": "1.21.1" } } diff --git a/src/dev/ci_setup/setup_env.sh b/src/dev/ci_setup/setup_env.sh index 823c70e80fe7c..6f64379ea4573 100644 --- a/src/dev/ci_setup/setup_env.sh +++ b/src/dev/ci_setup/setup_env.sh @@ -108,8 +108,7 @@ if [[ "$installNode" == "true" || ! $(which yarn) ]]; then ### ### downloading yarn ### - yarnVersion="$(node -e "console.log(String(require('./package.json').engines.yarn || '').replace(/^[^\d]+/,''))")" - npm install -g "yarn@^${yarnVersion}" + npm install -g "yarn@$(node -e "console.log(require('./package.json').engines.yarn)")" fi ### diff --git a/x-pack/package.json b/x-pack/package.json index 99e2a32bf3372..e9207ca57b865 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -351,7 +351,7 @@ "xregexp": "4.2.4" }, "engines": { - "yarn": "^1.21.1" + "yarn": "1.21.1" }, "workspaces": { "nohoist": [ From 8243f5dfba59ff1c6e50c0e4eaddaa5c4b7f8cc7 Mon Sep 17 00:00:00 2001 From: Brittany Joiner Date: Wed, 5 Feb 2020 15:26:19 -0500 Subject: [PATCH 02/41] Client.ip to metadata for RUM transactions (#56546) * Started on changes for adding clientIP. Cloned host ID section and replaced with client. * added client section to show clientIP Co-authored-by: Elastic Machine --- .../shared/MetadataTable/TransactionMetadata/sections.ts | 2 ++ .../public/components/shared/MetadataTable/sections.ts | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts index 18751efc6e1c1..3a9a21356ba35 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/sections.ts @@ -10,6 +10,7 @@ import { LABELS, HTTP, HOST, + CLIENT, CONTAINER, SERVICE, PROCESS, @@ -27,6 +28,7 @@ export const TRANSACTION_METADATA_SECTIONS: Section[] = [ TRANSACTION, HTTP, HOST, + CLIENT, CONTAINER, SERVICE, PROCESS, diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/sections.ts b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/sections.ts index ac8e9559357e3..d6c0a72b8bb08 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/sections.ts +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/sections.ts @@ -34,6 +34,14 @@ export const HOST: Section = { }) }; +export const CLIENT: Section = { + key: 'client', + label: i18n.translate('xpack.apm.metadataTable.section.clientLabel', { + defaultMessage: 'Client' + }), + properties: ['ip'] +}; + export const CONTAINER: Section = { key: 'container', label: i18n.translate('xpack.apm.metadataTable.section.containerLabel', { From 7276087e8a5d1b2f30a5e74a3ee17a4823e043a5 Mon Sep 17 00:00:00 2001 From: igoristic Date: Wed, 5 Feb 2020 15:40:54 -0500 Subject: [PATCH 03/41] Revert "Added new index pattern" (#56804) This reverts commit 0f175060d1794855f3b67efc5ad2b5e439d41cf7. --- .../__tests__/alerts_cluster_search.js | 32 +-- .../__tests__/alerts_clusters_aggregation.js | 163 ++++++------ .../server/lib/__tests__/ccs_utils.js | 22 +- .../get_nodes/__test__/get_node_ids.test.js | 2 +- .../__test__/get_paginated_nodes.test.js | 2 +- .../nodes/get_nodes/get_paginated_nodes.js | 2 +- .../elasticsearch/verify_monitoring_auth.js | 2 +- .../lib/logstash/get_paginated_pipelines.js | 2 +- .../get_collection_status_regular_index.js | 241 ------------------ .../setup/collection/get_collection_status.js | 4 +- .../__tests__/get_all_stats.js | 6 +- .../__tests__/get_cluster_uuids.js | 2 +- .../__tests__/get_es_stats.js | 2 +- .../__tests__/get_high_level_stats.js | 2 +- 14 files changed, 104 insertions(+), 380 deletions(-) delete mode 100644 x-pack/legacy/plugins/monitoring/server/lib/setup/collection/__test__/get_collection_status_regular_index.js diff --git a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js index 1e5615cc907ba..f6dafb5bb8c7e 100644 --- a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js +++ b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js @@ -55,7 +55,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs(mockQueryResult, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts,monitoring-alerts', + '.monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense ).then(alerts => { @@ -68,7 +68,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs(mockQueryResult, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts,monitoring-alerts', + '.monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense, { size: 3 } @@ -89,15 +89,9 @@ describe('Alerts Cluster Search', () => { issue_date: 'fake-issue_date', }, }; - return alertsClusterSearch( - mockReq, - '.monitoring-alerts,monitoring-alerts', - cluster, - checkLicense, - { - size: 3, - } - ).then(alerts => { + return alertsClusterSearch(mockReq, '.monitoring-alerts', cluster, checkLicense, { + size: 3, + }).then(alerts => { expect(alerts).to.have.length(3); expect(alerts[0]).to.eql(mockAlerts[0]); expect(alerts[1]).to.eql({ @@ -128,15 +122,9 @@ describe('Alerts Cluster Search', () => { issue_date: 'fake-issue_date', }, }; - return alertsClusterSearch( - mockReq, - '.monitoring-alerts,monitoring-alerts', - cluster, - checkLicense, - { - size: 3, - } - ).then(alerts => { + return alertsClusterSearch(mockReq, '.monitoring-alerts', cluster, checkLicense, { + size: 3, + }).then(alerts => { expect(alerts).to.have.length(1); expect(alerts[0]).to.eql({ metadata: { @@ -167,7 +155,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs({}, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts,monitoring-alerts', + '.monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense ).then(alerts => { @@ -189,7 +177,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs({}, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts,monitoring-alerts', + '.monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense ).then(alerts => { diff --git a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js index 9ee0d512a3c1c..efd9a933e1f81 100644 --- a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js +++ b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js @@ -73,37 +73,34 @@ describe('Alerts Clusters Aggregation', () => { it('aggregates alert count summary by cluster', () => { const { mockReq } = createStubs(mockQueryResult, featureStub); - return alertsClustersAggregation( - mockReq, - '.monitoring-alerts,monitoring-alerts', - clusters, - checkLicense - ).then(result => { - expect(result).to.eql({ - alertsMeta: { enabled: true }, - 'cluster-abc0': undefined, - 'cluster-abc1': { - count: 1, - high: 0, - low: 1, - medium: 0, - }, - 'cluster-abc2': { - count: 2, - high: 0, - low: 0, - medium: 2, - }, - 'cluster-abc3': { - count: 3, - high: 3, - low: 0, - medium: 0, - }, - 'cluster-no-license': undefined, - 'cluster-invalid': undefined, - }); - }); + return alertsClustersAggregation(mockReq, '.monitoring-alerts', clusters, checkLicense).then( + result => { + expect(result).to.eql({ + alertsMeta: { enabled: true }, + 'cluster-abc0': undefined, + 'cluster-abc1': { + count: 1, + high: 0, + low: 1, + medium: 0, + }, + 'cluster-abc2': { + count: 2, + high: 0, + low: 0, + medium: 2, + }, + 'cluster-abc3': { + count: 3, + high: 3, + low: 0, + medium: 0, + }, + 'cluster-no-license': undefined, + 'cluster-invalid': undefined, + }); + } + ); }); it('aggregates alert count summary by cluster include static alert', () => { @@ -116,7 +113,7 @@ describe('Alerts Clusters Aggregation', () => { return alertsClustersAggregation( mockReq, - '.monitoring-alerts,monitoring-alerts', + '.monitoring-alerts', newClusters, checkLicense ).then(result => { @@ -166,16 +163,13 @@ describe('Alerts Clusters Aggregation', () => { const checkLicense = () => ({ clusterAlerts: { enabled: true } }); const { mockReq } = createStubs(mockQueryResult, featureStub); - return alertsClustersAggregation( - mockReq, - '.monitoring-alerts,monitoring-alerts', - clusters, - checkLicense - ).then(result => { - expect(result).to.eql({ - alertsMeta: { enabled: false, message: 'monitoring cluster license is fail' }, - }); - }); + return alertsClustersAggregation(mockReq, '.monitoring-alerts', clusters, checkLicense).then( + result => { + expect(result).to.eql({ + alertsMeta: { enabled: false, message: 'monitoring cluster license is fail' }, + }); + } + ); }); it('returns the input set if disabled because production cluster checks', () => { @@ -187,56 +181,53 @@ describe('Alerts Clusters Aggregation', () => { const checkLicense = () => ({ clusterAlerts: { enabled: false } }); const { mockReq } = createStubs(mockQueryResult, featureStub); - return alertsClustersAggregation( - mockReq, - '.monitoring-alerts,monitoring-alerts', - clusters, - checkLicense - ).then(result => { - expect(result).to.eql({ - alertsMeta: { enabled: true }, - 'cluster-abc0': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc0-name] license type [test_license] does not support Cluster Alerts', + return alertsClustersAggregation(mockReq, '.monitoring-alerts', clusters, checkLicense).then( + result => { + expect(result).to.eql({ + alertsMeta: { enabled: true }, + 'cluster-abc0': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc0-name] license type [test_license] does not support Cluster Alerts', + }, }, - }, - 'cluster-abc1': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc1-name] license type [test_license] does not support Cluster Alerts', + 'cluster-abc1': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc1-name] license type [test_license] does not support Cluster Alerts', + }, }, - }, - 'cluster-abc2': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc2-name] license type [test_license] does not support Cluster Alerts', + 'cluster-abc2': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc2-name] license type [test_license] does not support Cluster Alerts', + }, }, - }, - 'cluster-abc3': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc3-name] license type [test_license] does not support Cluster Alerts', + 'cluster-abc3': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc3-name] license type [test_license] does not support Cluster Alerts', + }, }, - }, - 'cluster-no-license': { - clusterMeta: { - enabled: false, - message: `Cluster [cluster-no-license-name] license type [undefined] does not support Cluster Alerts`, + 'cluster-no-license': { + clusterMeta: { + enabled: false, + message: `Cluster [cluster-no-license-name] license type [undefined] does not support Cluster Alerts`, + }, }, - }, - 'cluster-invalid': { - clusterMeta: { - enabled: false, - message: `Cluster [cluster-invalid-name] license type [undefined] does not support Cluster Alerts`, + 'cluster-invalid': { + clusterMeta: { + enabled: false, + message: `Cluster [cluster-invalid-name] license type [undefined] does not support Cluster Alerts`, + }, }, - }, - }); - }); + }); + } + ); }); }); }); diff --git a/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js b/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js index 2d310962238fd..ad02807b5585e 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js @@ -10,8 +10,7 @@ import { parseCrossClusterPrefix, prefixIndexPattern } from '../ccs_utils'; describe('ccs_utils', () => { describe('prefixIndexPattern', () => { - const indexPattern = - '.monitoring-xyz-1-*,.monitoring-xyz-2-*,monitoring-xyz-1-*,monitoring-xyz-2-*'; + const indexPattern = '.monitoring-xyz-1-*,.monitoring-xyz-2-*'; it('returns the index pattern if ccs is not enabled', () => { const get = sinon.stub(); @@ -54,11 +53,9 @@ describe('ccs_utils', () => { const abcPattern = prefixIndexPattern(config, indexPattern, 'aBc'); const underscorePattern = prefixIndexPattern(config, indexPattern, 'cluster_one'); - expect(abcPattern).to.eql( - 'aBc:.monitoring-xyz-1-*,aBc:.monitoring-xyz-2-*,aBc:monitoring-xyz-1-*,aBc:monitoring-xyz-2-*' - ); + expect(abcPattern).to.eql('aBc:.monitoring-xyz-1-*,aBc:.monitoring-xyz-2-*'); expect(underscorePattern).to.eql( - 'cluster_one:.monitoring-xyz-1-*,cluster_one:.monitoring-xyz-2-*,cluster_one:monitoring-xyz-1-*,cluster_one:monitoring-xyz-2-*' + 'cluster_one:.monitoring-xyz-1-*,cluster_one:.monitoring-xyz-2-*' ); expect(get.callCount).to.eql(2); }); @@ -72,11 +69,7 @@ describe('ccs_utils', () => { const pattern = prefixIndexPattern(config, indexPattern, '*'); // it should have BOTH patterns so that it searches all CCS clusters and the local cluster - expect(pattern).to.eql( - '*:.monitoring-xyz-1-*,*:.monitoring-xyz-2-*,*:monitoring-xyz-1-*,*:monitoring-xyz-2-*' + - ',' + - indexPattern - ); + expect(pattern).to.eql('*:.monitoring-xyz-1-*,*:.monitoring-xyz-2-*' + ',' + indexPattern); expect(get.callCount).to.eql(1); }); }); @@ -84,25 +77,18 @@ describe('ccs_utils', () => { describe('parseCrossClusterPrefix', () => { it('returns ccs prefix for index with one', () => { expect(parseCrossClusterPrefix('abc:.monitoring-es-6-2017.07.28')).to.eql('abc'); - expect(parseCrossClusterPrefix('abc:monitoring-es-6-2017.07.28')).to.eql('abc'); expect(parseCrossClusterPrefix('abc_123:.monitoring-es-6-2017.07.28')).to.eql('abc_123'); - expect(parseCrossClusterPrefix('abc_123:monitoring-es-6-2017.07.28')).to.eql('abc_123'); expect(parseCrossClusterPrefix('broken:example:.monitoring-es-6-2017.07.28')).to.eql( 'broken' ); - expect(parseCrossClusterPrefix('broken:example:monitoring-es-6-2017.07.28')).to.eql('broken'); expect(parseCrossClusterPrefix('with-a-dash:.monitoring-es-6-2017.07.28')).to.eql( 'with-a-dash' ); - expect(parseCrossClusterPrefix('with-a-dash:monitoring-es-6-2017.07.28')).to.eql( - 'with-a-dash' - ); expect(parseCrossClusterPrefix('something:not-monitoring')).to.eql('something'); }); it('returns null when no prefix exists', () => { expect(parseCrossClusterPrefix('.monitoring-es-6-2017.07.28')).to.be(null); - expect(parseCrossClusterPrefix('monitoring-es-6-2017.07.28')).to.be(null); expect(parseCrossClusterPrefix('random')).to.be(null); }); }); diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js index a7827c7474a15..19fa99a783302 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js @@ -47,7 +47,7 @@ describe('getNodeIds', () => { }; const clusterUuid = '1cb'; - const result = await getNodeIds(req, '.monitoring-es-*,monitoring-es-*', { clusterUuid }, 10); + const result = await getNodeIds(req, '.monitoring-es-*', { clusterUuid }, 10); expect(result).toEqual([ { name: 'foobar', uuid: 1 }, { name: 'barfoo', uuid: 2 }, diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js index d1126e79b6940..c08ae91769b9d 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js @@ -45,7 +45,7 @@ describe('getPaginatedNodes', () => { }), }, }; - const esIndexPattern = '.monitoring-es-*,monitoring-es-*'; + const esIndexPattern = '.monitoring-es-*'; const clusterUuid = '1abc'; const metricSet = ['foo', 'bar']; const pagination = { index: 0, size: 10 }; diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js index e18d328e8725b..66393ef69df1d 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js @@ -20,7 +20,7 @@ import { getMetrics } from '../../../details/get_metrics'; * and returns that so the caller can perform their normal call to get the time-series data. * * @param {*} req - Server request object - * @param {*} esIndexPattern - The index pattern to search against (`.monitoring-es-*,monitoring-es-*`) + * @param {*} esIndexPattern - The index pattern to search against (`.monitoring-es-*`) * @param {*} uuids - The optional `clusterUuid` and `nodeUuid` to filter the results from * @param {*} metricSet - The array of metrics that are sortable in the UI * @param {*} pagination - ({ index, size }) diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js index 1d48d300f8eb6..8362ebec0206b 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js @@ -30,7 +30,7 @@ export async function verifyMonitoringAuth(req) { /** * Reach out to the Monitoring cluster and ensure that it believes the current user has the privileges necessary - * to make API calls against .monitoring-*,monitoring-* indices. + * to make API calls against .monitoring-* indices. * * @param req {Object} the server route handler request object * @return {Promise} That either resolves with no response (void) or an exception. diff --git a/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js b/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js index ffc7e9ce1d6c2..5dcdf5b676219 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js @@ -20,7 +20,7 @@ import { getMetrics } from '../details/get_metrics'; * and returns that so the caller can perform their normal call to get the time-series data. * * @param {*} req - Server request object - * @param {*} lsIndexPattern - The index pattern to search against (`.monitoring-logstash-*,monitoring-logstash-*`) + * @param {*} lsIndexPattern - The index pattern to search against (`.monitoring-logstash-*`) * @param {*} uuids - The optional `clusterUuid` and `logstashUuid` to filter the results from * @param {*} metricSet - The array of metrics that are sortable in the UI * @param {*} pagination - ({ index, size }) diff --git a/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/__test__/get_collection_status_regular_index.js b/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/__test__/get_collection_status_regular_index.js deleted file mode 100644 index 86a0533ee07db..0000000000000 --- a/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/__test__/get_collection_status_regular_index.js +++ /dev/null @@ -1,241 +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 expect from '@kbn/expect'; -import sinon from 'sinon'; -import { getCollectionStatus } from '../'; -import { getIndexPatterns } from '../../../cluster/get_index_patterns'; - -const liveClusterUuid = 'a12'; -const mockReq = (searchResult = {}) => { - return { - server: { - newPlatform: { - setup: { - plugins: { - usageCollection: { - getCollectorByType: () => ({ - isReady: () => false, - }), - }, - }, - }, - }, - config() { - return { - get: sinon - .stub() - .withArgs('server.uuid') - .returns('kibana-1234'), - }; - }, - usage: { - collectorSet: { - getCollectorByType: () => ({ - isReady: () => false, - }), - }, - }, - plugins: { - elasticsearch: { - getCluster() { - return { - callWithRequest(_req, type, params) { - if ( - type === 'transport.request' && - params && - params.path === '/_cluster/state/cluster_uuid' - ) { - return Promise.resolve({ cluster_uuid: liveClusterUuid }); - } - if (type === 'transport.request' && params && params.path === '/_nodes') { - return Promise.resolve({ nodes: {} }); - } - if (type === 'cat.indices') { - return Promise.resolve([1]); - } - return Promise.resolve(searchResult); - }, - }; - }, - }, - }, - }, - }; -}; - -describe('getCollectionStatus none system index', () => { - it('should handle all stack products with internal monitoring', async () => { - const req = mockReq({ - aggregations: { - indices: { - buckets: [ - { - key: 'monitoring-es-7-2019', - es_uuids: { buckets: [{ key: 'es_1' }] }, - }, - { - key: 'monitoring-kibana-7-2019', - kibana_uuids: { buckets: [{ key: 'kibana_1' }] }, - }, - { - key: 'monitoring-beats-7-2019', - beats_uuids: { - buckets: [ - { key: 'apm_1', beat_type: { buckets: [{ key: 'apm-server' }] } }, - { key: 'beats_1' }, - ], - }, - }, - { - key: 'monitoring-logstash-7-2019', - logstash_uuids: { buckets: [{ key: 'logstash_1' }] }, - }, - ], - }, - }, - }); - - const result = await getCollectionStatus(req, getIndexPatterns(req.server)); - - expect(result.kibana.totalUniqueInstanceCount).to.be(1); - expect(result.kibana.totalUniqueFullyMigratedCount).to.be(0); - expect(result.kibana.byUuid.kibana_1.isInternalCollector).to.be(true); - - expect(result.beats.totalUniqueInstanceCount).to.be(1); - expect(result.beats.totalUniqueFullyMigratedCount).to.be(0); - expect(result.beats.byUuid.beats_1.isInternalCollector).to.be(true); - - expect(result.apm.totalUniqueInstanceCount).to.be(1); - expect(result.apm.totalUniqueFullyMigratedCount).to.be(0); - expect(result.apm.byUuid.apm_1.isInternalCollector).to.be(true); - - expect(result.logstash.totalUniqueInstanceCount).to.be(1); - expect(result.logstash.totalUniqueFullyMigratedCount).to.be(0); - expect(result.logstash.byUuid.logstash_1.isInternalCollector).to.be(true); - - expect(result.elasticsearch.totalUniqueInstanceCount).to.be(1); - expect(result.elasticsearch.totalUniqueFullyMigratedCount).to.be(0); - expect(result.elasticsearch.byUuid.es_1.isInternalCollector).to.be(true); - }); - - it('should handle some stack products as fully migrated', async () => { - const req = mockReq({ - aggregations: { - indices: { - buckets: [ - { - key: 'monitoring-es-7-mb-2019', - es_uuids: { buckets: [{ key: 'es_1' }] }, - }, - { - key: 'monitoring-kibana-7-mb-2019', - kibana_uuids: { buckets: [{ key: 'kibana_1' }] }, - }, - { - key: 'monitoring-beats-7-2019', - beats_uuids: { buckets: [{ key: 'beats_1' }] }, - }, - { - key: 'monitoring-logstash-7-2019', - logstash_uuids: { buckets: [{ key: 'logstash_1' }] }, - }, - ], - }, - }, - }); - - const result = await getCollectionStatus(req, getIndexPatterns(req.server)); - - expect(result.kibana.totalUniqueInstanceCount).to.be(1); - expect(result.kibana.totalUniqueFullyMigratedCount).to.be(1); - expect(result.kibana.byUuid.kibana_1.isFullyMigrated).to.be(true); - - expect(result.beats.totalUniqueInstanceCount).to.be(1); - expect(result.beats.totalUniqueFullyMigratedCount).to.be(0); - expect(result.beats.byUuid.beats_1.isInternalCollector).to.be(true); - - expect(result.logstash.totalUniqueInstanceCount).to.be(1); - expect(result.logstash.totalUniqueFullyMigratedCount).to.be(0); - expect(result.logstash.byUuid.logstash_1.isInternalCollector).to.be(true); - - expect(result.elasticsearch.totalUniqueInstanceCount).to.be(1); - expect(result.elasticsearch.totalUniqueFullyMigratedCount).to.be(1); - expect(result.elasticsearch.byUuid.es_1.isFullyMigrated).to.be(true); - }); - - it('should handle some stack products as partially migrated', async () => { - const req = mockReq({ - aggregations: { - indices: { - buckets: [ - { - key: 'monitoring-es-7-mb-2019', - es_uuids: { buckets: [{ key: 'es_1' }] }, - }, - { - key: 'monitoring-kibana-7-mb-2019', - kibana_uuids: { buckets: [{ key: 'kibana_1' }, { key: 'kibana_2' }] }, - }, - { - key: 'monitoring-kibana-7-2019', - kibana_uuids: { buckets: [{ key: 'kibana_1', by_timestamp: { value: 12 } }] }, - }, - { - key: 'monitoring-beats-7-2019', - beats_uuids: { buckets: [{ key: 'beats_1' }] }, - }, - { - key: 'monitoring-logstash-7-2019', - logstash_uuids: { buckets: [{ key: 'logstash_1' }] }, - }, - ], - }, - }, - }); - - const result = await getCollectionStatus(req, getIndexPatterns(req.server)); - - expect(result.kibana.totalUniqueInstanceCount).to.be(2); - expect(result.kibana.totalUniqueFullyMigratedCount).to.be(1); - expect(result.kibana.byUuid.kibana_1.isPartiallyMigrated).to.be(true); - expect(result.kibana.byUuid.kibana_1.lastInternallyCollectedTimestamp).to.be(12); - - expect(result.beats.totalUniqueInstanceCount).to.be(1); - expect(result.beats.totalUniqueFullyMigratedCount).to.be(0); - expect(result.beats.byUuid.beats_1.isInternalCollector).to.be(true); - - expect(result.logstash.totalUniqueInstanceCount).to.be(1); - expect(result.logstash.totalUniqueFullyMigratedCount).to.be(0); - expect(result.logstash.byUuid.logstash_1.isInternalCollector).to.be(true); - - expect(result.elasticsearch.totalUniqueInstanceCount).to.be(1); - expect(result.elasticsearch.totalUniqueFullyMigratedCount).to.be(1); - expect(result.elasticsearch.byUuid.es_1.isFullyMigrated).to.be(true); - }); - - it('should detect products based on other indices', async () => { - const req = mockReq( - {}, - { - responses: [ - { hits: { total: { value: 1 } } }, - { hits: { total: { value: 1 } } }, - { hits: { total: { value: 1 } } }, - { hits: { total: { value: 1 } } }, - { hits: { total: { value: 1 } } }, - ], - } - ); - - const result = await getCollectionStatus(req, getIndexPatterns(req.server), liveClusterUuid); - - expect(result.kibana.detected.doesExist).to.be(true); - expect(result.elasticsearch.detected.doesExist).to.be(true); - expect(result.beats.detected.mightExist).to.be(true); - expect(result.logstash.detected.mightExist).to.be(true); - }); -}); diff --git a/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js b/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js index a12b48510a6ff..42d100b8af75e 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js @@ -242,7 +242,7 @@ async function hasNecessaryPermissions(req) { * Determines if we should ignore this bucket from this product. * * We need this logic because APM and Beats are separate products, but their - * monitoring data appears in the same index (.monitoring-beats-*,monitoring-beats-*) and the single + * monitoring data appears in the same index (.monitoring-beats-*) and the single * way to determine the difference between two documents in that index * is `beats_stats.beat.type` which we are performing a terms agg in the above query. * If that value is `apm-server` and we're attempting to calculating status for beats @@ -325,7 +325,7 @@ async function getLiveElasticsearchCollectionEnabled(req) { * } * @param {*} req Standard request object. Can contain a timeRange to use for the query - * @param {*} indexPatterns Map of index patterns to search against (will be all .monitoring-*,monitoring-* indices) + * @param {*} indexPatterns Map of index patterns to search against (will be all .monitoring-* indices) * @param {*} clusterUuid Optional and will be used to filter down the query if used * @param {*} nodeUuid Optional and will be used to filter down the query if used * @param {*} skipLiveData Optional and will not make any live api calls if set to true diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js index ea6792433ea0b..f27fde50242f4 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js @@ -19,11 +19,11 @@ describe.skip('get_all_stats', () => { get: sinon .stub() .withArgs('xpack.monitoring.elasticsearch.index_pattern') - .returns('.monitoring-es-N-*,monitoring-es-N-*') + .returns('.monitoring-es-N-*') .withArgs('xpack.monitoring.kibana.index_pattern') - .returns('.monitoring-kibana-N-*,monitoring-kibana-N-*') + .returns('.monitoring-kibana-N-*') .withArgs('xpack.monitoring.logstash.index_pattern') - .returns('.monitoring-logstash-N-*,monitoring-logstash-N-*') + .returns('.monitoring-logstash-N-*') .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js index 820e6e2c1ec28..1f62c677dbb21 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js @@ -20,7 +20,7 @@ describe('get_cluster_uuids', () => { get: sinon .stub() .withArgs('xpack.monitoring.elasticsearch.index_pattern') - .returns('.monitoring-es-N-*,monitoring-es-N-*') + .returns('.monitoring-es-N-*') .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js index 570a19e0766d4..536e831640fad 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js @@ -20,7 +20,7 @@ describe('get_es_stats', () => { get: sinon .stub() .withArgs('xpack.monitoring.elasticsearch.index_pattern') - .returns('.monitoring-es-N-*,monitoring-es-N-*') + .returns('.monitoring-es-N-*') .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js index dbdd3b8dbce4a..1c1f8dc888d01 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js @@ -24,7 +24,7 @@ describe('get_high_level_stats', () => { get: sinon .stub() .withArgs(`xpack.monitoring.${product}.index_pattern`) - .returns(`.monitoring-${product}-N-*,monitoring-${product}-N-*`) + .returns(`.monitoring-${product}-N-*`) .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), From 12de6a8459c433628beec4a2c49c23f4cf574ecf Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 5 Feb 2020 14:18:10 -0700 Subject: [PATCH 04/41] Fix compatibility with yarn 1.22.0 (#56917) * Revert "force yarn 1.21.1 until we can handle invalid output of 1.22.0 (#56914)" This reverts commit 5686010b46daa5c0acc48b3b3ade3f0ea246dd6c. * move the --json argument before `workspaces` so it still works * update kbn/pm dist --- package.json | 2 +- packages/kbn-pm/dist/index.js | 12 +++++++++--- packages/kbn-pm/src/utils/scripts.ts | 9 ++++++--- src/dev/ci_setup/setup_env.sh | 3 ++- x-pack/package.json | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 4aae657d74483..c9376e974492a 100644 --- a/package.json +++ b/package.json @@ -486,6 +486,6 @@ }, "engines": { "node": "10.18.0", - "yarn": "1.21.1" + "yarn": "^1.21.1" } } diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 8d17d285dce21..979808e170f46 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -56572,12 +56572,18 @@ function runScriptInPackageStreaming(script, args, pkg) { }); } async function yarnWorkspacesInfo(directory) { - const workspacesInfo = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', ['workspaces', 'info', '--json'], { + const { + stdout + } = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', ['--json', 'workspaces', 'info'], { cwd: directory, stdio: 'pipe' }); - const stdout = JSON.parse(workspacesInfo.stdout); - return JSON.parse(stdout.data); + + try { + return JSON.parse(JSON.parse(stdout).data); + } catch (error) { + throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); + } } /***/ }), diff --git a/packages/kbn-pm/src/utils/scripts.ts b/packages/kbn-pm/src/utils/scripts.ts index f12aeddec9163..009efa1285c0c 100644 --- a/packages/kbn-pm/src/utils/scripts.ts +++ b/packages/kbn-pm/src/utils/scripts.ts @@ -67,11 +67,14 @@ export function runScriptInPackageStreaming(script: string, args: string[], pkg: } export async function yarnWorkspacesInfo(directory: string): Promise { - const workspacesInfo = await spawn('yarn', ['workspaces', 'info', '--json'], { + const { stdout } = await spawn('yarn', ['--json', 'workspaces', 'info'], { cwd: directory, stdio: 'pipe', }); - const stdout = JSON.parse(workspacesInfo.stdout); - return JSON.parse(stdout.data); + try { + return JSON.parse(JSON.parse(stdout).data); + } catch (error) { + throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); + } } diff --git a/src/dev/ci_setup/setup_env.sh b/src/dev/ci_setup/setup_env.sh index 6f64379ea4573..823c70e80fe7c 100644 --- a/src/dev/ci_setup/setup_env.sh +++ b/src/dev/ci_setup/setup_env.sh @@ -108,7 +108,8 @@ if [[ "$installNode" == "true" || ! $(which yarn) ]]; then ### ### downloading yarn ### - npm install -g "yarn@$(node -e "console.log(require('./package.json').engines.yarn)")" + yarnVersion="$(node -e "console.log(String(require('./package.json').engines.yarn || '').replace(/^[^\d]+/,''))")" + npm install -g "yarn@^${yarnVersion}" fi ### diff --git a/x-pack/package.json b/x-pack/package.json index e9207ca57b865..99e2a32bf3372 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -351,7 +351,7 @@ "xregexp": "4.2.4" }, "engines": { - "yarn": "1.21.1" + "yarn": "^1.21.1" }, "workspaces": { "nohoist": [ From 7d3021ed5a46532c328a1f68064b7f2b838735a1 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Wed, 5 Feb 2020 14:23:06 -0700 Subject: [PATCH 05/41] Update AbortController library (#56661) * Update abort controller library * Bootstrap * Fix bad merge conflict Co-authored-by: Elastic Machine --- package.json | 2 +- packages/kbn-ui-shared-deps/package.json | 6 +++--- packages/kbn-ui-shared-deps/polyfills.js | 2 +- .../server/lib/abortable_request_handler.js | 2 +- .../server/lib/abortable_request_handler.test.js | 2 +- yarn.lock | 10 ++++++---- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index c9376e974492a..1314db651bf86 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "@types/react-grid-layout": "^0.16.7", "@types/recompose": "^0.30.5", "JSONStream": "1.3.5", - "abortcontroller-polyfill": "^1.3.0", + "abort-controller": "^3.0.0", "angular": "^1.7.9", "angular-aria": "^1.7.8", "angular-elastic": "^2.5.1", diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index ea15d2e34ea3a..8c8b8b8a21488 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -9,12 +9,12 @@ "kbn:watch": "node scripts/build --watch" }, "devDependencies": { + "abort-controller": "^3.0.0", "@elastic/eui": "18.3.0", "@elastic/charts": "^16.1.0", "@kbn/dev-utils": "1.0.0", "@kbn/i18n": "1.0.0", "@yarnpkg/lockfile": "^1.1.0", - "abortcontroller-polyfill": "^1.3.0", "angular": "^1.7.9", "core-js": "^3.2.1", "css-loader": "^2.1.1", @@ -24,13 +24,13 @@ "mini-css-extract-plugin": "0.8.0", "moment": "^2.24.0", "moment-timezone": "^0.5.27", + "react": "^16.12.0", "react-dom": "^16.12.0", "react-intl": "^2.8.0", - "react": "^16.12.0", "read-pkg": "^5.2.0", "regenerator-runtime": "^0.13.3", "symbol-observable": "^1.2.0", "webpack": "4.41.0", "whatwg-fetch": "^3.0.0" } -} \ No newline at end of file +} diff --git a/packages/kbn-ui-shared-deps/polyfills.js b/packages/kbn-ui-shared-deps/polyfills.js index d2305d643e4d2..612fbb9a78b50 100644 --- a/packages/kbn-ui-shared-deps/polyfills.js +++ b/packages/kbn-ui-shared-deps/polyfills.js @@ -21,6 +21,6 @@ require('core-js/stable'); require('regenerator-runtime/runtime'); require('custom-event-polyfill'); require('whatwg-fetch'); -require('abortcontroller-polyfill/dist/polyfill-patch-fetch'); +require('abort-controller/polyfill'); require('./vendor/childnode_remove_polyfill'); require('symbol-observable'); diff --git a/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.js b/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.js index 0b8786f0c2841..68216b92840fc 100644 --- a/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.js +++ b/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.js @@ -17,7 +17,7 @@ * under the License. */ -import { AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill'; +import { AbortController } from 'abort-controller'; /* * A simple utility for generating a handler that provides a signal to the handler that signals when diff --git a/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.test.js b/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.test.js index d79dd4ae4e449..1c154370d1674 100644 --- a/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.test.js +++ b/src/legacy/core_plugins/elasticsearch/server/lib/abortable_request_handler.test.js @@ -17,7 +17,7 @@ * under the License. */ -import { AbortSignal } from 'abortcontroller-polyfill/dist/cjs-ponyfill'; +import { AbortSignal } from 'abort-controller'; import { abortableRequestHandler } from './abortable_request_handler'; describe('abortableRequestHandler', () => { diff --git a/yarn.lock b/yarn.lock index a36c3e1501695..4a787532b1e1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5655,10 +5655,12 @@ abort-controller@^2.0.3: dependencies: event-target-shim "^5.0.0" -abortcontroller-polyfill@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.3.0.tgz#de69af32ae926c210b7efbcc29bf644ee4838b00" - integrity sha512-lbWQgf+eRvku3va8poBlDBO12FigTQr9Zb7NIjXrePrhxWVKdCP2wbDl1tLDaYa18PWTom3UEWwdH13S46I+yA== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" accept@3.x.x: version "3.0.2" From e9c31cd0b5d07f0de42895a5dc13586686a5a6e1 Mon Sep 17 00:00:00 2001 From: Brandon Kobel Date: Wed, 5 Feb 2020 13:53:01 -0800 Subject: [PATCH 06/41] Updating tree-kill to 1.2.2 (#55889) * Updating tree-kill to 1.2.2 * Building more stuff Co-authored-by: Elastic Machine --- package.json | 2 +- packages/kbn-dev-utils/package.json | 2 +- packages/kbn-es/package.json | 2 +- packages/kbn-pm/dist/index.js | 19 ++++++++++++++----- x-pack/package.json | 2 +- yarn.lock | 8 ++++---- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 1314db651bf86..305aeba900503 100644 --- a/package.json +++ b/package.json @@ -476,7 +476,7 @@ "strip-ansi": "^3.0.1", "supertest": "^3.1.0", "supertest-as-promised": "^4.0.2", - "tree-kill": "^1.2.1", + "tree-kill": "^1.2.2", "typescript": "3.7.2", "typings-tester": "^0.3.2", "vinyl-fs": "^3.0.3", diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json index cef29f33962cd..bea153d0a672b 100644 --- a/packages/kbn-dev-utils/package.json +++ b/packages/kbn-dev-utils/package.json @@ -18,7 +18,7 @@ "load-json-file": "^6.2.0", "moment": "^2.24.0", "rxjs": "^6.5.3", - "tree-kill": "^1.2.1", + "tree-kill": "^1.2.2", "tslib": "^1.9.3" }, "devDependencies": { diff --git a/packages/kbn-es/package.json b/packages/kbn-es/package.json index cb501dab3ddb7..f9d7bffed1e22 100644 --- a/packages/kbn-es/package.json +++ b/packages/kbn-es/package.json @@ -17,7 +17,7 @@ "node-fetch": "^2.6.0", "simple-git": "^1.91.0", "tar-fs": "^1.16.3", - "tree-kill": "^1.2.1", + "tree-kill": "^1.2.2", "yauzl": "^2.10.0" } } diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 979808e170f46..f3e401bedcef3 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -36382,15 +36382,24 @@ var spawn = childProcess.spawn; var exec = childProcess.exec; module.exports = function (pid, signal, callback) { + if (typeof signal === 'function' && callback === undefined) { + callback = signal; + signal = undefined; + } + + pid = parseInt(pid); + if (Number.isNaN(pid)) { + if (callback) { + return callback(new Error("pid must be a number")); + } else { + throw new Error("pid must be a number"); + } + } + var tree = {}; var pidsToProcess = {}; tree[pid] = []; pidsToProcess[pid] = 1; - - if (typeof signal === 'function' && callback === undefined) { - callback = signal; - signal = undefined; - } switch (process.platform) { case 'win32': diff --git a/x-pack/package.json b/x-pack/package.json index 99e2a32bf3372..040b6c080543e 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -161,7 +161,7 @@ "supertest": "^3.1.0", "supertest-as-promised": "^4.0.2", "tmp": "0.1.0", - "tree-kill": "^1.2.1", + "tree-kill": "^1.2.2", "ts-loader": "^6.0.4", "typescript": "3.7.2", "vinyl-fs": "^3.0.3", diff --git a/yarn.lock b/yarn.lock index 4a787532b1e1a..6e398bf4a9357 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29002,10 +29002,10 @@ traverse@0.6.6, traverse@^0.6.6, traverse@~0.6.6: resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= -tree-kill@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.1.tgz#5398f374e2f292b9dcc7b2e71e30a5c3bb6c743a" - integrity sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q== +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== treeify@^1.0.1, treeify@^1.1.0: version "1.1.0" From 51854c7620add22ba09485ca83cc501d1242a91c Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Wed, 5 Feb 2020 15:14:17 -0800 Subject: [PATCH 07/41] [NP migration] Shim ILM (#56068) - Move UI metric constants into public directory. - Convert server-side code to TS, largely with use of any. - Remove unused sendPut method from API service. - Update http error handling to consume NP http service errors. - Refactor DI pattern of Index Mangement extensions to require various NP service dependencies. - Inject NP http service into Index Management extensions. Remove dependency upon Angular's $http. --- .../extend_index_management.test.js.snap | 12 +- .../__jest__/components/edit_policy.test.js | 22 +- .../__jest__/components/policy_table.test.js | 20 +- .../__jest__/extend_index_management.test.js | 278 ++++++++++-------- .../common/constants/index.js | 24 -- .../common/constants/index.ts | 16 + .../common/constants/ui_metric.js | 21 -- .../index_lifecycle_management/index.js | 66 ----- .../index_lifecycle_management/index.ts | 62 ++++ .../index_lifecycle_data.js | 22 -- .../index_lifecycle_management/plugin.ts | 54 ++++ .../public/constants/index.js | 101 ------- .../public/index.js | 16 - .../public/legacy.ts | 105 +++++++ .../public/main.html | 3 - .../_index_lifecycle_management.scss | 0 .../{app.js => np_ready/application/app.tsx} | 9 +- .../np_ready/application/constants/index.ts | 103 +++++++ .../application/constants/ui_metric.ts | 21 ++ .../{ => np_ready/application}/index.scss | 0 .../public/np_ready/application/index.tsx | 63 ++++ .../sections/components/active_badge.js | 1 + .../application}/sections/components/index.js | 0 .../sections/components/learn_more_link.js | 5 +- .../sections/components/optional_label.js | 1 + .../components/phase_error_message.js | 1 + .../cold_phase/cold_phase.container.js | 3 +- .../components/cold_phase/cold_phase.js | 0 .../components/cold_phase/index.js | 0 .../delete_phase/delete_phase.container.js | 2 +- .../components/delete_phase/delete_phase.js | 6 +- .../components/delete_phase/index.js | 0 .../hot_phase/hot_phase.container.js | 3 +- .../components/hot_phase/hot_phase.js | 0 .../edit_policy/components/hot_phase/index.js | 0 .../edit_policy/components/min_age_input.js | 0 .../components/node_allocation/index.js | 0 .../node_allocation.container.js | 3 +- .../node_allocation/node_allocation.js | 0 .../components/node_attrs_details/index.js | 0 .../node_attrs_details.container.js | 3 +- .../node_attrs_details/node_attrs_details.js | 0 .../components/policy_json_flyout.js | 2 +- .../components/set_priority_input.js | 6 +- .../components/warm_phase/index.js | 0 .../warm_phase/warm_phase.container.js | 0 .../components/warm_phase/warm_phase.js | 6 +- .../edit_policy/edit_policy.container.js | 0 .../sections/edit_policy/edit_policy.js | 4 +- .../sections/edit_policy/form_errors.js | 0 .../sections/edit_policy/index.d.ts} | 2 +- .../sections/edit_policy/index.js | 0 .../no_match/components/no_match/index.js | 0 .../no_match/components/no_match/no_match.js | 0 .../policy_table/components/no_match/index.js | 0 .../add_policy_to_template_confirm_modal.js | 4 +- .../components/policy_table/confirm_delete.js | 5 +- .../components/policy_table/index.js | 0 .../policy_table/policy_table.container.js | 5 +- .../components/policy_table/policy_table.js | 8 +- .../sections/policy_table/index.d.ts | 7 + .../sections/policy_table/index.js | 0 .../np_ready/application/services/api.js | 81 +++++ .../application}/services/api_errors.js | 16 +- .../application/services/documentation.ts | 17 ++ .../application}/services/filter_items.js | 0 .../application}/services/find_errors.js | 0 .../services/flatten_panel_tree.js | 0 .../np_ready/application/services/http.ts | 35 +++ .../application}/services/index.js | 1 - .../application/services/navigation.ts} | 21 +- .../application/services/notification.ts | 13 + .../application}/services/sort_table.js | 0 .../application}/services/ui_metric.test.js | 5 +- .../application/services/ui_metric.ts} | 23 +- .../application}/store/actions/general.js | 0 .../application}/store/actions/index.js | 0 .../application}/store/actions/lifecycle.js | 10 +- .../application}/store/actions/nodes.js | 0 .../application}/store/actions/policies.js | 4 +- .../application}/store/defaults/cold_phase.js | 0 .../store/defaults/delete_phase.js | 0 .../application}/store/defaults/hot_phase.js | 0 .../application/store/defaults/index.d.ts | 9 + .../application}/store/defaults/index.js | 0 .../application}/store/defaults/warm_phase.js | 0 .../np_ready/application/store/index.d.ts | 7 + .../{ => np_ready/application}/store/index.js | 0 .../application}/store/reducers/general.js | 0 .../application}/store/reducers/index.js | 0 .../application}/store/reducers/nodes.js | 0 .../application}/store/reducers/policies.js | 0 .../application}/store/selectors/general.js | 0 .../application}/store/selectors/index.js | 0 .../application}/store/selectors/lifecycle.js | 0 .../application}/store/selectors/nodes.js | 0 .../application}/store/selectors/policies.js | 0 .../{ => np_ready/application}/store/store.js | 0 .../components/add_lifecycle_confirm_modal.js | 14 +- .../components/index_lifecycle_summary.js | 8 +- .../remove_lifecycle_confirm_modal.js | 10 +- .../extend_index_management/index.d.ts | 7 + .../extend_index_management/index.js | 64 +++- .../public/np_ready/index.ts | 10 + .../public/np_ready/plugin.tsx | 58 ++++ .../public/register_management_section.js | 20 -- .../public/register_routes.js | 57 ---- .../public/services/api.js | 95 ------ .../services/manage_angular_lifecycle.js | 23 -- ...actory.js => call_with_request_factory.ts} | 7 +- .../{index.js => index.ts} | 0 .../{check_license.js => check_license.ts} | 4 +- .../lib/check_license/{index.js => index.ts} | 0 .../lib/error_wrappers/{index.js => index.ts} | 0 ...p_custom_error.js => wrap_custom_error.ts} | 2 +- .../{wrap_es_error.js => wrap_es_error.ts} | 2 +- ...unknown_error.js => wrap_unknown_error.ts} | 2 +- .../server/lib/is_es_error/index.ts | 7 + .../server/lib/is_es_error/is_es_error.ts | 13 + .../__tests__/is_es_error_factory.js | 44 --- .../is_es_error_factory.js | 18 -- .../{index.js => index.ts} | 0 ...tory.js => license_pre_routing_factory.ts} | 8 +- .../{index.js => index.ts} | 0 ...checker.js => register_license_checker.ts} | 12 +- .../routes/api/index/{index.js => index.ts} | 0 ..._route.js => register_add_policy_route.ts} | 16 +- ...dex_routes.js => register_index_routes.ts} | 2 +- ...move_route.js => register_remove_route.ts} | 9 +- ...retry_route.js => register_retry_route.ts} | 9 +- .../api/nodes/{constants.js => constants.ts} | 2 +- .../routes/api/nodes/{index.js => index.ts} | 0 ...ils_route.js => register_details_route.ts} | 17 +- ...r_list_route.js => register_list_route.ts} | 15 +- ...des_routes.js => register_nodes_routes.ts} | 2 +- .../api/policies/{index.js => index.ts} | 0 ...eate_route.js => register_create_route.ts} | 9 +- ...lete_route.js => register_delete_route.ts} | 9 +- ...fetch_route.js => register_fetch_route.ts} | 20 +- ..._routes.js => register_policies_routes.ts} | 2 +- .../api/templates/{index.js => index.ts} | 0 ..._route.js => register_add_policy_route.ts} | 14 +- ...fetch_route.js => register_fetch_route.ts} | 13 +- ...ter_get_route.js => register_get_route.ts} | 9 +- ...routes.js => register_templates_routes.ts} | 2 +- .../index_lifecycle_management/shim.ts | 17 ++ .../index_actions_context_menu.js | 31 +- .../public/app/services/api.ts | 10 - .../public/app/services/notification.ts | 10 +- .../app/store/actions/extension_action.js | 4 +- .../public/register_routes.ts | 7 +- 151 files changed, 1191 insertions(+), 860 deletions(-) delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.js create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.ts delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/common/constants/ui_metric.js delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/index.js create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/index.ts delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/index_lifecycle_data.js create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/plugin.ts delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/constants/index.js delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/index.js create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/main.html rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/_index_lifecycle_management.scss (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{app.js => np_ready/application/app.tsx} (75%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/index.ts create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/ui_metric.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/index.scss (100%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/index.tsx rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/components/active_badge.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/components/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/components/learn_more_link.js (79%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/components/optional_label.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/components/phase_error_message.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/cold_phase/cold_phase.container.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/cold_phase/cold_phase.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/cold_phase/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/delete_phase/delete_phase.container.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/delete_phase/delete_phase.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/delete_phase/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/hot_phase/hot_phase.container.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/hot_phase/hot_phase.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/hot_phase/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/min_age_input.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/node_allocation/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/node_allocation/node_allocation.container.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/node_allocation/node_allocation.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/node_attrs_details/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/node_attrs_details/node_attrs_details.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/policy_json_flyout.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/set_priority_input.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/warm_phase/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/warm_phase/warm_phase.container.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/components/warm_phase/warm_phase.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/edit_policy.container.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/edit_policy.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/form_errors.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/{server/lib/is_es_error_factory/index.js => public/np_ready/application/sections/edit_policy/index.d.ts} (80%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/edit_policy/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/no_match/components/no_match/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/no_match/components/no_match/no_match.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/no_match/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js (98%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/policy_table/confirm_delete.js (96%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/policy_table/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/policy_table/policy_table.container.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/components/policy_table/policy_table.js (98%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/index.d.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/sections/policy_table/index.js (100%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/api.js rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/services/api_errors.js (69%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/documentation.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/services/filter_items.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/services/find_errors.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/services/flatten_panel_tree.js (100%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/http.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/services/index.js (82%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{services/navigation.js => np_ready/application/services/navigation.ts} (51%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/notification.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/services/sort_table.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/services/ui_metric.test.js (95%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{services/ui_metric.js => np_ready/application/services/ui_metric.ts} (76%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/actions/general.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/actions/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/actions/lifecycle.js (89%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/actions/nodes.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/actions/policies.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/defaults/cold_phase.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/defaults/delete_phase.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/defaults/hot_phase.js (100%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/index.d.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/defaults/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/defaults/warm_phase.js (100%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/index.d.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/reducers/general.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/reducers/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/reducers/nodes.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/reducers/policies.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/selectors/general.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/selectors/index.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/selectors/lifecycle.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/selectors/nodes.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/selectors/policies.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready/application}/store/store.js (100%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready}/extend_index_management/components/add_lifecycle_confirm_modal.js (96%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready}/extend_index_management/components/index_lifecycle_summary.js (99%) rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready}/extend_index_management/components/remove_lifecycle_confirm_modal.js (93%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.d.ts rename x-pack/legacy/plugins/index_lifecycle_management/public/{ => np_ready}/extend_index_management/index.js (76%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/index.ts create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/plugin.tsx delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/register_management_section.js delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/register_routes.js delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/services/api.js delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/public/services/manage_angular_lifecycle.js rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/{call_with_request_factory.js => call_with_request_factory.ts} (68%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/{check_license.js => check_license.ts} (97%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/{wrap_custom_error.js => wrap_custom_error.ts} (88%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/{wrap_es_error.js => wrap_es_error.ts} (92%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/{wrap_unknown_error.js => wrap_unknown_error.ts} (90%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/index.ts create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/is_es_error.ts delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js delete mode 100644 x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/is_es_error_factory.js rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/{license_pre_routing_factory.js => license_pre_routing_factory.ts} (79%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/{register_license_checker.js => register_license_checker.ts} (64%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/{register_add_policy_route.js => register_add_policy_route.ts} (79%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/{register_index_routes.js => register_index_routes.ts} (91%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/{register_remove_route.js => register_remove_route.ts} (84%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/{register_retry_route.js => register_retry_route.ts} (84%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/{constants.js => constants.ts} (86%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/{register_details_route.js => register_details_route.ts} (75%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/{register_list_route.js => register_list_route.ts} (80%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/{register_nodes_routes.js => register_nodes_routes.ts} (89%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/{register_create_route.js => register_create_route.ts} (84%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/{register_delete_route.js => register_delete_route.ts} (83%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/{register_fetch_route.js => register_fetch_route.ts} (79%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/{register_policies_routes.js => register_policies_routes.ts} (90%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/{index.js => index.ts} (100%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/{register_add_policy_route.js => register_add_policy_route.ts} (83%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/{register_fetch_route.js => register_fetch_route.ts} (87%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/{register_get_route.js => register_get_route.ts} (84%) rename x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/{register_templates_routes.js => register_templates_routes.ts} (90%) create mode 100644 x-pack/legacy/plugins/index_lifecycle_management/shim.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap index bd42346e36135..92aaa171551a0 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap +++ b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/__snapshots__/extend_index_management.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`ilm banner extension should return extension when any index has lifecycle error 1`] = ` +exports[`extend index management ilm banner extension should return extension when any index has lifecycle error 1`] = ` Object { "filter": Query { "ast": _AST { @@ -45,7 +45,7 @@ Object { } `; -exports[`ilm filter extension should return extension when any index has lifecycle policy 1`] = ` +exports[`extend index management ilm filter extension should return extension when any index has lifecycle policy 1`] = ` Array [ Object { "field": "ilm.managed", @@ -66,7 +66,7 @@ Array [ ] `; -exports[`ilm summary extension should return extension when index has lifecycle error 1`] = ` +exports[`extend index management ilm summary extension should return extension when index has lifecycle error 1`] = ` `; -exports[`ilm summary extension should return extension when index has lifecycle policy 1`] = ` +exports[`extend index management ilm summary extension should return extension when index has lifecycle policy 1`] = ` `; -exports[`remove lifecycle action extension should return extension when all indices have lifecycle policy 1`] = ` +exports[`extend index management remove lifecycle action extension should return extension when all indices have lifecycle policy 1`] = ` Object { "buttonLabel": "Remove lifecycle policy", "icon": "stopFilled", @@ -866,7 +866,7 @@ Object { } `; -exports[`retry lifecycle action extension should return extension when all indices have lifecycle errors 1`] = ` +exports[`extend index management retry lifecycle action extension should return extension when all indices have lifecycle errors 1`] = ` Object { "buttonLabel": "Retry lifecycle step", "icon": "play", diff --git a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js index 2c0ea7fe699b8..9d143c4d3fc8e 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.js @@ -7,17 +7,19 @@ import React from 'react'; import moment from 'moment-timezone'; import { Provider } from 'react-redux'; -import { fetchedPolicies, fetchedNodes } from '../../public/store/actions'; -import { indexLifecycleManagementStore } from '../../public/store'; -import { mountWithIntl } from '../../../../../test_utils/enzyme_helpers'; -import { EditPolicy } from '../../public/sections/edit_policy'; // axios has a $http like interface so using it to simulate $http import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; -import { setHttpClient } from '../../public/services/api'; -setHttpClient(axios.create({ adapter: axiosXhrAdapter })); import sinon from 'sinon'; import { findTestSubject } from '@elastic/eui/lib/test'; + +import { mountWithIntl } from '../../../../../test_utils/enzyme_helpers'; +import { fetchedPolicies, fetchedNodes } from '../../public/np_ready/application/store/actions'; +import { indexLifecycleManagementStore } from '../../public/np_ready/application/store'; +import { EditPolicy } from '../../public/np_ready/application/sections/edit_policy'; +import { init as initHttp } from '../../public/np_ready/application/services/http'; +import { init as initUiMetric } from '../../public/np_ready/application/services/ui_metric'; +import { init as initNotification } from '../../public/np_ready/application/services/notification'; import { positiveNumbersAboveZeroErrorMessage, positiveNumberRequiredMessage, @@ -31,7 +33,13 @@ import { policyNameMustBeDifferentErrorMessage, policyNameAlreadyUsedErrorMessage, maximumDocumentsRequiredMessage, -} from '../../public/store/selectors/lifecycle'; +} from '../../public/np_ready/application/store/selectors/lifecycle'; + +initHttp(axios.create({ adapter: axiosXhrAdapter }), path => path); +initUiMetric(() => () => {}); +initNotification({ + addDanger: () => {}, +}); jest.mock('ui/new_platform'); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/policy_table.test.js b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/policy_table.test.js index bdb412eace9f8..a3a9c5e59bfa4 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/policy_table.test.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/components/policy_table.test.js @@ -6,18 +6,24 @@ import moment from 'moment-timezone'; import React from 'react'; import { Provider } from 'react-redux'; -import { fetchedPolicies } from '../../public/store/actions'; -import { indexLifecycleManagementStore } from '../../public/store'; -import { mountWithIntl } from '../../../../../test_utils/enzyme_helpers'; -import { PolicyTable } from '../../public/sections/policy_table'; -import { findTestSubject, takeMountedSnapshot } from '@elastic/eui/lib/test'; // axios has a $http like interface so using it to simulate $http import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; -import { setHttpClient } from '../../public/services/api'; -setHttpClient(axios.create({ adapter: axiosXhrAdapter })); import sinon from 'sinon'; +import { findTestSubject, takeMountedSnapshot } from '@elastic/eui/lib/test'; + +import { mountWithIntl } from '../../../../../test_utils/enzyme_helpers'; +import { fetchedPolicies } from '../../public/np_ready/application/store/actions'; +import { indexLifecycleManagementStore } from '../../public/np_ready/application/store'; +import { PolicyTable } from '../../public/np_ready/application/sections/policy_table'; +import { init as initHttp } from '../../public/np_ready/application/services/http'; +import { init as initUiMetric } from '../../public/np_ready/application/services/ui_metric'; + +initHttp(axios.create({ adapter: axiosXhrAdapter }), path => path); +initUiMetric(() => () => {}); + jest.mock('ui/new_platform'); + let server = null; let store = null; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js index e23fe59568e14..cfae072b57a26 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js @@ -4,8 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { mountWithIntl } from '../../../../test_utils/enzyme_helpers'; import moment from 'moment-timezone'; +import axios from 'axios'; +import axiosXhrAdapter from 'axios/lib/adapters/xhr'; +import { mountWithIntl } from '../../../../test_utils/enzyme_helpers'; import { retryLifecycleActionExtension, removeLifecyclePolicyActionExtension, @@ -13,9 +15,18 @@ import { ilmBannerExtension, ilmFilterExtension, ilmSummaryExtension, -} from '../public/extend_index_management'; +} from '../public/np_ready/extend_index_management'; +import { init as initHttp } from '../public/np_ready/application/services/http'; +import { init as initUiMetric } from '../public/np_ready/application/services/ui_metric'; + +// We need to init the http with a mock for any tests that depend upon the http service. +// For example, add_lifecycle_confirm_modal makes an API request in its componentDidMount +// lifecycle method. If we don't mock this, CI will fail with "Call retries were exceeded". +initHttp(axios.create({ adapter: axiosXhrAdapter }), path => path); +initUiMetric(() => () => {}); jest.mock('ui/new_platform'); + const indexWithoutLifecyclePolicy = { health: 'yellow', status: 'open', @@ -33,6 +44,7 @@ const indexWithoutLifecyclePolicy = { managed: false, }, }; + const indexWithLifecyclePolicy = { health: 'yellow', status: 'open', @@ -58,6 +70,7 @@ const indexWithLifecyclePolicy = { step_time_millis: 1544187775867, }, }; + const indexWithLifecycleError = { health: 'yellow', status: 'open', @@ -95,132 +108,151 @@ const indexWithLifecycleError = { }, }, }; + moment.tz.setDefault('utc'); -describe('retry lifecycle action extension', () => { - test('should return null when no indices have index lifecycle policy', () => { - const extension = retryLifecycleActionExtension([indexWithoutLifecyclePolicy]); - expect(extension).toBeNull(); - }); - test('should return null when no index has lifecycle errors', () => { - const extension = retryLifecycleActionExtension([ - indexWithLifecyclePolicy, - indexWithLifecyclePolicy, - ]); - expect(extension).toBeNull(); - }); - test('should return null when not all indices have lifecycle errors', () => { - const extension = retryLifecycleActionExtension([ - indexWithLifecyclePolicy, - indexWithLifecycleError, - ]); - expect(extension).toBeNull(); - }); - test('should return extension when all indices have lifecycle errors', () => { - const extension = retryLifecycleActionExtension([ - indexWithLifecycleError, - indexWithLifecycleError, - ]); - expect(extension).toBeDefined(); - expect(extension).toMatchSnapshot(); - }); -}); -describe('remove lifecycle action extension', () => { - test('should return null when no indices have index lifecycle policy', () => { - const extension = removeLifecyclePolicyActionExtension([indexWithoutLifecyclePolicy]); - expect(extension).toBeNull(); - }); - test('should return null when some indices have index lifecycle policy', () => { - const extension = removeLifecyclePolicyActionExtension([ - indexWithoutLifecyclePolicy, - indexWithLifecyclePolicy, - ]); - expect(extension).toBeNull(); - }); - test('should return extension when all indices have lifecycle policy', () => { - const extension = removeLifecyclePolicyActionExtension([ - indexWithLifecycleError, - indexWithLifecycleError, - ]); - expect(extension).toBeDefined(); - expect(extension).toMatchSnapshot(); - }); -}); -describe('add lifecycle policy action extension', () => { - test('should return null when index has index lifecycle policy', () => { - const extension = addLifecyclePolicyActionExtension([indexWithLifecyclePolicy]); - expect(extension).toBeNull(); - }); - test('should return null when more than one index is passed', () => { - const extension = addLifecyclePolicyActionExtension([ - indexWithoutLifecyclePolicy, - indexWithoutLifecyclePolicy, - ]); - expect(extension).toBeNull(); - }); - test('should return extension when one index is passed and it does not have lifecycle policy', () => { - const extension = addLifecyclePolicyActionExtension([indexWithoutLifecyclePolicy]); - expect(extension.renderConfirmModal).toBeDefined; - const component = extension.renderConfirmModal(jest.fn()); - const rendered = mountWithIntl(component); - expect(rendered.exists('.euiModal--confirmation')); - }); -}); -describe('ilm banner extension', () => { - test('should return null when no index has index lifecycle policy', () => { - const extension = ilmBannerExtension([ - indexWithoutLifecyclePolicy, - indexWithoutLifecyclePolicy, - ]); - expect(extension).toBeNull(); - }); - test('should return null no index has lifecycle error', () => { - const extension = ilmBannerExtension([indexWithoutLifecyclePolicy, indexWithLifecyclePolicy]); - expect(extension).toBeNull(); - }); - test('should return extension when any index has lifecycle error', () => { - const extension = ilmBannerExtension([ - indexWithoutLifecyclePolicy, - indexWithLifecyclePolicy, - indexWithLifecycleError, - ]); - expect(extension).toBeDefined(); - expect(extension).toMatchSnapshot(); + +describe('extend index management', () => { + describe('retry lifecycle action extension', () => { + test('should return null when no indices have index lifecycle policy', () => { + const extension = retryLifecycleActionExtension({ indices: [indexWithoutLifecyclePolicy] }); + expect(extension).toBeNull(); + }); + + test('should return null when no index has lifecycle errors', () => { + const extension = retryLifecycleActionExtension({ + indices: [indexWithLifecyclePolicy, indexWithLifecyclePolicy], + }); + expect(extension).toBeNull(); + }); + + test('should return null when not all indices have lifecycle errors', () => { + const extension = retryLifecycleActionExtension({ + indices: [indexWithLifecyclePolicy, indexWithLifecycleError], + }); + expect(extension).toBeNull(); + }); + + test('should return extension when all indices have lifecycle errors', () => { + const extension = retryLifecycleActionExtension({ + indices: [indexWithLifecycleError, indexWithLifecycleError], + }); + expect(extension).toBeDefined(); + expect(extension).toMatchSnapshot(); + }); }); -}); -describe('ilm summary extension', () => { - test('should render null when index has no index lifecycle policy', () => { - const extension = ilmSummaryExtension(indexWithoutLifecyclePolicy); - const rendered = mountWithIntl(extension); - expect(rendered.isEmptyRender()).toBeTruthy(); + + describe('remove lifecycle action extension', () => { + test('should return null when no indices have index lifecycle policy', () => { + const extension = removeLifecyclePolicyActionExtension({ + indices: [indexWithoutLifecyclePolicy], + }); + expect(extension).toBeNull(); + }); + + test('should return null when some indices have index lifecycle policy', () => { + const extension = removeLifecyclePolicyActionExtension({ + indices: [indexWithoutLifecyclePolicy, indexWithLifecyclePolicy], + }); + expect(extension).toBeNull(); + }); + + test('should return extension when all indices have lifecycle policy', () => { + const extension = removeLifecyclePolicyActionExtension({ + indices: [indexWithLifecycleError, indexWithLifecycleError], + }); + expect(extension).toBeDefined(); + expect(extension).toMatchSnapshot(); + }); }); - test('should return extension when index has lifecycle policy', () => { - const extension = ilmSummaryExtension(indexWithLifecyclePolicy); - expect(extension).toBeDefined(); - const rendered = mountWithIntl(extension); - expect(rendered).toMatchSnapshot(); + + describe('add lifecycle policy action extension', () => { + test('should return null when index has index lifecycle policy', () => { + const extension = addLifecyclePolicyActionExtension({ indices: [indexWithLifecyclePolicy] }); + expect(extension).toBeNull(); + }); + + test('should return null when more than one index is passed', () => { + const extension = addLifecyclePolicyActionExtension({ + indices: [indexWithoutLifecyclePolicy, indexWithoutLifecyclePolicy], + }); + expect(extension).toBeNull(); + }); + + test('should return extension when one index is passed and it does not have lifecycle policy', () => { + const extension = addLifecyclePolicyActionExtension({ + indices: [indexWithoutLifecyclePolicy], + }); + expect(extension.renderConfirmModal).toBeDefined; + const component = extension.renderConfirmModal(jest.fn()); + const rendered = mountWithIntl(component); + expect(rendered.exists('.euiModal--confirmation')); + }); }); - test('should return extension when index has lifecycle error', () => { - const extension = ilmSummaryExtension(indexWithLifecycleError); - expect(extension).toBeDefined(); - const rendered = mountWithIntl(extension); - expect(rendered).toMatchSnapshot(); + + describe('ilm banner extension', () => { + test('should return null when no index has index lifecycle policy', () => { + const extension = ilmBannerExtension([ + indexWithoutLifecyclePolicy, + indexWithoutLifecyclePolicy, + ]); + expect(extension).toBeNull(); + }); + + test('should return null no index has lifecycle error', () => { + const extension = ilmBannerExtension([indexWithoutLifecyclePolicy, indexWithLifecyclePolicy]); + expect(extension).toBeNull(); + }); + + test('should return extension when any index has lifecycle error', () => { + const extension = ilmBannerExtension([ + indexWithoutLifecyclePolicy, + indexWithLifecyclePolicy, + indexWithLifecycleError, + ]); + expect(extension).toBeDefined(); + expect(extension).toMatchSnapshot(); + }); }); -}); -describe('ilm filter extension', () => { - test('should return empty array when no indices have index lifecycle policy', () => { - const extension = ilmFilterExtension([ - indexWithoutLifecyclePolicy, - indexWithoutLifecyclePolicy, - ]); - expect(extension.length).toBe(0); + + describe('ilm summary extension', () => { + test('should render null when index has no index lifecycle policy', () => { + const extension = ilmSummaryExtension(indexWithoutLifecyclePolicy); + const rendered = mountWithIntl(extension); + expect(rendered.isEmptyRender()).toBeTruthy(); + }); + + test('should return extension when index has lifecycle policy', () => { + const extension = ilmSummaryExtension(indexWithLifecyclePolicy); + expect(extension).toBeDefined(); + const rendered = mountWithIntl(extension); + expect(rendered).toMatchSnapshot(); + }); + + test('should return extension when index has lifecycle error', () => { + const extension = ilmSummaryExtension(indexWithLifecycleError); + expect(extension).toBeDefined(); + const rendered = mountWithIntl(extension); + expect(rendered).toMatchSnapshot(); + }); }); - test('should return extension when any index has lifecycle policy', () => { - const extension = ilmFilterExtension([ - indexWithLifecyclePolicy, - indexWithoutLifecyclePolicy, - indexWithoutLifecyclePolicy, - ]); - expect(extension).toBeDefined(); - expect(extension).toMatchSnapshot(); + + describe('ilm filter extension', () => { + test('should return empty array when no indices have index lifecycle policy', () => { + const extension = ilmFilterExtension([ + indexWithoutLifecyclePolicy, + indexWithoutLifecyclePolicy, + ]); + expect(extension.length).toBe(0); + }); + + test('should return extension when any index has lifecycle policy', () => { + const extension = ilmFilterExtension([ + indexWithLifecyclePolicy, + indexWithoutLifecyclePolicy, + indexWithoutLifecyclePolicy, + ]); + expect(extension).toBeDefined(); + expect(extension).toMatchSnapshot(); + }); }); }); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.js b/x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.js deleted file mode 100644 index d01df3c6beeec..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.js +++ /dev/null @@ -1,24 +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. - */ - -export const BASE_PATH = '/management/elasticsearch/index_lifecycle_management/'; -export const PLUGIN_ID = 'index_lifecycle_management'; -export { - UIM_APP_NAME, - UIM_APP_LOAD, - UIM_POLICY_CREATE, - UIM_POLICY_UPDATE, - UIM_POLICY_DELETE, - UIM_POLICY_ATTACH_INDEX, - UIM_POLICY_ATTACH_INDEX_TEMPLATE, - UIM_POLICY_DETACH_INDEX, - UIM_CONFIG_COLD_PHASE, - UIM_CONFIG_WARM_PHASE, - UIM_CONFIG_SET_PRIORITY, - UIM_CONFIG_FREEZE_INDEX, - UIM_INDEX_RETRY_STEP, - UIM_EDIT_CLICK, -} from './ui_metric'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.ts b/x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.ts new file mode 100644 index 0000000000000..9193efb561a0f --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/common/constants/index.ts @@ -0,0 +1,16 @@ +/* + * 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 PLUGIN = { + ID: 'index_lifecycle_management', + TITLE: i18n.translate('xpack.indexLifecycleMgmt.appTitle', { + defaultMessage: 'Index Lifecycle Policies', + }), +}; + +export const BASE_PATH = '/management/elasticsearch/index_lifecycle_management/'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/common/constants/ui_metric.js b/x-pack/legacy/plugins/index_lifecycle_management/common/constants/ui_metric.js deleted file mode 100644 index bc673b5b7a5e5..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/common/constants/ui_metric.js +++ /dev/null @@ -1,21 +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. - */ - -export const UIM_APP_NAME = 'index_lifecycle_management'; - -export const UIM_APP_LOAD = 'app_load'; -export const UIM_POLICY_CREATE = 'policy_create'; -export const UIM_POLICY_UPDATE = 'policy_update'; -export const UIM_POLICY_DELETE = 'policy_delete'; -export const UIM_POLICY_ATTACH_INDEX = 'policy_attach_index'; -export const UIM_POLICY_ATTACH_INDEX_TEMPLATE = 'policy_attach_index_template'; -export const UIM_POLICY_DETACH_INDEX = 'policy_detach_index'; -export const UIM_CONFIG_COLD_PHASE = 'config_cold_phase'; -export const UIM_CONFIG_WARM_PHASE = 'config_warm_phase'; -export const UIM_CONFIG_SET_PRIORITY = 'config_set_priority'; -export const UIM_CONFIG_FREEZE_INDEX = 'config_freeze_index'; -export const UIM_INDEX_RETRY_STEP = 'index_retry_step'; -export const UIM_EDIT_CLICK = 'edit_click'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/index.js b/x-pack/legacy/plugins/index_lifecycle_management/index.js deleted file mode 100644 index 5a8f6548af97f..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/index.js +++ /dev/null @@ -1,66 +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 { resolve } from 'path'; -import { registerTemplatesRoutes } from './server/routes/api/templates'; -import { registerNodesRoutes } from './server/routes/api/nodes'; -import { registerPoliciesRoutes } from './server/routes/api/policies'; -import { registerIndexRoutes } from './server/routes/api/index'; -import { registerLicenseChecker } from './server/lib/register_license_checker'; -import { PLUGIN_ID } from './common/constants'; -import { indexLifecycleDataEnricher } from './index_lifecycle_data'; - -export function indexLifecycleManagement(kibana) { - return new kibana.Plugin({ - config: Joi => { - return Joi.object({ - enabled: Joi.boolean().default(true), - ui: Joi.object({ - enabled: Joi.boolean().default(true), - }).default(), - filteredNodeAttributes: Joi.array() - .items(Joi.string()) - .default([]), - }).default(); - }, - id: PLUGIN_ID, - publicDir: resolve(__dirname, 'public'), - configPrefix: 'xpack.ilm', - require: ['kibana', 'elasticsearch', 'xpack_main', 'index_management'], - uiExports: { - styleSheetPaths: resolve(__dirname, 'public/index.scss'), - managementSections: ['plugins/index_lifecycle_management'], - injectDefaultVars(server) { - const config = server.config(); - return { - ilmUiEnabled: config.get('xpack.ilm.ui.enabled'), - }; - }, - }, - isEnabled(config) { - return ( - config.get('xpack.ilm.enabled') && - config.has('xpack.index_management.enabled') && - config.get('xpack.index_management.enabled') - ); - }, - init: function(server) { - registerLicenseChecker(server); - registerTemplatesRoutes(server); - registerNodesRoutes(server); - registerPoliciesRoutes(server); - registerIndexRoutes(server); - - if ( - server.config().get('xpack.ilm.ui.enabled') && - server.plugins.index_management && - server.plugins.index_management.addIndexManagementDataEnricher - ) { - server.plugins.index_management.addIndexManagementDataEnricher(indexLifecycleDataEnricher); - } - }, - }); -} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/index.ts b/x-pack/legacy/plugins/index_lifecycle_management/index.ts new file mode 100644 index 0000000000000..9b14b7143bf44 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/index.ts @@ -0,0 +1,62 @@ +/* + * 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 { Legacy } from 'kibana'; +import { resolve } from 'path'; +import { PLUGIN } from './common/constants'; +import { Plugin as IndexLifecycleManagementPlugin } from './plugin'; +import { createShim } from './shim'; + +export function indexLifecycleManagement(kibana: any) { + return new kibana.Plugin({ + id: PLUGIN.ID, + configPrefix: 'xpack.ilm', + publicDir: resolve(__dirname, 'public'), + require: ['kibana', 'elasticsearch', 'xpack_main', 'index_management'], + uiExports: { + styleSheetPaths: resolve(__dirname, 'public/np_ready/application/index.scss'), + managementSections: ['plugins/index_lifecycle_management/legacy'], + injectDefaultVars(server: Legacy.Server) { + const config = server.config(); + return { + ilmUiEnabled: config.get('xpack.ilm.ui.enabled'), + }; + }, + }, + config: (Joi: any) => { + return Joi.object({ + // display menu item + ui: Joi.object({ + enabled: Joi.boolean().default(true), + }).default(), + + // enable plugin + enabled: Joi.boolean().default(true), + + filteredNodeAttributes: Joi.array() + .items(Joi.string()) + .default([]), + }).default(); + }, + isEnabled(config: any) { + return ( + config.get('xpack.ilm.enabled') && + config.has('xpack.index_management.enabled') && + config.get('xpack.index_management.enabled') + ); + }, + init(server: Legacy.Server) { + const core = server.newPlatform.setup.core; + const plugins = {}; + const __LEGACY = createShim(server); + + const indexLifecycleManagementPlugin = new IndexLifecycleManagementPlugin(); + + // Set up plugin. + indexLifecycleManagementPlugin.setup(core, plugins, __LEGACY); + }, + }); +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/index_lifecycle_data.js b/x-pack/legacy/plugins/index_lifecycle_management/index_lifecycle_data.js deleted file mode 100644 index 57b90204ce224..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/index_lifecycle_data.js +++ /dev/null @@ -1,22 +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. - */ - -export const indexLifecycleDataEnricher = async (indicesList, callWithRequest) => { - if (!indicesList || !indicesList.length) { - return; - } - const params = { - path: '/*/_ilm/explain', - method: 'GET', - }; - const { indices: ilmIndicesData } = await callWithRequest('transport.request', params); - return indicesList.map(index => { - return { - ...index, - ilm: { ...(ilmIndicesData[index.name] || {}) }, - }; - }); -}; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/plugin.ts b/x-pack/legacy/plugins/index_lifecycle_management/plugin.ts new file mode 100644 index 0000000000000..8d7f937039203 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/plugin.ts @@ -0,0 +1,54 @@ +/* + * 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 } from 'kibana/server'; +import { LegacySetup } from './shim'; +import { registerLicenseChecker } from './server/lib/register_license_checker'; +import { registerIndexRoutes } from './server/routes/api/index'; +import { registerNodesRoutes } from './server/routes/api/nodes'; +import { registerPoliciesRoutes } from './server/routes/api/policies'; +import { registerTemplatesRoutes } from './server/routes/api/templates'; + +const indexLifecycleDataEnricher = async (indicesList: any, callWithRequest: any) => { + if (!indicesList || !indicesList.length) { + return; + } + const params = { + path: '/*/_ilm/explain', + method: 'GET', + }; + const { indices: ilmIndicesData } = await callWithRequest('transport.request', params); + return indicesList.map((index: any): any => { + return { + ...index, + ilm: { ...(ilmIndicesData[index.name] || {}) }, + }; + }); +}; + +export class Plugin { + public setup(core: CoreSetup, plugins: any, __LEGACY: LegacySetup): void { + const { server } = __LEGACY; + + registerLicenseChecker(server); + + // Register routes. + registerIndexRoutes(server); + registerNodesRoutes(server); + registerPoliciesRoutes(server); + registerTemplatesRoutes(server); + + const serverPlugins = server.plugins as any; + + if ( + server.config().get('xpack.ilm.ui.enabled') && + serverPlugins.index_management && + serverPlugins.index_management.addIndexManagementDataEnricher + ) { + serverPlugins.index_management.addIndexManagementDataEnricher(indexLifecycleDataEnricher); + } + } +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/constants/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/constants/index.js deleted file mode 100644 index bc1244dc7b281..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/constants/index.js +++ /dev/null @@ -1,101 +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. - */ - -export const SET_PHASE_DATA = 'SET_PHASE_DATA'; -export const SET_SELECTED_NODE_ATTRS = 'SET_SELECTED_NODE_ATTRS'; -export const PHASE_HOT = 'hot'; -export const PHASE_WARM = 'warm'; -export const PHASE_COLD = 'cold'; -export const PHASE_DELETE = 'delete'; - -export const PHASE_ENABLED = 'phaseEnabled'; - -export const PHASE_ROLLOVER_ENABLED = 'rolloverEnabled'; -export const WARM_PHASE_ON_ROLLOVER = 'warmPhaseOnRollover'; -export const PHASE_ROLLOVER_ALIAS = 'selectedAlias'; -export const PHASE_ROLLOVER_MAX_AGE = 'selectedMaxAge'; -export const PHASE_ROLLOVER_MAX_AGE_UNITS = 'selectedMaxAgeUnits'; -export const PHASE_ROLLOVER_MAX_SIZE_STORED = 'selectedMaxSizeStored'; -export const PHASE_ROLLOVER_MAX_DOCUMENTS = 'selectedMaxDocuments'; -export const PHASE_ROLLOVER_MAX_SIZE_STORED_UNITS = 'selectedMaxSizeStoredUnits'; -export const PHASE_ROLLOVER_MINIMUM_AGE = 'selectedMinimumAge'; -export const PHASE_ROLLOVER_MINIMUM_AGE_UNITS = 'selectedMinimumAgeUnits'; - -export const PHASE_FORCE_MERGE_SEGMENTS = 'selectedForceMergeSegments'; -export const PHASE_FORCE_MERGE_ENABLED = 'forceMergeEnabled'; -export const PHASE_FREEZE_ENABLED = 'freezeEnabled'; - -export const PHASE_SHRINK_ENABLED = 'shrinkEnabled'; - -export const PHASE_NODE_ATTRS = 'selectedNodeAttrs'; -export const PHASE_PRIMARY_SHARD_COUNT = 'selectedPrimaryShardCount'; -export const PHASE_REPLICA_COUNT = 'selectedReplicaCount'; -export const PHASE_INDEX_PRIORITY = 'phaseIndexPriority'; - -export const PHASE_ATTRIBUTES_THAT_ARE_NUMBERS_VALIDATE = [ - PHASE_ROLLOVER_MINIMUM_AGE, - PHASE_FORCE_MERGE_SEGMENTS, - PHASE_PRIMARY_SHARD_COUNT, - PHASE_REPLICA_COUNT, - PHASE_INDEX_PRIORITY, -]; -export const PHASE_ATTRIBUTES_THAT_ARE_NUMBERS = [ - ...PHASE_ATTRIBUTES_THAT_ARE_NUMBERS_VALIDATE, - PHASE_ROLLOVER_MAX_AGE, - PHASE_ROLLOVER_MAX_SIZE_STORED, - PHASE_ROLLOVER_MAX_DOCUMENTS, -]; - -export const STRUCTURE_INDEX_TEMPLATE = 'indexTemplate'; -export const STRUCTURE_TEMPLATE_SELECTION = 'templateSelection'; -export const STRUCTURE_TEMPLATE_NAME = 'templateName'; -export const STRUCTURE_CONFIGURATION = 'configuration'; -export const STRUCTURE_NODE_ATTRS = 'node_attrs'; -export const STRUCTURE_PRIMARY_NODES = 'primary_nodes'; -export const STRUCTURE_REPLICAS = 'replicas'; - -export const STRUCTURE_POLICY_CONFIGURATION = 'policyConfiguration'; - -export const STRUCTURE_REVIEW = 'review'; -export const STRUCTURE_POLICY_NAME = 'policyName'; -export const STRUCTURE_INDEX_NAME = 'indexName'; -export const STRUCTURE_ALIAS_NAME = 'aliasName'; - -export const ERROR_STRUCTURE = { - [PHASE_HOT]: { - [PHASE_ROLLOVER_ALIAS]: [], - [PHASE_ROLLOVER_MAX_AGE]: [], - [PHASE_ROLLOVER_MAX_AGE_UNITS]: [], - [PHASE_ROLLOVER_MAX_SIZE_STORED]: [], - [PHASE_ROLLOVER_MAX_DOCUMENTS]: [], - [PHASE_ROLLOVER_MAX_SIZE_STORED_UNITS]: [], - [PHASE_INDEX_PRIORITY]: [], - }, - [PHASE_WARM]: { - [PHASE_ROLLOVER_ALIAS]: [], - [PHASE_ROLLOVER_MINIMUM_AGE]: [], - [PHASE_ROLLOVER_MINIMUM_AGE_UNITS]: [], - [PHASE_NODE_ATTRS]: [], - [PHASE_PRIMARY_SHARD_COUNT]: [], - [PHASE_REPLICA_COUNT]: [], - [PHASE_FORCE_MERGE_SEGMENTS]: [], - [PHASE_INDEX_PRIORITY]: [], - }, - [PHASE_COLD]: { - [PHASE_ROLLOVER_ALIAS]: [], - [PHASE_ROLLOVER_MINIMUM_AGE]: [], - [PHASE_ROLLOVER_MINIMUM_AGE_UNITS]: [], - [PHASE_NODE_ATTRS]: [], - [PHASE_REPLICA_COUNT]: [], - [PHASE_INDEX_PRIORITY]: [], - }, - [PHASE_DELETE]: { - [PHASE_ROLLOVER_ALIAS]: [], - [PHASE_ROLLOVER_MINIMUM_AGE]: [], - [PHASE_ROLLOVER_MINIMUM_AGE_UNITS]: [], - }, - [STRUCTURE_POLICY_NAME]: [], -}; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/index.js deleted file mode 100644 index ef44f5dbfeca4..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/index.js +++ /dev/null @@ -1,16 +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 './register_management_section'; -import './register_routes'; - -import chrome from 'ui/chrome'; -import { addAllExtensions } from './extend_index_management'; - -// Only add extensions if ILM UI is enabled -if (chrome.getInjected('ilmUiEnabled')) { - addAllExtensions(); -} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts new file mode 100644 index 0000000000000..3c21a644c0f78 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts @@ -0,0 +1,105 @@ +/* + * 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 { App } from 'src/core/public'; + +/* Legacy Imports */ +import { npSetup, npStart } from 'ui/new_platform'; +import chrome from 'ui/chrome'; +import routes from 'ui/routes'; +import { management } from 'ui/management'; +import { createUiStatsReporter } from '../../../../../src/legacy/core_plugins/ui_metric/public'; + +import { PLUGIN, BASE_PATH } from '../common/constants'; +import { createPlugin } from './np_ready'; +import { addAllExtensions } from './np_ready/extend_index_management'; + +if (chrome.getInjected('ilmUiEnabled')) { + // We have to initialize this outside of the NP lifecycle, otherwise these extensions won't + // be available in Index Management unless the user visits ILM first. + addAllExtensions(); + + // This method handles the cleanup needed when route is scope is destroyed. It also prevents Angular + // from destroying scope when route changes and both old route and new route are this same route. + const manageAngularLifecycle = ($scope: any, $route: any, unmount: () => void) => { + 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; + } + }); + $scope.$on('$destroy', () => { + if (deregister) { + deregister(); + } + unmount(); + }); + }; + + // Once this app no longer depends upon Angular's routing (e.g. for the "redirect" service), we can + // use the Management plugin's API to register this app within the Elasticsearch section. + const esSection = management.getSection('elasticsearch'); + esSection.register('index_lifecycle_policies', { + visible: true, + display: PLUGIN.TITLE, + order: 2, + url: `#${BASE_PATH}policies`, + }); + + const REACT_ROOT_ID = 'indexLifecycleManagementReactRoot'; + + const template = ` +
+ + `; + + routes.when(`${BASE_PATH}:view?/:action?/:id?`, { + template, + controllerAs: 'indexLifecycleManagement', + controller: class IndexLifecycleManagementController { + constructor($scope: any, $route: any, kbnUrl: any, $rootScope: any) { + $scope.$$postDigest(() => { + const element = document.getElementById(REACT_ROOT_ID)!; + const { core } = npSetup; + + const coreDependencies = { + ...core, + application: { + ...core.application, + async register(app: App) { + const unmountApp = await app.mount({ ...npStart } as any, { + element, + appBasePath: '', + onAppLeave: () => undefined, + }); + manageAngularLifecycle($scope, $route, unmountApp as any); + }, + }, + }; + + // The Plugin interface won't allow us to pass __LEGACY as a third argument, so we'll just + // sneak it inside of the plugins argument for now. + const pluginDependencies = { + __LEGACY: { + redirect: (path: string) => { + $scope.$evalAsync(() => { + kbnUrl.redirect(path); + }); + }, + createUiStatsReporter, + }, + }; + + const plugin = createPlugin({} as any); + plugin.setup(coreDependencies, pluginDependencies); + }); + } + } as any, + } as any); +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/main.html b/x-pack/legacy/plugins/index_lifecycle_management/public/main.html deleted file mode 100644 index d54cba0632cdf..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/main.html +++ /dev/null @@ -1,3 +0,0 @@ - -
- diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/_index_lifecycle_management.scss b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/_index_lifecycle_management.scss similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/_index_lifecycle_management.scss rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/_index_lifecycle_management.scss diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/app.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/app.tsx similarity index 75% rename from x-pack/legacy/plugins/index_lifecycle_management/public/app.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/app.tsx index 87a2b45c7fedd..6738d7caa4444 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/app.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/app.tsx @@ -6,13 +6,16 @@ import React, { useEffect } from 'react'; import { HashRouter, Switch, Route, Redirect } from 'react-router-dom'; -import { BASE_PATH, UIM_APP_LOAD } from '../common/constants'; +import { METRIC_TYPE } from '@kbn/analytics'; + +import { BASE_PATH } from '../../../common/constants'; +import { UIM_APP_LOAD } from './constants'; import { EditPolicy } from './sections/edit_policy'; import { PolicyTable } from './sections/policy_table'; -import { trackUiMetric } from './services'; +import { trackUiMetric } from './services/ui_metric'; export const App = () => { - useEffect(() => trackUiMetric('loaded', UIM_APP_LOAD), []); + useEffect(() => trackUiMetric(METRIC_TYPE.LOADED, UIM_APP_LOAD), []); return ( diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/index.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/index.ts new file mode 100644 index 0000000000000..a631a38fbcb7e --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/index.ts @@ -0,0 +1,103 @@ +/* + * 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. + */ + +export * from './ui_metric'; + +export const SET_PHASE_DATA: string = 'SET_PHASE_DATA'; +export const SET_SELECTED_NODE_ATTRS: string = 'SET_SELECTED_NODE_ATTRS'; +export const PHASE_HOT: string = 'hot'; +export const PHASE_WARM: string = 'warm'; +export const PHASE_COLD: string = 'cold'; +export const PHASE_DELETE: string = 'delete'; + +export const PHASE_ENABLED: string = 'phaseEnabled'; + +export const PHASE_ROLLOVER_ENABLED: string = 'rolloverEnabled'; +export const WARM_PHASE_ON_ROLLOVER: string = 'warmPhaseOnRollover'; +export const PHASE_ROLLOVER_ALIAS: string = 'selectedAlias'; +export const PHASE_ROLLOVER_MAX_AGE: string = 'selectedMaxAge'; +export const PHASE_ROLLOVER_MAX_AGE_UNITS: string = 'selectedMaxAgeUnits'; +export const PHASE_ROLLOVER_MAX_SIZE_STORED: string = 'selectedMaxSizeStored'; +export const PHASE_ROLLOVER_MAX_DOCUMENTS: string = 'selectedMaxDocuments'; +export const PHASE_ROLLOVER_MAX_SIZE_STORED_UNITS: string = 'selectedMaxSizeStoredUnits'; +export const PHASE_ROLLOVER_MINIMUM_AGE: string = 'selectedMinimumAge'; +export const PHASE_ROLLOVER_MINIMUM_AGE_UNITS: string = 'selectedMinimumAgeUnits'; + +export const PHASE_FORCE_MERGE_SEGMENTS: string = 'selectedForceMergeSegments'; +export const PHASE_FORCE_MERGE_ENABLED: string = 'forceMergeEnabled'; +export const PHASE_FREEZE_ENABLED: string = 'freezeEnabled'; + +export const PHASE_SHRINK_ENABLED: string = 'shrinkEnabled'; + +export const PHASE_NODE_ATTRS: string = 'selectedNodeAttrs'; +export const PHASE_PRIMARY_SHARD_COUNT: string = 'selectedPrimaryShardCount'; +export const PHASE_REPLICA_COUNT: string = 'selectedReplicaCount'; +export const PHASE_INDEX_PRIORITY: string = 'phaseIndexPriority'; + +export const PHASE_ATTRIBUTES_THAT_ARE_NUMBERS_VALIDATE: string[] = [ + PHASE_ROLLOVER_MINIMUM_AGE, + PHASE_FORCE_MERGE_SEGMENTS, + PHASE_PRIMARY_SHARD_COUNT, + PHASE_REPLICA_COUNT, + PHASE_INDEX_PRIORITY, +]; +export const PHASE_ATTRIBUTES_THAT_ARE_NUMBERS: string[] = [ + ...PHASE_ATTRIBUTES_THAT_ARE_NUMBERS_VALIDATE, + PHASE_ROLLOVER_MAX_AGE, + PHASE_ROLLOVER_MAX_SIZE_STORED, + PHASE_ROLLOVER_MAX_DOCUMENTS, +]; + +export const STRUCTURE_INDEX_TEMPLATE: string = 'indexTemplate'; +export const STRUCTURE_TEMPLATE_SELECTION: string = 'templateSelection'; +export const STRUCTURE_TEMPLATE_NAME: string = 'templateName'; +export const STRUCTURE_CONFIGURATION: string = 'configuration'; +export const STRUCTURE_NODE_ATTRS: string = 'node_attrs'; +export const STRUCTURE_PRIMARY_NODES: string = 'primary_nodes'; +export const STRUCTURE_REPLICAS: string = 'replicas'; + +export const STRUCTURE_POLICY_CONFIGURATION: string = 'policyConfiguration'; + +export const STRUCTURE_REVIEW: string = 'review'; +export const STRUCTURE_POLICY_NAME: string = 'policyName'; +export const STRUCTURE_INDEX_NAME: string = 'indexName'; +export const STRUCTURE_ALIAS_NAME: string = 'aliasName'; + +export const ERROR_STRUCTURE: any = { + [PHASE_HOT]: { + [PHASE_ROLLOVER_ALIAS]: [], + [PHASE_ROLLOVER_MAX_AGE]: [], + [PHASE_ROLLOVER_MAX_AGE_UNITS]: [], + [PHASE_ROLLOVER_MAX_SIZE_STORED]: [], + [PHASE_ROLLOVER_MAX_DOCUMENTS]: [], + [PHASE_ROLLOVER_MAX_SIZE_STORED_UNITS]: [], + [PHASE_INDEX_PRIORITY]: [], + }, + [PHASE_WARM]: { + [PHASE_ROLLOVER_ALIAS]: [], + [PHASE_ROLLOVER_MINIMUM_AGE]: [], + [PHASE_ROLLOVER_MINIMUM_AGE_UNITS]: [], + [PHASE_NODE_ATTRS]: [], + [PHASE_PRIMARY_SHARD_COUNT]: [], + [PHASE_REPLICA_COUNT]: [], + [PHASE_FORCE_MERGE_SEGMENTS]: [], + [PHASE_INDEX_PRIORITY]: [], + }, + [PHASE_COLD]: { + [PHASE_ROLLOVER_ALIAS]: [], + [PHASE_ROLLOVER_MINIMUM_AGE]: [], + [PHASE_ROLLOVER_MINIMUM_AGE_UNITS]: [], + [PHASE_NODE_ATTRS]: [], + [PHASE_REPLICA_COUNT]: [], + [PHASE_INDEX_PRIORITY]: [], + }, + [PHASE_DELETE]: { + [PHASE_ROLLOVER_ALIAS]: [], + [PHASE_ROLLOVER_MINIMUM_AGE]: [], + [PHASE_ROLLOVER_MINIMUM_AGE_UNITS]: [], + }, + [STRUCTURE_POLICY_NAME]: [], +}; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/ui_metric.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/ui_metric.ts new file mode 100644 index 0000000000000..ee4dbb8582cef --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/constants/ui_metric.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. + */ + +export const UIM_APP_NAME: string = 'index_lifecycle_management'; + +export const UIM_APP_LOAD: string = 'app_load'; +export const UIM_POLICY_CREATE: string = 'policy_create'; +export const UIM_POLICY_UPDATE: string = 'policy_update'; +export const UIM_POLICY_DELETE: string = 'policy_delete'; +export const UIM_POLICY_ATTACH_INDEX: string = 'policy_attach_index'; +export const UIM_POLICY_ATTACH_INDEX_TEMPLATE: string = 'policy_attach_index_template'; +export const UIM_POLICY_DETACH_INDEX: string = 'policy_detach_index'; +export const UIM_CONFIG_COLD_PHASE: string = 'config_cold_phase'; +export const UIM_CONFIG_WARM_PHASE: string = 'config_warm_phase'; +export const UIM_CONFIG_SET_PRIORITY: string = 'config_set_priority'; +export const UIM_CONFIG_FREEZE_INDEX: string = 'config_freeze_index'; +export const UIM_INDEX_RETRY_STEP: string = 'index_retry_step'; +export const UIM_EDIT_CLICK: string = 'edit_click'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/index.scss b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/index.scss similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/index.scss rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/index.scss diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/index.tsx b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/index.tsx new file mode 100644 index 0000000000000..b87a633d65c9c --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/index.tsx @@ -0,0 +1,63 @@ +/* + * 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 React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { Provider } from 'react-redux'; +import { DocLinksStart, ToastsSetup, HttpSetup, FatalErrorsSetup } from 'src/core/public'; + +import { App } from './app'; +import { indexLifecycleManagementStore } from './store'; +import { init as initHttp } from './services/http'; +import { init as initNavigation } from './services/navigation'; +import { init as initDocumentation } from './services/documentation'; +import { init as initUiMetric } from './services/ui_metric'; +import { init as initNotification } from './services/notification'; + +export interface LegacySetup { + redirect: any; + createUiStatsReporter: any; +} + +interface AppDependencies { + legacy: LegacySetup; + I18nContext: any; + http: HttpSetup; + toasts: ToastsSetup; + fatalErrors: FatalErrorsSetup; + docLinks: DocLinksStart; + element: HTMLElement; +} + +export const renderApp = (appDependencies: AppDependencies) => { + const { + legacy: { redirect, createUiStatsReporter }, + I18nContext, + http, + toasts, + fatalErrors, + docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, + element, + } = appDependencies; + + // Initialize services + initHttp(http); + initNavigation(redirect); + initDocumentation(`${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`); + initUiMetric(createUiStatsReporter); + initNotification(toasts, fatalErrors); + + render( + + + + + , + element + ); + + return () => unmountComponentAtNode(element); +}; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/active_badge.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/active_badge.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/active_badge.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/active_badge.js index df0236b63e41f..f39e103cffd25 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/active_badge.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/active_badge.js @@ -6,6 +6,7 @@ import React from 'react'; import { EuiBadge } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; + export const ActiveBadge = () => { return ( diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/learn_more_link.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/learn_more_link.js similarity index 79% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/learn_more_link.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/learn_more_link.js index afa26cf6389a6..2284b9e39835c 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/learn_more_link.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/learn_more_link.js @@ -6,17 +6,16 @@ import React from 'react'; import { EuiLink } from '@elastic/eui'; -import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; import { FormattedMessage } from '@kbn/i18n/react'; -const esBase = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`; +import { createDocLink } from '../../services/documentation'; export class LearnMoreLink extends React.PureComponent { render() { const { href, docPath, text } = this.props; let url; if (docPath) { - url = `${esBase}${docPath}`; + url = createDocLink(docPath); } else { url = href; } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/optional_label.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/optional_label.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/optional_label.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/optional_label.js index dc9909941e67e..8b464070386f2 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/optional_label.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/optional_label.js @@ -5,6 +5,7 @@ */ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; + export const OptionalLabel = () => { return ( diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/phase_error_message.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/phase_error_message.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/phase_error_message.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/phase_error_message.js index c5fd0984ca6f3..904ac7c25f2f9 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/components/phase_error_message.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/components/phase_error_message.js @@ -6,6 +6,7 @@ import React from 'react'; import { EuiBadge } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; + export const PhaseErrorMessage = ({ isShowingErrors }) => { return isShowingErrors ? ( diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/cold_phase/cold_phase.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/cold_phase/cold_phase.container.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/cold_phase/cold_phase.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/cold_phase/cold_phase.container.js index 8e73f4b9ede3c..1f2468e79ebd3 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/cold_phase/cold_phase.container.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/cold_phase/cold_phase.container.js @@ -5,10 +5,11 @@ */ import { connect } from 'react-redux'; -import { ColdPhase as PresentationComponent } from './cold_phase'; + import { getPhase } from '../../../../store/selectors'; import { setPhaseData } from '../../../../store/actions'; import { PHASE_COLD, PHASE_HOT, PHASE_ROLLOVER_ENABLED } from '../../../../constants'; +import { ColdPhase as PresentationComponent } from './cold_phase'; export const ColdPhase = connect( state => ({ diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/cold_phase/cold_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/cold_phase/cold_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/cold_phase/cold_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/cold_phase/cold_phase.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/cold_phase/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/cold_phase/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/cold_phase/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/cold_phase/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/delete_phase.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/delete_phase.container.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/delete_phase.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/delete_phase.container.js index 64a5d4ad651d7..74ec9b2c98ed9 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/delete_phase.container.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/delete_phase.container.js @@ -5,10 +5,10 @@ */ import { connect } from 'react-redux'; -import { DeletePhase as PresentationComponent } from './delete_phase'; import { getPhase } from '../../../../store/selectors'; import { setPhaseData } from '../../../../store/actions'; import { PHASE_DELETE, PHASE_HOT, PHASE_ROLLOVER_ENABLED } from '../../../../constants'; +import { DeletePhase as PresentationComponent } from './delete_phase'; export const DeletePhase = connect( state => ({ diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/delete_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/delete_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/delete_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/delete_phase.js index cec8ba5ac8167..146b5c36847db 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/delete_phase.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/delete_phase.js @@ -5,13 +5,13 @@ */ import React, { PureComponent, Fragment } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; import PropTypes from 'prop-types'; -import { MinAgeInput } from '../min_age_input'; - +import { FormattedMessage } from '@kbn/i18n/react'; import { EuiDescribedFormGroup, EuiSwitch } from '@elastic/eui'; + import { PHASE_DELETE, PHASE_ENABLED } from '../../../../constants'; import { ActiveBadge, PhaseErrorMessage } from '../../../components'; +import { MinAgeInput } from '../min_age_input'; export class DeletePhase extends PureComponent { static propTypes = { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/delete_phase/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/delete_phase/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/hot_phase/hot_phase.container.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/hot_phase/hot_phase.container.js index cf4960e4e21f1..818af79466f6b 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.container.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/hot_phase/hot_phase.container.js @@ -5,10 +5,11 @@ */ import { connect } from 'react-redux'; -import { HotPhase as PresentationComponent } from './hot_phase'; + import { getPhase } from '../../../../store/selectors'; import { setPhaseData } from '../../../../store/actions'; import { PHASE_HOT, PHASE_WARM, WARM_PHASE_ON_ROLLOVER } from '../../../../constants'; +import { HotPhase as PresentationComponent } from './hot_phase'; export const HotPhase = connect( state => ({ diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/hot_phase/hot_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/hot_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/hot_phase/hot_phase.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/hot_phase/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/hot_phase/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/hot_phase/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/min_age_input.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/min_age_input.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/min_age_input.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/min_age_input.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_allocation/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_allocation/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_allocation/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_allocation/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_allocation/node_allocation.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_allocation/node_allocation.container.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_allocation/node_allocation.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_allocation/node_allocation.container.js index 178c2071fdff5..a92959a5b31cf 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_allocation/node_allocation.container.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_allocation/node_allocation.container.js @@ -5,9 +5,10 @@ */ import { connect } from 'react-redux'; -import { NodeAllocation as PresentationComponent } from './node_allocation'; + import { getNodeOptions } from '../../../../store/selectors'; import { fetchNodes } from '../../../../store/actions'; +import { NodeAllocation as PresentationComponent } from './node_allocation'; export const NodeAllocation = connect( state => ({ diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_allocation/node_allocation.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_allocation/node_allocation.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_allocation/node_allocation.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_allocation/node_allocation.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_attrs_details/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_attrs_details/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_attrs_details/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_attrs_details/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js index 8887b13740e04..ca7c310723b62 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.container.js @@ -5,9 +5,10 @@ */ import { connect } from 'react-redux'; -import { NodeAttrsDetails as PresentationComponent } from './node_attrs_details'; + import { getNodeDetails } from '../../../../store/selectors'; import { fetchNodeDetails } from '../../../../store/actions'; +import { NodeAttrsDetails as PresentationComponent } from './node_attrs_details'; export const NodeAttrsDetails = connect( (state, ownProps) => ({ diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_attrs_details/node_attrs_details.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/node_attrs_details/node_attrs_details.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/node_attrs_details/node_attrs_details.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/policy_json_flyout.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/policy_json_flyout.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/policy_json_flyout.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/policy_json_flyout.js index 3f8296a7b0525..b40f3763d8e01 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/policy_json_flyout.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/policy_json_flyout.js @@ -5,8 +5,8 @@ */ import React, { PureComponent } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; import PropTypes from 'prop-types'; +import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButtonEmpty, diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/set_priority_input.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/set_priority_input.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/set_priority_input.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/set_priority_input.js index fe65cc2d91455..09db792b689da 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/set_priority_input.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/set_priority_input.js @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { Fragment } from 'react'; -import { LearnMoreLink, OptionalLabel } from '../../components'; +import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFieldNumber, EuiTextColor, EuiDescribedFormGroup } from '@elastic/eui'; + import { PHASE_INDEX_PRIORITY } from '../../../constants'; +import { LearnMoreLink, OptionalLabel } from '../../components'; import { ErrableFormRow } from '../form_errors'; -import { FormattedMessage } from '@kbn/i18n/react'; + export const SetPriorityInput = props => { const { errors, phaseData, phase, setPhaseData, isShowingErrors } = props; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/warm_phase/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/warm_phase/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/warm_phase/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/warm_phase/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/warm_phase/warm_phase.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/warm_phase/warm_phase.container.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/warm_phase/warm_phase.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/warm_phase/warm_phase.container.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/warm_phase/warm_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/warm_phase/warm_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/warm_phase/warm_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/warm_phase/warm_phase.js index 77afd4f7051dc..133e6b617c71e 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/components/warm_phase/warm_phase.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/components/warm_phase/warm_phase.js @@ -5,9 +5,9 @@ */ import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import PropTypes from 'prop-types'; import { EuiTextColor, EuiFlexGroup, @@ -29,10 +29,10 @@ import { PHASE_REPLICA_COUNT, PHASE_SHRINK_ENABLED, } from '../../../../constants'; +import { LearnMoreLink, ActiveBadge, PhaseErrorMessage, OptionalLabel } from '../../../components'; +import { ErrableFormRow } from '../../form_errors'; import { SetPriorityInput } from '../set_priority_input'; import { NodeAllocation } from '../node_allocation'; -import { ErrableFormRow } from '../../form_errors'; -import { LearnMoreLink, ActiveBadge, PhaseErrorMessage, OptionalLabel } from '../../../components'; import { MinAgeInput } from '../min_age_input'; export class WarmPhase extends PureComponent { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/edit_policy.container.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/edit_policy.container.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/edit_policy.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/edit_policy.js index 6e08ce6be0fa7..040ce189ba2e6 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/edit_policy.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/edit_policy.js @@ -6,7 +6,6 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import { toastNotifications } from 'ui/notify'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -36,6 +35,7 @@ import { STRUCTURE_POLICY_NAME, } from '../../constants'; +import { toasts } from '../../services/notification'; import { goToPolicyList } from '../../services/navigation'; import { findFirstError } from '../../services/find_errors'; import { LearnMoreLink } from '../components'; @@ -107,7 +107,7 @@ export class EditPolicy extends Component { this.setState({ isShowingErrors: true }); const { saveLifecyclePolicy, lifecycle, saveAsNewPolicy, firstError } = this.props; if (firstError) { - toastNotifications.addDanger( + toasts.addDanger( i18n.translate('xpack.indexLifecycleMgmt.editPolicy.formErrorsMessage', { defaultMessage: 'Please fix the errors on this page.', }) diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/form_errors.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/form_errors.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/form_errors.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/form_errors.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/index.d.ts similarity index 80% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/index.d.ts index 441648a8701e0..5f15d929a4916 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/index.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/index.d.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { isEsErrorFactory } from './is_es_error_factory'; +export declare const EditPolicy: any; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/edit_policy/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/edit_policy/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/no_match/components/no_match/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/no_match/components/no_match/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/no_match/components/no_match/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/no_match/components/no_match/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/no_match/components/no_match/no_match.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/no_match/components/no_match/no_match.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/no_match/components/no_match/no_match.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/no_match/components/no_match/no_match.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/no_match/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/no_match/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/no_match/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/no_match/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js similarity index 98% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js index 7aae114c3bffe..6129678edf3b7 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/add_policy_to_template_confirm_modal.js @@ -19,8 +19,8 @@ import { EuiSpacer, EuiText, } from '@elastic/eui'; -import { toastNotifications } from 'ui/notify'; +import { toasts } from '../../../../services/notification'; import { addLifecyclePolicyToTemplate, loadIndexTemplates } from '../../../../services/api'; import { showApiError } from '../../../../services/api_errors'; import { LearnMoreLink } from '../../../components/learn_more_link'; @@ -59,7 +59,7 @@ export class AddPolicyToTemplateConfirmModal extends Component { values: { policyName, templateName }, } ); - toastNotifications.addSuccess(message); + toasts.addSuccess(message); onCancel(); } catch (e) { const title = i18n.translate( diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/confirm_delete.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/confirm_delete.js similarity index 96% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/confirm_delete.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/confirm_delete.js index c1e47c733545c..0ecc9cc13ecd0 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/confirm_delete.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/confirm_delete.js @@ -8,7 +8,8 @@ import React, { Component } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui'; -import { toastNotifications } from 'ui/notify'; + +import { toasts } from '../../../../services/notification'; import { deletePolicy } from '../../../../services/api'; import { showApiError } from '../../../../services/api_errors'; @@ -23,7 +24,7 @@ export class ConfirmDelete extends Component { defaultMessage: 'Deleted policy {policyName}', values: { policyName }, }); - toastNotifications.addSuccess(message); + toasts.addSuccess(message); } catch (e) { const title = i18n.translate('xpack.indexLifecycleMgmt.confirmDelete.errorMessage', { defaultMessage: 'Error deleting policy {policyName}', diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/policy_table.container.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.container.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/policy_table.container.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.container.js index 0688284606b1f..7db980abeba8a 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/policy_table.container.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.container.js @@ -5,7 +5,7 @@ */ import { connect } from 'react-redux'; -import { PolicyTable as PresentationComponent } from './policy_table'; + import { fetchPolicies, policyFilterChanged, @@ -13,6 +13,7 @@ import { policyPageSizeChanged, policySortChanged, } from '../../../../store/actions'; + import { getPolicies, getPageOfPolicies, @@ -22,6 +23,8 @@ import { isPolicyListLoaded, } from '../../../../store/selectors'; +import { PolicyTable as PresentationComponent } from './policy_table'; + const mapDispatchToProps = dispatch => { return { policyFilterChanged: filter => { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/policy_table.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.js similarity index 98% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/policy_table.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.js index ed3cb5d9d3cd2..eba7f75aa9baf 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/components/policy_table/policy_table.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.js @@ -34,13 +34,15 @@ import { EuiPageContent, EuiScreenReaderOnly, } from '@elastic/eui'; + import { RIGHT_ALIGNMENT } from '@elastic/eui/lib/services'; -import { getIndexListUri } from '../../../../../../index_management/public/app/services/navigation'; -import { BASE_PATH, UIM_EDIT_CLICK } from '../../../../../common/constants'; +import { getIndexListUri } from '../../../../../../../../index_management/public/app/services/navigation'; +import { BASE_PATH } from '../../../../../../../common/constants'; +import { UIM_EDIT_CLICK } from '../../../../constants'; import { getPolicyPath } from '../../../../services/navigation'; import { flattenPanelTree } from '../../../../services/flatten_panel_tree'; -import { trackUiMetric } from '../../../../services'; +import { trackUiMetric } from '../../../../services/ui_metric'; import { NoMatch } from '../no_match'; import { ConfirmDelete } from './confirm_delete'; import { AddPolicyToTemplateConfirmModal } from './add_policy_to_template_confirm_modal'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/index.d.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/index.d.ts new file mode 100644 index 0000000000000..fa1b1129523eb --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/index.d.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export declare const PolicyTable: any; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/sections/policy_table/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/api.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/api.js new file mode 100644 index 0000000000000..f13bbcb6162b8 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/api.js @@ -0,0 +1,81 @@ +/* + * 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 { + UIM_POLICY_DELETE, + UIM_POLICY_ATTACH_INDEX, + UIM_POLICY_ATTACH_INDEX_TEMPLATE, + UIM_POLICY_DETACH_INDEX, + UIM_INDEX_RETRY_STEP, +} from '../constants'; + +import { trackUiMetric } from './ui_metric'; +import { sendGet, sendPost, sendDelete } from './http'; + +// The extend_index_management module that we support an injected httpClient here. + +export async function loadNodes(httpClient) { + return await sendGet(`nodes/list`, httpClient); +} + +export async function loadNodeDetails(selectedNodeAttrs, httpClient) { + return await sendGet(`nodes/${selectedNodeAttrs}/details`, httpClient); +} + +export async function loadIndexTemplates(httpClient) { + return await sendGet(`templates`, httpClient); +} + +export async function loadIndexTemplate(templateName, httpClient) { + if (!templateName) { + return {}; + } + return await sendGet(`templates/${templateName}`, httpClient); +} + +export async function loadPolicies(withIndices, httpClient) { + const query = withIndices ? '?withIndices=true' : ''; + return await sendGet('policies', query, httpClient); +} + +export async function savePolicy(policy, httpClient) { + return await sendPost(`policies`, policy, httpClient); +} + +export async function deletePolicy(policyName, httpClient) { + const response = await sendDelete(`policies/${encodeURIComponent(policyName)}`, httpClient); + // Only track successful actions. + trackUiMetric('count', UIM_POLICY_DELETE); + return response; +} + +export const retryLifecycleForIndex = async (indexNames, httpClient) => { + const response = await sendPost(`index/retry`, { indexNames }, httpClient); + // Only track successful actions. + trackUiMetric('count', UIM_INDEX_RETRY_STEP); + return response; +}; + +export const removeLifecycleForIndex = async (indexNames, httpClient) => { + const response = await sendPost(`index/remove`, { indexNames }, httpClient); + // Only track successful actions. + trackUiMetric('count', UIM_POLICY_DETACH_INDEX); + return response; +}; + +export const addLifecyclePolicyToIndex = async (body, httpClient) => { + const response = await sendPost(`index/add`, body, httpClient); + // Only track successful actions. + trackUiMetric('count', UIM_POLICY_ATTACH_INDEX); + return response; +}; + +export const addLifecyclePolicyToTemplate = async (body, httpClient) => { + const response = await sendPost(`template`, body, httpClient); + // Only track successful actions. + trackUiMetric('count', UIM_POLICY_ATTACH_INDEX_TEMPLATE); + return response; +}; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/api_errors.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/api_errors.js similarity index 69% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/api_errors.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/api_errors.js index bacaf13405898..af107b5cff4b1 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/services/api_errors.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/api_errors.js @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fatalError, toastNotifications } from 'ui/notify'; +import { fatalErrors, toasts } from './notification'; function createToastConfig(error, errorTitle) { - // Expect an error in the shape provided by Angular's $http service. - if (error && error.data) { - const { error: errorString, statusCode, message } = error.data; + if (error && error.body) { + const { error: errorString, statusCode, message } = error.body; + return { title: errorTitle, text: `${statusCode}: ${errorString}. ${message}`, @@ -21,22 +21,22 @@ export function showApiWarning(error, errorTitle) { const toastConfig = createToastConfig(error, errorTitle); if (toastConfig) { - return toastNotifications.addWarning(toastConfig); + return toasts.addWarning(toastConfig); } // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - return fatalError(error, errorTitle); + return fatalErrors(error, errorTitle); } export function showApiError(error, errorTitle) { const toastConfig = createToastConfig(error, errorTitle); if (toastConfig) { - return toastNotifications.addDanger(toastConfig); + return toasts.addDanger(toastConfig); } // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - fatalError(error, errorTitle); + fatalErrors.add(error, errorTitle); } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/documentation.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/documentation.ts new file mode 100644 index 0000000000000..d459d304d5c71 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/documentation.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export let skippingDisconnectedClustersUrl: string; +export let remoteClustersUrl: string; +export let transportPortUrl: string; + +let _esDocBasePath: string; + +export function init(esDocBasePath: string): void { + _esDocBasePath = esDocBasePath; +} + +export const createDocLink = (docPath: string): string => `${_esDocBasePath}${docPath}`; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/filter_items.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/filter_items.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/filter_items.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/filter_items.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/find_errors.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/find_errors.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/find_errors.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/find_errors.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/flatten_panel_tree.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/flatten_panel_tree.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/flatten_panel_tree.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/flatten_panel_tree.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/http.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/http.ts new file mode 100644 index 0000000000000..bbda1ebd2e0e5 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/http.ts @@ -0,0 +1,35 @@ +/* + * 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. + */ + +let _httpClient: any; + +export function init(httpClient: any): void { + _httpClient = httpClient; +} + +function getFullPath(path: string): string { + const apiPrefix = '/api/index_lifecycle_management'; + + if (path) { + return `${apiPrefix}/${path}`; + } + + return apiPrefix; +} + +// The extend_index_management module requires that we support an injected httpClient here. + +export function sendPost(path: string, payload: any, httpClient = _httpClient): any { + return httpClient.post(getFullPath(path), { body: JSON.stringify(payload) }); +} + +export function sendGet(path: string, query: any, httpClient = _httpClient): any { + return httpClient.get(getFullPath(path), { query }); +} + +export function sendDelete(path: string, httpClient = _httpClient): any { + return httpClient.delete(getFullPath(path)); +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/index.js similarity index 82% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/index.js index 9d8eeb9b9a808..a82b581309d29 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/services/index.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/index.js @@ -6,4 +6,3 @@ export { filterItems } from './filter_items'; export { sortTable } from './sort_table'; -export { trackUiMetric, getUiMetricsForPhases } from './ui_metric'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/navigation.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/navigation.ts similarity index 51% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/navigation.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/navigation.ts index 177b30dc37e0a..943f9a49d0ab6 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/services/navigation.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/navigation.ts @@ -4,19 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ -let urlService; -import { BASE_PATH } from '../../common/constants'; -export const setUrlService = aUrlService => { - urlService = aUrlService; -}; -export const getUrlService = () => { - return urlService; -}; +import { BASE_PATH } from '../../../../common/constants'; + +// This depends upon Angular, which is why we use this provider pattern to access it within +// our React app. +let _redirect: any; + +export function init(redirect: any) { + _redirect = redirect; +} export const goToPolicyList = () => { - urlService.change(`${BASE_PATH}policies`); + _redirect(`${BASE_PATH}policies`); }; -export const getPolicyPath = policyName => { +export const getPolicyPath = (policyName: string): string => { return encodeURI(`#${BASE_PATH}policies/edit/${encodeURIComponent(policyName)}`); }; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/notification.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/notification.ts new file mode 100644 index 0000000000000..7d24bc31006b4 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/notification.ts @@ -0,0 +1,13 @@ +/* + * 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. + */ + +export let toasts: any; +export let fatalErrors: any; + +export function init(_toasts: any, _fatalErrors: any): void { + toasts = _toasts; + fatalErrors = _fatalErrors; +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/sort_table.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/sort_table.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/sort_table.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/sort_table.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/ui_metric.test.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/ui_metric.test.js similarity index 95% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/ui_metric.test.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/ui_metric.test.js index 85e3365d064f2..99e6bfb99472c 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/services/ui_metric.test.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/ui_metric.test.js @@ -5,16 +5,15 @@ */ import { + PHASE_INDEX_PRIORITY, UIM_CONFIG_COLD_PHASE, UIM_CONFIG_WARM_PHASE, UIM_CONFIG_SET_PRIORITY, UIM_CONFIG_FREEZE_INDEX, -} from '../../common/constants'; +} from '../constants'; import { defaultColdPhase, defaultWarmPhase } from '../store/defaults'; -import { PHASE_INDEX_PRIORITY } from '../constants'; - import { getUiMetricsForPhases } from './ui_metric'; jest.mock('ui/new_platform'); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/ui_metric.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/ui_metric.ts similarity index 76% rename from x-pack/legacy/plugins/index_lifecycle_management/public/services/ui_metric.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/ui_metric.ts index f54924b85ab55..d9f2c26048317 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/services/ui_metric.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/services/ui_metric.ts @@ -5,7 +5,8 @@ */ import { get } from 'lodash'; -import { createUiStatsReporter } from '../../../../../../src/legacy/core_plugins/ui_metric/public'; + +import { createUiStatsReporter } from '../../../../../../../../src/legacy/core_plugins/ui_metric/public'; import { UIM_APP_NAME, @@ -13,15 +14,23 @@ import { UIM_CONFIG_WARM_PHASE, UIM_CONFIG_SET_PRIORITY, UIM_CONFIG_FREEZE_INDEX, -} from '../../common/constants'; - -import { PHASE_HOT, PHASE_WARM, PHASE_COLD, PHASE_INDEX_PRIORITY } from '../constants'; + PHASE_HOT, + PHASE_WARM, + PHASE_COLD, + PHASE_INDEX_PRIORITY, +} from '../constants'; import { defaultColdPhase, defaultWarmPhase, defaultHotPhase } from '../store/defaults'; -export const trackUiMetric = createUiStatsReporter(UIM_APP_NAME); +export let trackUiMetric: ReturnType; + +export function init(getReporter: typeof createUiStatsReporter): void { + if (getReporter) { + trackUiMetric = getReporter(UIM_APP_NAME); + } +} -export function getUiMetricsForPhases(phases) { +export function getUiMetricsForPhases(phases: any): any { const phaseUiMetrics = [ { metric: UIM_CONFIG_COLD_PHASE, @@ -58,7 +67,7 @@ export function getUiMetricsForPhases(phases) { }, ]; - const trackedUiMetrics = phaseUiMetrics.reduce((tracked, { metric, isTracked }) => { + const trackedUiMetrics = phaseUiMetrics.reduce((tracked: any, { metric, isTracked }) => { if (isTracked()) { tracked.push(metric); } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/general.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/general.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/general.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/general.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/lifecycle.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/lifecycle.js similarity index 89% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/lifecycle.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/lifecycle.js index 8379a03b1e68b..0bb6543482bd6 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/lifecycle.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/lifecycle.js @@ -3,14 +3,14 @@ * 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 { toastNotifications } from 'ui/notify'; -import { UIM_POLICY_CREATE, UIM_POLICY_UPDATE } from '../../../common/constants'; +import { i18n } from '@kbn/i18n'; +import { UIM_POLICY_CREATE, UIM_POLICY_UPDATE } from '../../constants'; import { showApiError } from '../../services/api_errors'; +import { toasts } from '../../services/notification'; import { savePolicy as savePolicyApi } from '../../services/api'; -import { trackUiMetric, getUiMetricsForPhases } from '../../services'; +import { trackUiMetric, getUiMetricsForPhases } from '../../services/ui_metric'; export const saveLifecyclePolicy = (lifecycle, isNew) => async () => { try { @@ -41,6 +41,6 @@ export const saveLifecyclePolicy = (lifecycle, isNew) => async () => { lifecycleName: lifecycle.name, }, }); - toastNotifications.addSuccess(message); + toasts.addSuccess(message); return true; }; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/nodes.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/nodes.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/nodes.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/nodes.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/policies.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/policies.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/policies.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/policies.js index c048a315deab7..b6064af6e38b2 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/store/actions/policies.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/actions/policies.js @@ -5,10 +5,12 @@ */ import { i18n } from '@kbn/i18n'; -import { showApiError } from '../../services/api_errors'; import { createAction } from 'redux-actions'; + +import { showApiError } from '../../services/api_errors'; import { loadPolicies } from '../../services/api'; import { SET_PHASE_DATA } from '../../constants'; + export const fetchedPolicies = createAction('FETCHED_POLICIES'); export const setSelectedPolicy = createAction('SET_SELECTED_POLICY'); export const unsetSelectedPolicy = createAction('UNSET_SELECTED_POLICY'); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/cold_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/cold_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/cold_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/cold_phase.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/delete_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/delete_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/delete_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/delete_phase.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/hot_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/hot_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/hot_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/hot_phase.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/index.d.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/index.d.ts new file mode 100644 index 0000000000000..889e038f9e2c4 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/index.d.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export declare const defaultColdPhase: any; +export declare const defaultWarmPhase: any; +export declare const defaultHotPhase: any; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/warm_phase.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/warm_phase.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/defaults/warm_phase.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/defaults/warm_phase.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/index.d.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/index.d.ts new file mode 100644 index 0000000000000..8617a7045a5c3 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/index.d.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export declare const indexLifecycleManagementStore: any; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/general.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/general.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/general.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/general.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/nodes.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/nodes.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/nodes.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/nodes.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/policies.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/policies.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/reducers/policies.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/reducers/policies.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/general.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/general.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/general.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/general.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/index.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/index.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/lifecycle.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/lifecycle.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/lifecycle.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/lifecycle.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/nodes.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/nodes.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/nodes.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/nodes.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/policies.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/policies.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/selectors/policies.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/selectors/policies.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/store/store.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/store.js similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/public/store/store.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/store/store.js diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/add_lifecycle_confirm_modal.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/add_lifecycle_confirm_modal.js similarity index 96% rename from x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/add_lifecycle_confirm_modal.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/add_lifecycle_confirm_modal.js index 940cdf2357993..5b8f2d197daf4 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/add_lifecycle_confirm_modal.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/add_lifecycle_confirm_modal.js @@ -7,6 +7,7 @@ import React, { Component, Fragment } from 'react'; import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import { EuiLink, EuiSelect, @@ -21,11 +22,12 @@ import { EuiSpacer, EuiModalHeaderTitle, } from '@elastic/eui'; -import { BASE_PATH } from '../../../common/constants'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { toastNotifications } from 'ui/notify'; -import { loadPolicies, addLifecyclePolicyToIndex } from '../../services/api'; -import { showApiError } from '../../services/api_errors'; + +import { BASE_PATH } from '../../../../common/constants'; +import { loadPolicies, addLifecyclePolicyToIndex } from '../../application/services/api'; +import { showApiError } from '../../application/services/api_errors'; +import { toasts } from '../../application/services/notification'; + export class AddLifecyclePolicyConfirmModal extends Component { constructor(props) { super(props); @@ -55,7 +57,7 @@ export class AddLifecyclePolicyConfirmModal extends Component { }; await addLifecyclePolicyToIndex(body, httpClient); closeModal(); - toastNotifications.addSuccess( + toasts.addSuccess( i18n.translate( 'xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.addPolicyToIndexSuccess', { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/index_lifecycle_summary.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/index_lifecycle_summary.js similarity index 99% rename from x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/index_lifecycle_summary.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/index_lifecycle_summary.js index d6bbfa3d4d270..7e15e9861dd75 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/index_lifecycle_summary.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/index_lifecycle_summary.js @@ -6,6 +6,8 @@ import React, { Component, Fragment } from 'react'; import moment from 'moment-timezone'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButtonEmpty, EuiCallOut, @@ -21,9 +23,9 @@ import { EuiPopover, EuiPopoverTitle, } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { getPolicyPath } from '../../services/navigation'; + +import { getPolicyPath } from '../../application/services/navigation'; + const getHeaders = () => { return { policy: i18n.translate( diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/remove_lifecycle_confirm_modal.js similarity index 93% rename from x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/remove_lifecycle_confirm_modal.js index 97373f046047c..0ba5ed1720084 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/components/remove_lifecycle_confirm_modal.js @@ -6,12 +6,12 @@ import React, { Component, Fragment } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { toastNotifications } from 'ui/notify'; +import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui'; -import { removeLifecycleForIndex } from '../../services/api'; -import { showApiError } from '../../services/api_errors'; +import { removeLifecycleForIndex } from '../../application/services/api'; +import { showApiError } from '../../application/services/api_errors'; +import { toasts } from '../../application/services/notification'; export class RemoveLifecyclePolicyConfirmModal extends Component { constructor(props) { @@ -29,7 +29,7 @@ export class RemoveLifecyclePolicyConfirmModal extends Component { try { await removeLifecycleForIndex(indexNames, httpClient); closeModal(); - toastNotifications.addSuccess( + toasts.addSuccess( i18n.translate( 'xpack.indexLifecycleMgmt.indexManagementTable.removeLifecyclePolicyConfirmModal.removePolicySuccess', { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.d.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.d.ts new file mode 100644 index 0000000000000..086ba67703122 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.d.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export declare const addAllExtensions: any; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.js similarity index 76% rename from x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.js index b6e7d92f4251d..422a7986aa057 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/extend_index_management/index.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.js @@ -3,23 +3,39 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import React from 'react'; -import { IndexLifecycleSummary } from './components/index_lifecycle_summary'; -import { AddLifecyclePolicyConfirmModal } from './components/add_lifecycle_confirm_modal'; -import { RemoveLifecyclePolicyConfirmModal } from './components/remove_lifecycle_confirm_modal'; import { get, every, any } from 'lodash'; import { i18n } from '@kbn/i18n'; +import { EuiSearchBar } from '@elastic/eui'; + import { addSummaryExtension, addBannerExtension, addActionExtension, addFilterExtension, -} from '../../../index_management/public/index_management_extensions'; -import { retryLifecycleForIndex } from '../services/api'; -import { EuiSearchBar } from '@elastic/eui'; +} from '../../../../index_management/public/index_management_extensions'; + +import { init as initUiMetric } from '../application/services/ui_metric'; +import { init as initNotification } from '../application/services/notification'; +import { retryLifecycleForIndex } from '../application/services/api'; +import { IndexLifecycleSummary } from './components/index_lifecycle_summary'; +import { AddLifecyclePolicyConfirmModal } from './components/add_lifecycle_confirm_modal'; +import { RemoveLifecyclePolicyConfirmModal } from './components/remove_lifecycle_confirm_modal'; const stepPath = 'ilm.step'; -export const retryLifecycleActionExtension = indices => { + +export const retryLifecycleActionExtension = ({ + indices, + createUiStatsReporter, + toasts, + fatalErrors, +}) => { + // These are hacks that we can remove once the New Platform migration is done. They're needed here + // because API requests and API errors require them. + initUiMetric(createUiStatsReporter); + initNotification(toasts, fatalErrors); + const allHaveErrors = every(indices, index => { return index.ilm && index.ilm.failed_step; }); @@ -44,7 +60,19 @@ export const retryLifecycleActionExtension = indices => { }; }; -export const removeLifecyclePolicyActionExtension = (indices, reloadIndices) => { +export const removeLifecyclePolicyActionExtension = ({ + indices, + reloadIndices, + createUiStatsReporter, + toasts, + fatalErrors, + httpClient, +}) => { + // These are hacks that we can remove once the New Platform migration is done. They're needed here + // because API requests and API errors require them. + initUiMetric(createUiStatsReporter); + initNotification(toasts, fatalErrors); + const allHaveIlm = every(indices, index => { return index.ilm && index.ilm.managed; }); @@ -53,12 +81,13 @@ export const removeLifecyclePolicyActionExtension = (indices, reloadIndices) => } const indexNames = indices.map(({ name }) => name); return { - renderConfirmModal: (closeModal, httpClient) => { + renderConfirmModal: closeModal => { return ( ); @@ -71,7 +100,19 @@ export const removeLifecyclePolicyActionExtension = (indices, reloadIndices) => }; }; -export const addLifecyclePolicyActionExtension = (indices, reloadIndices) => { +export const addLifecyclePolicyActionExtension = ({ + indices, + reloadIndices, + createUiStatsReporter, + toasts, + fatalErrors, + httpClient, +}) => { + // These are hacks that we can remove once the New Platform migration is done. They're needed here + // because API requests and API errors require them. + initUiMetric(createUiStatsReporter); + initNotification(toasts, fatalErrors); + if (indices.length !== 1) { return null; } @@ -83,12 +124,13 @@ export const addLifecyclePolicyActionExtension = (indices, reloadIndices) => { } const indexName = index.name; return { - renderConfirmModal: (closeModal, httpClient) => { + renderConfirmModal: closeModal => { return ( diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/index.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/index.ts new file mode 100644 index 0000000000000..1af0b697a9283 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/index.ts @@ -0,0 +1,10 @@ +/* + * 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 { PluginInitializerContext } from 'src/core/public'; +import { IndexLifecycleManagementPlugin } from './plugin'; + +export const createPlugin = (ctx: PluginInitializerContext) => new IndexLifecycleManagementPlugin(); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/plugin.tsx b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/plugin.tsx new file mode 100644 index 0000000000000..e2897f09fa892 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/plugin.tsx @@ -0,0 +1,58 @@ +/* + * 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, CoreStart, Plugin } from 'src/core/public'; +import { PLUGIN } from '../../common/constants'; +import { LegacySetup } from './application'; + +interface PluginsSetup { + __LEGACY: LegacySetup; +} + +export class IndexLifecycleManagementPlugin implements Plugin { + setup(core: CoreSetup, plugins: PluginsSetup) { + // Extract individual core dependencies. + const { + application, + notifications: { toasts }, + fatalErrors, + http, + } = core; + + // The Plugin interface won't allow us to pass __LEGACY as a third argument, so we'll just + // sneak it inside of the plugins parameter for now. + const { __LEGACY } = plugins; + + application.register({ + id: PLUGIN.ID, + title: PLUGIN.TITLE, + async mount(config, mountPoint) { + const { + core: { + docLinks, + i18n: { Context: I18nContext }, + }, + } = config; + + const { element } = mountPoint; + const { renderApp } = await import('./application'); + + // Inject all dependencies into our app. + return renderApp({ + legacy: { ...__LEGACY }, + I18nContext, + http, + toasts, + fatalErrors, + docLinks, + element, + }); + }, + }); + } + start(core: CoreStart, plugins: any) {} + stop() {} +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/register_management_section.js b/x-pack/legacy/plugins/index_lifecycle_management/public/register_management_section.js deleted file mode 100644 index aeb2f04220444..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/register_management_section.js +++ /dev/null @@ -1,20 +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 chrome from 'ui/chrome'; -import { management } from 'ui/management'; -import { i18n } from '@kbn/i18n'; -import { BASE_PATH } from '../common/constants'; -const esSection = management.getSection('elasticsearch'); -if (chrome.getInjected('ilmUiEnabled')) { - esSection.register('index_lifecycle_policies', { - visible: true, - display: i18n.translate('xpack.indexLifecycleMgmt.appTitle', { - defaultMessage: 'Index Lifecycle Policies', - }), - order: 2, - url: `#${BASE_PATH}policies`, - }); -} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/register_routes.js b/x-pack/legacy/plugins/index_lifecycle_management/public/register_routes.js deleted file mode 100644 index ae28b72c4d5ea..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/register_routes.js +++ /dev/null @@ -1,57 +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 React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import { Provider } from 'react-redux'; -import { setHttpClient } from './services/api'; -import chrome from 'ui/chrome'; -import { App } from './app'; -import { BASE_PATH } from '../common/constants'; -import { indexLifecycleManagementStore } from './store'; -import { I18nContext } from 'ui/i18n'; -import { setUrlService } from './services/navigation'; - -import routes from 'ui/routes'; - -import template from './main.html'; -import { manageAngularLifecycle } from './services/manage_angular_lifecycle'; -let elem; -const renderReact = async elem => { - render( - - - - - , - elem - ); -}; -if (chrome.getInjected('ilmUiEnabled')) { - routes.when(`${BASE_PATH}:view?/:action?/:id?`, { - template: template, - controllerAs: 'indexLifecycleManagement', - controller: class IndexLifecycleManagementController { - constructor($scope, $route, $http, kbnUrl, $rootScope) { - // clean up previously rendered React app if one exists - // this happens because of React Router redirects - elem && unmountComponentAtNode(elem); - setHttpClient($http); - setUrlService({ - change(url) { - kbnUrl.change(url); - $rootScope.$digest(); - }, - }); - $scope.$$postDigest(() => { - elem = document.getElementById('indexLifecycleManagementReactRoot'); - renderReact(elem); - manageAngularLifecycle($scope, $route, elem); - }); - } - }, - }); -} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/api.js b/x-pack/legacy/plugins/index_lifecycle_management/public/services/api.js deleted file mode 100644 index 758402a115c68..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/services/api.js +++ /dev/null @@ -1,95 +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 chrome from 'ui/chrome'; -import { - UIM_POLICY_DELETE, - UIM_POLICY_ATTACH_INDEX, - UIM_POLICY_ATTACH_INDEX_TEMPLATE, - UIM_POLICY_DETACH_INDEX, - UIM_INDEX_RETRY_STEP, -} from '../../common/constants'; -import { trackUiMetric } from './ui_metric'; - -let httpClient; -export const setHttpClient = client => { - httpClient = client; -}; -export const getHttpClient = () => { - return httpClient; -}; -const apiPrefix = chrome.addBasePath('/api/index_lifecycle_management'); - -export async function loadNodes(httpClient = getHttpClient()) { - const response = await httpClient.get(`${apiPrefix}/nodes/list`); - return response.data; -} - -export async function loadNodeDetails(selectedNodeAttrs, httpClient = getHttpClient()) { - const response = await httpClient.get(`${apiPrefix}/nodes/${selectedNodeAttrs}/details`); - return response.data; -} - -export async function loadIndexTemplates(httpClient = getHttpClient()) { - const response = await httpClient.get(`${apiPrefix}/templates`); - return response.data; -} - -export async function loadIndexTemplate(templateName, httpClient = getHttpClient()) { - if (!templateName) { - return {}; - } - const response = await httpClient.get(`${apiPrefix}/templates/${templateName}`); - return response.data; -} - -export async function loadPolicies(withIndices, httpClient = getHttpClient()) { - const response = await httpClient.get( - `${apiPrefix}/policies${withIndices ? '?withIndices=true' : ''}` - ); - return response.data; -} - -export async function savePolicy(policy, httpClient = getHttpClient()) { - const response = await httpClient.post(`${apiPrefix}/policies`, policy); - return response.data; -} - -export async function deletePolicy(policyName, httpClient = getHttpClient()) { - const response = await httpClient.delete( - `${apiPrefix}/policies/${encodeURIComponent(policyName)}` - ); - // Only track successful actions. - trackUiMetric('count', UIM_POLICY_DELETE); - return response.data; -} - -export const retryLifecycleForIndex = async (indexNames, httpClient = getHttpClient()) => { - const response = await httpClient.post(`${apiPrefix}/index/retry`, { indexNames }); - // Only track successful actions. - trackUiMetric('count', UIM_INDEX_RETRY_STEP); - return response.data; -}; - -export const removeLifecycleForIndex = async (indexNames, httpClient = getHttpClient()) => { - const response = await httpClient.post(`${apiPrefix}/index/remove`, { indexNames }); - // Only track successful actions. - trackUiMetric('count', UIM_POLICY_DETACH_INDEX); - return response.data; -}; - -export const addLifecyclePolicyToIndex = async (body, httpClient = getHttpClient()) => { - const response = await httpClient.post(`${apiPrefix}/index/add`, body); - // Only track successful actions. - trackUiMetric('count', UIM_POLICY_ATTACH_INDEX); - return response.data; -}; - -export const addLifecyclePolicyToTemplate = async (body, httpClient = getHttpClient()) => { - const response = await httpClient.post(`${apiPrefix}/template`, body); - // Only track successful actions. - trackUiMetric('count', UIM_POLICY_ATTACH_INDEX_TEMPLATE); - return response.data; -}; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/services/manage_angular_lifecycle.js b/x-pack/legacy/plugins/index_lifecycle_management/public/services/manage_angular_lifecycle.js deleted file mode 100644 index 3813e632a0a73..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/services/manage_angular_lifecycle.js +++ /dev/null @@ -1,23 +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 { unmountComponentAtNode } from 'react-dom'; - -export const manageAngularLifecycle = ($scope, $route, elem) => { - const lastRoute = $route.current; - - const deregister = $scope.$on('$locationChangeSuccess', () => { - const currentRoute = $route.current; - if (lastRoute.$$route.template === currentRoute.$$route.template) { - $route.current = lastRoute; - } - }); - - $scope.$on('$destroy', () => { - deregister && deregister(); - elem && unmountComponentAtNode(elem); - }); -}; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/call_with_request_factory.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/call_with_request_factory.ts similarity index 68% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/call_with_request_factory.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/call_with_request_factory.ts index 7359a831994f9..1b28dc4fde4f7 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/call_with_request_factory.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/call_with_request_factory.ts @@ -5,14 +5,15 @@ */ import { once } from 'lodash'; +import { Legacy } from 'kibana'; -const callWithRequest = once(server => { +const callWithRequest = once((server: Legacy.Server): any => { const cluster = server.plugins.elasticsearch.getCluster('data'); return cluster.callWithRequest; }); -export const callWithRequestFactory = (server, request) => { - return (...args) => { +export const callWithRequestFactory = (server: Legacy.Server, request: any) => { + return (...args: any[]) => { return callWithRequest(server)(request, ...args); }; }; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/call_with_request_factory/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/check_license.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/check_license.ts similarity index 97% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/check_license.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/check_license.ts index 7534f3cd0934e..b35ab14964d55 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/check_license.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/check_license.ts @@ -3,8 +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 { i18n } from '@kbn/i18n'; -export function checkLicense(xpackLicenseInfo) { + +export function checkLicense(xpackLicenseInfo: any): any { const pluginName = 'Index Lifecycle Policies'; // If, for some reason, we cannot get the license information diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/check_license/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_custom_error.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_custom_error.ts similarity index 88% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_custom_error.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_custom_error.ts index 3295113d38ee5..c5780e7c83fb5 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_custom_error.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_custom_error.ts @@ -13,6 +13,6 @@ import Boom from 'boom'; * @param statusCode Error status code * @return Object Boom error response */ -export function wrapCustomError(err, statusCode) { +export function wrapCustomError(err: any, statusCode: any): any { return Boom.boomify(err, { statusCode }); } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_es_error.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_es_error.ts similarity index 92% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_es_error.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_es_error.ts index 183a7ff25cb9a..6980a5afa5eac 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_es_error.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_es_error.ts @@ -13,7 +13,7 @@ import Boom from 'boom'; * @param statusCodeToMessageMap Object Optional map of HTTP status codes => error messages * @return Object Boom error response */ -export function wrapEsError(err, statusCodeToMessageMap = {}) { +export function wrapEsError(err: any, statusCodeToMessageMap: any = {}): any { const statusCode = err.statusCode; // If no custom message if specified for the error's status code, just diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_unknown_error.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_unknown_error.ts similarity index 90% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_unknown_error.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_unknown_error.ts index ffd915c513362..ede1baec286f3 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_unknown_error.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/error_wrappers/wrap_unknown_error.ts @@ -12,6 +12,6 @@ import Boom from 'boom'; * @param err Object Unknown error * @return Object Boom error response */ -export function wrapUnknownError(err) { +export function wrapUnknownError(err: any): any { return Boom.boomify(err); } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/index.ts b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/index.ts new file mode 100644 index 0000000000000..a9a3c61472d8c --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { isEsError } from './is_es_error'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/is_es_error.ts b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/is_es_error.ts new file mode 100644 index 0000000000000..2f514b93e5016 --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error/is_es_error.ts @@ -0,0 +1,13 @@ +/* + * 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 * as legacyElasticsearch from 'elasticsearch'; + +const esErrorsParent = legacyElasticsearch.errors._Abstract; + +export function isEsError(err: Error): boolean { + return err instanceof esErrorsParent; +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js deleted file mode 100644 index 5f2141cce9395..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js +++ /dev/null @@ -1,44 +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 expect from '@kbn/expect'; -import { isEsErrorFactory } from '../is_es_error_factory'; -import { set } from 'lodash'; - -class MockAbstractEsError {} - -describe('is_es_error_factory', () => { - let mockServer; - let isEsError; - - beforeEach(() => { - const mockEsErrors = { - _Abstract: MockAbstractEsError, - }; - mockServer = {}; - set(mockServer, 'plugins.elasticsearch.getCluster', () => ({ errors: mockEsErrors })); - - isEsError = isEsErrorFactory(mockServer); - }); - - describe('#isEsErrorFactory', () => { - it('should return a function', () => { - expect(isEsError).to.be.a(Function); - }); - - describe('returned function', () => { - it('should return true if passed-in err is a known esError', () => { - const knownEsError = new MockAbstractEsError(); - expect(isEsError(knownEsError)).to.be(true); - }); - - it('should return false if passed-in err is not a known esError', () => { - const unknownEsError = {}; - expect(isEsError(unknownEsError)).to.be(false); - }); - }); - }); -}); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/is_es_error_factory.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/is_es_error_factory.js deleted file mode 100644 index 6c17554385ef8..0000000000000 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/is_es_error_factory/is_es_error_factory.js +++ /dev/null @@ -1,18 +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 { memoize } from 'lodash'; - -const esErrorsFactory = memoize(server => { - return server.plugins.elasticsearch.getCluster('admin').errors; -}); - -export function isEsErrorFactory(server) { - const esErrors = esErrorsFactory(server); - return function isEsError(err) { - return err instanceof esErrors._Abstract; - }; -} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/license_pre_routing_factory.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts similarity index 79% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/license_pre_routing_factory.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts index 8c1a080484a30..e348125967c14 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/license_pre_routing_factory.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts @@ -5,15 +5,17 @@ */ import { once } from 'lodash'; +import { Legacy } from 'kibana'; + +import { PLUGIN } from '../../../common/constants'; import { wrapCustomError } from '../error_wrappers'; -import { PLUGIN_ID } from '../../../common/constants'; -export const licensePreRoutingFactory = once(server => { +export const licensePreRoutingFactory = once((server: Legacy.Server) => { const xpackMainPlugin = server.plugins.xpack_main; // License checking and enable/disable logic function licensePreRouting() { - const licenseCheckResults = xpackMainPlugin.info.feature(PLUGIN_ID).getLicenseCheckResults(); + const licenseCheckResults = xpackMainPlugin.info.feature(PLUGIN.ID).getLicenseCheckResults(); if (!licenseCheckResults.isAvailable) { const error = new Error(licenseCheckResults.message); const statusCode = 403; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/register_license_checker.js b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/register_license_checker.ts similarity index 64% rename from x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/register_license_checker.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/register_license_checker.ts index 260fc15c7a83f..8e3b89fa20e33 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/register_license_checker.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/lib/register_license_checker/register_license_checker.ts @@ -4,18 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Legacy } from 'kibana'; +// @ts-ignore import { mirrorPluginStatus } from '../../../../../server/lib/mirror_plugin_status'; +import { PLUGIN } from '../../../common/constants'; import { checkLicense } from '../check_license'; -import { PLUGIN_ID } from '../../../common/constants'; -export function registerLicenseChecker(server) { - const xpackMainPlugin = server.plugins.xpack_main; - const ilmPlugin = server.plugins.index_lifecycle_management; +export function registerLicenseChecker(server: Legacy.Server) { + const xpackMainPlugin = server.plugins.xpack_main as any; + const ilmPlugin = (server.plugins as any).index_lifecycle_management; mirrorPluginStatus(xpackMainPlugin, ilmPlugin); xpackMainPlugin.status.once('green', () => { // Register a function that is called whenever the xpack info changes, // to re-compute the license check results for this plugin - xpackMainPlugin.info.feature(PLUGIN_ID).registerLicenseCheckResultsGenerator(checkLicense); + xpackMainPlugin.info.feature(PLUGIN.ID).registerLicenseCheckResultsGenerator(checkLicense); }); } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts similarity index 79% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts index 632864b3d9767..c3e235220931c 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts @@ -5,11 +5,16 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -async function addLifecyclePolicy(callWithRequest, indexName, policyName, alias) { +async function addLifecyclePolicy( + callWithRequest: any, + indexName: string, + policyName: string, + alias: string +) { const body = { lifecycle: { name: policyName, @@ -26,16 +31,15 @@ async function addLifecyclePolicy(callWithRequest, indexName, policyName, alias) return callWithRequest('transport.request', params); } -export function registerAddPolicyRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerAddPolicyRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/index/add', method: 'POST', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); - const { indexName, policyName, alias } = request.payload; + const { indexName, policyName, alias } = request.payload as any; try { const response = await addLifecyclePolicy(callWithRequest, indexName, policyName, alias); return response; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_index_routes.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_index_routes.ts similarity index 91% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_index_routes.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_index_routes.ts index ac8d024a51b03..74eb1a86a93ba 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_index_routes.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_index_routes.ts @@ -8,7 +8,7 @@ import { registerRetryRoute } from './register_retry_route'; import { registerRemoveRoute } from './register_remove_route'; import { registerAddPolicyRoute } from './register_add_policy_route'; -export function registerIndexRoutes(server) { +export function registerIndexRoutes(server: any) { registerRetryRoute(server); registerRemoveRoute(server); registerAddPolicyRoute(server); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts similarity index 84% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts index df056064ebc1f..ed3b5a97a3b42 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts @@ -5,11 +5,11 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -async function removeLifecycle(callWithRequest, indexNames) { +async function removeLifecycle(callWithRequest: any, indexNames: string[]) { const responses = []; for (let i = 0; i < indexNames.length; i++) { const indexName = indexNames[i]; @@ -24,14 +24,13 @@ async function removeLifecycle(callWithRequest, indexNames) { return Promise.all(responses); } -export function registerRemoveRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerRemoveRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/index/remove', method: 'POST', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts similarity index 84% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts index 4e3bd42dcbe6a..89278edbecea2 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts @@ -5,11 +5,11 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -async function retryLifecycle(callWithRequest, indexNames) { +async function retryLifecycle(callWithRequest: any, indexNames: string[]) { const responses = []; for (let i = 0; i < indexNames.length; i++) { const indexName = indexNames[i]; @@ -24,14 +24,13 @@ async function retryLifecycle(callWithRequest, indexNames) { return Promise.all(responses); } -export function registerRetryRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerRetryRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/index/retry', method: 'POST', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/constants.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/constants.ts similarity index 86% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/constants.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/constants.ts index 2e2b84a76002e..7a85c5e7c02d4 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/constants.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/constants.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export const NODE_ATTRS_KEYS_TO_IGNORE = [ +export const NODE_ATTRS_KEYS_TO_IGNORE: string[] = [ 'ml.enabled', 'ml.machine_memory', 'ml.max_open_jobs', diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts similarity index 75% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts index 6c4e5b58da757..c2c3f8bf07028 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts @@ -5,18 +5,18 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -function findMatchingNodes(stats, nodeAttrs) { - return Object.entries(stats.nodes).reduce((accum, [nodeId, stats]) => { - const attributes = stats.attributes || {}; +function findMatchingNodes(stats: any, nodeAttrs: string): any { + return Object.entries(stats.nodes).reduce((accum: any[], [nodeId, nodeStats]: [any, any]) => { + const attributes = nodeStats.attributes || {}; for (const [key, value] of Object.entries(attributes)) { if (`${key}:${value}` === nodeAttrs) { accum.push({ nodeId, - stats, + stats: nodeStats, }); break; } @@ -25,7 +25,7 @@ function findMatchingNodes(stats, nodeAttrs) { }, []); } -async function fetchNodeStats(callWithRequest) { +async function fetchNodeStats(callWithRequest: any): Promise { const params = { format: 'json', }; @@ -33,14 +33,13 @@ async function fetchNodeStats(callWithRequest) { return await callWithRequest('nodes.stats', params); } -export function registerDetailsRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerDetailsRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/nodes/{nodeAttrs}/details', method: 'GET', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts similarity index 80% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts index d12b5454c1442..edbe4289ed83c 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts @@ -5,14 +5,14 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; import { NODE_ATTRS_KEYS_TO_IGNORE } from './constants'; -function convertStatsIntoList(stats, attributesToBeFiltered) { - return Object.entries(stats.nodes).reduce((accum, [nodeId, stats]) => { - const attributes = stats.attributes || {}; +function convertStatsIntoList(stats: any, attributesToBeFiltered: string[]): any { + return Object.entries(stats.nodes).reduce((accum: any, [nodeId, nodeStats]: [any, any]) => { + const attributes = nodeStats.attributes || {}; for (const [key, value] of Object.entries(attributes)) { if (!attributesToBeFiltered.includes(key)) { const attributeString = `${key}:${value}`; @@ -24,7 +24,7 @@ function convertStatsIntoList(stats, attributesToBeFiltered) { }, {}); } -async function fetchNodeStats(callWithRequest) { +async function fetchNodeStats(callWithRequest: any): Promise { const params = { format: 'json', }; @@ -32,17 +32,16 @@ async function fetchNodeStats(callWithRequest) { return await callWithRequest('nodes.stats', params); } -export function registerListRoute(server) { +export function registerListRoute(server: any) { const config = server.config(); const filteredNodeAttributes = config.get('xpack.ilm.filteredNodeAttributes'); const attributesToBeFiltered = [...NODE_ATTRS_KEYS_TO_IGNORE, ...filteredNodeAttributes]; - const isEsError = isEsErrorFactory(server); const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/nodes/list', method: 'GET', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_nodes_routes.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_nodes_routes.ts similarity index 89% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_nodes_routes.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_nodes_routes.ts index 341f1d4f1ebf3..4486d97038657 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_nodes_routes.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/nodes/register_nodes_routes.ts @@ -7,7 +7,7 @@ import { registerListRoute } from './register_list_route'; import { registerDetailsRoute } from './register_details_route'; -export function registerNodesRoutes(server) { +export function registerNodesRoutes(server: any) { registerListRoute(server); registerDetailsRoute(server); } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts similarity index 84% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts index d1716472029d5..f6bc96dd498a4 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts @@ -5,11 +5,11 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -async function createPolicy(callWithRequest, policy) { +async function createPolicy(callWithRequest: any, policy: any): Promise { const body = { policy: { phases: policy.phases, @@ -25,14 +25,13 @@ async function createPolicy(callWithRequest, policy) { return await callWithRequest('transport.request', params); } -export function registerCreateRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerCreateRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/policies', method: 'POST', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts similarity index 83% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts index ea8d7ae7e0436..c84f2efd92d8f 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts @@ -5,11 +5,11 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -async function deletePolicies(policyNames, callWithRequest) { +async function deletePolicies(policyNames: string, callWithRequest: any): Promise { const params = { method: 'DELETE', path: `/_ilm/policy/${encodeURIComponent(policyNames)}`, @@ -20,14 +20,13 @@ async function deletePolicies(policyNames, callWithRequest) { return await callWithRequest('transport.request', params); } -export function registerDeleteRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerDeleteRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/policies/{policyNames}', method: 'DELETE', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); const { policyNames } = request.params; try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts similarity index 79% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts index df2053ed2f8c4..c65f849a47d87 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts @@ -5,15 +5,16 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -function formatPolicies(policiesMap) { +function formatPolicies(policiesMap: any): any { if (policiesMap.status === 404) { return []; } - return Object.keys(policiesMap).reduce((accum, lifecycleName) => { + + return Object.keys(policiesMap).reduce((accum: any[], lifecycleName: string) => { const policyEntry = policiesMap[lifecycleName]; accum.push({ ...policyEntry, @@ -23,7 +24,7 @@ function formatPolicies(policiesMap) { }, []); } -async function fetchPolicies(callWithRequest) { +async function fetchPolicies(callWithRequest: any): Promise { const params = { method: 'GET', path: '/_ilm/policy', @@ -33,7 +34,7 @@ async function fetchPolicies(callWithRequest) { return await callWithRequest('transport.request', params); } -async function addLinkedIndices(policiesMap, callWithRequest) { +async function addLinkedIndices(policiesMap: any, callWithRequest: any) { if (policiesMap.status === 404) { return policiesMap; } @@ -44,8 +45,8 @@ async function addLinkedIndices(policiesMap, callWithRequest) { ignore: [404], }; - const policyExplanation = await callWithRequest('transport.request', params); - Object.entries(policyExplanation.indices).forEach(([indexName, { policy }]) => { + const policyExplanation: any = await callWithRequest('transport.request', params); + Object.entries(policyExplanation.indices).forEach(([indexName, { policy }]: [string, any]) => { if (policy && policiesMap[policy]) { policiesMap[policy].linkedIndices = policiesMap[policy].linkedIndices || []; policiesMap[policy].linkedIndices.push(indexName); @@ -53,14 +54,13 @@ async function addLinkedIndices(policiesMap, callWithRequest) { }); } -export function registerFetchRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerFetchRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/policies', method: 'GET', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); const { withIndices } = request.query; try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_policies_routes.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_policies_routes.ts similarity index 90% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_policies_routes.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_policies_routes.ts index bcb5971a1c34f..279b016da178f 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_policies_routes.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/policies/register_policies_routes.ts @@ -8,7 +8,7 @@ import { registerFetchRoute } from './register_fetch_route'; import { registerCreateRoute } from './register_create_route'; import { registerDeleteRoute } from './register_delete_route'; -export function registerPoliciesRoutes(server) { +export function registerPoliciesRoutes(server: any) { registerFetchRoute(server); registerCreateRoute(server); registerDeleteRoute(server); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/index.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/index.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/index.ts diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts similarity index 83% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts index e21f4615aaeb9..57e5a91f60f5b 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts @@ -4,18 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import { merge } from 'lodash'; + import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -import { merge } from 'lodash'; -async function getIndexTemplate(callWithRequest, templateName) { +async function getIndexTemplate(callWithRequest: any, templateName: string): Promise { const response = await callWithRequest('indices.getTemplate', { name: templateName }); return response[templateName]; } -async function updateIndexTemplate(callWithRequest, indexTemplatePatch) { +async function updateIndexTemplate(callWithRequest: any, indexTemplatePatch: any): Promise { // Fetch existing template const template = await getIndexTemplate(callWithRequest, indexTemplatePatch.templateName); merge(template, { @@ -39,14 +40,13 @@ async function updateIndexTemplate(callWithRequest, indexTemplatePatch) { return await callWithRequest('transport.request', params); } -export function registerAddPolicyRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerAddPolicyRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/template', method: 'POST', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts similarity index 87% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts index c27bf393526e8..fd58f471d69bb 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts @@ -5,7 +5,7 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; @@ -17,7 +17,7 @@ import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_facto * @param {String} templateName The index template * @param {Array} indexPatterns Index patterns */ -function isReservedSystemTemplate(templateName, indexPatterns) { +function isReservedSystemTemplate(templateName: string, indexPatterns: string[]): boolean { return ( templateName.startsWith('kibana_index_template') || (templateName.startsWith('.') && @@ -27,7 +27,7 @@ function isReservedSystemTemplate(templateName, indexPatterns) { ); } -function filterAndFormatTemplates(templates) { +function filterAndFormatTemplates(templates: any): any { const formattedTemplates = []; const templateNames = Object.keys(templates); for (const templateName of templateNames) { @@ -49,7 +49,7 @@ function filterAndFormatTemplates(templates) { return formattedTemplates; } -async function fetchTemplates(callWithRequest) { +async function fetchTemplates(callWithRequest: any): Promise { const params = { method: 'GET', path: '/_template', @@ -59,14 +59,13 @@ async function fetchTemplates(callWithRequest) { return await callWithRequest('transport.request', params); } -export function registerFetchRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerFetchRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/templates', method: 'GET', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); try { diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.ts similarity index 84% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.ts index 102ffb12a698d..3edaea6e15818 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_get_route.ts @@ -5,11 +5,11 @@ */ import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { isEsError } from '../../../lib/is_es_error'; import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers'; import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory'; -async function fetchTemplate(callWithRequest, templateName) { +async function fetchTemplate(callWithRequest: any, templateName: string): Promise { const params = { method: 'GET', path: `/_template/${encodeURIComponent(templateName)}`, @@ -20,14 +20,13 @@ async function fetchTemplate(callWithRequest, templateName) { return await callWithRequest('transport.request', params); } -export function registerGetRoute(server) { - const isEsError = isEsErrorFactory(server); +export function registerGetRoute(server: any) { const licensePreRouting = licensePreRoutingFactory(server); server.route({ path: '/api/index_lifecycle_management/templates/{templateName}', method: 'GET', - handler: async request => { + handler: async (request: any) => { const callWithRequest = callWithRequestFactory(server, request); const templateName = request.params.templateName; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_templates_routes.js b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_templates_routes.ts similarity index 90% rename from x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_templates_routes.js rename to x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_templates_routes.ts index f70590a0d99ca..424b2d36b1ba2 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_templates_routes.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/server/routes/api/templates/register_templates_routes.ts @@ -8,7 +8,7 @@ import { registerFetchRoute } from './register_fetch_route'; import { registerGetRoute } from './register_get_route'; import { registerAddPolicyRoute } from './register_add_policy_route'; -export function registerTemplatesRoutes(server) { +export function registerTemplatesRoutes(server: any) { registerFetchRoute(server); registerGetRoute(server); registerAddPolicyRoute(server); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/shim.ts b/x-pack/legacy/plugins/index_lifecycle_management/shim.ts new file mode 100644 index 0000000000000..18b3d9ef28b6a --- /dev/null +++ b/x-pack/legacy/plugins/index_lifecycle_management/shim.ts @@ -0,0 +1,17 @@ +/* + * 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 { Legacy } from 'kibana'; + +export interface LegacySetup { + server: Legacy.Server; +} + +export function createShim(server: Legacy.Server): LegacySetup { + return { + server, + }; +} diff --git a/x-pack/legacy/plugins/index_management/public/app/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js b/x-pack/legacy/plugins/index_management/public/app/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js index ea1fcdc51fc4d..5ed651e3125cf 100644 --- a/x-pack/legacy/plugins/index_management/public/app/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js +++ b/x-pack/legacy/plugins/index_management/public/app/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js @@ -22,10 +22,22 @@ import { EuiOverlayMask, EuiCheckbox, } from '@elastic/eui'; + +// We will be able to remove these after the NP migration is complete. +import { fatalError } from 'ui/notify'; +import { createUiStatsReporter } from '../../../../../../../../../../src/legacy/core_plugins/ui_metric/public'; +import { httpService } from '../../../../services/http'; +import { notificationService } from '../../../../services/notification'; + import { flattenPanelTree } from '../../../../lib/flatten_panel_tree'; import { INDEX_OPEN } from '../../../../../../common/constants'; import { getActionExtensions } from '../../../../../index_management_extensions'; -import { getHttpClient } from '../../../../services/api'; + +// We will be able to remove this after the NP migration is complete and we can just inject the +// NP fatalErrors service.. +const getNewPlatformCompatibleFatalErrorService = () => ({ + add: fatalError.bind(fatalError), +}); export class IndexActionsContextMenu extends Component { constructor(props) { @@ -211,7 +223,20 @@ export class IndexActionsContextMenu extends Component { }, }); getActionExtensions().forEach(actionExtension => { - const actionExtensionDefinition = actionExtension(indices, reloadIndices); + const actionExtensionDefinition = actionExtension({ + indices, + reloadIndices, + // These config options can be removed once the NP migration out of legacy is complete. + // They're needed for now because ILM's extensions make API calls which require these + // dependencies, but they're not available unless the app's "setup" lifecycle stage occurs. + // Within the old platform, "setup" only occurs once the user actually visits the app. + // Once ILM and IM have been moved out of legacy this hack won't be necessary. + createUiStatsReporter, + toasts: notificationService.toasts, + fatalErrors: getNewPlatformCompatibleFatalErrorService(), + httpClient: httpService.httpClient, + }); + if (actionExtensionDefinition) { const { buttonLabel, @@ -727,7 +752,7 @@ export class IndexActionsContextMenu extends Component { return (
{this.state.renderConfirmModal - ? this.state.renderConfirmModal(this.closeConfirmModal, getHttpClient()) + ? this.state.renderConfirmModal(this.closeConfirmModal) : null} { - httpClient = client; -}; - -export const getHttpClient = () => { - return httpClient; -}; - export async function loadIndices() { const response = await httpService.httpClient.get(`${API_BASE_PATH}/indices`); return response.data ? response.data : response; diff --git a/x-pack/legacy/plugins/index_management/public/app/services/notification.ts b/x-pack/legacy/plugins/index_management/public/app/services/notification.ts index 2e63253ccae67..85558a7023491 100644 --- a/x-pack/legacy/plugins/index_management/public/app/services/notification.ts +++ b/x-pack/legacy/plugins/index_management/public/app/services/notification.ts @@ -7,14 +7,18 @@ import { NotificationsStart } from '../../../../../../../src/core/public'; class NotificationService { - private toasts: any; + private _toasts: any; public init(notifications: NotificationsStart): void { - this.toasts = notifications.toasts; + this._toasts = notifications.toasts; + } + + public get toasts() { + return this._toasts; } private addToasts = (title: string, type: 'danger' | 'warning' | 'success', text?: string) => { - this.toasts.add({ + this._toasts.add({ title, color: type, text, diff --git a/x-pack/legacy/plugins/index_management/public/app/store/actions/extension_action.js b/x-pack/legacy/plugins/index_management/public/app/store/actions/extension_action.js index dc2d2e346f803..277a71999492f 100644 --- a/x-pack/legacy/plugins/index_management/public/app/store/actions/extension_action.js +++ b/x-pack/legacy/plugins/index_management/public/app/store/actions/extension_action.js @@ -6,7 +6,7 @@ import { reloadIndices } from '../actions'; import { notificationService } from '../../services/notification'; -import { getHttpClient } from '../../services/api'; +import { httpService } from '../../services/http'; export const performExtensionAction = ({ requestMethod, @@ -14,7 +14,7 @@ export const performExtensionAction = ({ successMessage, }) => async dispatch => { try { - await requestMethod(indexNames, getHttpClient()); + await requestMethod(indexNames, httpService.httpClient); } catch (error) { notificationService.showDangerToast(error.message); return; diff --git a/x-pack/legacy/plugins/index_management/public/register_routes.ts b/x-pack/legacy/plugins/index_management/public/register_routes.ts index 778d0733d04c0..378a53cf65555 100644 --- a/x-pack/legacy/plugins/index_management/public/register_routes.ts +++ b/x-pack/legacy/plugins/index_management/public/register_routes.ts @@ -10,7 +10,6 @@ import { CoreStart } from '../../../../../src/core/public'; import { mountReactApp, unmountReactApp } from './app'; import { REACT_ROOT_ID } from './app/constants'; import { BASE_PATH } from '../common/constants'; -import { setHttpClient } from './app/services/api'; import template from './index.html'; import { manageAngularLifecycle } from './app/lib/manage_angular_lifecycle'; @@ -20,15 +19,11 @@ let elem: HTMLElement | null; export const registerRoutes = (core: CoreStart) => { routes.when(`${BASE_PATH}:view?/:action?/:id?`, { template, - controller: ($scope: any, $route: any, $http: ng.IHttpService) => { + controller: ($scope: any, $route: any) => { // clean up previously rendered React app if one exists // this happens because of React Router redirects unmountReactApp(elem); - // TODO $http is still needed for the ILM actions - // Once ILM is migrated to NP, it should be able to be removed - setHttpClient($http); - $scope.$$postDigest(() => { elem = document.getElementById(REACT_ROOT_ID); mountReactApp(elem, { core }); From 93e627fe47a0af7349a1affe6c55f24b07943a70 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Wed, 5 Feb 2020 18:12:51 -0600 Subject: [PATCH 08/41] [SIEM] Remove legacy ui imports (#56630) * Replace uses of chrome.getBasePath with NP equivalent * Prefer functional form of ApolloLink creation Mainly because there's no mention of direct instantiation in their documentation. * Replace uses of chrome.getBasePath with custom hook This ultimately uses useKibana() for now, but that will change in the future. * Refactor our frontend lib composition to use core instead of chrome This gets rid of our last usage of chrome.getBasePath. * Remove unused ui modules These have been unused since we excised our dependence on angular. * Remove unused mocks chrome.getBasePath has been deprecated and is unused within SIEM. * Mock core HTTP service in tests Now that some of these components are implicitly using the http service to get the app's basepath, we need to mock it out. There is a more robust set of mocks provided for core services, but I don't want to pull that in yet as we're only using this single method, and it should be addressed when we start paring this down to more fine-grained mocks for each test/component. * Define singleton module for our kibana services The app is currently retrieving services in one of three ways: * from the ui/new_platform module * from 'ui/chrome' * from the KibanaContext, via hooks or HOCs This module is the first step in consolidating those. We'll initialize it on plugin start(), and then populate the context with the same references. ui/chrome will eventually be removed. * Populate KibanaContext via our services module This ensures that all references to these services are coming from the same place, which is easier to reason about and also easier to mock/test. * Move our kibana-based hooks to a more appropriate location These hooks all use the `useKibana()` context hook under the hood, so it's slightly less confusing to nest them under lib/kibana/hooks. * Remove outstanding uses of chrome.getUiSettingsClient This uses our services singleton to fetch the NP UISettings client directly, rather than through ui/chrome. Modifies the singleton to export a function rather than a variable, as this allows us to guard against any misuse, and allows us to mock the module more easily in tests as well. * Replace ui/i18n with NP equivalent The i18n provider comes from the core i18n plugin, now. * Replace use of ui/chrome in new overview page * Replace use of npStart with our facade These are functionally equivalent, but getServices is under our control and won't go away. * Retrive data plugin dependencies through consistent code path One of our components was destructuring and then re-exporting ui/new_platform code. This works, it's just a little surprising. This refactors the code to use getServices and useKibana() as appropriate. * Pass kibana services to our React component We have a few very specific needs for uses of these services outside of react, so I've decided to keep that singleton as small as possible until we can refactor out their need. * Remove uses of kibana services during module evaluation There was an issue here where we were calling into UISettings when our redux code was imported. With the ui/chrome module this just worked, but now that we're using getServices, those calls were blowing up as the services had not yet been initialized. The current solution is to defer the initial state creation (which accesses UI settings) to start time, when we have our UISettings service available. This refactored the default_date_settings helpers and tests pretty significantly: I consolidated those helpers into two functions for timeRange settings and refreshInterval settings, respectively. * Replace static settings functions with short-circuited regular functions Adds tests for this invocation, too. * Refactor getIndexPatterns to accept the savedObjects client This removes one more use of our global getServices helper, and instead pulls from the kibana context. * Clean up our use of the data plugin This removes our one use of getServices with the data plugin, opting instead for a `useKibana` hook in the calling component. This cleans up any unnecessary mocks, and converts the needed ones to mock out useKibana, for now. * Limit what we can retrieve from getServices All these uses are now code smells. To prevent their proliferation, let's try to whitelist which services are available to just what we need. * Replace breadcrumbs with NP equivalent * Convert our getServices module to a singleton Class Rather than relying on our build system for proper closures, this enforces that behavior via plain ol' javascript. Co-authored-by: Elastic Machine --- x-pack/legacy/plugins/siem/public/app/app.tsx | 55 ++- .../public/components/charts/areachart.tsx | 2 +- .../public/components/charts/barchart.tsx | 2 +- .../embeddables/embedded_map.test.tsx | 6 - .../index_patterns_missing_prompt.tsx | 10 +- .../map_tool_tip/map_tool_tip.test.tsx | 6 - .../point_tool_tip_content.test.tsx | 6 - .../components/formatted_date/index.test.tsx | 4 +- .../components/formatted_date/index.tsx | 3 +- .../public/components/help_menu/index.tsx | 9 +- .../ml/anomaly/use_anomalies_table_data.ts | 3 +- .../components/ml/api/anomalies_table_data.ts | 4 +- .../components/ml/api/get_ml_capabilities.ts | 18 +- .../siem/public/components/ml_popover/api.tsx | 32 +- .../ml_popover/jobs_table/jobs_table.test.tsx | 2 + .../ml_popover/jobs_table/jobs_table.tsx | 10 +- .../ml_popover/popover_description.test.tsx | 2 + .../ml_popover/popover_description.tsx | 6 +- .../ml_popover/upgrade_contents.test.tsx | 2 + .../ml_popover/upgrade_contents.tsx | 4 +- .../navigation/breadcrumbs/index.test.ts | 28 +- .../navigation/breadcrumbs/index.ts | 16 +- .../components/navigation/index.test.tsx | 274 +++++------ .../public/components/navigation/index.tsx | 38 +- .../components/open_timeline/helpers.ts | 7 +- .../index.test.tsx | 26 +- .../add_filter_to_global_search_bar/index.tsx | 15 +- .../page/network/users_table/index.test.tsx | 6 - .../components/recent_timelines/helpers.ts | 18 +- .../public/components/search_bar/index.tsx | 36 +- .../components/url_state/index.test.tsx | 16 +- .../url_state/index_mocked.test.tsx | 19 +- .../url_state/initialize_redux_by_url.tsx | 10 +- .../siem/public/components/url_state/types.ts | 10 +- .../components/url_state/use_url_state.tsx | 4 + .../containers/detection_engine/rules/api.ts | 59 +-- .../detection_engine/signals/api.ts | 24 +- .../plugins/siem/public/hooks/api/api.tsx | 8 +- .../legacy/plugins/siem/public/hooks/index.ts | 7 - .../siem/public/hooks/use_index_patterns.tsx | 4 +- .../siem/public/lib/compose/helpers.test.ts | 4 +- .../siem/public/lib/compose/helpers.ts | 9 +- .../public/lib/compose/kibana_compose.tsx | 15 +- .../siem/public/lib/kibana/__mocks__/index.ts | 4 + .../kibana/hooks.ts} | 6 +- .../plugins/siem/public/lib/kibana/index.ts | 28 +- .../siem/public/lib/kibana/kibana_react.ts | 31 ++ .../siem/public/lib/kibana/services.ts | 27 ++ .../detection_engine_empty_page.tsx | 5 +- .../pages/detection_engine/rules/utils.ts | 4 +- .../siem/public/pages/hosts/details/utils.ts | 4 +- .../public/pages/hosts/hosts_empty_page.tsx | 6 +- .../public/pages/network/ip_details/utils.ts | 7 +- .../pages/network/network_empty_page.tsx | 6 +- .../public/pages/overview/overview.test.tsx | 6 - .../pages/overview/overview_empty/index.tsx | 6 +- x-pack/legacy/plugins/siem/public/plugin.tsx | 7 +- .../siem/public/store/inputs/reducer.ts | 77 ++- .../plugins/siem/public/store/reducer.ts | 7 +- .../utils/default_date_settings.test.ts | 438 ++++++++---------- .../public/utils/default_date_settings.ts | 130 +----- .../routes/__mocks__/_mock_server.ts | 2 - 62 files changed, 801 insertions(+), 839 deletions(-) delete mode 100644 x-pack/legacy/plugins/siem/public/hooks/index.ts rename x-pack/legacy/plugins/siem/public/{hooks/use_ui_settings.ts => lib/kibana/hooks.ts} (78%) create mode 100644 x-pack/legacy/plugins/siem/public/lib/kibana/kibana_react.ts create mode 100644 x-pack/legacy/plugins/siem/public/lib/kibana/services.ts diff --git a/x-pack/legacy/plugins/siem/public/app/app.tsx b/x-pack/legacy/plugins/siem/public/app/app.tsx index 5f9199735d8c0..030cb72750649 100644 --- a/x-pack/legacy/plugins/siem/public/app/app.tsx +++ b/x-pack/legacy/plugins/siem/public/app/app.tsx @@ -16,9 +16,8 @@ import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; import { BehaviorSubject } from 'rxjs'; import { pluck } from 'rxjs/operators'; -import { I18nContext } from 'ui/i18n'; -import { KibanaContextProvider, useUiSetting$ } from '../lib/kibana'; +import { KibanaContextProvider, useKibana, useUiSetting$ } from '../lib/kibana'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; import { DEFAULT_DARK_MODE } from '../../common/constants'; @@ -27,7 +26,7 @@ import { compose } from '../lib/compose/kibana_compose'; import { AppFrontendLibs, AppApolloClient } from '../lib/lib'; import { CoreStart, StartPlugins } from '../plugin'; import { PageRouter } from '../routes'; -import { createStore } from '../store'; +import { createStore, createInitialState } from '../store'; import { GlobalToaster, ManageGlobalToaster } from '../components/toasters'; import { MlCapabilitiesProvider } from '../components/ml/permissions/ml_capabilities_provider'; @@ -46,33 +45,30 @@ const AppPluginRootComponent: React.FC = ({ apolloClient, history, }) => ( - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + ); const AppPluginRoot = memo(AppPluginRootComponent); const StartAppComponent: FC = libs => { + const { i18n } = useKibana().services; const history = createHashHistory(); const libs$ = new BehaviorSubject(libs); - const store = createStore(undefined, libs$.pipe(pluck('apolloClient'))); + const store = createStore(createInitialState(), libs$.pipe(pluck('apolloClient'))); const [darkMode] = useUiSetting$(DEFAULT_DARK_MODE); const theme = useMemo( () => ({ @@ -83,7 +79,16 @@ const StartAppComponent: FC = libs => { ); return ( - + + + + + ); }; @@ -103,7 +108,7 @@ const SiemAppComponent: React.FC = ({ core, plugins }) => ...plugins, }} > - + ); diff --git a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx index 71f22efadc6ed..57f78080abc60 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx @@ -18,7 +18,7 @@ import { import { getOr, get, isNull, isNumber } from 'lodash/fp'; import { AutoSizer } from '../auto_sizer'; import { ChartPlaceHolder } from './chart_place_holder'; -import { useTimeZone } from '../../hooks'; +import { useTimeZone } from '../../lib/kibana'; import { chartDefaultSettings, ChartSeriesConfigs, diff --git a/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx b/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx index 8c342ad2d037f..d9dd302dae724 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx @@ -9,7 +9,7 @@ import { Chart, BarSeries, Axis, Position, ScaleType, Settings } from '@elastic/ import { getOr, get, isNumber } from 'lodash/fp'; import deepmerge from 'deepmerge'; -import { useTimeZone } from '../../hooks'; +import { useTimeZone } from '../../lib/kibana'; import { AutoSizer } from '../auto_sizer'; import { ChartPlaceHolder } from './chart_place_holder'; import { diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx index c752273777d2f..a807b4d6a838b 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx @@ -11,12 +11,6 @@ import { useIndexPatterns } from '../../hooks/use_index_patterns'; import { EmbeddedMapComponent } from './embedded_map'; import { SetQuery } from './types'; -jest.mock('../search_bar', () => ({ - siemFilterManager: { - addFilters: jest.fn(), - }, -})); - const mockUseIndexPatterns = useIndexPatterns as jest.Mock; jest.mock('../../hooks/use_index_patterns'); mockUseIndexPatterns.mockImplementation(() => [true, []]); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx index cba7e5ba1fd93..abd33505b67b9 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx @@ -7,13 +7,13 @@ import { EuiButton, EuiCode, EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; -import chrome from 'ui/chrome'; -import { useKibana } from '../../lib/kibana'; +import { useKibana, useBasePath } from '../../lib/kibana'; import * as i18n from './translations'; export const IndexPatternsMissingPromptComponent = () => { - const docLinks = useKibana().services.docLinks; + const { docLinks } = useKibana().services; + const kibanaBasePath = `${useBasePath()}/app/kibana`; return ( { values={{ defaultIndex: ( @@ -61,7 +61,7 @@ export const IndexPatternsMissingPromptComponent = () => { } actions={ ({ - siemFilterManager: { - addFilters: jest.fn(), - }, -})); - describe('MapToolTip', () => { test('placeholder component renders correctly against snapshot', () => { const wrapper = shallow(); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx index a9d70e4f35d35..c90af16b0d99a 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx @@ -14,12 +14,6 @@ import { HostDetailsLink, IPDetailsLink } from '../../links'; import { useMountAppended } from '../../../utils/use_mount_appended'; import { FlowTarget } from '../../../graphql/types'; -jest.mock('../../search_bar', () => ({ - siemFilterManager: { - addFilters: jest.fn(), - }, -})); - describe('PointToolTipContent', () => { const mount = useMountAppended(); diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx index 0d8222ce85e1b..2ca67057039df 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.test.tsx @@ -7,13 +7,13 @@ import { mount, shallow } from 'enzyme'; import React from 'react'; -import { useDateFormat, useTimeZone } from '../../hooks'; +import { useDateFormat, useTimeZone } from '../../lib/kibana'; import { TestProviders } from '../../mock'; import { getEmptyString, getEmptyValue } from '../empty_value'; import { PreferenceFormattedDate, FormattedDate, FormattedRelativePreferenceDate } from '.'; -jest.mock('../../hooks'); +jest.mock('../../lib/kibana'); const mockUseDateFormat = useDateFormat as jest.Mock; const mockUseTimeZone = useTimeZone as jest.Mock; diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx index fb579a14b0457..f74ee995c965b 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/formatted_date/index.tsx @@ -8,9 +8,8 @@ import moment from 'moment-timezone'; import React from 'react'; import { FormattedRelative } from '@kbn/i18n/react'; -import { useDateFormat, useTimeZone } from '../../hooks'; +import { useDateFormat, useTimeZone, useUiSetting$ } from '../../lib/kibana'; import { getOrEmptyTagFromValue } from '../empty_value'; -import { useUiSetting$ } from '../../lib/kibana'; import { LocalizedDateTooltip } from '../localized_date_tooltip'; import { getMaybeDate } from './maybe_date'; diff --git a/x-pack/legacy/plugins/siem/public/components/help_menu/index.tsx b/x-pack/legacy/plugins/siem/public/components/help_menu/index.tsx index 732d83ac6e736..e74299f57c934 100644 --- a/x-pack/legacy/plugins/siem/public/components/help_menu/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/help_menu/index.tsx @@ -5,13 +5,14 @@ */ import React, { useEffect } from 'react'; -import chrome from 'ui/chrome'; import { i18n } from '@kbn/i18n'; -import { documentationLinks } from 'ui/documentation_links'; +import { useKibana } from '../../lib/kibana'; export const HelpMenu = React.memo(() => { + const { chrome, docLinks } = useKibana().services; + useEffect(() => { - chrome.helpExtension.set({ + chrome.setHelpExtension({ appName: i18n.translate('xpack.siem.chrome.help.appName', { defaultMessage: 'SIEM', }), @@ -20,7 +21,7 @@ export const HelpMenu = React.memo(() => { content: i18n.translate('xpack.siem.chrome.helpMenu.documentation', { defaultMessage: 'SIEM documentation', }), - href: documentationLinks.siem.guide, + href: docLinks.links.siem.guide, iconType: 'documents', linkType: 'custom', }, diff --git a/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts b/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts index 48277b0b6fa52..0baa1ef7cdd05 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml/anomaly/use_anomalies_table_data.ts @@ -14,9 +14,8 @@ import { useStateToaster } from '../../toasters'; import { errorToToaster } from '../api/error_to_toaster'; import * as i18n from './translations'; -import { useUiSetting$ } from '../../../lib/kibana'; +import { useTimeZone, useUiSetting$ } from '../../../lib/kibana'; import { DEFAULT_ANOMALY_SCORE } from '../../../../common/constants'; -import { useTimeZone } from '../../../hooks'; interface Args { influencers?: InfluencerInput[]; diff --git a/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts b/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts index cb84d9182d2e0..35dbbf012272e 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml/api/anomalies_table_data.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from 'ui/new_platform'; import { Anomalies, InfluencerInput, CriteriaFields } from '../types'; import { throwIfNotOk } from '../../../hooks/api/api'; +import { KibanaServices } from '../../../lib/kibana'; export interface Body { jobIds: string[]; @@ -22,7 +22,7 @@ export interface Body { } export const anomaliesTableData = async (body: Body, signal: AbortSignal): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( '/api/ml/results/anomalies_table_data', { method: 'POST', diff --git a/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts b/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts index dcfd7365f8e0d..feafbba2024dc 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml/api/get_ml_capabilities.ts @@ -4,10 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from 'ui/new_platform'; - import { InfluencerInput, MlCapabilities } from '../types'; import { throwIfNotOk } from '../../../hooks/api/api'; +import { KibanaServices } from '../../../lib/kibana'; export interface Body { jobIds: string[]; @@ -23,12 +22,15 @@ export interface Body { } export const getMlCapabilities = async (signal: AbortSignal): Promise => { - const response = await npStart.core.http.fetch('/api/ml/ml_capabilities', { - method: 'GET', - asResponse: true, - asSystemRequest: true, - signal, - }); + const response = await KibanaServices.get().http.fetch( + '/api/ml/ml_capabilities', + { + method: 'GET', + asResponse: true, + asSystemRequest: true, + signal, + } + ); await throwIfNotOk(response.response); return response.body!; diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx index cf939d8e09b7e..120fd8c404ffd 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/api.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from 'ui/new_platform'; - import { CheckRecognizerProps, CloseJobsResponse, @@ -21,6 +19,7 @@ import { } from './types'; import { throwIfErrorAttached, throwIfErrorAttachedToSetup } from '../ml/api/throw_if_not_ok'; import { throwIfNotOk } from '../../hooks/api/api'; +import { KibanaServices } from '../../lib/kibana'; /** * Checks the ML Recognizer API to see if a given indexPattern has any compatible modules @@ -32,7 +31,7 @@ export const checkRecognizer = async ({ indexPatternName, signal, }: CheckRecognizerProps): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `/api/ml/modules/recognize/${indexPatternName}`, { method: 'GET', @@ -53,7 +52,7 @@ export const checkRecognizer = async ({ * @param signal to cancel request */ export const getModules = async ({ moduleId = '', signal }: GetModulesProps): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `/api/ml/modules/get_module/${moduleId}`, { method: 'GET', @@ -83,7 +82,7 @@ export const setupMlJob = async ({ groups = ['siem'], prefix = '', }: MlSetupArgs): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `/api/ml/modules/setup/${configTemplate}`, { method: 'POST', @@ -119,7 +118,7 @@ export const startDatafeeds = async ({ datafeedIds: string[]; start: number; }): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( '/api/ml/jobs/force_start_datafeeds', { method: 'POST', @@ -149,7 +148,7 @@ export const stopDatafeeds = async ({ }: { datafeedIds: string[]; }): Promise<[StopDatafeedResponse | ErrorResponse, CloseJobsResponse]> => { - const stopDatafeedsResponse = await npStart.core.http.fetch( + const stopDatafeedsResponse = await KibanaServices.get().http.fetch( '/api/ml/jobs/stop_datafeeds', { method: 'POST', @@ -165,7 +164,7 @@ export const stopDatafeeds = async ({ const stopDatafeedsResponseJson = stopDatafeedsResponse.body!; const datafeedPrefix = 'datafeed-'; - const closeJobsResponse = await npStart.core.http.fetch( + const closeJobsResponse = await KibanaServices.get().http.fetch( '/api/ml/jobs/close_jobs', { method: 'POST', @@ -194,13 +193,16 @@ export const stopDatafeeds = async ({ * @param signal to cancel request */ export const getJobsSummary = async (signal: AbortSignal): Promise => { - const response = await npStart.core.http.fetch('/api/ml/jobs/jobs_summary', { - method: 'POST', - body: JSON.stringify({}), - asResponse: true, - asSystemRequest: true, - signal, - }); + const response = await KibanaServices.get().http.fetch( + '/api/ml/jobs/jobs_summary', + { + method: 'POST', + body: JSON.stringify({}), + asResponse: true, + asSystemRequest: true, + signal, + } + ); await throwIfNotOk(response.response); return response.body!; diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx index fa524d8ff3dbc..c9307afbd3dbf 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx @@ -11,6 +11,8 @@ import { mockSiemJobs } from '../__mocks__/api'; import { cloneDeep } from 'lodash/fp'; import { SiemJob } from '../types'; +jest.mock('../../../lib/kibana'); + describe('JobsTableComponent', () => { let siemJobs: SiemJob[]; let onJobStateChangeMock = jest.fn(); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx index 34597f1761629..5bca802a21747 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx @@ -6,7 +6,6 @@ /* eslint-disable react/display-name */ -import chrome from 'ui/chrome'; import React, { useEffect, useState } from 'react'; import { @@ -23,6 +22,7 @@ import { } from '@elastic/eui'; import styled from 'styled-components'; +import { useBasePath } from '../../../lib/kibana'; import * as i18n from './translations'; import { JobSwitch } from './job_switch'; import { SiemJob } from '../types'; @@ -38,7 +38,8 @@ const truncateThreshold = 200; const getJobsTableColumns = ( isLoading: boolean, - onJobStateChange: (job: SiemJob, latestTimestampMs: number, enable: boolean) => Promise + onJobStateChange: (job: SiemJob, latestTimestampMs: number, enable: boolean) => Promise, + basePath: string ) => [ { name: i18n.COLUMN_JOB_NAME, @@ -46,7 +47,7 @@ const getJobsTableColumns = ( {id} @@ -97,6 +98,7 @@ export interface JobTableProps { export const JobsTableComponent = ({ isLoading, jobs, onJobStateChange }: JobTableProps) => { const [pageIndex, setPageIndex] = useState(0); + const basePath = useBasePath(); const pageSize = 5; const pagination = { @@ -114,7 +116,7 @@ export const JobsTableComponent = ({ isLoading, jobs, onJobStateChange }: JobTab } diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.test.tsx index e611a5234da5e..a179c0e266940 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.test.tsx @@ -8,6 +8,8 @@ import { shallow } from 'enzyme'; import React from 'react'; import { PopoverDescriptionComponent } from './popover_description'; +jest.mock('../../lib/kibana'); + describe('JobsTableFilters', () => { test('renders correctly against snapshot', () => { const wrapper = shallow(); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx index c9cc1c5d4e539..20e8dd2492fef 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx @@ -7,7 +7,8 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; import { EuiLink, EuiText } from '@elastic/eui'; -import chrome from 'ui/chrome'; + +import { useBasePath } from '../../lib/kibana'; export const PopoverDescriptionComponent = () => ( @@ -16,7 +17,7 @@ export const PopoverDescriptionComponent = () => ( defaultMessage="Run any of the Machine Learning jobs below to view anomalous events throughout the SIEM application. We’ve provided a few common detection jobs to get you started. If you wish to add your own custom jobs, simply create and tag them with “SIEM” from the {machineLearning} application for inclusion here." values={{ machineLearning: ( - + ( /> ); - PopoverDescriptionComponent.displayName = 'PopoverDescriptionComponent'; export const PopoverDescription = React.memo(PopoverDescriptionComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.test.tsx index 2ba08073b25b9..1d2d344c3b7af 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.test.tsx @@ -8,6 +8,8 @@ import { shallow } from 'enzyme'; import React from 'react'; import { UpgradeContentsComponent } from './upgrade_contents'; +jest.mock('../../lib/kibana'); + describe('JobsTableFilters', () => { test('renders correctly against snapshot', () => { const wrapper = shallow(); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.tsx index a337e234f11d3..5a483e0d5b876 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/upgrade_contents.tsx @@ -5,7 +5,6 @@ */ import React from 'react'; -import chrome from 'ui/chrome'; import styled from 'styled-components'; import { @@ -18,6 +17,7 @@ import { EuiFlexItem, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; +import { useBasePath } from '../../lib/kibana'; import * as i18n from './translations'; const PopoverContentsDiv = styled.div` @@ -59,7 +59,7 @@ export const UpgradeContentsComponent = () => ( diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts b/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts index fc0a37bc751c7..7770780fb9613 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts +++ b/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import chrome from 'ui/chrome'; import '../../../mock/match_media'; import { encodeIpv6 } from '../../../lib/helpers'; @@ -13,23 +12,11 @@ import { RouteSpyState, SiemRouteType } from '../../../utils/route/types'; import { TabNavigationProps } from '../tab_navigation/types'; import { NetworkRouteType } from '../../../pages/network/navigation/types'; -jest.mock('ui/chrome', () => ({ - getBasePath: () => { - return ''; - }, - breadcrumbs: { - set: jest.fn(), - }, - getUiSettingsClient: () => ({ - get: jest.fn(), - }), -})); - -jest.mock('../../search_bar', () => ({ - siemFilterManager: { - addFilters: jest.fn(), - }, -})); +const setBreadcrumbsMock = jest.fn(); +const chromeMock = { + setBreadcrumbs: setBreadcrumbsMock, + // eslint-disable-next-line @typescript-eslint/no-explicit-any +} as any; const mockDefaultTab = (pageName: string): SiemRouteType | undefined => { switch (pageName) { @@ -217,10 +204,11 @@ describe('Navigation Breadcrumbs', () => { ]); }); }); + describe('setBreadcrumbs()', () => { test('should call chrome breadcrumb service with correct breadcrumbs', () => { - setBreadcrumbs(getMockObject('hosts', '/hosts', hostName)); - expect(chrome.breadcrumbs.set).toBeCalledWith([ + setBreadcrumbs(getMockObject('hosts', '/hosts', hostName), chromeMock); + expect(setBreadcrumbsMock).toBeCalledWith([ { text: 'SIEM', href: '#/link-to/overview' }, { text: 'Hosts', diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.ts b/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.ts index 91055bca066c4..e8d5032fd7548 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.ts +++ b/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.ts @@ -4,10 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import chrome, { Breadcrumb } from 'ui/chrome'; - import { getOr, omit } from 'lodash/fp'; + +import { ChromeBreadcrumb } from '../../../../../../../../src/core/public'; import { APP_NAME } from '../../../../common/constants'; +import { StartServices } from '../../../plugin'; import { getBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../pages/hosts/details/utils'; import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../pages/network/ip_details'; import { getBreadcrumbs as getDetectionRulesBreadcrumbs } from '../../../pages/detection_engine/rules/utils'; @@ -19,14 +20,17 @@ import { TabNavigationProps } from '../tab_navigation/types'; import { getSearch } from '../helpers'; import { SearchNavTab } from '../types'; -export const setBreadcrumbs = (spyState: RouteSpyState & TabNavigationProps) => { +export const setBreadcrumbs = ( + spyState: RouteSpyState & TabNavigationProps, + chrome: StartServices['chrome'] +) => { const breadcrumbs = getBreadcrumbsForRoute(spyState); if (breadcrumbs) { - chrome.breadcrumbs.set(breadcrumbs); + chrome.setBreadcrumbs(breadcrumbs); } }; -export const siemRootBreadcrumb: Breadcrumb[] = [ +export const siemRootBreadcrumb: ChromeBreadcrumb[] = [ { text: APP_NAME, href: getOverviewUrl(), @@ -44,7 +48,7 @@ const isDetectionsRoutes = (spyState: RouteSpyState) => export const getBreadcrumbsForRoute = ( object: RouteSpyState & TabNavigationProps -): Breadcrumb[] | null => { +): ChromeBreadcrumb[] | null => { const spyState: RouteSpyState = omit('navTabs', object); if (isHostsRoutes(spyState) && object.navTabs) { const tempNav: SearchNavTab = { urlKey: 'host', isDetailPage: false }; diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx index 56be39f67b1bd..ac7a4a0ee52b7 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx @@ -61,79 +61,83 @@ describe('SIEM Navigation', () => { }; const wrapper = mount(); test('it calls setBreadcrumbs with correct path on mount', () => { - expect(setBreadcrumbs).toHaveBeenNthCalledWith(1, { - detailName: undefined, - navTabs: { - detections: { - disabled: false, - href: '#/link-to/detections', - id: 'detections', - name: 'Detections', - urlKey: 'detections', - }, - hosts: { - disabled: false, - href: '#/link-to/hosts', - id: 'hosts', - name: 'Hosts', - urlKey: 'host', - }, - network: { - disabled: false, - href: '#/link-to/network', - id: 'network', - name: 'Network', - urlKey: 'network', - }, - overview: { - disabled: false, - href: '#/link-to/overview', - id: 'overview', - name: 'Overview', - urlKey: 'overview', - }, - timelines: { - disabled: false, - href: '#/link-to/timelines', - id: 'timelines', - name: 'Timelines', - urlKey: 'timeline', - }, - }, - pageName: 'hosts', - pathName: '/hosts', - search: '', - tabName: 'authentications', - query: { query: '', language: 'kuery' }, - filters: [], - savedQuery: undefined, - timeline: { - id: '', - isOpen: false, - }, - timerange: { - global: { - linkTo: ['timeline'], - timerange: { - from: 1558048243696, - fromStr: 'now-24h', - kind: 'relative', - to: 1558134643697, - toStr: 'now', + expect(setBreadcrumbs).toHaveBeenNthCalledWith( + 1, + { + detailName: undefined, + navTabs: { + detections: { + disabled: false, + href: '#/link-to/detections', + id: 'detections', + name: 'Detections', + urlKey: 'detections', + }, + hosts: { + disabled: false, + href: '#/link-to/hosts', + id: 'hosts', + name: 'Hosts', + urlKey: 'host', + }, + network: { + disabled: false, + href: '#/link-to/network', + id: 'network', + name: 'Network', + urlKey: 'network', + }, + overview: { + disabled: false, + href: '#/link-to/overview', + id: 'overview', + name: 'Overview', + urlKey: 'overview', + }, + timelines: { + disabled: false, + href: '#/link-to/timelines', + id: 'timelines', + name: 'Timelines', + urlKey: 'timeline', }, }, + pageName: 'hosts', + pathName: '/hosts', + search: '', + tabName: 'authentications', + query: { query: '', language: 'kuery' }, + filters: [], + savedQuery: undefined, timeline: { - linkTo: ['global'], - timerange: { - from: 1558048243696, - fromStr: 'now-24h', - kind: 'relative', - to: 1558134643697, - toStr: 'now', + id: '', + isOpen: false, + }, + timerange: { + global: { + linkTo: ['timeline'], + timerange: { + from: 1558048243696, + fromStr: 'now-24h', + kind: 'relative', + to: 1558134643697, + toStr: 'now', + }, + }, + timeline: { + linkTo: ['global'], + timerange: { + from: 1558048243696, + fromStr: 'now-24h', + kind: 'relative', + to: 1558134643697, + toStr: 'now', + }, }, }, }, - }); + undefined + ); }); test('it calls setBreadcrumbs with correct path on update', () => { wrapper.setProps({ @@ -142,76 +146,80 @@ describe('SIEM Navigation', () => { tabName: undefined, }); wrapper.update(); - expect(setBreadcrumbs).toHaveBeenNthCalledWith(1, { - detailName: undefined, - filters: [], - navTabs: { - detections: { - disabled: false, - href: '#/link-to/detections', - id: 'detections', - name: 'Detections', - urlKey: 'detections', - }, - hosts: { - disabled: false, - href: '#/link-to/hosts', - id: 'hosts', - name: 'Hosts', - urlKey: 'host', - }, - network: { - disabled: false, - href: '#/link-to/network', - id: 'network', - name: 'Network', - urlKey: 'network', - }, - overview: { - disabled: false, - href: '#/link-to/overview', - id: 'overview', - name: 'Overview', - urlKey: 'overview', - }, - timelines: { - disabled: false, - href: '#/link-to/timelines', - id: 'timelines', - name: 'Timelines', - urlKey: 'timeline', - }, - }, - pageName: 'hosts', - pathName: '/hosts', - query: { language: 'kuery', query: '' }, - savedQuery: undefined, - search: '', - state: undefined, - tabName: 'authentications', - timeline: { id: '', isOpen: false }, - timerange: { - global: { - linkTo: ['timeline'], - timerange: { - from: 1558048243696, - fromStr: 'now-24h', - kind: 'relative', - to: 1558134643697, - toStr: 'now', + expect(setBreadcrumbs).toHaveBeenNthCalledWith( + 1, + { + detailName: undefined, + filters: [], + navTabs: { + detections: { + disabled: false, + href: '#/link-to/detections', + id: 'detections', + name: 'Detections', + urlKey: 'detections', + }, + hosts: { + disabled: false, + href: '#/link-to/hosts', + id: 'hosts', + name: 'Hosts', + urlKey: 'host', + }, + network: { + disabled: false, + href: '#/link-to/network', + id: 'network', + name: 'Network', + urlKey: 'network', + }, + overview: { + disabled: false, + href: '#/link-to/overview', + id: 'overview', + name: 'Overview', + urlKey: 'overview', + }, + timelines: { + disabled: false, + href: '#/link-to/timelines', + id: 'timelines', + name: 'Timelines', + urlKey: 'timeline', }, }, - timeline: { - linkTo: ['global'], - timerange: { - from: 1558048243696, - fromStr: 'now-24h', - kind: 'relative', - to: 1558134643697, - toStr: 'now', + pageName: 'hosts', + pathName: '/hosts', + query: { language: 'kuery', query: '' }, + savedQuery: undefined, + search: '', + state: undefined, + tabName: 'authentications', + timeline: { id: '', isOpen: false }, + timerange: { + global: { + linkTo: ['timeline'], + timerange: { + from: 1558048243696, + fromStr: 'now-24h', + kind: 'relative', + to: 1558134643697, + toStr: 'now', + }, + }, + timeline: { + linkTo: ['global'], + timerange: { + from: 1558048243696, + fromStr: 'now-24h', + kind: 'relative', + to: 1558134643697, + toStr: 'now', + }, }, }, }, - }); + undefined + ); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx index 040a6e7847b77..e40cc887ab5ff 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx @@ -10,6 +10,7 @@ import React, { useEffect } from 'react'; import { connect } from 'react-redux'; import { compose } from 'redux'; +import { useKibana } from '../../lib/kibana'; import { RouteSpyState } from '../../utils/route/types'; import { useRouteSpy } from '../../utils/route/use_route_spy'; import { makeMapStateToProps } from '../url_state/helpers'; @@ -31,25 +32,30 @@ export const SiemNavigationComponent: React.FC { + const { chrome } = useKibana().services; + useEffect(() => { if (pathName) { - setBreadcrumbs({ - query: urlState.query, - detailName, - filters: urlState.filters, - navTabs, - pageName, - pathName, - savedQuery: urlState.savedQuery, - search, - tabName, - flowTarget, - timerange: urlState.timerange, - timeline: urlState.timeline, - state, - }); + setBreadcrumbs( + { + query: urlState.query, + detailName, + filters: urlState.filters, + navTabs, + pageName, + pathName, + savedQuery: urlState.savedQuery, + search, + tabName, + flowTarget, + timerange: urlState.timerange, + timeline: urlState.timeline, + state, + }, + chrome + ); } - }, [pathName, search, navTabs, urlState, state]); + }, [chrome, pathName, search, navTabs, urlState, state]); return ( ({ if (onOpenTimeline != null) { onOpenTimeline(timeline); } else if (updateTimeline) { + const { from, to } = getTimeRangeSettings(); updateTimeline({ duplicate, - from: getOr(getDefaultFromValue(), 'dateRange.start', timeline), + from: getOr(from, 'dateRange.start', timeline), id: 'timeline-1', notes, timeline: { ...timeline, show: openTimeline, }, - to: getOr(getDefaultToValue(), 'dateRange.end', timeline), + to: getOr(to, 'dateRange.end', timeline), })(); } }) diff --git a/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.test.tsx index 345701c97901f..54a516fef69ed 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.test.tsx @@ -9,21 +9,22 @@ import React from 'react'; import { apolloClientObservable, mockGlobalState, TestProviders } from '../../../mock'; import { createStore, State } from '../../../store'; -import { siemFilterManager } from '../../search_bar'; import { AddFilterToGlobalSearchBar } from '.'; -import { esFilters } from '../../../../../../../../src/plugins/data/public'; -interface MockSiemFilterManager { - addFilters: (filters: esFilters.Filter[]) => void; -} -const mockSiemFilterManager: MockSiemFilterManager = siemFilterManager as MockSiemFilterManager; -jest.mock('../../search_bar', () => ({ - siemFilterManager: { - addFilters: jest.fn(), - }, -})); const mockAddFilters = jest.fn(); -mockSiemFilterManager.addFilters = mockAddFilters; +jest.mock('../../../lib/kibana', () => ({ + useKibana: () => ({ + services: { + data: { + query: { + filterManager: { + addFilters: mockAddFilters, + }, + }, + }, + }, + }), +})); describe('AddFilterToGlobalSearchBar Component', () => { const state: State = mockGlobalState; @@ -31,6 +32,7 @@ describe('AddFilterToGlobalSearchBar Component', () => { beforeEach(() => { store = createStore(state, apolloClientObservable); + mockAddFilters.mockClear(); }); test('Rendering', async () => { diff --git a/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.tsx index 012d8322fa329..d6f1e2dd509be 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/add_filter_to_global_search_bar/index.tsx @@ -5,12 +5,12 @@ */ import { EuiIcon, EuiPanel, EuiToolTip } from '@elastic/eui'; -import React from 'react'; +import React, { useCallback } from 'react'; import styled from 'styled-components'; -import { WithHoverActions } from '../../with_hover_actions'; -import { siemFilterManager } from '../../search_bar'; import { esFilters } from '../../../../../../../../src/plugins/data/public'; +import { WithHoverActions } from '../../with_hover_actions'; +import { useKibana } from '../../../lib/kibana'; import * as i18n from './translations'; @@ -24,12 +24,15 @@ interface OwnProps { export const AddFilterToGlobalSearchBar = React.memo( ({ children, filter, onFilterAdded }) => { - const addToKql = () => { - siemFilterManager.addFilters(filter); + const { filterManager } = useKibana().services.data.query; + + const addToKql = useCallback(() => { + filterManager.addFilters(filter); if (onFilterAdded != null) { onFilterAdded(); } - }; + }, [filter, filterManager, onFilterAdded]); + return ( ({ - siemFilterManager: { - addFilters: jest.fn(), - }, -})); - describe('Users Table Component', () => { const loadPage = jest.fn(); const state: State = mockGlobalState; diff --git a/x-pack/legacy/plugins/siem/public/components/recent_timelines/helpers.ts b/x-pack/legacy/plugins/siem/public/components/recent_timelines/helpers.ts index 61b49da01dc3a..41fa90f1776e6 100644 --- a/x-pack/legacy/plugins/siem/public/components/recent_timelines/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/recent_timelines/helpers.ts @@ -5,22 +5,16 @@ */ import { throwIfNotOk } from '../../hooks/api/api'; +import { KibanaServices } from '../../lib/kibana'; import { MeApiResponse } from './recent_timelines'; -export const getMeApiUrl = (getBasePath: () => string): string => - `${getBasePath()}/internal/security/me`; - -export const fetchUsername = async (meApiUrl: string) => { - const response = await fetch(meApiUrl, { +export const fetchUsername = async () => { + const response = await KibanaServices.get().http.fetch('/internal/security/me', { method: 'GET', credentials: 'same-origin', - headers: { - 'content-type': 'application/json', - }, + asResponse: true, }); - await throwIfNotOk(response); - const apiResponse: MeApiResponse = await response.json(); - - return apiResponse.username; + await throwIfNotOk(response.response); + return response.body!.username; }; diff --git a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx index 089bade4a4144..7ea13ca97a9c8 100644 --- a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx @@ -10,11 +10,10 @@ import { connect } from 'react-redux'; import { Dispatch } from 'redux'; import { Subscription } from 'rxjs'; import styled from 'styled-components'; -import { IIndexPattern } from 'src/plugins/data/public'; +import { FilterManager, IIndexPattern, TimeRange, Query, esFilters } from 'src/plugins/data/public'; import { SavedQuery } from 'src/legacy/core_plugins/data/public'; import { OnTimeChangeProps } from '@elastic/eui'; -import { npStart } from 'ui/new_platform'; import { inputsActions } from '../../store/inputs'; import { InputsRange } from '../../store/inputs/model'; @@ -33,11 +32,7 @@ import { toStrSelector, } from './selectors'; import { timelineActions, hostsActions, networkActions } from '../../store/actions'; -import { TimeRange, Query, esFilters } from '../../../../../../../src/plugins/data/public'; - -export const siemFilterManager = npStart.plugins.data.query.filterManager; -export const savedQueryService = npStart.plugins.data.query.savedQueries; -const { SearchBar } = npStart.plugins.data.ui; +import { useKibana } from '../../lib/kibana'; interface SiemSearchBarRedux { end: number; @@ -93,7 +88,12 @@ const SearchBarComponent = memo { - const { timefilter } = npStart.plugins.data.query.timefilter; + const { data } = useKibana().services; + const { + timefilter: { timefilter }, + filterManager, + } = data.query; + if (fromStr != null && toStr != null) { timefilter.setTime({ from: fromStr, to: toStr }); } else if (start != null && end != null) { @@ -114,6 +114,7 @@ const SearchBarComponent = memo q.refetch && (q.refetch as inputsModel.Refetch)()); } }, - [id, queries] + [id, queries, filterManager] ); const onSaved = useCallback( @@ -191,6 +193,7 @@ const SearchBarComponent = memo { let isSubscribed = true; const subscriptions = new Subscription(); subscriptions.add( - siemFilterManager.getUpdates$().subscribe({ + filterManager.getUpdates$().subscribe({ next: () => { if (isSubscribed) { setSearchBarFilter({ id, - filters: siemFilterManager.getFilters(), + filters: filterManager.getFilters(), }); } }, @@ -256,7 +260,7 @@ const SearchBarComponent = memo [indexPattern], [indexPattern]); return ( - void; -export const dispatchUpdateSearch = (dispatch: Dispatch) => ({ +const dispatchUpdateSearch = (dispatch: Dispatch) => ({ end, filters, id, @@ -335,6 +340,7 @@ export const dispatchUpdateSearch = (dispatch: Dispatch) => ({ savedQuery, start, timelineId, + filterManager, updateTime = false, }: UpdateReduxSearchBar): void => { if (updateTime) { @@ -379,7 +385,7 @@ export const dispatchUpdateSearch = (dispatch: Dispatch) => ({ ); } if (filters != null) { - siemFilterManager.setFilters(filters); + filterManager.setFilters(filters); } if (savedQuery != null || resetSavedQuery) { dispatch(inputsActions.setSavedQuery({ id, savedQuery })); diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/index.test.tsx index ab290c2f2fd67..9a9bb409936fc 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/index.test.tsx @@ -25,7 +25,6 @@ import { useUrlStateHooks } from './use_url_state'; let mockProps: UrlStateContainerPropTypes; -// const mockUseRouteSpy: jest.Mock = useRouteSpy as jest.Mock; const mockRouteSpy: RouteSpyState = { pageName: SiemPageName.network, detailName: undefined, @@ -37,10 +36,17 @@ jest.mock('../../utils/route/use_route_spy', () => ({ useRouteSpy: () => [mockRouteSpy], })); -jest.mock('../search_bar', () => ({ - siemFilterManager: { - setFilters: jest.fn(), - }, +jest.mock('../../lib/kibana', () => ({ + useKibana: () => ({ + services: { + data: { + query: { + filterManager: {}, + savedQueries: {}, + }, + }, + }, + }), })); describe('UrlStateContainer', () => { diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/index_mocked.test.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/index_mocked.test.tsx index f673b77ea13c5..6995bc8bf1d40 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/index_mocked.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/index_mocked.test.tsx @@ -15,14 +15,21 @@ import { getFilterQuery, getMockPropsObj, mockHistory, testCases } from './test_ import { UrlStateContainerPropTypes } from './types'; import { useUrlStateHooks } from './use_url_state'; -jest.mock('../search_bar', () => ({ - siemFilterManager: { - addFilters: jest.fn(), - }, -})); - let mockProps: UrlStateContainerPropTypes; +jest.mock('../../lib/kibana', () => ({ + useKibana: () => ({ + services: { + data: { + query: { + filterManager: {}, + savedQueries: {}, + }, + }, + }, + }), +})); + describe('UrlStateContainer - lodash.throttle mocked to test update url', () => { afterEach(() => { jest.clearAllMocks(); diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/initialize_redux_by_url.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/initialize_redux_by_url.tsx index 013983c78a3a5..e182b879651f1 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/initialize_redux_by_url.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/initialize_redux_by_url.tsx @@ -6,7 +6,6 @@ import { get, isEmpty } from 'lodash/fp'; import { Dispatch } from 'redux'; -import { SavedQuery } from 'src/legacy/core_plugins/data/public'; import { Query, esFilters } from 'src/plugins/data/public'; import { inputsActions } from '../../store/actions'; @@ -17,7 +16,6 @@ import { AbsoluteTimeRange, RelativeTimeRange, } from '../../store/inputs/model'; -import { savedQueryService, siemFilterManager } from '../search_bar'; import { CONSTANTS } from './constants'; import { decodeRisonUrlState } from './helpers'; @@ -30,8 +28,10 @@ export const dispatchSetInitialStateFromUrl = ( ): DispatchSetInitialStateFromUrl => ({ apolloClient, detailName, + filterManager, indexPattern, pageName, + savedQueries, updateTimeline, updateTimelineIsLoading, urlStateToUpdate, @@ -125,14 +125,14 @@ export const dispatchSetInitialStateFromUrl = ( if (urlKey === CONSTANTS.filters) { const filters: esFilters.Filter[] = decodeRisonUrlState(newUrlStateString); - siemFilterManager.setFilters(filters || []); + filterManager.setFilters(filters || []); } if (urlKey === CONSTANTS.savedQuery) { const savedQueryId: string = decodeRisonUrlState(newUrlStateString); if (savedQueryId !== '') { - savedQueryService.getSavedQuery(savedQueryId).then((savedQueryData: SavedQuery) => { - siemFilterManager.setFilters(savedQueryData.attributes.filters || []); + savedQueries.getSavedQuery(savedQueryId).then(savedQueryData => { + filterManager.setFilters(savedQueryData.attributes.filters || []); dispatch( inputsActions.setFilterQuery({ id: 'global', diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts index be1ae1ad63bd4..b5ad26330e671 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts @@ -6,7 +6,13 @@ import ApolloClient from 'apollo-client'; import { ActionCreator } from 'typescript-fsa'; -import { IIndexPattern, Query, esFilters } from 'src/plugins/data/public'; +import { + IIndexPattern, + Query, + esFilters, + FilterManager, + SavedQueryService, +} from 'src/plugins/data/public'; import { UrlInputsModel } from '../../store/inputs/model'; import { RouteSpyState } from '../../utils/route/types'; @@ -120,8 +126,10 @@ export interface UrlStateToRedux { export interface SetInitialStateFromUrl { apolloClient: ApolloClient | ApolloClient<{}> | undefined; detailName: string | undefined; + filterManager: FilterManager; indexPattern: IIndexPattern | undefined; pageName: string; + savedQueries: SavedQueryService; updateTimeline: DispatchUpdateTimeline; updateTimelineIsLoading: ActionCreator; urlStateToUpdate: UrlStateToRedux[]; diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx index d7fece5731972..173eabe895c2b 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx @@ -9,6 +9,7 @@ import { isEqual, difference, isEmpty } from 'lodash/fp'; import { useEffect, useRef, useState } from 'react'; import { Query, esFilters } from 'src/plugins/data/public'; +import { useKibana } from '../../lib/kibana'; import { UrlInputsModel } from '../../store/inputs/model'; import { useApolloClient } from '../../utils/apollo_context'; @@ -56,6 +57,7 @@ export const useUrlStateHooks = ({ }: UrlStateContainerPropTypes) => { const [isInitializing, setIsInitializing] = useState(true); const apolloClient = useApolloClient(); + const { filterManager, savedQueries } = useKibana().services.data.query; const prevProps = usePrevious({ pathName, urlState }); const replaceStateInLocation = ( @@ -142,8 +144,10 @@ export const useUrlStateHooks = ({ setInitialStateFromUrl({ apolloClient, detailName, + filterManager, indexPattern, pageName, + savedQueries, updateTimeline, updateTimelineIsLoading, urlStateToUpdate, diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts index 06fb0c6dc3480..da98944d5f0c9 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/api.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from 'ui/new_platform'; - import { AddRulesProps, DeleteRulesProps, @@ -24,6 +22,7 @@ import { ImportRulesResponse, PrePackagedRulesStatusResponse, } from './types'; +import { KibanaServices } from '../../../lib/kibana'; import { throwIfNotOk } from '../../../hooks/api/api'; import { DETECTION_ENGINE_RULES_URL, @@ -41,7 +40,7 @@ import * as i18n from '../../../pages/detection_engine/rules/translations'; * @param signal to cancel request */ export const addRule = async ({ rule, signal }: AddRulesProps): Promise => { - const response = await npStart.core.http.fetch(DETECTION_ENGINE_RULES_URL, { + const response = await KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { method: rule.id != null ? 'PUT' : 'POST', body: JSON.stringify(rule), asResponse: true, @@ -95,7 +94,7 @@ export const fetchRules = async ({ ...(filters.length ? { filter: filters.join(' AND ') } : {}), }; - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `${DETECTION_ENGINE_RULES_URL}/_find`, { method: 'GET', @@ -117,7 +116,7 @@ export const fetchRules = async ({ * */ export const fetchRuleById = async ({ id, signal }: FetchRuleProps): Promise => { - const response = await npStart.core.http.fetch(DETECTION_ENGINE_RULES_URL, { + const response = await KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { method: 'GET', query: { id }, asResponse: true, @@ -137,7 +136,7 @@ export const fetchRuleById = async ({ id, signal }: FetchRuleProps): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `${DETECTION_ENGINE_RULES_URL}/_bulk_update`, { method: 'PUT', @@ -158,7 +157,7 @@ export const enableRules = async ({ ids, enabled }: EnableRulesProps): Promise> => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`, { method: 'PUT', @@ -177,7 +176,7 @@ export const deleteRules = async ({ ids }: DeleteRulesProps): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `${DETECTION_ENGINE_RULES_URL}/_bulk_create`, { method: 'POST', @@ -215,11 +214,14 @@ export const duplicateRules = async ({ rules }: DuplicateRulesProps): Promise => { - const response = await npStart.core.http.fetch(DETECTION_ENGINE_PREPACKAGED_URL, { - method: 'PUT', - signal, - asResponse: true, - }); + const response = await KibanaServices.get().http.fetch( + DETECTION_ENGINE_PREPACKAGED_URL, + { + method: 'PUT', + signal, + asResponse: true, + } + ); await throwIfNotOk(response.response); return true; @@ -242,7 +244,7 @@ export const importRules = async ({ const formData = new FormData(); formData.append('file', fileToImport); - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( `${DETECTION_ENGINE_RULES_URL}/_import`, { method: 'POST', @@ -279,16 +281,19 @@ export const exportRules = async ({ ? JSON.stringify({ objects: ruleIds.map(rule => ({ rule_id: rule })) }) : undefined; - const response = await npStart.core.http.fetch(`${DETECTION_ENGINE_RULES_URL}/_export`, { - method: 'POST', - body, - query: { - exclude_export_details: excludeExportDetails, - file_name: filename, - }, - signal, - asResponse: true, - }); + const response = await KibanaServices.get().http.fetch( + `${DETECTION_ENGINE_RULES_URL}/_export`, + { + method: 'POST', + body, + query: { + exclude_export_details: excludeExportDetails, + file_name: filename, + }, + signal, + asResponse: true, + } + ); await throwIfNotOk(response.response); return response.body!; @@ -309,7 +314,7 @@ export const getRuleStatusById = async ({ id: string; signal: AbortSignal; }): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( DETECTION_ENGINE_RULES_STATUS_URL, { method: 'GET', @@ -330,7 +335,7 @@ export const getRuleStatusById = async ({ * */ export const fetchTags = async ({ signal }: { signal: AbortSignal }): Promise => { - const response = await npStart.core.http.fetch(DETECTION_ENGINE_TAGS_URL, { + const response = await KibanaServices.get().http.fetch(DETECTION_ENGINE_TAGS_URL, { method: 'GET', signal, asResponse: true, @@ -352,7 +357,7 @@ export const getPrePackagedRulesStatus = async ({ }: { signal: AbortSignal; }): Promise => { - const response = await npStart.core.http.fetch( + const response = await KibanaServices.get().http.fetch( DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL, { method: 'GET', diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts index d0da70e646124..085bde3e54ef1 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/api.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from 'ui/new_platform'; - +import { KibanaServices } from '../../../lib/kibana'; import { throwIfNotOk } from '../../../hooks/api/api'; import { DETECTION_ENGINE_QUERY_SIGNALS_URL, @@ -33,7 +32,7 @@ export const fetchQuerySignals = async ({ query, signal, }: QuerySignals): Promise> => { - const response = await npStart.core.http.fetch>( + const response = await KibanaServices.get().http.fetch>( DETECTION_ENGINE_QUERY_SIGNALS_URL, { method: 'POST', @@ -59,7 +58,7 @@ export const updateSignalStatus = async ({ status, signal, }: UpdateSignalStatusProps): Promise => { - const response = await npStart.core.http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { + const response = await KibanaServices.get().http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { method: 'POST', body: JSON.stringify({ status, ...query }), asResponse: true, @@ -77,7 +76,7 @@ export const updateSignalStatus = async ({ */ export const getSignalIndex = async ({ signal }: BasicSignals): Promise => { try { - return await npStart.core.http.fetch(DETECTION_ENGINE_INDEX_URL, { + return await KibanaServices.get().http.fetch(DETECTION_ENGINE_INDEX_URL, { method: 'GET', signal, }); @@ -95,11 +94,14 @@ export const getSignalIndex = async ({ signal }: BasicSignals): Promise => { - const response = await npStart.core.http.fetch(DETECTION_ENGINE_PRIVILEGES_URL, { - method: 'GET', - signal, - asResponse: true, - }); + const response = await KibanaServices.get().http.fetch( + DETECTION_ENGINE_PRIVILEGES_URL, + { + method: 'GET', + signal, + asResponse: true, + } + ); await throwIfNotOk(response.response); return response.body!; @@ -112,7 +114,7 @@ export const getUserPrivilege = async ({ signal }: BasicSignals): Promise => { try { - return await npStart.core.http.fetch(DETECTION_ENGINE_INDEX_URL, { + return await KibanaServices.get().http.fetch(DETECTION_ENGINE_INDEX_URL, { method: 'POST', signal, }); diff --git a/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx b/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx index f5f32da7d8c0b..e29e2ed193f94 100644 --- a/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx +++ b/x-pack/legacy/plugins/siem/public/hooks/api/api.tsx @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from 'ui/new_platform'; import * as i18n from '../translations'; +import { StartServices } from '../../plugin'; import { parseJsonFromBody, ToasterErrors } from '../../components/ml/api/throw_if_not_ok'; import { IndexPatternSavedObject, IndexPatternSavedObjectAttributes } from '../types'; @@ -14,8 +14,10 @@ import { IndexPatternSavedObject, IndexPatternSavedObjectAttributes } from '../t * * TODO: Refactor to context provider: https://github.com/elastic/siem-team/issues/448 */ -export const getIndexPatterns = async (): Promise => { - const response = await npStart.core.savedObjects.client.find({ +export const getIndexPatterns = async ( + savedObjects: StartServices['savedObjects'] +): Promise => { + const response = await savedObjects.client.find({ type: 'index-pattern', fields: ['title'], perPage: 10000, diff --git a/x-pack/legacy/plugins/siem/public/hooks/index.ts b/x-pack/legacy/plugins/siem/public/hooks/index.ts deleted file mode 100644 index 5049e4587d383..0000000000000 --- a/x-pack/legacy/plugins/siem/public/hooks/index.ts +++ /dev/null @@ -1,7 +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. - */ - -export { useDateFormat, useTimeZone } from './use_ui_settings'; diff --git a/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx b/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx index 35bed69e8617e..e10d4873f1b6e 100644 --- a/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx +++ b/x-pack/legacy/plugins/siem/public/hooks/use_index_patterns.tsx @@ -6,6 +6,7 @@ import { useEffect, useState } from 'react'; +import { useKibana } from '../lib/kibana'; import { useStateToaster } from '../components/toasters'; import { errorToToaster } from '../components/ml/api/error_to_toaster'; @@ -19,6 +20,7 @@ export const useIndexPatterns = (refreshToggle = false): Return => { const [indexPatterns, setIndexPatterns] = useState([]); const [isLoading, setIsLoading] = useState(true); const [, dispatchToaster] = useStateToaster(); + const { savedObjects } = useKibana().services; useEffect(() => { let isSubscribed = true; @@ -26,7 +28,7 @@ export const useIndexPatterns = (refreshToggle = false): Return => { async function fetchIndexPatterns() { try { - const data = await getIndexPatterns(); + const data = await getIndexPatterns(savedObjects); if (isSubscribed) { setIndexPatterns(data); diff --git a/x-pack/legacy/plugins/siem/public/lib/compose/helpers.test.ts b/x-pack/legacy/plugins/siem/public/lib/compose/helpers.test.ts index b135e299e2e43..af4521b4f6e2c 100644 --- a/x-pack/legacy/plugins/siem/public/lib/compose/helpers.test.ts +++ b/x-pack/legacy/plugins/siem/public/lib/compose/helpers.test.ts @@ -21,7 +21,7 @@ const mockHttpLink = { mockHttpLink: 'mockHttpLink' }; // @ts-ignore withClientState.mockReturnValue(mockWithClientState); // @ts-ignore -apolloLinkHttp.HttpLink.mockImplementation(() => mockHttpLink); +apolloLinkHttp.createHttpLink.mockImplementation(() => mockHttpLink); describe('getLinks helper', () => { test('It should return links in correct order', () => { @@ -31,7 +31,7 @@ describe('getLinks helper', () => { introspectionQueryResultData, }), }); - const links = getLinks(mockCache); + const links = getLinks(mockCache, 'basePath'); expect(links[0]).toEqual(errorLink); expect(links[1]).toEqual(reTryOneTimeOnErrorLink); expect(links[2]).toEqual(mockWithClientState); diff --git a/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts b/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts index 9cdd4148134ad..b698fc55cc5e5 100644 --- a/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/lib/compose/helpers.ts @@ -4,23 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HttpLink } from 'apollo-link-http'; +import { createHttpLink } from 'apollo-link-http'; import { withClientState } from 'apollo-link-state'; import { InMemoryCache } from 'apollo-cache-inmemory'; -import chrome from 'ui/chrome'; import { errorLink, reTryOneTimeOnErrorLink } from '../../containers/errors'; -export const getLinks = (cache: InMemoryCache) => [ +export const getLinks = (cache: InMemoryCache, basePath: string) => [ errorLink, reTryOneTimeOnErrorLink, withClientState({ cache, resolvers: {}, }), - new HttpLink({ + createHttpLink({ credentials: 'same-origin', headers: { 'kbn-xsrf': 'true' }, - uri: `${chrome.getBasePath()}/api/siem/graphql`, + uri: `${basePath}/api/siem/graphql`, }), ]; diff --git a/x-pack/legacy/plugins/siem/public/lib/compose/kibana_compose.tsx b/x-pack/legacy/plugins/siem/public/lib/compose/kibana_compose.tsx index 00dfbcd8a4d8f..c742ced4c504c 100644 --- a/x-pack/legacy/plugins/siem/public/lib/compose/kibana_compose.tsx +++ b/x-pack/legacy/plugins/siem/public/lib/compose/kibana_compose.tsx @@ -7,29 +7,26 @@ import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'; import ApolloClient from 'apollo-client'; import { ApolloLink } from 'apollo-link'; -import 'ui/autoload/all'; -// @ts-ignore: path dynamic for kibana -import { uiModules } from 'ui/modules'; import introspectionQueryResultData from '../../graphql/introspection.json'; +import { CoreStart } from '../../plugin'; import { AppFrontendLibs } from '../lib'; import { getLinks } from './helpers'; -export function compose(): AppFrontendLibs { +export function compose(core: CoreStart): AppFrontendLibs { const cache = new InMemoryCache({ dataIdFromObject: () => null, fragmentMatcher: new IntrospectionFragmentMatcher({ introspectionQueryResultData, }), }); + const basePath = core.http.basePath.get(); - const graphQLOptions = { + const apolloClient = new ApolloClient({ connectToDevTools: process.env.NODE_ENV !== 'production', cache, - link: ApolloLink.from(getLinks(cache)), - }; - - const apolloClient = new ApolloClient(graphQLOptions); + link: ApolloLink.from(getLinks(cache, basePath)), + }); const libs: AppFrontendLibs = { apolloClient, diff --git a/x-pack/legacy/plugins/siem/public/lib/kibana/__mocks__/index.ts b/x-pack/legacy/plugins/siem/public/lib/kibana/__mocks__/index.ts index 93fd37c4d14cb..227680d79912f 100644 --- a/x-pack/legacy/plugins/siem/public/lib/kibana/__mocks__/index.ts +++ b/x-pack/legacy/plugins/siem/public/lib/kibana/__mocks__/index.ts @@ -12,8 +12,12 @@ import { createWithKibanaMock, } from '../../../mock/kibana_react'; +export const KibanaServices = { get: jest.fn() }; export const useKibana = jest.fn(createUseKibanaMock()); export const useUiSetting = jest.fn(createUseUiSettingMock()); export const useUiSetting$ = jest.fn(createUseUiSetting$Mock()); +export const useTimeZone = jest.fn(); +export const useDateFormat = jest.fn(); +export const useBasePath = jest.fn(() => '/test/base/path'); export const withKibana = jest.fn(createWithKibanaMock()); export const KibanaContextProvider = jest.fn(createKibanaContextProviderMock()); diff --git a/x-pack/legacy/plugins/siem/public/hooks/use_ui_settings.ts b/x-pack/legacy/plugins/siem/public/lib/kibana/hooks.ts similarity index 78% rename from x-pack/legacy/plugins/siem/public/hooks/use_ui_settings.ts rename to x-pack/legacy/plugins/siem/public/lib/kibana/hooks.ts index 7eb0242e8e116..a4a70c77833c0 100644 --- a/x-pack/legacy/plugins/siem/public/hooks/use_ui_settings.ts +++ b/x-pack/legacy/plugins/siem/public/lib/kibana/hooks.ts @@ -6,8 +6,8 @@ import moment from 'moment-timezone'; -import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_FORMAT_TZ } from '../../common/constants'; -import { useUiSetting } from '../lib/kibana'; +import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_FORMAT_TZ } from '../../../common/constants'; +import { useUiSetting, useKibana } from './kibana_react'; export const useDateFormat = (): string => useUiSetting(DEFAULT_DATE_FORMAT); @@ -15,3 +15,5 @@ export const useTimeZone = (): string => { const timeZone = useUiSetting(DEFAULT_DATE_FORMAT_TZ); return timeZone === 'Browser' ? moment.tz.guess() : timeZone; }; + +export const useBasePath = (): string => useKibana().services.http.basePath.get(); diff --git a/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts b/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts index 012a1cfef5da2..fd201d51e73a6 100644 --- a/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts +++ b/x-pack/legacy/plugins/siem/public/lib/kibana/index.ts @@ -4,28 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - KibanaContextProvider, - KibanaReactContextValue, - useKibana, - useUiSetting, - useUiSetting$, - withKibana, -} from '../../../../../../../src/plugins/kibana_react/public'; -import { StartServices } from '../../plugin'; - -export type KibanaContext = KibanaReactContextValue; -export interface WithKibanaProps { - kibana: KibanaContext; -} - -// eslint-disable-next-line react-hooks/rules-of-hooks -const typedUseKibana = () => useKibana(); - -export { - KibanaContextProvider, - typedUseKibana as useKibana, - useUiSetting, - useUiSetting$, - withKibana, -}; +export * from './hooks'; +export * from './kibana_react'; +export * from './services'; diff --git a/x-pack/legacy/plugins/siem/public/lib/kibana/kibana_react.ts b/x-pack/legacy/plugins/siem/public/lib/kibana/kibana_react.ts new file mode 100644 index 0000000000000..012a1cfef5da2 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/lib/kibana/kibana_react.ts @@ -0,0 +1,31 @@ +/* + * 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 { + KibanaContextProvider, + KibanaReactContextValue, + useKibana, + useUiSetting, + useUiSetting$, + withKibana, +} from '../../../../../../../src/plugins/kibana_react/public'; +import { StartServices } from '../../plugin'; + +export type KibanaContext = KibanaReactContextValue; +export interface WithKibanaProps { + kibana: KibanaContext; +} + +// eslint-disable-next-line react-hooks/rules-of-hooks +const typedUseKibana = () => useKibana(); + +export { + KibanaContextProvider, + typedUseKibana as useKibana, + useUiSetting, + useUiSetting$, + withKibana, +}; diff --git a/x-pack/legacy/plugins/siem/public/lib/kibana/services.ts b/x-pack/legacy/plugins/siem/public/lib/kibana/services.ts new file mode 100644 index 0000000000000..3a6a3f13dc5ce --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/lib/kibana/services.ts @@ -0,0 +1,27 @@ +/* + * 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 { StartServices } from '../../plugin'; + +type GlobalServices = Pick; + +export class KibanaServices { + private static services?: GlobalServices; + + public static init({ http, uiSettings }: StartServices) { + this.services = { http, uiSettings }; + } + + public static get(): GlobalServices { + if (!this.services) { + throw new Error( + 'Kibana services not set - are you trying to import this module from outside of the SIEM app?' + ); + } + + return this.services; + } +} diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx index bf7a2109fd3b5..7516bb13a9e75 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx @@ -5,19 +5,16 @@ */ import React from 'react'; -import chrome from 'ui/chrome'; import { useKibana } from '../../lib/kibana'; import { EmptyPage } from '../../components/empty_page'; import * as i18n from '../common/translations'; -const basePath = chrome.getBasePath(); - export const DetectionEngineEmptyPage = React.memo(() => ( const isRuleEditPage = (pathname: string) => pathname.includes('/rules') && pathname.includes('/edit'); -export const getBreadcrumbs = (params: RouteSpyState, search: string[]): Breadcrumb[] => { +export const getBreadcrumbs = (params: RouteSpyState, search: string[]): ChromeBreadcrumb[] => { let breadcrumb = [ { text: i18nDetections.PAGE_TITLE, diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts b/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts index c321478f10174..c4680dc3d795e 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/utils.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Breadcrumb } from 'ui/chrome'; import { get, isEmpty } from 'lodash/fp'; +import { ChromeBreadcrumb } from '../../../../../../../../src/core/public'; import { hostsModel } from '../../../store'; import { HostsTableType } from '../../../store/hosts/model'; import { getHostsUrl, getHostDetailsUrl } from '../../../components/link_to/redirect_to_hosts'; @@ -25,7 +25,7 @@ const TabNameMappedToI18nKey: Record = { [HostsTableType.alerts]: i18n.NAVIGATION_ALERTS_TITLE, }; -export const getBreadcrumbs = (params: HostRouteSpyState, search: string[]): Breadcrumb[] => { +export const getBreadcrumbs = (params: HostRouteSpyState, search: string[]): ChromeBreadcrumb[] => { let breadcrumb = [ { text: i18n.PAGE_TITLE, diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_empty_page.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_empty_page.tsx index c29e532b3d513..bded0b90e187b 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_empty_page.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_empty_page.tsx @@ -5,17 +5,15 @@ */ import React from 'react'; -import chrome from 'ui/chrome'; import { EmptyPage } from '../../components/empty_page'; import { useKibana } from '../../lib/kibana'; import * as i18n from '../common/translations'; -const basePath = chrome.getBasePath(); - export const HostsEmptyPage = React.memo(() => { - const docLinks = useKibana().services.docLinks; + const { http, docLinks } = useKibana().services; + const basePath = http.basePath.get(); return ( = { [NetworkRouteType.tls]: i18n.NAVIGATION_TLS_TITLE, }; -export const getBreadcrumbs = (params: NetworkRouteSpyState, search: string[]): Breadcrumb[] => { +export const getBreadcrumbs = ( + params: NetworkRouteSpyState, + search: string[] +): ChromeBreadcrumb[] => { let breadcrumb = [ { text: i18n.PAGE_TITLE, diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network_empty_page.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network_empty_page.tsx index 78a3ae147fd0f..22db00400bf8a 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/network_empty_page.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/network_empty_page.tsx @@ -5,16 +5,14 @@ */ import React from 'react'; -import chrome from 'ui/chrome'; import { useKibana } from '../../lib/kibana'; import { EmptyPage } from '../../components/empty_page'; import * as i18n from '../common/translations'; -const basePath = chrome.getBasePath(); - export const NetworkEmptyPage = React.memo(() => { - const docLinks = useKibana().services.docLinks; + const { http, docLinks } = useKibana().services; + const basePath = http.basePath.get(); return ( ({ - getBasePath: () => { - return ''; - }, getKibanaVersion: () => { return 'v8.0.0'; }, breadcrumbs: { set: jest.fn(), }, - getUiSettingsClient: () => ({ - get: jest.fn(), - }), })); // Test will fail because we will to need to mock some core services to make the test work diff --git a/x-pack/legacy/plugins/siem/public/pages/overview/overview_empty/index.tsx b/x-pack/legacy/plugins/siem/public/pages/overview/overview_empty/index.tsx index 9565b764b09e7..1325826f172c7 100644 --- a/x-pack/legacy/plugins/siem/public/pages/overview/overview_empty/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/overview/overview_empty/index.tsx @@ -5,16 +5,14 @@ */ import React from 'react'; -import chrome from 'ui/chrome'; import * as i18nCommon from '../../common/translations'; import { EmptyPage } from '../../../components/empty_page'; import { useKibana } from '../../../lib/kibana'; -const basePath = chrome.getBasePath(); - const OverviewEmptyComponent: React.FC = () => { - const docLinks = useKibana().services.docLinks; + const { http, docLinks } = useKibana().services; + const basePath = http.basePath.get(); return ( { id: this.id, title: this.name, async mount(context, params) { - const [coreStart, pluginsStart] = await core.getStartServices(); + const [coreStart, startPlugins] = await core.getStartServices(); const { renderApp } = await import('./app'); - return renderApp(coreStart, pluginsStart as StartPlugins, params); + return renderApp(coreStart, startPlugins as StartPlugins, params); }, }); @@ -66,6 +67,8 @@ export class Plugin implements IPlugin { } public start(core: CoreStart, plugins: StartPlugins) { + KibanaServices.init({ ...core, ...plugins }); + return {}; } diff --git a/x-pack/legacy/plugins/siem/public/store/inputs/reducer.ts b/x-pack/legacy/plugins/siem/public/store/inputs/reducer.ts index 8f9f8809a1e86..b64d7cea47e0f 100644 --- a/x-pack/legacy/plugins/siem/public/store/inputs/reducer.ts +++ b/x-pack/legacy/plugins/siem/public/store/inputs/reducer.ts @@ -7,6 +7,7 @@ import { get } from 'lodash/fp'; import { reducerWithInitialState } from 'typescript-fsa-reducers'; +import { getIntervalSettings, getTimeRangeSettings } from '../../utils/default_date_settings'; import { deleteAllQuery, setAbsoluteRangeDatePicker, @@ -39,14 +40,6 @@ import { deleteOneQuery as helperDeleteOneQuery, } from './helpers'; import { InputsModel, TimeRange } from './model'; -import { - getDefaultFromValue, - getDefaultToValue, - getDefaultFromString, - getDefaultToString, - getDefaultIntervalKind, - getDefaultIntervalDuration, -} from '../../utils/default_date_settings'; export type InputsState = InputsModel; @@ -54,16 +47,10 @@ export const initialInputsState: InputsState = { global: { timerange: { kind: 'relative', - fromStr: getDefaultFromString(), - toStr: getDefaultToString(), - from: getDefaultFromValue(), - to: getDefaultToValue(), + ...getTimeRangeSettings(false), }, queries: [], - policy: { - kind: getDefaultIntervalKind(), - duration: getDefaultIntervalDuration(), - }, + policy: getIntervalSettings(false), linkTo: ['timeline'], query: { query: '', @@ -74,16 +61,10 @@ export const initialInputsState: InputsState = { timeline: { timerange: { kind: 'relative', - fromStr: getDefaultFromString(), - toStr: getDefaultToString(), - from: getDefaultFromValue(), - to: getDefaultToValue(), + ...getTimeRangeSettings(false), }, queries: [], - policy: { - kind: getDefaultIntervalKind(), - duration: getDefaultIntervalDuration(), - }, + policy: getIntervalSettings(false), linkTo: ['global'], query: { query: '', @@ -93,6 +74,54 @@ export const initialInputsState: InputsState = { }, }; +export const createInitialInputsState = (): InputsState => { + const { from, fromStr, to, toStr } = getTimeRangeSettings(); + const { kind, duration } = getIntervalSettings(); + + return { + global: { + timerange: { + kind: 'relative', + fromStr, + toStr, + from, + to, + }, + queries: [], + policy: { + kind, + duration, + }, + linkTo: ['timeline'], + query: { + query: '', + language: 'kuery', + }, + filters: [], + }, + timeline: { + timerange: { + kind: 'relative', + fromStr, + toStr, + from, + to, + }, + queries: [], + policy: { + kind, + duration, + }, + linkTo: ['global'], + query: { + query: '', + language: 'kuery', + }, + filters: [], + }, + }; +}; + export const inputsReducer = reducerWithInitialState(initialInputsState) .case(setTimelineRangeDatePicker, (state, { from, to }) => { return { diff --git a/x-pack/legacy/plugins/siem/public/store/reducer.ts b/x-pack/legacy/plugins/siem/public/store/reducer.ts index 3c93dfa61b768..32554653febd5 100644 --- a/x-pack/legacy/plugins/siem/public/store/reducer.ts +++ b/x-pack/legacy/plugins/siem/public/store/reducer.ts @@ -9,7 +9,7 @@ import { combineReducers } from 'redux'; import { appReducer, AppState, initialAppState } from './app'; import { dragAndDropReducer, DragAndDropState, initialDragAndDropState } from './drag_and_drop'; import { hostsReducer, HostsState, initialHostsState } from './hosts'; -import { initialInputsState, inputsReducer, InputsState } from './inputs'; +import { createInitialInputsState, initialInputsState, inputsReducer, InputsState } from './inputs'; import { initialNetworkState, networkReducer, NetworkState } from './network'; import { initialTimelineState, timelineReducer } from './timeline/reducer'; import { TimelineState } from './timeline/types'; @@ -32,6 +32,11 @@ export const initialState: State = { timeline: initialTimelineState, }; +export const createInitialState = (): State => ({ + ...initialState, + inputs: createInitialInputsState(), +}); + export const reducer = combineReducers({ app: appReducer, dragAndDrop: dragAndDropReducer, diff --git a/x-pack/legacy/plugins/siem/public/utils/default_date_settings.test.ts b/x-pack/legacy/plugins/siem/public/utils/default_date_settings.test.ts index 2507c2cf81c51..9dc179ba7a6e2 100644 --- a/x-pack/legacy/plugins/siem/public/utils/default_date_settings.test.ts +++ b/x-pack/legacy/plugins/siem/public/utils/default_date_settings.test.ts @@ -4,19 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import chrome from 'ui/chrome'; +import moment from 'moment'; + import { - getDefaultFromString, + getTimeRangeSettings, + getIntervalSettings, DefaultTimeRangeSetting, - getDefaultToString, - getDefaultFromValue, - getDefaultToValue, - getDefaultFromMoment, - getDefaultToMoment, DefaultIntervalSetting, - getDefaultIntervalKind, - getDefaultIntervalDuration, - parseDateString, parseDateWithDefault, } from './default_date_settings'; import { @@ -28,8 +22,8 @@ import { DEFAULT_INTERVAL_VALUE, DEFAULT_INTERVAL_TYPE, } from '../../common/constants'; +import { KibanaServices } from '../lib/kibana'; import { Policy } from '../store/inputs/model'; -import moment from 'moment'; // Change the constants to be static values so we can test against those instead of // relative sliding date times. Jest cannot access these outer scoped variables so @@ -46,6 +40,9 @@ jest.mock('../../common/constants', () => ({ DEFAULT_SIEM_TIME_RANGE: 'siem:timeDefaults', })); +jest.mock('../lib/kibana'); +const mockGetServices = KibanaServices.get as jest.Mock; + /** * We utilize the internal chrome mocking that is built in to be able to mock different time range * scenarios here or the absence of a time range setting. @@ -59,16 +56,20 @@ const mockTimeRange = ( value: DEFAULT_INTERVAL_VALUE, } ) => { - chrome.getUiSettingsClient().get.mockImplementation((key: string) => { - switch (key) { - case DEFAULT_SIEM_TIME_RANGE: - return timeRange; - case DEFAULT_SIEM_REFRESH_INTERVAL: - return interval; - default: - throw new Error(`Unexpected config key: ${key}`); - } - }); + mockGetServices.mockImplementation(() => ({ + uiSettings: { + get: (key: string) => { + switch (key) { + case DEFAULT_SIEM_TIME_RANGE: + return timeRange; + case DEFAULT_SIEM_REFRESH_INTERVAL: + return interval; + default: + throw new Error(`Unexpected config key: ${key}`); + } + }, + }, + })); }; /** @@ -87,445 +88,392 @@ const isMalformedTimeRange = (timeRange: unknown): timeRange is DefaultTimeRange const isMalformedInterval = (interval: unknown): interval is DefaultIntervalSetting => typeof interval === 'object'; -describe('default_date_settings', () => { - beforeEach(() => { - chrome.getUiSettingsClient().get.mockClear(); - }); - - describe('#getDefaultFromString', () => { +describe('getTimeRangeSettings', () => { + describe('fromStr', () => { test('should return the DEFAULT_FROM constant by default', () => { mockTimeRange(); - const stringDefault = getDefaultFromString(); - expect(stringDefault).toBe(DEFAULT_FROM); + const { fromStr } = getTimeRangeSettings(); + expect(fromStr).toBe(DEFAULT_FROM); }); test('should return a custom from range', () => { mockTimeRange({ from: 'now-15m' }); - const stringDefault = getDefaultFromString(); - expect(stringDefault).toBe('now-15m'); + const { fromStr } = getTimeRangeSettings(); + expect(fromStr).toBe('now-15m'); }); test('should return the DEFAULT_FROM when the whole object is null', () => { mockTimeRange(null); - const stringDefault = getDefaultFromString(); - expect(stringDefault).toBe(DEFAULT_FROM); + const { fromStr } = getTimeRangeSettings(); + expect(fromStr).toBe(DEFAULT_FROM); }); test('should return the DEFAULT_FROM when the whole object is undefined', () => { mockTimeRange(null); - const stringDefault = getDefaultFromString(); - expect(stringDefault).toBe(DEFAULT_FROM); + const { fromStr } = getTimeRangeSettings(); + expect(fromStr).toBe(DEFAULT_FROM); }); test('should return the DEFAULT_FROM when the from value is null', () => { mockTimeRange({ from: null }); - const stringDefault = getDefaultFromString(); - expect(stringDefault).toBe(DEFAULT_FROM); + const { fromStr } = getTimeRangeSettings(); + expect(fromStr).toBe(DEFAULT_FROM); }); test('should return the DEFAULT_FROM when the from value is undefined', () => { mockTimeRange({ from: undefined }); - const stringDefault = getDefaultFromString(); - expect(stringDefault).toBe(DEFAULT_FROM); + const { fromStr } = getTimeRangeSettings(); + expect(fromStr).toBe(DEFAULT_FROM); }); test('should return the DEFAULT_FROM when the from value is malformed', () => { const malformedTimeRange = { from: true }; if (isMalformedTimeRange(malformedTimeRange)) { mockTimeRange(malformedTimeRange); - const stringDefault = getDefaultFromString(); - expect(stringDefault).toBe(DEFAULT_FROM); + const { fromStr } = getTimeRangeSettings(); + expect(fromStr).toBe(DEFAULT_FROM); } else { throw Error('Was expecting an object to be used for the malformed time range'); } }); + + describe('without UISettings', () => { + beforeEach(() => { + mockGetServices.mockImplementation(() => { + throw new Error('should not have been called'); + }); + }); + + it('is DEFAULT_FROM', () => { + const { fromStr } = getTimeRangeSettings(false); + expect(fromStr).toBe(DEFAULT_FROM); + }); + }); }); - describe('#getDefaultToString', () => { + describe('toStr', () => { test('should return the DEFAULT_TO constant by default', () => { mockTimeRange(); - const stringDefault = getDefaultToString(); - expect(stringDefault).toBe(DEFAULT_TO); + const { toStr } = getTimeRangeSettings(); + expect(toStr).toBe(DEFAULT_TO); }); test('should return a custom from range', () => { mockTimeRange({ to: 'now-15m' }); - const stringDefault = getDefaultToString(); - expect(stringDefault).toBe('now-15m'); + const { toStr } = getTimeRangeSettings(); + expect(toStr).toBe('now-15m'); }); test('should return the DEFAULT_TO when the whole object is null', () => { mockTimeRange(null); - const stringDefault = getDefaultToString(); - expect(stringDefault).toBe(DEFAULT_TO); + const { toStr } = getTimeRangeSettings(); + expect(toStr).toBe(DEFAULT_TO); }); test('should return the DEFAULT_TO when the whole object is undefined', () => { mockTimeRange(null); - const stringDefault = getDefaultToString(); - expect(stringDefault).toBe(DEFAULT_TO); + const { toStr } = getTimeRangeSettings(); + expect(toStr).toBe(DEFAULT_TO); }); test('should return the DEFAULT_TO when the to value is null', () => { mockTimeRange({ from: null }); - const stringDefault = getDefaultToString(); - expect(stringDefault).toBe(DEFAULT_TO); + const { toStr } = getTimeRangeSettings(); + expect(toStr).toBe(DEFAULT_TO); }); test('should return the DEFAULT_TO when the from value is undefined', () => { mockTimeRange({ to: undefined }); - const stringDefault = getDefaultToString(); - expect(stringDefault).toBe(DEFAULT_TO); + const { toStr } = getTimeRangeSettings(); + expect(toStr).toBe(DEFAULT_TO); }); test('should return the DEFAULT_TO when the to value is malformed', () => { const malformedTimeRange = { to: true }; if (isMalformedTimeRange(malformedTimeRange)) { mockTimeRange(malformedTimeRange); - const stringDefault = getDefaultToString(); - expect(stringDefault).toBe(DEFAULT_TO); + const { toStr } = getTimeRangeSettings(); + expect(toStr).toBe(DEFAULT_TO); } else { throw Error('Was expecting an object to be used for the malformed time range'); } }); + + describe('without UISettings', () => { + beforeEach(() => { + mockGetServices.mockImplementation(() => { + throw new Error('should not have been called'); + }); + }); + + it('is DEFAULT_TO', () => { + const { toStr } = getTimeRangeSettings(false); + expect(toStr).toBe(DEFAULT_TO); + }); + }); }); - describe('#getDefaultFromValue', () => { + describe('from', () => { test('should return DEFAULT_FROM', () => { mockTimeRange(); - const value = getDefaultFromValue(); - expect(value).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + const { from } = getTimeRangeSettings(); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); }); test('should return a custom from range', () => { - const from = '2019-08-30T17:49:18.396Z'; - mockTimeRange({ from }); - const value = getDefaultFromValue(); - expect(value).toBe(new Date(from).valueOf()); + const mockFrom = '2019-08-30T17:49:18.396Z'; + mockTimeRange({ from: mockFrom }); + const { from } = getTimeRangeSettings(); + expect(from).toBe(new Date(mockFrom).valueOf()); }); test('should return the DEFAULT_FROM when the whole object is null', () => { mockTimeRange(null); - const stringDefault = getDefaultFromValue(); - expect(stringDefault).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + const { from } = getTimeRangeSettings(); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); }); test('should return the DEFAULT_FROM when the whole object is undefined', () => { mockTimeRange(null); - const stringDefault = getDefaultFromValue(); - expect(stringDefault).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + const { from } = getTimeRangeSettings(); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); }); test('should return the DEFAULT_FROM when the from value is null', () => { mockTimeRange({ from: null }); - const stringDefault = getDefaultFromValue(); - expect(stringDefault).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + const { from } = getTimeRangeSettings(); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); }); test('should return the DEFAULT_FROM when the from value is undefined', () => { mockTimeRange({ from: undefined }); - const stringDefault = getDefaultFromValue(); - expect(stringDefault).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + const { from } = getTimeRangeSettings(); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); }); test('should return the DEFAULT_FROM when the from value is malformed', () => { const malformedTimeRange = { from: true }; if (isMalformedTimeRange(malformedTimeRange)) { mockTimeRange(malformedTimeRange); - const stringDefault = getDefaultFromValue(); - expect(stringDefault).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + const { from } = getTimeRangeSettings(); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); } else { throw Error('Was expecting an object to be used for the malformed time range'); } }); + + describe('without UISettings', () => { + beforeEach(() => { + mockGetServices.mockImplementation(() => { + throw new Error('should not have been called'); + }); + }); + + it('is DEFAULT_FROM in epoch', () => { + const { from } = getTimeRangeSettings(false); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + }); + }); }); - describe('#getDefaultToValue', () => { + describe('to', () => { test('should return DEFAULT_TO', () => { mockTimeRange(); - const value = getDefaultToValue(); - expect(value).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + const { to } = getTimeRangeSettings(); + expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); }); test('should return a custom from range', () => { - const to = '2000-08-30T17:49:18.396Z'; - mockTimeRange({ to }); - const value = getDefaultToValue(); - expect(value).toBe(new Date(to).valueOf()); + const mockTo = '2000-08-30T17:49:18.396Z'; + mockTimeRange({ to: mockTo }); + const { to } = getTimeRangeSettings(); + expect(to).toBe(new Date(mockTo).valueOf()); }); test('should return the DEFAULT_TO_DATE when the whole object is null', () => { mockTimeRange(null); - const stringDefault = getDefaultToValue(); - expect(stringDefault).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + const { to } = getTimeRangeSettings(); + expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); }); test('should return the DEFAULT_TO_DATE when the whole object is undefined', () => { mockTimeRange(null); - const stringDefault = getDefaultToValue(); - expect(stringDefault).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + const { to } = getTimeRangeSettings(); + expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); }); test('should return the DEFAULT_TO_DATE when the from value is null', () => { mockTimeRange({ from: null }); - const stringDefault = getDefaultToValue(); - expect(stringDefault).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + const { to } = getTimeRangeSettings(); + expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); }); test('should return the DEFAULT_TO_DATE when the from value is undefined', () => { mockTimeRange({ from: undefined }); - const stringDefault = getDefaultToValue(); - expect(stringDefault).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + const { to } = getTimeRangeSettings(); + expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); }); test('should return the DEFAULT_TO_DATE when the from value is malformed', () => { const malformedTimeRange = { from: true }; if (isMalformedTimeRange(malformedTimeRange)) { mockTimeRange(malformedTimeRange); - const stringDefault = getDefaultToValue(); - expect(stringDefault).toBe(new Date(DEFAULT_TO_DATE).valueOf()); - } else { - throw Error('Was expecting an object to be used for the malformed time range'); - } - }); - }); - - describe('#getDefaultFromMoment', () => { - test('should return DEFAULT_FROM', () => { - mockTimeRange(); - const value = getDefaultFromMoment(); - expect(value.valueOf()).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); - }); - - test('should return a custom from range', () => { - const from = '2019-08-30T17:49:18.396Z'; - mockTimeRange({ from }); - const value = getDefaultFromMoment(); - expect(value.valueOf()).toBe(new Date(from).valueOf()); - }); - - test('should return the DEFAULT_FROM when the whole object is null', () => { - mockTimeRange(null); - const defaultMoment = getDefaultFromMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); - }); - - test('should return the DEFAULT_FROM when the whole object is undefined', () => { - mockTimeRange(null); - const defaultMoment = getDefaultFromMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); - }); - - test('should return the DEFAULT_FROM when the from value is null', () => { - mockTimeRange({ from: null }); - const defaultMoment = getDefaultFromMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); - }); - - test('should return the DEFAULT_FROM when the from value is undefined', () => { - mockTimeRange({ from: undefined }); - const defaultMoment = getDefaultFromMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); - }); - - test('should return the DEFAULT_FROM when the from value is malformed', () => { - const malformedTimeRange = { from: true }; - if (isMalformedTimeRange(malformedTimeRange)) { - mockTimeRange(malformedTimeRange); - const defaultMoment = getDefaultFromMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + const { to } = getTimeRangeSettings(); + expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); } else { throw Error('Was expecting an object to be used for the malformed time range'); } }); - }); - - describe('#getDefaultToMoment', () => { - test('should return DEFAULT_TO', () => { - mockTimeRange(); - const value = getDefaultToMoment(); - expect(value.valueOf()).toBe(new Date(DEFAULT_TO).valueOf()); - }); - - test('should return a custom range', () => { - const to = '2019-08-30T17:49:18.396Z'; - mockTimeRange({ to }); - const value = getDefaultToMoment(); - expect(value.valueOf()).toBe(new Date(to).valueOf()); - }); - test('should return the DEFAULT_TO when the whole object is null', () => { - mockTimeRange(null); - const defaultMoment = getDefaultToMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_TO).valueOf()); - }); - - test('should return the DEFAULT_TO when the whole object is undefined', () => { - mockTimeRange(null); - const defaultMoment = getDefaultToMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_TO).valueOf()); - }); - - test('should return the DEFAULT_TO when the from value is null', () => { - mockTimeRange({ from: null }); - const defaultMoment = getDefaultToMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_TO).valueOf()); - }); - - test('should return the DEFAULT_TO when the from value is undefined', () => { - mockTimeRange({ from: undefined }); - const defaultMoment = getDefaultToMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_TO).valueOf()); - }); + describe('without UISettings', () => { + beforeEach(() => { + mockGetServices.mockImplementation(() => { + throw new Error('should not have been called'); + }); + }); - test('should return the DEFAULT_TO when the from value is malformed', () => { - const malformedTimeRange = { from: true }; - if (isMalformedTimeRange(malformedTimeRange)) { - mockTimeRange(malformedTimeRange); - const defaultMoment = getDefaultToMoment(); - expect(defaultMoment.valueOf()).toBe(new Date(DEFAULT_TO).valueOf()); - } else { - throw Error('Was expecting an object to be used for the malformed time range'); - } + it('is DEFAULT_TO in epoch', () => { + const { to } = getTimeRangeSettings(false); + expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + }); }); }); +}); - describe('#getDefaultIntervalKind', () => { +describe('getIntervalSettings', () => { + describe('kind', () => { test('should return default', () => { mockTimeRange(); - const value = getDefaultIntervalKind(); - expect(value).toBe(DEFAULT_INTERVAL_TYPE); + const { kind } = getIntervalSettings(); + expect(kind).toBe(DEFAULT_INTERVAL_TYPE); }); test('should return an interval when given non paused value', () => { const interval: DefaultIntervalSetting = { pause: false }; mockTimeRange(undefined, interval); - const value = getDefaultIntervalKind(); + const { kind } = getIntervalSettings(); const expected: Policy['kind'] = 'interval'; - expect(value).toBe(expected); + expect(kind).toBe(expected); }); test('should return a manual when given a paused value', () => { const interval: DefaultIntervalSetting = { pause: true }; mockTimeRange(undefined, interval); - const value = getDefaultIntervalKind(); + const { kind } = getIntervalSettings(); const expected: Policy['kind'] = 'manual'; - expect(value).toBe(expected); + expect(kind).toBe(expected); }); test('should return the default when the whole object is null', () => { mockTimeRange(undefined, null); - const value = getDefaultIntervalKind(); - expect(value).toBe(DEFAULT_INTERVAL_TYPE); + const { kind } = getIntervalSettings(); + expect(kind).toBe(DEFAULT_INTERVAL_TYPE); }); test('should return the default when the whole object is undefined', () => { mockTimeRange(undefined, undefined); - const value = getDefaultIntervalKind(); - expect(value).toBe(DEFAULT_INTERVAL_TYPE); + const { kind } = getIntervalSettings(); + expect(kind).toBe(DEFAULT_INTERVAL_TYPE); }); test('should return the default when the value is null', () => { mockTimeRange(undefined, { pause: null }); - const value = getDefaultIntervalKind(); - expect(value).toBe(DEFAULT_INTERVAL_TYPE); + const { kind } = getIntervalSettings(); + expect(kind).toBe(DEFAULT_INTERVAL_TYPE); }); test('should return the default when the value is undefined', () => { mockTimeRange(undefined, { pause: undefined }); - const value = getDefaultIntervalKind(); - expect(value).toBe(DEFAULT_INTERVAL_TYPE); + const { kind } = getIntervalSettings(); + expect(kind).toBe(DEFAULT_INTERVAL_TYPE); }); test('should return the default when the from value is malformed', () => { const malformedInterval = { pause: 'whoops a string' }; if (isMalformedInterval(malformedInterval)) { mockTimeRange(undefined, malformedInterval); - const value = getDefaultIntervalKind(); - expect(value).toBe(DEFAULT_INTERVAL_TYPE); + const { kind } = getIntervalSettings(); + expect(kind).toBe(DEFAULT_INTERVAL_TYPE); } else { throw Error('Was expecting an object to be used for the malformed interval'); } }); + + describe('without UISettings', () => { + beforeEach(() => { + mockGetServices.mockImplementation(() => { + throw new Error('should not have been called'); + }); + }); + + it('is DEFAULT_INTERVAL_TYPE', () => { + const { kind } = getIntervalSettings(false); + expect(kind).toBe(DEFAULT_INTERVAL_TYPE); + }); + }); }); - describe('#getDefaultIntervalDuration', () => { + describe('duration', () => { test('should return default', () => { mockTimeRange(); - const value = getDefaultIntervalDuration(); - expect(value).toBe(DEFAULT_INTERVAL_VALUE); + const { duration } = getIntervalSettings(); + expect(duration).toBe(DEFAULT_INTERVAL_VALUE); }); test('should return a value when given a paused value', () => { const interval: DefaultIntervalSetting = { value: 5 }; mockTimeRange(undefined, interval); - const value = getDefaultIntervalDuration(); + const { duration } = getIntervalSettings(); const expected: Policy['duration'] = 5; - expect(value).toBe(expected); + expect(duration).toBe(expected); }); test('should return the default when the whole object is null', () => { mockTimeRange(undefined, null); - const value = getDefaultIntervalDuration(); - expect(value).toBe(DEFAULT_INTERVAL_VALUE); + const { duration } = getIntervalSettings(); + expect(duration).toBe(DEFAULT_INTERVAL_VALUE); }); test('should return the default when the whole object is undefined', () => { mockTimeRange(undefined, undefined); - const value = getDefaultIntervalDuration(); - expect(value).toBe(DEFAULT_INTERVAL_VALUE); + const { duration } = getIntervalSettings(); + expect(duration).toBe(DEFAULT_INTERVAL_VALUE); }); test('should return the default when the value is null', () => { mockTimeRange(undefined, { value: null }); - const value = getDefaultIntervalDuration(); - expect(value).toBe(DEFAULT_INTERVAL_VALUE); + const { duration } = getIntervalSettings(); + expect(duration).toBe(DEFAULT_INTERVAL_VALUE); }); test('should return the default when the value is undefined', () => { mockTimeRange(undefined, { value: undefined }); - const value = getDefaultIntervalDuration(); - expect(value).toBe(DEFAULT_INTERVAL_VALUE); + const { duration } = getIntervalSettings(); + expect(duration).toBe(DEFAULT_INTERVAL_VALUE); }); test('should return the default when the value is malformed', () => { const malformedInterval = { value: 'whoops a string' }; if (isMalformedInterval(malformedInterval)) { mockTimeRange(undefined, malformedInterval); - const value = getDefaultIntervalDuration(); - expect(value).toBe(DEFAULT_INTERVAL_VALUE); + const { duration } = getIntervalSettings(); + expect(duration).toBe(DEFAULT_INTERVAL_VALUE); } else { throw Error('Was expecting an object to be used for the malformed interval'); } }); - }); - describe('#parseDateString', () => { - test('should return the first value as a moment if everything is ok', () => { - const value = parseDateString( - '1930-05-31T13:03:54.234Z', - '1940-05-31T13:03:54.234Z', - moment('1950-05-31T13:03:54.234Z') - ); - expect(value.valueOf()).toBe(new Date('1930-05-31T13:03:54.234Z').valueOf()); - }); + describe('without UISettings', () => { + beforeEach(() => { + mockGetServices.mockImplementation(() => { + throw new Error('should not have been called'); + }); + }); - test('should return the second value as a moment if the first is null', () => { - const value = parseDateString( - null, - '1940-05-31T13:03:54.234Z', - moment('1950-05-31T13:03:54.234Z') - ); - expect(value.valueOf()).toBe(new Date('1940-05-31T13:03:54.234Z').valueOf()); - }); - - test('should return the second value as a moment if the first is undefined', () => { - const value = parseDateString( - null, - '1940-05-31T13:03:54.234Z', - moment('1950-05-31T13:03:54.234Z') - ); - expect(value.valueOf()).toBe(new Date('1940-05-31T13:03:54.234Z').valueOf()); + it('is DEFAULT_INTERVAL_VALUE', () => { + const { duration } = getIntervalSettings(false); + expect(duration).toBe(DEFAULT_INTERVAL_VALUE); + }); }); }); diff --git a/x-pack/legacy/plugins/siem/public/utils/default_date_settings.ts b/x-pack/legacy/plugins/siem/public/utils/default_date_settings.ts index 273988c167255..c4869a4851ae5 100644 --- a/x-pack/legacy/plugins/siem/public/utils/default_date_settings.ts +++ b/x-pack/legacy/plugins/siem/public/utils/default_date_settings.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import chrome from 'ui/chrome'; import dateMath from '@elastic/datemath'; import moment from 'moment'; -import { isString, isBoolean, isNumber } from 'lodash/fp'; +import { isBoolean, isNumber, isString } from 'lodash/fp'; + import { DEFAULT_SIEM_TIME_RANGE, DEFAULT_SIEM_REFRESH_INTERVAL, @@ -16,6 +16,7 @@ import { DEFAULT_INTERVAL_TYPE, DEFAULT_INTERVAL_VALUE, } from '../../common/constants'; +import { KibanaServices } from '../lib/kibana'; import { Policy } from '../store/inputs/model'; interface DefaultTimeRange { @@ -29,7 +30,6 @@ interface DefaultInterval { } export type DefaultTimeRangeSetting = DefaultTimeRange | null | undefined; - export type DefaultIntervalSetting = DefaultInterval | null | undefined; // Defaults for if everything fails including dateMath.parse(DEFAULT_FROM) or dateMath.parse(DEFAULT_TO) @@ -38,117 +38,37 @@ const DEFAULT_FROM_MOMENT = moment().subtract(24, 'hours'); const DEFAULT_TO_MOMENT = moment(); /** - * Returns the default SIEM time range "from" string. This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead - */ -export const getDefaultFromString = (): string => { - const defaultTimeRange: DefaultTimeRangeSetting = chrome - .getUiSettingsClient() - .get(DEFAULT_SIEM_TIME_RANGE); - if (defaultTimeRange != null && isString(defaultTimeRange.from)) { - return defaultTimeRange.from; - } else { - return DEFAULT_FROM; - } -}; - -/** - * Returns the default SIEM time range "to" string. This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead + * Retrieves timeRange settings to populate filters + * + * @param {Boolean} uiSettings Whether to respect the user's UI settings. Defaults to true. */ -export const getDefaultToString = (): string => { - const defaultTimeRange: DefaultTimeRangeSetting = chrome - .getUiSettingsClient() - .get(DEFAULT_SIEM_TIME_RANGE); - if (defaultTimeRange != null && isString(defaultTimeRange.to)) { - return defaultTimeRange.to; - } else { - return DEFAULT_TO; - } -}; - -/** - * Returns the default SIEM time range "from" Epoch. This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead - */ -export const getDefaultFromValue = (): number => getDefaultFromMoment().valueOf(); - -/** - * Returns the default SIEM time range "from" moment. This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead - */ -export const getDefaultFromMoment = (): moment.Moment => { - const defaultTimeRange: DefaultTimeRangeSetting = chrome - .getUiSettingsClient() - .get(DEFAULT_SIEM_TIME_RANGE); - if (defaultTimeRange != null && isString(defaultTimeRange.from)) { - return parseDateString(defaultTimeRange.from, DEFAULT_FROM, DEFAULT_FROM_MOMENT); - } else { - return parseDateWithDefault(DEFAULT_FROM, DEFAULT_FROM_MOMENT); - } -}; +export const getTimeRangeSettings = (uiSettings = true) => { + const timeRange = uiSettings + ? KibanaServices.get().uiSettings.get(DEFAULT_SIEM_TIME_RANGE) + : null; -/** - * Returns the default SIEM time range "to" Epoch. This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead - */ -export const getDefaultToValue = (): number => getDefaultToMoment().valueOf(); + const fromStr = (isString(timeRange?.from) && timeRange?.from) || DEFAULT_FROM; + const toStr = (isString(timeRange?.to) && timeRange?.to) || DEFAULT_TO; + const from = parseDateWithDefault(fromStr, DEFAULT_FROM_MOMENT).valueOf(); + const to = parseDateWithDefault(toStr, DEFAULT_TO_MOMENT).valueOf(); -/** - * Returns the default SIEM time range "to" moment. This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead - */ -export const getDefaultToMoment = (): moment.Moment => { - const defaultTimeRange: DefaultTimeRangeSetting = chrome - .getUiSettingsClient() - .get(DEFAULT_SIEM_TIME_RANGE); - if (defaultTimeRange != null && isString(defaultTimeRange.to)) { - return parseDateString(defaultTimeRange.to, DEFAULT_TO, DEFAULT_TO_MOMENT); - } else { - return parseDateWithDefault(DEFAULT_TO, DEFAULT_TO_MOMENT); - } + return { from, fromStr, to, toStr }; }; /** - * Returns the default SIEM interval "kind". This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead + * Retrieves refreshInterval settings to populate filters + * + * @param {Boolean} uiSettings Whether to respect the user's UI settings. Defaults to true. */ -export const getDefaultIntervalKind = (): Policy['kind'] => { - const defaultInterval: DefaultIntervalSetting = chrome - .getUiSettingsClient() - .get(DEFAULT_SIEM_REFRESH_INTERVAL); - if (defaultInterval != null && isBoolean(defaultInterval.pause)) { - return defaultInterval.pause ? 'manual' : 'interval'; - } else { - return DEFAULT_INTERVAL_TYPE; - } -}; +export const getIntervalSettings = (uiSettings = true): Policy => { + const interval = uiSettings + ? KibanaServices.get().uiSettings.get(DEFAULT_SIEM_REFRESH_INTERVAL) + : null; -/** - * Returns the default SIEM interval "duration". This should be used only in - * non-ReactJS code. For ReactJS code, use the settings context hook instead - */ -export const getDefaultIntervalDuration = (): Policy['duration'] => { - const defaultInterval: DefaultIntervalSetting = chrome - .getUiSettingsClient() - .get(DEFAULT_SIEM_REFRESH_INTERVAL); - if (defaultInterval != null && isNumber(defaultInterval.value)) { - return defaultInterval.value; - } else { - return DEFAULT_INTERVAL_VALUE; - } -}; + const duration = (isNumber(interval?.value) && interval?.value) || DEFAULT_INTERVAL_VALUE; + const kind = isBoolean(interval?.pause) && !interval?.pause ? 'interval' : DEFAULT_INTERVAL_TYPE; -export const parseDateString = ( - dateString: string | null | undefined, - defaultDateString: string, - defaultDate: moment.Moment -): moment.Moment => { - if (dateString != null) { - return parseDateWithDefault(dateString, defaultDate); - } else { - return parseDateWithDefault(defaultDateString, defaultDate); - } + return { kind, duration }; }; export const parseDateWithDefault = ( diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/_mock_server.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/_mock_server.ts index 4bf7b3279374b..5b85012fd9f08 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/_mock_server.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/_mock_server.ts @@ -58,7 +58,6 @@ export const createMockServer = (config: Record = defaultConfig) })), }; server.decorate('request', 'getAlertsClient', () => alertsClient); - server.decorate('request', 'getBasePath', () => '/s/default'); server.plugins.elasticsearch = (elasticsearch as unknown) as ElasticsearchPlugin; server.plugins.spaces = { getSpaceId: () => 'default' }; server.plugins.actions = { @@ -91,7 +90,6 @@ export const createMockServerWithoutAlertClientDecoration = ( } as any; // The types have really bad conflicts at the moment so I have to use any const actionsClient = actionsClientMock.create(); - serverWithoutAlertClient.decorate('request', 'getBasePath', () => '/s/default'); return { serverWithoutAlertClient: serverWithoutAlertClient as ServerFacade & Hapi.Server, From 6a6931a68642d3881c4a68aef6d1c32814f54c6a Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 6 Feb 2020 00:51:16 +0000 Subject: [PATCH 09/41] Improve webpack memory footprint (#56885) * chore(NA): introduce futureEmitAssets option. chore(NA): bump related webpack dependencies. * chore(NA): remove minimizer compress on dll compiler. * chore(NA): re enable dead code removal. * chore(NA): remove not needed file * docs(NA): add todo on dll compiler to remove this on webpack 5 --- src/optimize/base_optimizer.js | 1 + .../dynamic_dll_plugin/dll_config_model.js | 1 + yarn.lock | 17 ++++++++++++----- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index efff7f0aa2b46..d9df2a1955df3 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -256,6 +256,7 @@ export default class BaseOptimizer { profile: this.profile || false, output: { + futureEmitAssets: true, // TODO: remove on webpack 5 path: this.uiBundles.getWorkingDir(), filename: '[name].bundle.js', sourceMapFilename: '[file].map', diff --git a/src/optimize/dynamic_dll_plugin/dll_config_model.js b/src/optimize/dynamic_dll_plugin/dll_config_model.js index c7ab2fe30dd14..3e31b0a7a2ead 100644 --- a/src/optimize/dynamic_dll_plugin/dll_config_model.js +++ b/src/optimize/dynamic_dll_plugin/dll_config_model.js @@ -48,6 +48,7 @@ function generateDLL(config) { entry: dllEntry, context: dllContext, output: { + futureEmitAssets: true, // TODO: remove on webpack 5 filename: dllBundleFilename, path: dllOutputPath, publicPath: dllPublicPath, diff --git a/yarn.lock b/yarn.lock index 6e398bf4a9357..4635114018039 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16342,12 +16342,12 @@ icss-replace-symbols@^1.1.0: resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== +icss-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.0.0.tgz#d52cf4bcdcfa1c45c2dbefb4ffdf6b00ef608098" + integrity sha512-bA/xGiwWM17qjllIs9X/y0EjsB7e0AV08F3OL8UPsoNkNRibIuu8f1eKTnQ8QO1DteKKTxTUAn+IEWUToIwGOA== dependencies: - postcss "^7.0.14" + postcss "^7.0.5" icss-utils@^4.1.0: version "4.1.0" @@ -16356,6 +16356,13 @@ icss-utils@^4.1.0: dependencies: postcss "^7.0.14" +icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + idx@^2.5.6: version "2.5.6" resolved "https://registry.yarnpkg.com/idx/-/idx-2.5.6.tgz#1f824595070100ae9ad585c86db08dc74f83a59d" From a379a995ad8b5abac1863438153998ff53366100 Mon Sep 17 00:00:00 2001 From: Brandon Kobel Date: Wed, 5 Feb 2020 18:54:10 -0800 Subject: [PATCH 10/41] Updating angular-* packages to 1.7.9 to appease the scanners (#56924) * Updating angular-* packages to 1.7.9 to appease the scanners * Forgot the x-pack/package.json --- package.json | 8 ++++---- x-pack/package.json | 4 ++-- yarn.lock | 40 ++++++++++++++++++++-------------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 305aeba900503..27c2ffbba2c28 100644 --- a/package.json +++ b/package.json @@ -146,11 +146,11 @@ "JSONStream": "1.3.5", "abort-controller": "^3.0.0", "angular": "^1.7.9", - "angular-aria": "^1.7.8", + "angular-aria": "^1.7.9", "angular-elastic": "^2.5.1", "angular-recursion": "^1.0.5", - "angular-route": "^1.7.8", - "angular-sanitize": "^1.7.8", + "angular-route": "^1.7.9", + "angular-sanitize": "^1.7.9", "angular-sortable-view": "^0.0.17", "autoprefixer": "9.6.1", "babel-loader": "^8.0.6", @@ -380,7 +380,7 @@ "@types/zen-observable": "^0.8.0", "@typescript-eslint/eslint-plugin": "^2.15.0", "@typescript-eslint/parser": "^2.15.0", - "angular-mocks": "^1.7.8", + "angular-mocks": "^1.7.9", "archiver": "^3.1.1", "axe-core": "^3.3.2", "babel-eslint": "^10.0.3", diff --git a/x-pack/package.json b/x-pack/package.json index 040b6c080543e..921f6ad991188 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -193,8 +193,8 @@ "@slack/webhook": "^5.0.0", "@turf/boolean-contains": "6.0.1", "angular": "^1.7.9", - "angular-resource": "1.7.8", - "angular-sanitize": "1.7.8", + "angular-resource": "1.7.9", + "angular-sanitize": "1.7.9", "angular-ui-ace": "0.2.3", "apollo-cache-inmemory": "1.6.2", "apollo-client": "^2.3.8", diff --git a/yarn.lock b/yarn.lock index 4635114018039..7c14f67a5b297 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6005,10 +6005,10 @@ ammo@3.x.x: dependencies: hoek "5.x.x" -angular-aria@^1.7.8: - version "1.7.8" - resolved "https://registry.yarnpkg.com/angular-aria/-/angular-aria-1.7.8.tgz#3954250ef516b57cdd3cdf41ff4ee6fcfdc84ceb" - integrity sha512-facq/111sZKL2wUUqRA1GnGt+lZ8KAcX9Aw04cNA+OyEkoaoRC77NY4VSOTQxghlSd0OPAdLeFnmETnuiWrpLg== +angular-aria@^1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/angular-aria/-/angular-aria-1.7.9.tgz#90c61895ffbd876e95915222b32a7bd0070af7e3" + integrity sha512-luI3Jemd1AbOQW0krdzfEG3fM0IFtLY0bSSqIDEx3POE0XjKIC1MkrO8Csyq9PPgueLphyAPofzUwZ8YeZ88SA== angular-elastic@^2.5.1: version "2.5.1" @@ -6017,30 +6017,30 @@ angular-elastic@^2.5.1: dependencies: angular ">=1.0.6" -angular-mocks@^1.7.8: - version "1.7.8" - resolved "https://registry.yarnpkg.com/angular-mocks/-/angular-mocks-1.7.8.tgz#95e7887ca91d1a3e176cc22f2d1941d284ce9767" - integrity sha512-LB13ESBT0eJrhQhfPXyLR9qm4LI9g44hyBFwUqZKEHEA4DpfxVTu0ONipiNoN0zWtmEAezA8u2gjcoaO2TStig== +angular-mocks@^1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/angular-mocks/-/angular-mocks-1.7.9.tgz#0a3b7e28b9a493b4e3010ed2b0f69a68e9b4f79b" + integrity sha512-LQRqqiV3sZ7NTHBnNmLT0bXtE5e81t97+hkJ56oU0k3dqKv1s6F+nBWRlOVzqHWPGFOiPS8ZJVdrS8DFzHyNIA== angular-recursion@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/angular-recursion/-/angular-recursion-1.0.5.tgz#cd405428a0bf55faf52eaa7988c1fe69cd930543" integrity sha1-zUBUKKC/Vfr1Lqp5iMH+ac2TBUM= -angular-resource@1.7.8: - version "1.7.8" - resolved "https://registry.yarnpkg.com/angular-resource/-/angular-resource-1.7.8.tgz#9577dbcc02cdbb76398febc5fc7ee103c86c5c50" - integrity sha512-zuPQ0ZX9Q8WnZ0KMtJlKYUSIXWRQSbFzMkRV9zG8cYYSsMAZlXar5Hqmd5gzxC3O28AGM7BCEJ+iYs3UNL4qdA== +angular-resource@1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/angular-resource/-/angular-resource-1.7.9.tgz#fa53623fae2c60debe2410d692447dcb0ba02396" + integrity sha512-rXXhCE2qT31Pn4Sl+2XL+ntv4zxnA2OzY+clCl8/pOp/s/gIzxpQlEtXipo3QK8Qur3glbIkeF/bJw+gjVAdUw== -angular-route@^1.7.8: - version "1.7.8" - resolved "https://registry.yarnpkg.com/angular-route/-/angular-route-1.7.8.tgz#d502aa605dcbb253a93e844c0adf51c9bc36b9fa" - integrity sha512-VVk89PH0fsY5kfbx+N7IVX1IwnaPWYhMGY0uA+rjej2v1sjvrTx1SLkxUK4E0UpW1hXeLJhN7ncBcwoBiPtAtA== +angular-route@^1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/angular-route/-/angular-route-1.7.9.tgz#f9910a2af0ba3ad7a969c5dd369b8360d0d5e4ef" + integrity sha512-vRoj5hzdQtWbODhWJqDzD1iNOEfCKshO6GFBuPVV7RHlPjzIc4R2dHCc7Qiv/8F3LDxJDohc6vSnTDMLHuaqeA== -angular-sanitize@1.7.8, angular-sanitize@^1.7.8: - version "1.7.8" - resolved "https://registry.yarnpkg.com/angular-sanitize/-/angular-sanitize-1.7.8.tgz#87d59f754bb18d286dfd9d6ce867299c094c6719" - integrity sha512-sVq51is1cVNiPytH4JIEd7iRW0OBIRQGNETWkz1c/jnLv2sBf9oDxEd8enwDz/W2ULBIpqJPK/3AsIxmZyh9pA== +angular-sanitize@1.7.9, angular-sanitize@^1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/angular-sanitize/-/angular-sanitize-1.7.9.tgz#6b4d5e826abdabd352b13a7c65c8c74daf6a7b15" + integrity sha512-nB/xe7JQWF9nLvhHommAICQ3eWrfRETo0EVGFESi952CDzDa+GAJ/2BFBNw44QqQPxj1Xua/uYKrbLsOGWZdbQ== angular-sortable-view@^0.0.17: version "0.0.17" From f2c06a864850d362e9a3b56cad4a70b975392f57 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 5 Feb 2020 21:57:43 -0800 Subject: [PATCH 11/41] Update Node.js to version 10.19.0 (#56940) Signed-off-by: Tyler Smalley --- .node-version | 2 +- .nvmrc | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.node-version b/.node-version index 06c9b9d306348..5b7269c0a98f3 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -10.18.0 +10.19.0 diff --git a/.nvmrc b/.nvmrc index 06c9b9d306348..5b7269c0a98f3 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -10.18.0 +10.19.0 diff --git a/package.json b/package.json index 27c2ffbba2c28..1502d61e529d9 100644 --- a/package.json +++ b/package.json @@ -485,7 +485,7 @@ "zlib": "^1.0.5" }, "engines": { - "node": "10.18.0", + "node": "10.19.0", "yarn": "^1.21.1" } } From 81c1b5220ac17a9f90976ff0b5d2cd9b9f400597 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 6 Feb 2020 08:11:06 +0100 Subject: [PATCH 12/41] [NP] add plugin integrations testing strategies (#56278) * add plugin integration section * NITs/wording --- src/core/TESTING.md | 295 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 293 insertions(+), 2 deletions(-) diff --git a/src/core/TESTING.md b/src/core/TESTING.md index 23c0879e4411e..4dfab8830a506 100644 --- a/src/core/TESTING.md +++ b/src/core/TESTING.md @@ -548,9 +548,300 @@ _How to test SO operations_ _How to test ES clients_ -## Plugin Integrations +## Plugin integrations -_How to test against specific plugin APIs (eg. data plugin)_ +In the new platform, all plugin's dependencies to other plugins are explicitly declared in their `kibana.json` +manifest. As for `core`, the dependencies `setup` and `start` contracts are injected in your plugin's respective +`setup` and `start` phases. One of the upsides with testing is that every usage of the dependencies is explicit, +and that the plugin's contracts must be propagated to the parts of the code using them, meaning that isolating a +specific logical component for unit testing is way easier than in legacy. + +The approach to test parts of a plugin's code that is relying on other plugins is quite similar to testing +code using `core` APIs: it's expected to mock the dependency, and make it return the value the test is expecting. + +Most plugins are defining mocks for their contracts. The convention is to expose them in a `mocks` file in +`my_plugin/server` and/or `my_plugin/public`. For example for the `data` plugin, the client-side mocks are located in +`src/plugins/data/public/mocks.ts`. When such mocks are present, it's strongly recommended to use them +when testing against dependencies. Otherwise, one should create it's own mocked implementation of the dependency's +contract (and should probably ping the plugin's owner to ask them to add proper contract mocks). + +### Preconditions + +For these examples, we are going to see how we should test the `myPlugin` plugin. + +This plugin declares the `data` plugin as a `required` dependency and the `usageCollection` plugin as an `optional` +one. It also exposes a `getSpecialSuggestions` API in it's start contract, which relies on the `data` plugin to retrieve +data. + +`MyPlugin` plugin definition: + +```typescript +// src/plugins/myplugin/public/plugin.ts +import { CoreSetup, CoreStart, Plugin } from 'kibana/public'; +import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public'; +import { UsageCollectionSetup } from '../../usage_collection/public'; +import { SuggestionsService } from './suggestions'; + +interface MyPluginSetupDeps { + data: DataPublicPluginSetup; + usageCollection?: UsageCollectionSetup; +} + +interface MyPluginStartDeps { + data: DataPublicPluginStart; +} + +export class MyPlugin implements Plugin { + private suggestionsService = new SuggestionsService(); + + public setup(core: CoreSetup, { data, usageCollection }: MyPluginSetupDeps) { + // setup our internal service + this.suggestionsService.setup(data); + + // an example on using an optional dependency that will be tested + if (usageCollection) { + usageCollection.allowTrackUserAgent(true); + } + + return {}; + } + + public start(core: CoreStart, { data }: MyPluginStartDeps) { + const suggestions = this.suggestionsService.start(data); + return { + getSpecialSuggestions: (query: string) => suggestions.getSuggestions(query), + }; + } + + public stop() {} +} + +export type MyPluginSetup = ReturnType; +export type MyPluginStart = ReturnType; +``` + +The underlying `SuggestionsService` implementation: + +```typescript +// src/plugins/myplugin/public/suggestions/suggestion_service.ts +import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../data/public'; + +// stubs for testing purposes +const suggestDependingOn = (...args: any[]) => []; +const baseOptions = {} as any; +export const defaultSuggestions = [ + { + text: 'a default suggestion', + }, +] as any[]; + +export class SuggestionsService { + public setup(data: DataPublicPluginSetup) { + // register a suggestion provider to the `data` dependency plugin + data.autocomplete.addQuerySuggestionProvider('fr', async args => { + return suggestDependingOn(args); + }); + } + + public start(data: DataPublicPluginStart) { + return { + getSuggestions: async (query: string) => { + // use the `data` plugin contract to retrieve arbitrary data + // note: this logic does not really make any sense and is only here to introduce a behavior to test + const baseSuggestions = await data.autocomplete.getQuerySuggestions({ + ...baseOptions, + query, + }); + if (!baseSuggestions || baseSuggestions.length === 0) { + return defaultSuggestions; + } + return baseSuggestions.filter(suggestion => suggestion.type !== 'conjunction'); + }, + }; + } +} +``` + +### Testing dependencies usages + +A plugin should test expected usage and calls on it's dependency plugins' API. + +Some calls, such as 'registration' APIs exposed from dependency plugins, should be checked, +to ensure both that they are actually executed, and performed with the correct parameters. + +For our example plugin's `SuggestionsService`, we should assert that the suggestion provider is correctly +registered to the `data` plugin during the `setup` phase, and that `getSuggestions` calls +`autocomplete.getQuerySuggestions` with the correct parameters. + +```typescript +// src/plugins/myplugin/public/suggestions/suggestion_service.test.ts +import { + dataPluginMock, + Setup as DataPluginSetupMock, + Start as DataPluginStartMock, +} from '../../../data/public/mocks'; +import { SuggestionsService } from './suggestion_service'; + +describe('SuggestionsService', () => { + let service: SuggestionsService; + let dataSetup: DataPluginSetupMock; + let dataStart: DataPluginStartMock; + + beforeEach(() => { + service = new SuggestionsService(); + dataSetup = dataPluginMock.createSetupContract(); + dataStart = dataPluginMock.createStartContract(); + }); + + describe('#setup', () => { + it('registers the query suggestion provider to the data plugin', () => { + service.setup(dataSetup); + + expect(dataSetup.autocomplete.addQuerySuggestionProvider).toHaveBeenCalledTimes(1); + expect(dataSetup.autocomplete.addQuerySuggestionProvider).toHaveBeenCalledWith( + 'fr', + expect.any(Function) + ); + }); + }); + + describe('#start', () => { + describe('#getSuggestions', () => { + it('calls getQuerySuggestions with the correct query', async () => { + service.setup(dataSetup); + const serviceStart = service.start(dataStart); + + await serviceStart.getSuggestions('some query'); + + expect(dataStart.autocomplete.getQuerySuggestions).toHaveBeenCalledTimes(1); + expect(dataStart.autocomplete.getQuerySuggestions).toHaveBeenCalledWith( + expect.objectContaining({ + query: 'some query', + }) + ); + }); + }); + }); +}); +``` + +### Testing components consuming the dependencies + +When testing parts of your plugin code that depends on the dependency plugin's data, the best approach +is to mock the dependency to be able to get the behavior expected for the test. + +In this example, we are going to mock the results of `autocomplete.getQuerySuggestions` to be able to test +the service's `getSuggestions` method. + +```typescript +// src/plugins/myplugin/public/suggestions/suggestion_service.ts + +describe('#start', () => { + describe('#getSuggestions', () => { + it('returns the default suggestions when autocomplete returns no results', async () => { + dataStart.autocomplete.getQuerySuggestions.mockResolvedValue([]); + + service.setup(dataSetup); + const serviceStart = service.start(dataStart); + + const results = await serviceStart.getSuggestions('some query'); + expect(results).toEqual(defaultSuggestions); + }); + + it('excludes conjunctions from the autocomplete results', async () => { + dataStart.autocomplete.getQuerySuggestions.mockResolvedValue([ + { + type: 'field', + text: 'field suggestion', + }, + { + type: 'conjunction', + text: 'conjunction suggestion', + }, + ]); + + service.setup(dataSetup); + const serviceStart = service.start(dataStart); + + const results = await serviceStart.getSuggestions('some query'); + + expect(results).toEqual([ + { + type: 'field', + text: 'field suggestion', + }, + ]); + }); + }); +}); +``` + +### Testing optional plugin dependencies + +Plugins should test that their behavior remains correct when their optional dependencies are either available or not. + +A basic test would be to ensure that the plugin properly initialize without error when the optional +dependency is missing: + +```typescript +// src/plugins/myplugin/public/plugin.test.ts +import { coreMock } from '../../../core/public/mocks'; +import { dataPluginMock } from '../../data/public/mocks'; +import { MyPlugin } from './plugin'; + +describe('Plugin', () => { + it('initializes correctly if usageCollection is disabled', () => { + const plugin = new MyPlugin(coreMock.createPluginInitializerContext()); + const coreSetup = coreMock.createSetup(); + const setupDeps = { + data: dataPluginMock.createSetupContract(), + // optional usageCollector dependency is not available + }; + + const coreStart = coreMock.createStart(); + const startDeps = { + data: dataPluginMock.createStartContract(), + }; + + expect(() => { + plugin.setup(coreSetup, setupDeps); + }).not.toThrow(); + expect(() => { + plugin.start(coreStart, startDeps); + }).not.toThrow(); + }); +}); +``` + +Then we should test that when optional dependency is properly used when present: + +```typescript +// src/plugins/myplugin/public/plugin.test.ts +import { coreMock } from '../../../core/public/mocks'; +import { dataPluginMock } from '../../data/public/mocks'; +import { usageCollectionPluginMock } from '../../usage_collection/public/mocks'; + +import { MyPlugin } from './plugin'; + +describe('Plugin', () => { + // [...] + + it('enables trackUserAgent when usageCollection is available', async () => { + const plugin = new MyPlugin(coreMock.createPluginInitializerContext()); + const coreSetup = coreMock.createSetup(); + const usageCollectionSetup = usageCollectionPluginMock.createSetupContract(); + const setupDeps = { + data: dataPluginMock.createSetupContract(), + usageCollection: usageCollectionSetup, + }; + + plugin.setup(coreSetup, setupDeps); + + expect(usageCollectionSetup.allowTrackUserAgent).toHaveBeenCalledTimes(1); + expect(usageCollectionSetup.allowTrackUserAgent).toHaveBeenCalledWith(true); + }); +}); +``` ## Plugin Contracts From d20a7d06b9efc3cb2cfdf3cc58f073dd3d2493dd Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 6 Feb 2020 08:47:39 +0100 Subject: [PATCH 13/41] [Console] Progress bar (#56628) * First round of UI updates - progress bar loader for in flight request - Network request status bar * Add notification about in flight request * Use nbsp; and update the EuiCode to use EuiBadge * Address PR feedback: - Clean up unused class names - Move the network request status bar to next to the nav bar with a grey line under it - Added the request in progress badge in the network request status bar - Removed logic forcing one request at a time! - Added notification for when a user is sending a request from a line with no request on it (no more 0 - None status). Also preserve the previuous request in this case * [NB] Fix for floating tools when request is past bottom of rendered text area!! This can be backported to 7.6 as it causes when a request is selected at the bottom of a large text buffer and the history viewer is opened. * Fix types * Update copy Remove unused SCSS Co-authored-by: Elastic Machine --- .../console_legacy/public/styles/_app.scss | 10 ++ .../public/application/components/index.ts | 1 + .../network_request_status_bar/index.ts | 20 +++ .../network_request_status_bar.tsx | 133 ++++++++++++++++++ .../application/containers/editor/editor.tsx | 53 ++++--- .../editor/legacy/console_editor/editor.tsx | 4 +- .../legacy/console_editor/editor_output.tsx | 21 +-- .../application/containers/main/main.tsx | 53 +++++-- .../send_request_to_es.ts | 46 ++++-- .../use_send_current_request_to_es.ts | 17 ++- .../legacy_core_editor/legacy_core_editor.ts | 31 ++-- .../public/application/stores/request.ts | 4 +- .../console/public/lib/es/{es.js => es.ts} | 20 +-- src/plugins/console/public/lib/es/index.ts | 20 +++ 14 files changed, 351 insertions(+), 82 deletions(-) create mode 100644 src/plugins/console/public/application/components/network_request_status_bar/index.ts create mode 100644 src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx rename src/plugins/console/public/lib/es/{es.js => es.ts} (76%) create mode 100644 src/plugins/console/public/lib/es/index.ts diff --git a/src/legacy/core_plugins/console_legacy/public/styles/_app.scss b/src/legacy/core_plugins/console_legacy/public/styles/_app.scss index 3b6297f9cdbff..865a4fc7fafb0 100644 --- a/src/legacy/core_plugins/console_legacy/public/styles/_app.scss +++ b/src/legacy/core_plugins/console_legacy/public/styles/_app.scss @@ -48,6 +48,7 @@ button { line-height: inherit; } + position: absolute; z-index: $euiZLevel1; top: 0; @@ -89,3 +90,12 @@ .conApp__settingsModal { min-width: 460px; } + +.conApp__requestProgressBarContainer { + position: relative; + z-index: $euiZLevel2; +} + +.conApp__tabsExtension { + border-bottom: $euiBorderThin; +} diff --git a/src/plugins/console/public/application/components/index.ts b/src/plugins/console/public/application/components/index.ts index eccde899a2640..d9a8aa9328b73 100644 --- a/src/plugins/console/public/application/components/index.ts +++ b/src/plugins/console/public/application/components/index.ts @@ -17,6 +17,7 @@ * under the License. */ +export { NetworkRequestStatusBar } from './network_request_status_bar'; export { SomethingWentWrongCallout } from './something_went_wrong_callout'; export { TopNavMenuItem, TopNavMenu } from './top_nav_menu'; export { ConsoleMenu } from './console_menu'; diff --git a/src/plugins/console/public/application/components/network_request_status_bar/index.ts b/src/plugins/console/public/application/components/network_request_status_bar/index.ts new file mode 100644 index 0000000000000..ce214c1cdfffa --- /dev/null +++ b/src/plugins/console/public/application/components/network_request_status_bar/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 { NetworkRequestStatusBar } from './network_request_status_bar'; diff --git a/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx new file mode 100644 index 0000000000000..6915ff15f374d --- /dev/null +++ b/src/plugins/console/public/application/components/network_request_status_bar/network_request_status_bar.tsx @@ -0,0 +1,133 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import React, { FunctionComponent } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiText, EuiToolTip } from '@elastic/eui'; + +export interface Props { + requestInProgress: boolean; + requestResult?: { + // Status code of the request, e.g., 200 + statusCode: number; + + // Status text of the request, e.g., OK + statusText: string; + + // Method of the request, e.g., GET + method: string; + + // The path of endpoint that was called, e.g., /_search + endpoint: string; + + // The time, in milliseconds, that the last request took + timeElapsedMs: number; + }; +} + +const mapStatusCodeToBadgeColor = (statusCode: number) => { + if (statusCode <= 199) { + return 'default'; + } + + if (statusCode <= 299) { + return 'secondary'; + } + + if (statusCode <= 399) { + return 'primary'; + } + + if (statusCode <= 499) { + return 'warning'; + } + + return 'danger'; +}; + +export const NetworkRequestStatusBar: FunctionComponent = ({ + requestInProgress, + requestResult, +}) => { + let content: React.ReactNode = null; + + if (requestInProgress) { + content = ( + + + {i18n.translate('console.requestInProgressBadgeText', { + defaultMessage: 'Request in progress', + })} + + + ); + } else if (requestResult) { + const { endpoint, method, statusCode, statusText, timeElapsedMs } = requestResult; + + content = ( + <> + + {`${method} ${ + endpoint.startsWith('/') ? endpoint : '/' + endpoint + }`} + } + > + + {/* Use   to ensure that no matter the width we don't allow line breaks */} + {statusCode} - {statusText} + + + + + + {i18n.translate('console.requestTimeElapasedBadgeTooltipContent', { + defaultMessage: 'Time Elapsed', + })} + + } + > + + + {timeElapsedMs} {'ms'} + + + + + + ); + } + + return ( + + {content} + + ); +}; diff --git a/src/plugins/console/public/application/containers/editor/editor.tsx b/src/plugins/console/public/application/containers/editor/editor.tsx index 5c7fe293651fb..0bfe837f2cd90 100644 --- a/src/plugins/console/public/application/containers/editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/editor.tsx @@ -17,14 +17,15 @@ * under the License. */ -import React, { useCallback } from 'react'; +import React, { useCallback, memo } from 'react'; import { debounce } from 'lodash'; +import { EuiProgress } from '@elastic/eui'; import { EditorContentSpinner } from '../../components'; import { Panel, PanelsContainer } from '../../../../../kibana_react/public'; import { Editor as EditorUI, EditorOutput } from './legacy/console_editor'; import { StorageKeys } from '../../../services'; -import { useEditorReadContext, useServicesContext } from '../../contexts'; +import { useEditorReadContext, useServicesContext, useRequestReadContext } from '../../contexts'; const INITIAL_PANEL_WIDTH = 50; const PANEL_MIN_WIDTH = '100px'; @@ -33,12 +34,13 @@ interface Props { loading: boolean; } -export const Editor = ({ loading }: Props) => { +export const Editor = memo(({ loading }: Props) => { const { services: { storage }, } = useServicesContext(); const { currentTextObject } = useEditorReadContext(); + const { requestInFlight } = useRequestReadContext(); const [firstPanelWidth, secondPanelWidth] = storage.get(StorageKeys.WIDTH, [ INITIAL_PANEL_WIDTH, @@ -55,23 +57,30 @@ export const Editor = ({ loading }: Props) => { if (!currentTextObject) return null; return ( - - - {loading ? ( - - ) : ( - - )} - - - {loading ? : } - - + <> + {requestInFlight ? ( +
+ +
+ ) : null} + + + {loading ? ( + + ) : ( + + )} + + + {loading ? : } + + + ); -}; +}); diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx index 759e3dbafb39c..b3e966ddffa4c 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx @@ -211,14 +211,14 @@ function EditorUI({ initialTextValue }: EditorProps) {