Skip to content

Commit e2a7c2b

Browse files
committed
WIP
1 parent 7e7884e commit e2a7c2b

File tree

13 files changed

+82
-16
lines changed

13 files changed

+82
-16
lines changed

x-pack/legacy/plugins/monitoring/public/components/apm/instances/instances.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
} from '@elastic/eui';
1919
import { Status } from './status';
2020
import { formatMetric } from '../../../lib/format_number';
21+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
2122
import { formatTimestampToDuration } from '../../../../common';
2223
import { i18n } from '@kbn/i18n';
2324
import { APM_SYSTEM_ID } from '../../../../common/constants';
@@ -56,7 +57,10 @@ function getColumns(setupMode) {
5657

5758
return (
5859
<Fragment>
59-
<EuiLink href={`#/apm/instances/${apm.uuid}`} data-test-subj={`apmLink-${name}`}>
60+
<EuiLink
61+
href={getSafeForExternalLink(`#/apm/instances/${apm.uuid}`)}
62+
data-test-subj={`apmLink-${name}`}
63+
>
6064
{name}
6165
</EuiLink>
6266
{setupModeStatus}

x-pack/legacy/plugins/monitoring/public/components/beats/listing/listing.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ import { formatMetric } from 'plugins/monitoring/lib/format_number';
1919
import { EuiMonitoringTable } from 'plugins/monitoring/components/table';
2020
import { i18n } from '@kbn/i18n';
2121
import { BEATS_SYSTEM_ID } from '../../../../common/constants';
22+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
2223
import { ListingCallOut } from '../../setup_mode/listing_callout';
2324
import { SetupModeBadge } from '../../setup_mode/badge';
2425
import { FormattedMessage } from '@kbn/i18n/react';
2526

2627
export class Listing extends PureComponent {
2728
getColumns() {
28-
const { kbnUrl, scope } = this.props.angular;
2929
const setupMode = this.props.setupMode;
3030

3131
return [
@@ -59,11 +59,7 @@ export class Listing extends PureComponent {
5959
return (
6060
<div>
6161
<EuiLink
62-
onClick={() => {
63-
scope.$evalAsync(() => {
64-
kbnUrl.changePath(`/beats/beat/${beat.uuid}`);
65-
});
66-
}}
62+
href={getSafeForExternalLink(`/beats/beat/${beat.uuid}`)}
6763
data-test-subj={`beatLink-${name}`}
6864
>
6965
{name}

x-pack/legacy/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { i18n } from '@kbn/i18n';
3232
import { FormattedMessage } from '@kbn/i18n/react';
3333
import { Reason } from '../../logs/reason';
3434
import { SetupModeTooltip } from '../../setup_mode/tooltip';
35+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
3536
import { ELASTICSEARCH_SYSTEM_ID } from '../../../../common/constants';
3637

3738
const calculateShards = shards => {
@@ -168,7 +169,7 @@ export function ElasticsearchPanel(props) {
168169
const showMlJobs = () => {
169170
// if license doesn't support ML, then `ml === null`
170171
if (props.ml) {
171-
const gotoURL = '#/elasticsearch/ml_jobs';
172+
const gotoURL = getSafeForExternalLink('#/elasticsearch/ml_jobs');
172173
return (
173174
<>
174175
<EuiDescriptionListTitle>

x-pack/legacy/plugins/monitoring/public/components/cluster/overview/license_text.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import React from 'react';
88
import moment from 'moment-timezone';
9+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
910
import { capitalize } from 'lodash';
1011
import { EuiLink } from '@elastic/eui';
1112
import { FormattedMessage } from '@kbn/i18n/react';
@@ -18,7 +19,7 @@ export function LicenseText({ license, showLicenseExpiration }) {
1819
}
1920

2021
return (
21-
<EuiLink href="#/license">
22+
<EuiLink href={getSafeForExternalLink('#/license')}>
2223
<FormattedMessage
2324
id="xpack.monitoring.cluster.overview.licenseText.toLicensePageLinkLabel"
2425
defaultMessage="{licenseType} license {willExpireOn}"

x-pack/legacy/plugins/monitoring/public/components/elasticsearch/ccr/ccr.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
EuiTextColor,
1818
EuiScreenReaderOnly,
1919
} from '@elastic/eui';
20-
20+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
2121
import './ccr.css';
2222
import { FormattedMessage } from '@kbn/i18n/react';
2323
import { i18n } from '@kbn/i18n';
@@ -65,7 +65,9 @@ export class Ccr extends Component {
6565
),
6666
render: shardId => {
6767
return (
68-
<EuiLink href={`#/elasticsearch/ccr/${index}/shard/${shardId}`}>
68+
<EuiLink
69+
href={getSafeForExternalLink(`#/elasticsearch/ccr/${index}/shard/${shardId}`)}
70+
>
6971
{shardId}
7072
</EuiLink>
7173
);

x-pack/legacy/plugins/monitoring/public/components/elasticsearch/indices/indices.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import React from 'react';
88
import { capitalize } from 'lodash';
99
import { LARGE_FLOAT, LARGE_BYTES, LARGE_ABBREVIATED } from '../../../../common/formatting';
1010
import { formatMetric } from '../../../lib/format_number';
11+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
1112
import { ElasticsearchStatusIcon } from '../status_icon';
1213
import { ClusterStatus } from '../cluster_status';
1314
import { EuiMonitoringTable } from '../../table';
@@ -34,7 +35,10 @@ const columns = [
3435
sortable: true,
3536
render: value => (
3637
<div data-test-subj="name">
37-
<EuiLink href={`#/elasticsearch/indices/${value}`} data-test-subj={`indexLink-${value}`}>
38+
<EuiLink
39+
href={getSafeForExternalLink(`#/elasticsearch/indices/${value}`)}
40+
data-test-subj={`indexLink-${value}`}
41+
>
3842
{value}
3943
</EuiLink>
4044
</div>

x-pack/legacy/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import React, { Fragment } from 'react';
88
import { NodeStatusIcon } from '../node';
99
import { extractIp } from '../../../lib/extract_ip'; // TODO this is only used for elasticsearch nodes summary / node detail, so it should be moved to components/elasticsearch/nodes/lib
10+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
1011
import { ClusterStatus } from '../cluster_status';
1112
import { EuiMonitoringSSPTable } from '../../table';
1213
import { MetricCell, OfflineCell } from './cells';
@@ -75,7 +76,7 @@ const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid) => {
7576
render: (value, node) => {
7677
let nameLink = (
7778
<EuiLink
78-
href={`#/elasticsearch/nodes/${node.resolver}`}
79+
href={getSafeForExternalLink(`#/elasticsearch/nodes/${node.resolver}`)}
7980
data-test-subj={`nodeLink-${node.resolver}`}
8081
>
8182
{value}

x-pack/legacy/plugins/monitoring/public/components/elasticsearch/shard_activity/recovery_index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import React from 'react';
88
import { EuiLink } from '@elastic/eui';
99
import { Snapshot } from './snapshot';
1010
import { FormattedMessage } from '@kbn/i18n/react';
11+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
1112

1213
export const RecoveryIndex = props => {
1314
const { name, shard, relocationType } = props;
1415

1516
return (
1617
<div>
17-
<EuiLink href={`#/elasticsearch/indices/${name}`}>{name}</EuiLink>
18+
<EuiLink href={getSafeForExternalLink(`#/elasticsearch/indices/${name}`)}>{name}</EuiLink>
1819
<br />
1920
<FormattedMessage
2021
id="xpack.monitoring.elasticsearch.shardActivity.recoveryIndex.shardDescription"

x-pack/legacy/plugins/monitoring/public/components/kibana/instances/instances.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { EuiMonitoringTable } from '../../table';
2121
import { KibanaStatusIcon } from '../status_icon';
2222
import { StatusIcon } from 'plugins/monitoring/components/status_icon';
2323
import { formatMetric, formatNumber } from '../../../lib/format_number';
24+
import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link';
2425
import { i18n } from '@kbn/i18n';
2526
import { FormattedMessage } from '@kbn/i18n/react';
2627
import { SetupModeBadge } from '../../setup_mode/badge';
@@ -68,7 +69,7 @@ const getColumns = setupMode => {
6869
return (
6970
<div>
7071
<EuiLink
71-
href={`#/kibana/instances/${kibana.kibana.uuid}`}
72+
href={getSafeForExternalLink(`#/kibana/instances/${kibana.kibana.uuid}`)}
7273
data-test-subj={`kibanaLink-${name}`}
7374
>
7475
{name}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import chrome from '../np_imports/ui/chrome';
8+
9+
export function getSafeForExternalLink(url: string) {
10+
const $injector = chrome.dangerouslyGetActiveInjector() as any;
11+
const globalState = $injector.get('globalState');
12+
if (url.startsWith('#/') && globalState.cluster_uuid) {
13+
const clusterUuid = globalState.ccs
14+
? `${globalState.ccs}:${globalState.cluster_uuid}`
15+
: globalState.cluster_uuid;
16+
return `#/_cluster/${clusterUuid}/${url.substr(2)}`;
17+
}
18+
return url;
19+
}

x-pack/legacy/plugins/monitoring/public/np_imports/angular/modules.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
import { PromiseServiceCreator } from './providers/promises';
2727
// @ts-ignore
2828
import { PrivateProvider } from './providers/private';
29+
import { getSafeForExternalLink } from '../../lib/get_safe_for_external_link';
2930

3031
type IPrivate = <T>(provider: (...injectable: any[]) => T) => T;
3132

@@ -134,7 +135,8 @@ function createHrefModule(core: AppMountContext['core']) {
134135
pre: (_$scope, _$el, $attr) => {
135136
$attr.$observe(name, val => {
136137
if (val) {
137-
$attr.$set('href', core.http.basePath.prepend(val as string));
138+
const url = getSafeForExternalLink(val as string);
139+
$attr.$set('href', core.http.basePath.prepend(url));
138140
}
139141
});
140142
},

x-pack/legacy/plugins/monitoring/public/views/all.js

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import './alerts';
1111
import './license';
1212
import './cluster/listing';
1313
import './cluster/overview';
14+
import './cluster/route';
1415
import './elasticsearch/overview';
1516
import './elasticsearch/indices';
1617
import './elasticsearch/index';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import uiRoutes from 'plugins/monitoring/np_imports/ui/routes';
7+
8+
uiRoutes.when('/_cluster/:clusterUuid/:route*', {
9+
template: '',
10+
controller: class {
11+
constructor($injector, $scope) {
12+
const $route = $injector.get('$route');
13+
const globalState = $injector.get('globalState');
14+
const kbnUrl = $injector.get('kbnUrl');
15+
16+
$scope.$evalAsync(() => {
17+
const route = $route.current.params.route;
18+
let ccs = null;
19+
let clusterUuid = $route.current.params.clusterUuid;
20+
if (clusterUuid.includes(':')) {
21+
const parts = clusterUuid.split(':');
22+
clusterUuid = parts[1];
23+
ccs = parts[0];
24+
}
25+
26+
globalState.cluster_uuid = clusterUuid;
27+
globalState.ccs = ccs;
28+
globalState.save();
29+
kbnUrl.changePath(route);
30+
});
31+
}
32+
},
33+
});

0 commit comments

Comments
 (0)