mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.14`: - [[Infra][APM] Fix uptime links display condition in Infra and APM (#181425)](https://github.com/elastic/kibana/pull/181425) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Carlos Crespo","email":"crespocarlos@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-04-29T12:06:03Z","message":"[Infra][APM] Fix uptime links display condition in Infra and APM (#181425)\n\ncloses [#178714](https://github.com/elastic/kibana/issues/178714)\r\n\r\n## Summary\r\n\r\nThis PR changes where link to legacy uptime is displayed to\r\nconditionally show it according to whether the plugin is enabled or not.\r\n\r\n<img width=\"962\" alt=\"image\"\r\nsrc=\"e2e659ae
-bc2e-49a6-a34b-9434f04b4617\">\r\n\r\n<img width=\"962\" alt=\"image\"\r\nsrc=\"4aa487f5
-4a61-4387-a9ed-12c9ed624410\">\r\n\r\n\r\n### How to test\r\n\r\nThe issue and the fix are the same in serverless and stateful\r\n\r\n#### APM \r\n- Run\r\n```\r\nnode scripts/synthtrace simple_trace.ts --from=now-15m --to=now --clean --target=http://elastic_serverless:changeme@localhost:9200 --kibana=http://elastic_serverless:changeme@0.0.0.0:5601\r\n```\r\n- Navigate to APM > Traces, click on \"Investigate\" \r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - \"Status\"\r\n**should** appear\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - \"Status\"\r\n**should not** appear\r\n- if `xpack.legacy_uptime.enabled: false` and `xpack.uptime.enabled:\r\ntrue` in kibana.yml - \"Status\" **should not** appear\r\n- if `observability:enableLegacyUptimeApp` is switched on in Advanced\r\nsettings - \"Status\" **should** appear\r\n\r\n#### Infra \r\n- Start a local kibana instance pointing to an oblt cluster\r\n- Navigate to Infrastructure, select `Kubernetes Pod` (other asset\r\ntypes, except hosts, share the same code) in `Show` dropdown\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - the link\r\nshould be **enabled**\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - the link to\r\nuptime should be **disabled**\r\n- if `xpack.legacy_uptime.enabled: false` and `xpack.uptime.enabled:\r\ntrue` in kibana.yml - the link to uptime should be **disabled**\r\n- if `observability:enableLegacyUptimeApp` is switched on in Advanced\r\nsettings - the link to uptime should be **enabled**\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"694acf7040dc56b6e2e4f37156d14a0028ff501b","branchLabelMapping":{"^v8.15.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-infra_services","v8.15.0"],"title":"[Infra][APM] Fix uptime links display condition in Infra and APM","number":181425,"url":"https://github.com/elastic/kibana/pull/181425","mergeCommit":{"message":"[Infra][APM] Fix uptime links display condition in Infra and APM (#181425)\n\ncloses [#178714](https://github.com/elastic/kibana/issues/178714)\r\n\r\n## Summary\r\n\r\nThis PR changes where link to legacy uptime is displayed to\r\nconditionally show it according to whether the plugin is enabled or not.\r\n\r\n<img width=\"962\" alt=\"image\"\r\nsrc=\"e2e659ae
-bc2e-49a6-a34b-9434f04b4617\">\r\n\r\n<img width=\"962\" alt=\"image\"\r\nsrc=\"4aa487f5
-4a61-4387-a9ed-12c9ed624410\">\r\n\r\n\r\n### How to test\r\n\r\nThe issue and the fix are the same in serverless and stateful\r\n\r\n#### APM \r\n- Run\r\n```\r\nnode scripts/synthtrace simple_trace.ts --from=now-15m --to=now --clean --target=http://elastic_serverless:changeme@localhost:9200 --kibana=http://elastic_serverless:changeme@0.0.0.0:5601\r\n```\r\n- Navigate to APM > Traces, click on \"Investigate\" \r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - \"Status\"\r\n**should** appear\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - \"Status\"\r\n**should not** appear\r\n- if `xpack.legacy_uptime.enabled: false` and `xpack.uptime.enabled:\r\ntrue` in kibana.yml - \"Status\" **should not** appear\r\n- if `observability:enableLegacyUptimeApp` is switched on in Advanced\r\nsettings - \"Status\" **should** appear\r\n\r\n#### Infra \r\n- Start a local kibana instance pointing to an oblt cluster\r\n- Navigate to Infrastructure, select `Kubernetes Pod` (other asset\r\ntypes, except hosts, share the same code) in `Show` dropdown\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - the link\r\nshould be **enabled**\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - the link to\r\nuptime should be **disabled**\r\n- if `xpack.legacy_uptime.enabled: false` and `xpack.uptime.enabled:\r\ntrue` in kibana.yml - the link to uptime should be **disabled**\r\n- if `observability:enableLegacyUptimeApp` is switched on in Advanced\r\nsettings - the link to uptime should be **enabled**\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"694acf7040dc56b6e2e4f37156d14a0028ff501b"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.15.0","branchLabelMappingKey":"^v8.15.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/181425","number":181425,"mergeCommit":{"message":"[Infra][APM] Fix uptime links display condition in Infra and APM (#181425)\n\ncloses [#178714](https://github.com/elastic/kibana/issues/178714)\r\n\r\n## Summary\r\n\r\nThis PR changes where link to legacy uptime is displayed to\r\nconditionally show it according to whether the plugin is enabled or not.\r\n\r\n<img width=\"962\" alt=\"image\"\r\nsrc=\"e2e659ae
-bc2e-49a6-a34b-9434f04b4617\">\r\n\r\n<img width=\"962\" alt=\"image\"\r\nsrc=\"4aa487f5
-4a61-4387-a9ed-12c9ed624410\">\r\n\r\n\r\n### How to test\r\n\r\nThe issue and the fix are the same in serverless and stateful\r\n\r\n#### APM \r\n- Run\r\n```\r\nnode scripts/synthtrace simple_trace.ts --from=now-15m --to=now --clean --target=http://elastic_serverless:changeme@localhost:9200 --kibana=http://elastic_serverless:changeme@0.0.0.0:5601\r\n```\r\n- Navigate to APM > Traces, click on \"Investigate\" \r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - \"Status\"\r\n**should** appear\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - \"Status\"\r\n**should not** appear\r\n- if `xpack.legacy_uptime.enabled: false` and `xpack.uptime.enabled:\r\ntrue` in kibana.yml - \"Status\" **should not** appear\r\n- if `observability:enableLegacyUptimeApp` is switched on in Advanced\r\nsettings - \"Status\" **should** appear\r\n\r\n#### Infra \r\n- Start a local kibana instance pointing to an oblt cluster\r\n- Navigate to Infrastructure, select `Kubernetes Pod` (other asset\r\ntypes, except hosts, share the same code) in `Show` dropdown\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - the link\r\nshould be **enabled**\r\n- if `xpack.legacy_uptime.enabled: false` in kibana.yml - the link to\r\nuptime should be **disabled**\r\n- if `xpack.legacy_uptime.enabled: false` and `xpack.uptime.enabled:\r\ntrue` in kibana.yml - the link to uptime should be **disabled**\r\n- if `observability:enableLegacyUptimeApp` is switched on in Advanced\r\nsettings - the link to uptime should be **enabled**\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>","sha":"694acf7040dc56b6e2e4f37156d14a0028ff501b"}}]}] BACKPORT--> Co-authored-by: Carlos Crespo <crespocarlos@users.noreply.github.com>
This commit is contained in:
parent
6e730eaaa0
commit
a4cb49799d
13 changed files with 167 additions and 106 deletions
|
@ -211,6 +211,7 @@ export type ApmFields = Fields<{
|
|||
span: { id: string };
|
||||
}>;
|
||||
'url.original': string;
|
||||
'url.domain': string;
|
||||
}> &
|
||||
ApmApplicationMetricFields &
|
||||
ExperimentalFields;
|
||||
|
|
|
@ -33,6 +33,9 @@ const scenario: Scenario<ApmFields> = async (runOptions) => {
|
|||
instance
|
||||
.transaction({ transactionName })
|
||||
.timestamp(timestamp)
|
||||
.defaults({
|
||||
'url.domain': 'foo.bar',
|
||||
})
|
||||
.duration(1000)
|
||||
.success()
|
||||
.children(
|
||||
|
|
|
@ -10,24 +10,26 @@ import { IBasePath } from '@kbn/core/public';
|
|||
import { Transaction } from '../../../../typings/es_schemas/ui/transaction';
|
||||
import { getSections } from './sections';
|
||||
import { apmRouter as apmRouterBase, ApmRouter } from '../../routing/apm_route_config';
|
||||
import {
|
||||
logsLocatorsMock,
|
||||
observabilityLogsExplorerLocatorsMock,
|
||||
} from '../../../context/apm_plugin/mock_apm_plugin_context';
|
||||
import { logsLocatorsMock } from '../../../context/apm_plugin/mock_apm_plugin_context';
|
||||
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';
|
||||
|
||||
const apmRouter = {
|
||||
...apmRouterBase,
|
||||
link: (...args: [any]) => `some-basepath/app/apm${apmRouterBase.link(...args)}`,
|
||||
} as ApmRouter;
|
||||
|
||||
const { allDatasetsLocator } = observabilityLogsExplorerLocatorsMock;
|
||||
const { nodeLogsLocator, traceLogsLocator } = logsLocatorsMock;
|
||||
const uptimeLocator = sharePluginMock.createLocator();
|
||||
|
||||
const expectLogsLocatorsToBeCalled = () => {
|
||||
expect(nodeLogsLocator.getRedirectUrl).toBeCalledTimes(3);
|
||||
expect(traceLogsLocator.getRedirectUrl).toBeCalledTimes(1);
|
||||
};
|
||||
|
||||
const expectUptimeLocatorToBeCalled = () => {
|
||||
expect(uptimeLocator.getRedirectUrl).toBeCalledTimes(1);
|
||||
};
|
||||
|
||||
describe('Transaction action menu', () => {
|
||||
const basePath = {
|
||||
prepend: (url: string) => {
|
||||
|
@ -60,8 +62,8 @@ describe('Transaction action menu', () => {
|
|||
basePath,
|
||||
location,
|
||||
apmRouter,
|
||||
allDatasetsLocator,
|
||||
logsLocators: logsLocatorsMock,
|
||||
uptimeLocator,
|
||||
infraLinksAvailable: false,
|
||||
rangeFrom: 'now-24h',
|
||||
rangeTo: 'now',
|
||||
|
@ -110,6 +112,7 @@ describe('Transaction action menu', () => {
|
|||
},
|
||||
],
|
||||
]);
|
||||
expectUptimeLocatorToBeCalled();
|
||||
expectLogsLocatorsToBeCalled();
|
||||
});
|
||||
|
||||
|
@ -127,7 +130,7 @@ describe('Transaction action menu', () => {
|
|||
basePath,
|
||||
location,
|
||||
apmRouter,
|
||||
allDatasetsLocator,
|
||||
uptimeLocator,
|
||||
logsLocators: logsLocatorsMock,
|
||||
infraLinksAvailable: true,
|
||||
rangeFrom: 'now-24h',
|
||||
|
@ -195,6 +198,7 @@ describe('Transaction action menu', () => {
|
|||
},
|
||||
],
|
||||
]);
|
||||
expectUptimeLocatorToBeCalled();
|
||||
expectLogsLocatorsToBeCalled();
|
||||
});
|
||||
|
||||
|
@ -212,7 +216,7 @@ describe('Transaction action menu', () => {
|
|||
basePath,
|
||||
location,
|
||||
apmRouter,
|
||||
allDatasetsLocator,
|
||||
uptimeLocator,
|
||||
logsLocators: logsLocatorsMock,
|
||||
infraLinksAvailable: true,
|
||||
rangeFrom: 'now-24h',
|
||||
|
@ -280,6 +284,7 @@ describe('Transaction action menu', () => {
|
|||
},
|
||||
],
|
||||
]);
|
||||
expectUptimeLocatorToBeCalled();
|
||||
expectLogsLocatorsToBeCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,18 +10,16 @@ import { Location } from 'history';
|
|||
import { IBasePath } from '@kbn/core/public';
|
||||
import { isEmpty, pickBy } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import url from 'url';
|
||||
import type { getLogsLocatorsFromUrlService } from '@kbn/logs-shared-plugin/common';
|
||||
import { findInventoryFields } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { LocatorPublic } from '@kbn/share-plugin/common';
|
||||
import { AllDatasetsLocatorParams } from '@kbn/deeplinks-observability/locators';
|
||||
import type { ProfilingLocators } from '@kbn/observability-shared-plugin/public';
|
||||
import { LocatorPublic } from '@kbn/share-plugin/common';
|
||||
import { SerializableRecord } from '@kbn/utility-types';
|
||||
import { Environment } from '../../../../common/environment_rt';
|
||||
import type { Transaction } from '../../../../typings/es_schemas/ui/transaction';
|
||||
import { getDiscoverHref } from '../links/discover_links/discover_link';
|
||||
import { getDiscoverQuery } from '../links/discover_links/discover_transaction_link';
|
||||
import { getInfraHref } from '../links/infra_link';
|
||||
import { fromQuery } from '../links/url_helpers';
|
||||
import { SectionRecord, getNonEmptySections, Action } from './sections_helper';
|
||||
import { HOST_NAME, TRACE_ID } from '../../../../common/es_fields/apm';
|
||||
import { ApmRouter } from '../../routing/apm_route_config';
|
||||
|
@ -42,11 +40,11 @@ export const getSections = ({
|
|||
location,
|
||||
apmRouter,
|
||||
infraLinksAvailable,
|
||||
uptimeLocator,
|
||||
profilingLocators,
|
||||
rangeFrom,
|
||||
rangeTo,
|
||||
environment,
|
||||
allDatasetsLocator,
|
||||
logsLocators,
|
||||
dataViewId,
|
||||
}: {
|
||||
|
@ -55,11 +53,11 @@ export const getSections = ({
|
|||
location: Location;
|
||||
apmRouter: ApmRouter;
|
||||
infraLinksAvailable: boolean;
|
||||
uptimeLocator?: LocatorPublic<SerializableRecord>;
|
||||
profilingLocators?: ProfilingLocators;
|
||||
rangeFrom: string;
|
||||
rangeTo: string;
|
||||
environment: Environment;
|
||||
allDatasetsLocator: LocatorPublic<AllDatasetsLocatorParams>;
|
||||
logsLocators: ReturnType<typeof getLogsLocatorsFromUrlService>;
|
||||
dataViewId?: string;
|
||||
}) => {
|
||||
|
@ -72,19 +70,16 @@ export const getSections = ({
|
|||
const time = Math.round(transaction.timestamp.us / 1000);
|
||||
const infraMetricsQuery = getInfraMetricsQuery(transaction);
|
||||
|
||||
const uptimeLink = url.format({
|
||||
pathname: basePath.prepend('/app/uptime'),
|
||||
search: `?${fromQuery(
|
||||
pickBy(
|
||||
{
|
||||
dateRangeStart: rangeFrom,
|
||||
dateRangeEnd: rangeTo,
|
||||
search: `url.domain:"${transaction.url?.domain}"`,
|
||||
},
|
||||
(val) => !isEmpty(val)
|
||||
)
|
||||
)}`,
|
||||
});
|
||||
const uptimeLink = uptimeLocator?.getRedirectUrl(
|
||||
pickBy(
|
||||
{
|
||||
dateRangeStart: rangeFrom,
|
||||
dateRangeEnd: rangeTo,
|
||||
search: `url.domain:"${transaction.url?.domain}"`,
|
||||
},
|
||||
(val) => !isEmpty(val)
|
||||
)
|
||||
);
|
||||
|
||||
// Logs hrefs
|
||||
const podLogsHref = logsLocators.nodeLogsLocator.getRedirectUrl({
|
||||
|
@ -231,7 +226,7 @@ export const getSections = ({
|
|||
defaultMessage: 'Status',
|
||||
}),
|
||||
href: uptimeLink,
|
||||
condition: !!transaction.url?.domain,
|
||||
condition: !!transaction.url?.domain && !!uptimeLink,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ import * as Transactions from './__fixtures__/mock_data';
|
|||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import * as useAdHocApmDataView from '../../../hooks/use_adhoc_apm_data_view';
|
||||
import { useProfilingIntegrationSetting } from '../../../hooks/use_profiling_integration_setting';
|
||||
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/common';
|
||||
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';
|
||||
|
||||
const apmContextMock = {
|
||||
...mockApmPluginContextValue,
|
||||
|
@ -52,6 +54,15 @@ const apmContextMock = {
|
|||
if (id === TRACE_LOGS_LOCATOR_ID) {
|
||||
return logsLocatorsMock.traceLogsLocator;
|
||||
}
|
||||
if (id === uptimeOverviewLocatorID) {
|
||||
return {
|
||||
...sharePluginMock.createLocator(),
|
||||
getRedirectUrl: jest.fn(
|
||||
() =>
|
||||
'http://localhost/basepath/app/uptime?dateRangeStart=now-24h&dateRangeEnd=now&search=url.domain:%22example.com%22'
|
||||
),
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -21,12 +21,9 @@ import {
|
|||
import React, { useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import {
|
||||
AllDatasetsLocatorParams,
|
||||
ALL_DATASETS_LOCATOR_ID,
|
||||
} from '@kbn/deeplinks-observability/locators';
|
||||
import type { ProfilingLocators } from '@kbn/observability-shared-plugin/public';
|
||||
import { getLogsLocatorsFromUrlService } from '@kbn/logs-shared-plugin/common';
|
||||
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/common';
|
||||
import { useAnyOfApmParams } from '../../../hooks/use_apm_params';
|
||||
import { ApmFeatureFlagName } from '../../../../common/apm_feature_flags';
|
||||
import { Transaction } from '../../../../typings/es_schemas/ui/transaction';
|
||||
|
@ -124,10 +121,10 @@ function ActionMenuSections({
|
|||
const apmRouter = useApmRouter();
|
||||
const { dataView } = useAdHocApmDataView();
|
||||
|
||||
const allDatasetsLocator =
|
||||
share.url.locators.get<AllDatasetsLocatorParams>(ALL_DATASETS_LOCATOR_ID)!;
|
||||
const logsLocators = getLogsLocatorsFromUrlService(share.url);
|
||||
|
||||
const uptimeLocator = share.url.locators.get(uptimeOverviewLocatorID);
|
||||
|
||||
const infraLinksAvailable = useApmFeatureFlag(ApmFeatureFlagName.InfraUiAvailable);
|
||||
|
||||
const {
|
||||
|
@ -145,11 +142,11 @@ function ActionMenuSections({
|
|||
location,
|
||||
apmRouter,
|
||||
infraLinksAvailable,
|
||||
uptimeLocator,
|
||||
profilingLocators,
|
||||
rangeFrom,
|
||||
rangeTo,
|
||||
environment,
|
||||
allDatasetsLocator,
|
||||
logsLocators,
|
||||
dataViewId: dataView?.id,
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
import { findInventoryModel, findInventoryFields } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { getLogsLocatorsFromUrlService } from '@kbn/logs-shared-plugin/common';
|
||||
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/common';
|
||||
import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana';
|
||||
import { AlertFlyout } from '../../../../../alerting/inventory/components/alert_flyout';
|
||||
import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../../lib/lib';
|
||||
|
@ -46,6 +47,7 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
|
|||
const { services } = useKibanaContextForPlugin();
|
||||
const { application, share } = services;
|
||||
const { nodeLogsLocator } = getLogsLocatorsFromUrlService(share.url);
|
||||
const uptimeLocator = share.url.locators.get(uptimeOverviewLocatorID);
|
||||
const uiCapabilities = application?.capabilities;
|
||||
// Due to the changing nature of the fields between APM and this UI,
|
||||
// We need to have some exceptions until 7.0 & ECS is finalized. Reference
|
||||
|
@ -60,7 +62,8 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
|
|||
inventoryModel.crosslinkSupport.apm && uiCapabilities?.apm && uiCapabilities?.apm.show;
|
||||
const showUptimeLink =
|
||||
inventoryModel.crosslinkSupport.uptime &&
|
||||
(['pod', 'container'].includes(nodeType) || node.ip);
|
||||
(['pod', 'container'].includes(nodeType) || node.ip) &&
|
||||
!!uptimeLocator;
|
||||
const showCreateAlertLink = uiCapabilities?.infrastructure?.save;
|
||||
|
||||
const inventoryId = useMemo(() => {
|
||||
|
@ -144,7 +147,7 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
|
|||
defaultMessage: '{inventoryName} in Uptime',
|
||||
values: { inventoryName: inventoryModel.singularDisplayName },
|
||||
}),
|
||||
onClick: () => navigateToUptime(share.url.locators, nodeType, node),
|
||||
onClick: () => (showUptimeLink ? navigateToUptime({ uptimeLocator, nodeType, node }) : {}),
|
||||
isDisabled: !showUptimeLink,
|
||||
};
|
||||
|
||||
|
|
|
@ -5,15 +5,19 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
|
||||
import { LocatorClient } from '@kbn/share-plugin/common/url_service/locators';
|
||||
import { LocatorPublic } from '@kbn/share-plugin/common/url_service/locators';
|
||||
import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { SerializableRecord } from '@kbn/utility-types';
|
||||
import { InfraWaffleMapNode } from '../../../../lib/lib';
|
||||
|
||||
export const navigateToUptime = (
|
||||
locators: LocatorClient,
|
||||
nodeType: InventoryItemType,
|
||||
node: InfraWaffleMapNode
|
||||
) => {
|
||||
return locators.get(uptimeOverviewLocatorID)!.navigate({ [nodeType]: node.id, ip: node.ip });
|
||||
export const navigateToUptime = ({
|
||||
uptimeLocator,
|
||||
nodeType,
|
||||
node,
|
||||
}: {
|
||||
uptimeLocator: LocatorPublic<SerializableRecord>;
|
||||
nodeType: InventoryItemType;
|
||||
node: InfraWaffleMapNode;
|
||||
}) => {
|
||||
return uptimeLocator.navigate({ [nodeType]: node.id, ip: node.ip });
|
||||
};
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
*/
|
||||
import { LocatorPublic } from '@kbn/share-plugin/public';
|
||||
import { SerializableRecord } from '@kbn/utility-types';
|
||||
import { uptimeOverviewNavigatorParams } from './overview';
|
||||
import { monitorDetailNavigatorParams } from './monitor_detail';
|
||||
import { editMonitorNavigatorParams } from './edit_monitor';
|
||||
import { syntheticsSettingsNavigatorParams } from './settings';
|
||||
|
||||
export const locators: Array<Pick<LocatorPublic<SerializableRecord>, 'id' | 'getLocation'>> = [
|
||||
uptimeOverviewNavigatorParams,
|
||||
monitorDetailNavigatorParams,
|
||||
editMonitorNavigatorParams,
|
||||
syntheticsSettingsNavigatorParams,
|
||||
|
|
|
@ -1,50 +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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
|
||||
import { OVERVIEW_ROUTE } from '../../../common/constants/ui';
|
||||
|
||||
const formatSearchKey = (key: string, value: string) => `${key}: "${value}"`;
|
||||
|
||||
async function navigate({
|
||||
ip,
|
||||
host,
|
||||
container,
|
||||
pod,
|
||||
}: {
|
||||
ip?: string;
|
||||
host?: string;
|
||||
container?: string;
|
||||
pod?: string;
|
||||
}) {
|
||||
const searchParams: string[] = [];
|
||||
|
||||
if (host) searchParams.push(formatSearchKey('host.name', host));
|
||||
if (container) searchParams.push(formatSearchKey('container.id', container));
|
||||
if (pod) searchParams.push(formatSearchKey('kubernetes.pod.uid', pod));
|
||||
|
||||
if (ip) {
|
||||
searchParams.push(formatSearchKey(`host.ip`, ip));
|
||||
searchParams.push(formatSearchKey(`monitor.ip`, ip));
|
||||
}
|
||||
|
||||
const searchString = searchParams.join(' OR ');
|
||||
|
||||
const path =
|
||||
searchParams.length === 0 ? OVERVIEW_ROUTE : OVERVIEW_ROUTE + `?search=${searchString}`;
|
||||
|
||||
return {
|
||||
app: 'uptime',
|
||||
path,
|
||||
state: {},
|
||||
};
|
||||
}
|
||||
|
||||
export const uptimeOverviewNavigatorParams = {
|
||||
id: uptimeOverviewLocatorID,
|
||||
getLocation: navigate,
|
||||
};
|
|
@ -5,34 +5,36 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { OVERVIEW_ROUTE } from '../../../common/constants';
|
||||
import { uptimeOverviewNavigatorParams } from './overview';
|
||||
import { OVERVIEW_ROUTE } from '../../common/constants';
|
||||
import { UptimeOverviewLocatorDefinition } from './overview';
|
||||
|
||||
describe('uptimeOverviewNavigatorParams', () => {
|
||||
const uptimeOverviewNavigator = new UptimeOverviewLocatorDefinition();
|
||||
|
||||
it('supplies the correct app name', async () => {
|
||||
const location = await uptimeOverviewNavigatorParams.getLocation({});
|
||||
const location = await uptimeOverviewNavigator.getLocation({});
|
||||
expect(location.app).toEqual('uptime');
|
||||
});
|
||||
|
||||
it('creates the expected path when no params specified', async () => {
|
||||
const location = await uptimeOverviewNavigatorParams.getLocation({});
|
||||
const location = await uptimeOverviewNavigator.getLocation({});
|
||||
expect(location.path).toEqual(OVERVIEW_ROUTE);
|
||||
});
|
||||
|
||||
it('creates a path with expected search when ip is specified', async () => {
|
||||
const location = await uptimeOverviewNavigatorParams.getLocation({ ip: '127.0.0.1' });
|
||||
const location = await uptimeOverviewNavigator.getLocation({ ip: '127.0.0.1' });
|
||||
expect(location.path).toEqual(
|
||||
`${OVERVIEW_ROUTE}?search=host.ip: "127.0.0.1" OR monitor.ip: "127.0.0.1"`
|
||||
);
|
||||
});
|
||||
|
||||
it('creates a path with expected search when hostname is specified', async () => {
|
||||
const location = await uptimeOverviewNavigatorParams.getLocation({ host: 'elastic.co' });
|
||||
const location = await uptimeOverviewNavigator.getLocation({ host: 'elastic.co' });
|
||||
expect(location.path).toEqual(`${OVERVIEW_ROUTE}?search=host.name: "elastic.co"`);
|
||||
});
|
||||
|
||||
it('creates a path with expected search when multiple host keys are specified', async () => {
|
||||
const location = await uptimeOverviewNavigatorParams.getLocation({
|
||||
const location = await uptimeOverviewNavigator.getLocation({
|
||||
host: 'elastic.co',
|
||||
ip: '127.0.0.1',
|
||||
});
|
||||
|
@ -42,7 +44,7 @@ describe('uptimeOverviewNavigatorParams', () => {
|
|||
});
|
||||
|
||||
it('creates a path with expected search when multiple kubernetes pod is specified', async () => {
|
||||
const location = await uptimeOverviewNavigatorParams.getLocation({
|
||||
const location = await uptimeOverviewNavigator.getLocation({
|
||||
pod: 'foo',
|
||||
ip: '10.0.0.1',
|
||||
});
|
||||
|
@ -52,9 +54,20 @@ describe('uptimeOverviewNavigatorParams', () => {
|
|||
});
|
||||
|
||||
it('creates a path with expected search when docker container is specified', async () => {
|
||||
const location = await uptimeOverviewNavigatorParams.getLocation({
|
||||
const location = await uptimeOverviewNavigator.getLocation({
|
||||
container: 'foo',
|
||||
});
|
||||
expect(location.path).toEqual(`${OVERVIEW_ROUTE}?search=container.id: "foo"`);
|
||||
});
|
||||
|
||||
it('creates a path with expected search and date range', async () => {
|
||||
const location = await uptimeOverviewNavigator.getLocation({
|
||||
search: 'foo',
|
||||
dateRangeStart: 'now-15m',
|
||||
dateRangeEnd: 'now',
|
||||
});
|
||||
expect(location.path).toEqual(
|
||||
`${OVERVIEW_ROUTE}?search=foo&dateRangeStart=now-15m&dateRangeEnd=now`
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
|
||||
import type { LocatorDefinition } from '@kbn/share-plugin/common';
|
||||
import type { SerializableRecord } from '@kbn/utility-types';
|
||||
import { OVERVIEW_ROUTE } from '../../common/constants';
|
||||
|
||||
const formatSearchKey = (key: string, value: string) => `${key}: "${value}"`;
|
||||
|
||||
export interface UptimeOverviewLocatorInfraParams extends SerializableRecord {
|
||||
ip?: string;
|
||||
host?: string;
|
||||
container?: string;
|
||||
pod?: string;
|
||||
}
|
||||
|
||||
export interface UptimeOverviewLocatorParams extends SerializableRecord {
|
||||
dateRangeStart?: string;
|
||||
dateRangeEnd?: string;
|
||||
search?: string;
|
||||
}
|
||||
|
||||
function isUptimeOverviewLocatorParams(
|
||||
args: UptimeOverviewLocatorInfraParams | UptimeOverviewLocatorParams
|
||||
): args is UptimeOverviewLocatorParams {
|
||||
return (
|
||||
(args as UptimeOverviewLocatorParams).search !== undefined ||
|
||||
(args as UptimeOverviewLocatorParams).dateRangeEnd !== undefined ||
|
||||
(args as UptimeOverviewLocatorParams).dateRangeStart !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
export class UptimeOverviewLocatorDefinition
|
||||
implements LocatorDefinition<UptimeOverviewLocatorInfraParams | UptimeOverviewLocatorParams>
|
||||
{
|
||||
public readonly id = uptimeOverviewLocatorID;
|
||||
|
||||
public readonly getLocation = async (
|
||||
params: UptimeOverviewLocatorInfraParams | UptimeOverviewLocatorParams
|
||||
) => {
|
||||
let qs = '';
|
||||
|
||||
if (isUptimeOverviewLocatorParams(params)) {
|
||||
qs = Object.entries(params)
|
||||
.map(([key, value]) => {
|
||||
if (value) {
|
||||
return `${key}=${value}`;
|
||||
}
|
||||
})
|
||||
.join('&');
|
||||
} else {
|
||||
const searchParams: string[] = [];
|
||||
if (params.host) searchParams.push(formatSearchKey('host.name', params.host));
|
||||
if (params.container) searchParams.push(formatSearchKey('container.id', params.container));
|
||||
if (params.pod) searchParams.push(formatSearchKey('kubernetes.pod.uid', params.pod));
|
||||
if (params.ip) {
|
||||
searchParams.push(formatSearchKey(`host.ip`, params.ip));
|
||||
searchParams.push(formatSearchKey(`monitor.ip`, params.ip));
|
||||
}
|
||||
if (searchParams.length > 0) {
|
||||
qs = `search=${searchParams.join(' OR ')}`;
|
||||
}
|
||||
}
|
||||
|
||||
const path = `${OVERVIEW_ROUTE}${qs ? `?${qs}` : ''}`;
|
||||
|
||||
return {
|
||||
app: 'uptime',
|
||||
path,
|
||||
state: {},
|
||||
};
|
||||
};
|
||||
}
|
|
@ -241,6 +241,9 @@ export class UptimePlugin
|
|||
function registerUptimeRoutesWithNavigation(coreStart: CoreStart, plugins: ClientPluginsStart) {
|
||||
async function getUptimeSections() {
|
||||
if (coreStart.application.capabilities.uptime?.show) {
|
||||
const { UptimeOverviewLocatorDefinition } = await import('./locators/overview');
|
||||
plugins.share.url.locators.create(new UptimeOverviewLocatorDefinition());
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'Uptime',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue