mirror of https://github.com/linkerd/linkerd2.git
Add Jaeger links to the Linkerd dashboard (#4177)
* Add Jaeger reverse proxy * add jaegerLink to the metrics table * update MetricsTable tests * Add optional jaeger link * rename grafana_proxy to reverse_proxy Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>
This commit is contained in:
parent
2a95d373c4
commit
2be43a5f9d
|
@ -206,7 +206,9 @@ spec:
|
||||||
{{- include "partials.proxy.labels" .Values.global.proxy | nindent 8}}
|
{{- include "partials.proxy.labels" .Values.global.proxy | nindent 8}}
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: {{.Values.jaeger.image}}
|
- args:
|
||||||
|
- --query.base-path=/jaeger
|
||||||
|
image: {{.Values.jaeger.image}}
|
||||||
imagePullPolicy: {{.Values.global.imagePullPolicy}}
|
imagePullPolicy: {{.Values.global.imagePullPolicy}}
|
||||||
name: jaeger
|
name: jaeger
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -64,6 +64,9 @@ spec:
|
||||||
- args:
|
- args:
|
||||||
- -api-addr=linkerd-controller-api.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:8085
|
- -api-addr=linkerd-controller-api.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:8085
|
||||||
- -grafana-addr=linkerd-grafana.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:3000
|
- -grafana-addr=linkerd-grafana.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:3000
|
||||||
|
{{- if .Values.tracing.enabled }}
|
||||||
|
- -jaeger-addr={{.Values.tracing.jaeger.name}}.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:16686
|
||||||
|
{{- end}}
|
||||||
- -controller-namespace={{.Values.global.namespace}}
|
- -controller-namespace={{.Values.global.namespace}}
|
||||||
- -log-level={{.Values.controllerLogLevel}}
|
- -log-level={{.Values.controllerLogLevel}}
|
||||||
{{- if .Values.enforcedHostRegexp }}
|
{{- if .Values.enforcedHostRegexp }}
|
||||||
|
|
|
@ -801,6 +801,7 @@ spec:
|
||||||
- args:
|
- args:
|
||||||
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
||||||
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
||||||
|
- -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686
|
||||||
- -controller-namespace=linkerd
|
- -controller-namespace=linkerd
|
||||||
- -log-level=info
|
- -log-level=info
|
||||||
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
||||||
|
@ -2615,7 +2616,9 @@ spec:
|
||||||
linkerd.io/proxy-deployment: linkerd-jaeger
|
linkerd.io/proxy-deployment: linkerd-jaeger
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: jaegertracing/all-in-one:1.17.1
|
- args:
|
||||||
|
- --query.base-path=/jaeger
|
||||||
|
image: jaegertracing/all-in-one:1.17.1
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
name: jaeger
|
name: jaeger
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -1714,6 +1714,7 @@ spec:
|
||||||
- args:
|
- args:
|
||||||
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
||||||
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
||||||
|
- -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686
|
||||||
- -controller-namespace=linkerd
|
- -controller-namespace=linkerd
|
||||||
- -log-level=info
|
- -log-level=info
|
||||||
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
||||||
|
@ -3512,7 +3513,9 @@ spec:
|
||||||
linkerd.io/proxy-deployment: linkerd-jaeger
|
linkerd.io/proxy-deployment: linkerd-jaeger
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: jaegertracing/all-in-one:1.17.1
|
- args:
|
||||||
|
- --query.base-path=/jaeger
|
||||||
|
image: jaegertracing/all-in-one:1.17.1
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
name: jaeger
|
name: jaeger
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -1641,6 +1641,7 @@ spec:
|
||||||
- args:
|
- args:
|
||||||
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
||||||
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
||||||
|
- -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686
|
||||||
- -controller-namespace=linkerd
|
- -controller-namespace=linkerd
|
||||||
- -log-level=info
|
- -log-level=info
|
||||||
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
||||||
|
@ -3481,7 +3482,9 @@ spec:
|
||||||
linkerd.io/proxy-deployment: linkerd-jaeger
|
linkerd.io/proxy-deployment: linkerd-jaeger
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: jaegertracing/all-in-one:1.17.1
|
- args:
|
||||||
|
- --query.base-path=/jaeger
|
||||||
|
image: jaegertracing/all-in-one:1.17.1
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
name: jaeger
|
name: jaeger
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -807,6 +807,7 @@ spec:
|
||||||
- args:
|
- args:
|
||||||
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
||||||
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
||||||
|
- -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686
|
||||||
- -controller-namespace=linkerd
|
- -controller-namespace=linkerd
|
||||||
- -log-level=info
|
- -log-level=info
|
||||||
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
||||||
|
@ -2635,7 +2636,9 @@ spec:
|
||||||
linkerd.io/proxy-deployment: linkerd-jaeger
|
linkerd.io/proxy-deployment: linkerd-jaeger
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: jaegertracing/all-in-one:1.17.1
|
- args:
|
||||||
|
- --query.base-path=/jaeger
|
||||||
|
image: jaegertracing/all-in-one:1.17.1
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
name: jaeger
|
name: jaeger
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -1647,6 +1647,7 @@ spec:
|
||||||
- args:
|
- args:
|
||||||
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
||||||
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
||||||
|
- -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686
|
||||||
- -controller-namespace=linkerd
|
- -controller-namespace=linkerd
|
||||||
- -log-level=info
|
- -log-level=info
|
||||||
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
||||||
|
@ -3499,7 +3500,9 @@ spec:
|
||||||
linkerd.io/proxy-deployment: linkerd-jaeger
|
linkerd.io/proxy-deployment: linkerd-jaeger
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: jaegertracing/all-in-one:1.17.1
|
- args:
|
||||||
|
- --query.base-path=/jaeger
|
||||||
|
image: jaegertracing/all-in-one:1.17.1
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
name: jaeger
|
name: jaeger
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -1647,6 +1647,7 @@ spec:
|
||||||
- args:
|
- args:
|
||||||
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
- -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085
|
||||||
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
- -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000
|
||||||
|
- -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686
|
||||||
- -controller-namespace=linkerd
|
- -controller-namespace=linkerd
|
||||||
- -log-level=info
|
- -log-level=info
|
||||||
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
- -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$
|
||||||
|
@ -3501,7 +3502,9 @@ spec:
|
||||||
linkerd.io/proxy-deployment: linkerd-jaeger
|
linkerd.io/proxy-deployment: linkerd-jaeger
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- image: jaegertracing/all-in-one:1.17.1
|
- args:
|
||||||
|
- --query.base-path=/jaeger
|
||||||
|
image: jaegertracing/all-in-one:1.17.1
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
name: jaeger
|
name: jaeger
|
||||||
ports:
|
ports:
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import _isEmpty from 'lodash/isEmpty';
|
||||||
|
import { jaegerIcon } from './util/SvgWrappers.jsx';
|
||||||
|
|
||||||
|
function jaegerQuery(name, namespace, resource) {
|
||||||
|
if (_isEmpty(namespace)) {
|
||||||
|
return `{"linkerd.io/workload-ns"%3A"${name}"}`;
|
||||||
|
} else if (resource === 'pod') {
|
||||||
|
return `{"hostname"%3A"${name}"%2C"linkerd.io/workload-ns"%3A"${namespace}"}`;
|
||||||
|
} else {
|
||||||
|
return `{"linkerd.io%2Fproxy-${resource}"%3A"${name}"%2C"linkerd.io/workload-ns"%3A"${namespace}"}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const JaegerLink = ({ PrefixedLink, name, namespace, resource }) => {
|
||||||
|
const link = `/jaeger/search?service=linkerd-proxy&tags=${jaegerQuery(name, namespace, resource)}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PrefixedLink
|
||||||
|
to={link}
|
||||||
|
targetBlank>
|
||||||
|
|
||||||
|
{jaegerIcon}
|
||||||
|
</PrefixedLink>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
JaegerLink.propTypes = {
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
namespace: PropTypes.string,
|
||||||
|
PrefixedLink: PropTypes.func.isRequired,
|
||||||
|
resource: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
JaegerLink.defaultProps = {
|
||||||
|
namespace: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JaegerLink;
|
|
@ -3,6 +3,7 @@ import BaseTable from './BaseTable.jsx';
|
||||||
import ErrorModal from './ErrorModal.jsx';
|
import ErrorModal from './ErrorModal.jsx';
|
||||||
import GrafanaLink from './GrafanaLink.jsx';
|
import GrafanaLink from './GrafanaLink.jsx';
|
||||||
import Grid from '@material-ui/core/Grid';
|
import Grid from '@material-ui/core/Grid';
|
||||||
|
import JaegerLink from './JaegerLink.jsx';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import SuccessRateMiniChart from './util/SuccessRateMiniChart.jsx';
|
import SuccessRateMiniChart from './util/SuccessRateMiniChart.jsx';
|
||||||
|
@ -110,7 +111,7 @@ const trafficSplitDetailColumns = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, PrefixedLink, isTcpTable, grafana) => {
|
const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, PrefixedLink, isTcpTable, grafana, jaeger) => {
|
||||||
const isAuthorityTable = resource === 'authority';
|
const isAuthorityTable = resource === 'authority';
|
||||||
const isTrafficSplitTable = resource === 'trafficsplit';
|
const isTrafficSplitTable = resource === 'trafficsplit';
|
||||||
const isMultiResourceTable = resource === 'multi_resource';
|
const isMultiResourceTable = resource === 'multi_resource';
|
||||||
|
@ -154,6 +155,26 @@ const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, Prefix
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const jaegerColumn = {
|
||||||
|
title: 'Jaeger',
|
||||||
|
key: 'JaegerDashboard',
|
||||||
|
isNumeric: true,
|
||||||
|
render: row => {
|
||||||
|
if (!isAuthorityTable && (!row.added || _get(row, 'pods.totalPods') === '0')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<JaegerLink
|
||||||
|
name={row.name}
|
||||||
|
namespace={row.namespace}
|
||||||
|
resource={row.type}
|
||||||
|
PrefixedLink={PrefixedLink} />
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const nameColumn = {
|
const nameColumn = {
|
||||||
title: isMultiResourceTable ? 'Resource' : friendlyTitle(resource).singular,
|
title: isMultiResourceTable ? 'Resource' : friendlyTitle(resource).singular,
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
@ -200,9 +221,14 @@ const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, Prefix
|
||||||
columns.splice(1, 0, meshedColumn);
|
columns.splice(1, 0, meshedColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTrafficSplitTable && grafana !== '') {
|
if (!isTrafficSplitTable) {
|
||||||
|
if (grafana !== '') {
|
||||||
columns = columns.concat(grafanaColumn);
|
columns = columns.concat(grafanaColumn);
|
||||||
}
|
}
|
||||||
|
if (jaeger !== '') {
|
||||||
|
columns = columns.concat(jaegerColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!showNamespaceColumn) {
|
if (!showNamespaceColumn) {
|
||||||
return columns;
|
return columns;
|
||||||
|
@ -224,12 +250,12 @@ const preprocessMetrics = metrics => {
|
||||||
return tableData;
|
return tableData;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MetricsTable = ({ metrics, resource, showNamespaceColumn, showName, title, api, isTcpTable, selectedNamespace, grafana }) => {
|
const MetricsTable = ({ metrics, resource, showNamespaceColumn, showName, title, api, isTcpTable, selectedNamespace, grafana, jaeger }) => {
|
||||||
const showNsColumn = resource === 'namespace' || selectedNamespace !== '_all' ? false : showNamespaceColumn;
|
const showNsColumn = resource === 'namespace' || selectedNamespace !== '_all' ? false : showNamespaceColumn;
|
||||||
const showNameColumn = resource !== 'trafficsplit' ? true : showName;
|
const showNameColumn = resource !== 'trafficsplit' ? true : showName;
|
||||||
let orderBy = 'name';
|
let orderBy = 'name';
|
||||||
if (resource === 'trafficsplit' && !showNameColumn) { orderBy = 'leaf'; }
|
if (resource === 'trafficsplit' && !showNameColumn) { orderBy = 'leaf'; }
|
||||||
const columns = columnDefinitions(resource, showNsColumn, showNameColumn, api.PrefixedLink, isTcpTable, grafana);
|
const columns = columnDefinitions(resource, showNsColumn, showNameColumn, api.PrefixedLink, isTcpTable, grafana, jaeger);
|
||||||
const rows = preprocessMetrics(metrics);
|
const rows = preprocessMetrics(metrics);
|
||||||
return (
|
return (
|
||||||
<BaseTable
|
<BaseTable
|
||||||
|
@ -251,6 +277,7 @@ MetricsTable.propTypes = {
|
||||||
metrics: PropTypes.arrayOf(processedMetricsPropType),
|
metrics: PropTypes.arrayOf(processedMetricsPropType),
|
||||||
resource: PropTypes.string.isRequired,
|
resource: PropTypes.string.isRequired,
|
||||||
selectedNamespace: PropTypes.string.isRequired,
|
selectedNamespace: PropTypes.string.isRequired,
|
||||||
|
jaeger: PropTypes.string,
|
||||||
showName: PropTypes.bool,
|
showName: PropTypes.bool,
|
||||||
showNamespaceColumn: PropTypes.bool,
|
showNamespaceColumn: PropTypes.bool,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
|
@ -261,6 +288,7 @@ MetricsTable.defaultProps = {
|
||||||
showNamespaceColumn: true,
|
showNamespaceColumn: true,
|
||||||
showName: true,
|
showName: true,
|
||||||
title: '',
|
title: '',
|
||||||
|
jaeger: '',
|
||||||
isTcpTable: false,
|
isTcpTable: false,
|
||||||
metrics: [],
|
metrics: [],
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,6 +84,20 @@ describe('Tests for <MetricsTable>', () => {
|
||||||
expect(table.props().tableColumns).toHaveLength(8);
|
expect(table.props().tableColumns).toHaveLength(8);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('render table with all columens including jaeger', () => {
|
||||||
|
let extraProps = _merge({}, defaultProps, {
|
||||||
|
metrics: [],
|
||||||
|
resource: "deployment",
|
||||||
|
showNamespaceColumn: false,
|
||||||
|
jaeger: 'jaeger.xyz'
|
||||||
|
});
|
||||||
|
const component = mount(routerWrap(MetricsTable, extraProps));
|
||||||
|
const table = component.find("BaseTable");
|
||||||
|
|
||||||
|
expect(table).toBeDefined();
|
||||||
|
expect(table.props().tableColumns).toHaveLength(9);
|
||||||
|
});
|
||||||
|
|
||||||
it('adds apex, leaf and weight columns, and omits meshed and grafana column, for a trafficsplit resource', () => {
|
it('adds apex, leaf and weight columns, and omits meshed and grafana column, for a trafficsplit resource', () => {
|
||||||
let extraProps = _merge({}, defaultProps, { metrics: [], resource: "trafficsplit"});
|
let extraProps = _merge({}, defaultProps, { metrics: [], resource: "trafficsplit"});
|
||||||
const component = mount(routerWrap(MetricsTable, extraProps));
|
const component = mount(routerWrap(MetricsTable, extraProps));
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,7 @@ func main() {
|
||||||
metricsAddr := cmd.String("metrics-addr", ":9994", "address to serve scrapable metrics on")
|
metricsAddr := cmd.String("metrics-addr", ":9994", "address to serve scrapable metrics on")
|
||||||
apiAddr := cmd.String("api-addr", "127.0.0.1:8085", "address of the linkerd-controller-api service")
|
apiAddr := cmd.String("api-addr", "127.0.0.1:8085", "address of the linkerd-controller-api service")
|
||||||
grafanaAddr := cmd.String("grafana-addr", "", "address of the linkerd-grafana service")
|
grafanaAddr := cmd.String("grafana-addr", "", "address of the linkerd-grafana service")
|
||||||
|
jaegerAddr := cmd.String("jaeger-addr", "", "address of the jaeger service")
|
||||||
templateDir := cmd.String("template-dir", "templates", "directory to search for template files")
|
templateDir := cmd.String("template-dir", "templates", "directory to search for template files")
|
||||||
staticDir := cmd.String("static-dir", "app/dist", "directory to search for static files")
|
staticDir := cmd.String("static-dir", "app/dist", "directory to search for static files")
|
||||||
reload := cmd.Bool("reload", true, "reloading set to true or false")
|
reload := cmd.Bool("reload", true, "reloading set to true or false")
|
||||||
|
@ -97,7 +98,7 @@ func main() {
|
||||||
log.Fatalf("invalid --enforced-host parameter: %s", err)
|
log.Fatalf("invalid --enforced-host parameter: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
server := srv.NewServer(*addr, *grafanaAddr, *templateDir, *staticDir, uuid,
|
server := srv.NewServer(*addr, *grafanaAddr, *jaegerAddr, *templateDir, *staticDir, uuid,
|
||||||
*controllerNamespace, clusterDomain, *reload, reHost, client, k8sAPI, hc)
|
*controllerNamespace, clusterDomain, *reload, reHost, client, k8sAPI, hc)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -28,7 +28,9 @@ type (
|
||||||
controllerNamespace string
|
controllerNamespace string
|
||||||
clusterDomain string
|
clusterDomain string
|
||||||
grafana string
|
grafana string
|
||||||
grafanaProxy *grafanaProxy
|
jaeger string
|
||||||
|
grafanaProxy *reverseProxy
|
||||||
|
jaegerProxy *reverseProxy
|
||||||
hc healthChecker
|
hc healthChecker
|
||||||
statCache *cache.Cache
|
statCache *cache.Cache
|
||||||
}
|
}
|
||||||
|
@ -46,6 +48,7 @@ func (h *handler) handleIndex(w http.ResponseWriter, req *http.Request, p httpro
|
||||||
ControllerNamespace: h.controllerNamespace,
|
ControllerNamespace: h.controllerNamespace,
|
||||||
PathPrefix: pathPfx,
|
PathPrefix: pathPfx,
|
||||||
Grafana: h.grafana,
|
Grafana: h.grafana,
|
||||||
|
Jaeger: h.jaeger,
|
||||||
}
|
}
|
||||||
|
|
||||||
version, err := h.apiClient.Version(req.Context(), &pb.Empty{}) // TODO: remove and call /api/version from web app
|
version, err := h.apiClient.Version(req.Context(), &pb.Empty{}) // TODO: remove and call /api/version from web app
|
||||||
|
@ -95,3 +98,7 @@ func (h *handler) handleProfileDownload(w http.ResponseWriter, req *http.Request
|
||||||
func (h *handler) handleGrafana(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
|
func (h *handler) handleGrafana(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
|
||||||
h.grafanaProxy.ServeHTTP(w, req)
|
h.grafanaProxy.ServeHTTP(w, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *handler) handleJaeger(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
|
||||||
|
h.jaegerProxy.ServeHTTP(w, req)
|
||||||
|
}
|
||||||
|
|
|
@ -6,19 +6,19 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// grafanaProxy is an HTTP reverse proxy that forwards all web requests
|
// reverseProxy is an HTTP reverse proxy that forwards all web requests
|
||||||
// containing paths prefixed with "/grafana" to the grafana service. The proxy
|
// containing paths prefixed to the corresponding service. The proxy
|
||||||
// strips the "/grafana" prefix and rewrites the Host header before sending.
|
// strips the prefix and rewrites the Host header before sending.
|
||||||
type grafanaProxy struct {
|
type reverseProxy struct {
|
||||||
*httputil.ReverseProxy
|
*httputil.ReverseProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGrafanaProxy(addr string) *grafanaProxy {
|
func newReverseProxy(addr string, prefix string) *reverseProxy {
|
||||||
director := func(req *http.Request) {
|
director := func(req *http.Request) {
|
||||||
req.Host = addr
|
req.Host = addr
|
||||||
req.URL.Host = addr
|
req.URL.Host = addr
|
||||||
req.URL.Scheme = "http"
|
req.URL.Scheme = "http"
|
||||||
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/grafana")
|
req.URL.Path = strings.TrimPrefix(req.URL.Path, prefix)
|
||||||
|
|
||||||
// the default director implementation does this, so we will too
|
// the default director implementation does this, so we will too
|
||||||
if _, ok := req.Header["User-Agent"]; !ok {
|
if _, ok := req.Header["User-Agent"]; !ok {
|
||||||
|
@ -27,7 +27,7 @@ func newGrafanaProxy(addr string) *grafanaProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &grafanaProxy{
|
return &reverseProxy{
|
||||||
ReverseProxy: &httputil.ReverseProxy{Director: director},
|
ReverseProxy: &httputil.ReverseProxy{Director: director},
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -52,6 +52,7 @@ type (
|
||||||
Error bool
|
Error bool
|
||||||
ErrorMessage string
|
ErrorMessage string
|
||||||
PathPrefix string
|
PathPrefix string
|
||||||
|
Jaeger string
|
||||||
Grafana string
|
Grafana string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ Please see https://linkerd.io/dns-rebinding for an explanation of what is happen
|
||||||
func NewServer(
|
func NewServer(
|
||||||
addr string,
|
addr string,
|
||||||
grafanaAddr string,
|
grafanaAddr string,
|
||||||
|
jaegerAddr string,
|
||||||
templateDir string,
|
templateDir string,
|
||||||
staticDir string,
|
staticDir string,
|
||||||
uuid string,
|
uuid string,
|
||||||
|
@ -115,8 +117,10 @@ func NewServer(
|
||||||
uuid: uuid,
|
uuid: uuid,
|
||||||
controllerNamespace: controllerNamespace,
|
controllerNamespace: controllerNamespace,
|
||||||
clusterDomain: clusterDomain,
|
clusterDomain: clusterDomain,
|
||||||
|
grafanaProxy: newReverseProxy(grafanaAddr, "/grafana"),
|
||||||
|
jaegerProxy: newReverseProxy(jaegerAddr, ""),
|
||||||
grafana: grafanaAddr,
|
grafana: grafanaAddr,
|
||||||
grafanaProxy: newGrafanaProxy(grafanaAddr),
|
jaeger: jaegerAddr,
|
||||||
hc: hc,
|
hc: hc,
|
||||||
statCache: cache.New(statExpiration, statCleanupInterval),
|
statCache: cache.New(statExpiration, statCleanupInterval),
|
||||||
}
|
}
|
||||||
|
@ -191,13 +195,10 @@ func NewServer(
|
||||||
server.router.GET("/api/resource-definition", handler.handleAPIResourceDefinition)
|
server.router.GET("/api/resource-definition", handler.handleAPIResourceDefinition)
|
||||||
|
|
||||||
// grafana proxy
|
// grafana proxy
|
||||||
server.router.DELETE("/grafana/*grafanapath", handler.handleGrafana)
|
server.handleAllOperationsForPath("/grafana/*grafanapath", handler.handleGrafana)
|
||||||
server.router.GET("/grafana/*grafanapath", handler.handleGrafana)
|
|
||||||
server.router.HEAD("/grafana/*grafanapath", handler.handleGrafana)
|
// jaeger proxy
|
||||||
server.router.OPTIONS("/grafana/*grafanapath", handler.handleGrafana)
|
server.handleAllOperationsForPath("/jaeger/*jaegerpath", handler.handleJaeger)
|
||||||
server.router.PATCH("/grafana/*grafanapath", handler.handleGrafana)
|
|
||||||
server.router.POST("/grafana/*grafanapath", handler.handleGrafana)
|
|
||||||
server.router.PUT("/grafana/*grafanapath", handler.handleGrafana)
|
|
||||||
|
|
||||||
return httpServer
|
return httpServer
|
||||||
}
|
}
|
||||||
|
@ -243,6 +244,16 @@ func (s *Server) loadTemplate(templateFile string) (template *template.Template,
|
||||||
return template, err
|
return template, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) handleAllOperationsForPath(path string, handle httprouter.Handle) {
|
||||||
|
s.router.DELETE(path, handle)
|
||||||
|
s.router.GET(path, handle)
|
||||||
|
s.router.HEAD(path, handle)
|
||||||
|
s.router.OPTIONS(path, handle)
|
||||||
|
s.router.PATCH(path, handle)
|
||||||
|
s.router.POST(path, handle)
|
||||||
|
s.router.PUT(path, handle)
|
||||||
|
}
|
||||||
|
|
||||||
func safelyJoinPath(rootPath, userPath string) string {
|
func safelyJoinPath(rootPath, userPath string) string {
|
||||||
return filepath.Join(rootPath, path.Clean("/"+userPath))
|
return filepath.Join(rootPath, path.Clean("/"+userPath))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
data-go-version="{{.Data.GoVersion}}"
|
data-go-version="{{.Data.GoVersion}}"
|
||||||
data-controller-namespace="{{.ControllerNamespace}}"
|
data-controller-namespace="{{.ControllerNamespace}}"
|
||||||
data-uuid="{{.UUID}}"
|
data-uuid="{{.UUID}}"
|
||||||
data-grafana="{{.Grafana}}">
|
data-grafana="{{.Grafana}}"
|
||||||
|
data-jaeger="{{.Jaeger}}">
|
||||||
{{ if .Error }}
|
{{ if .Error }}
|
||||||
<p>Failed to call public API: {{ .ErrorMessage }}</p>
|
<p>Failed to call public API: {{ .ErrorMessage }}</p>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
Loading…
Reference in New Issue