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:
Tarun Pothulapati 2020-05-07 21:35:56 +00:00 committed by GitHub
parent 2a95d373c4
commit 2be43a5f9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 2745 additions and 30 deletions

View File

@ -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:

View File

@ -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 }}

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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>
&nbsp;&nbsp;
{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;

View File

@ -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: [],
}; };

View File

@ -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

View File

@ -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() {

View File

@ -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)
}

View File

@ -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},
} }
} }

View File

@ -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))
} }

View File

@ -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 }}