mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
152 lines
4.1 KiB
TypeScript
152 lines
4.1 KiB
TypeScript
/**
|
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
*/
|
|
|
|
import React from "react";
|
|
import { observer, disposeOnUnmount } from "mobx-react";
|
|
import type { Cluster } from "../../../../common/cluster/cluster";
|
|
import { SubTitle } from "../../layout/sub-title";
|
|
import { Select, SelectOption } from "../../select";
|
|
import { Input } from "../../input";
|
|
import { observable, computed, autorun, makeObservable } from "mobx";
|
|
import { productName } from "../../../../common/vars";
|
|
import { MetricProviderInfo, metricsApi } from "../../../../common/k8s-api/endpoints/metrics.api";
|
|
import { Spinner } from "../../spinner";
|
|
|
|
interface Props {
|
|
cluster: Cluster;
|
|
}
|
|
|
|
@observer
|
|
export class ClusterPrometheusSetting extends React.Component<Props> {
|
|
@observable path = "";
|
|
@observable provider = "";
|
|
@observable loading = true;
|
|
@observable loadedOptions: MetricProviderInfo[] = [];
|
|
|
|
@computed get options(): SelectOption<string>[] {
|
|
return [
|
|
{ value: "", label: "Auto detect" },
|
|
...this.loadedOptions.map(({ name, id }) => ({ value: id, label: name })),
|
|
];
|
|
}
|
|
|
|
constructor(props: Props) {
|
|
super(props);
|
|
makeObservable(this);
|
|
}
|
|
|
|
@computed get canEditPrometheusPath(): boolean {
|
|
return Boolean(
|
|
this.loadedOptions
|
|
.find(opt => opt.id === this.provider)
|
|
?.isConfigurable,
|
|
);
|
|
}
|
|
|
|
componentDidMount() {
|
|
disposeOnUnmount(this,
|
|
autorun(() => {
|
|
const { prometheus, prometheusProvider } = this.props.cluster.preferences;
|
|
|
|
if (prometheus) {
|
|
const prefix = prometheus.prefix || "";
|
|
|
|
this.path = `${prometheus.namespace}/${prometheus.service}:${prometheus.port}${prefix}`;
|
|
} else {
|
|
this.path = "";
|
|
}
|
|
|
|
if (prometheusProvider) {
|
|
this.provider = prometheusProvider.type;
|
|
} else {
|
|
this.provider = "";
|
|
}
|
|
}),
|
|
);
|
|
|
|
metricsApi
|
|
.getMetricProviders()
|
|
.then(values => {
|
|
this.loading = false;
|
|
|
|
if (values) {
|
|
this.loadedOptions = values;
|
|
}
|
|
});
|
|
}
|
|
|
|
parsePrometheusPath = () => {
|
|
if (!this.provider || !this.path) {
|
|
return null;
|
|
}
|
|
const parsed = this.path.split(/\/|:/, 3);
|
|
const apiPrefix = this.path.substring(parsed.join("/").length);
|
|
|
|
if (!parsed[0] || !parsed[1] || !parsed[2]) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
namespace: parsed[0],
|
|
service: parsed[1],
|
|
port: parseInt(parsed[2]),
|
|
prefix: apiPrefix,
|
|
};
|
|
};
|
|
|
|
onSaveProvider = () => {
|
|
this.props.cluster.preferences.prometheusProvider = this.provider ?
|
|
{ type: this.provider } :
|
|
null;
|
|
};
|
|
|
|
onSavePath = () => {
|
|
this.props.cluster.preferences.prometheus = this.parsePrometheusPath();
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<>
|
|
<section>
|
|
<SubTitle title="Prometheus"/>
|
|
{
|
|
this.loading
|
|
? <Spinner />
|
|
: <>
|
|
<Select
|
|
value={this.provider}
|
|
onChange={({ value }) => {
|
|
this.provider = value;
|
|
this.onSaveProvider();
|
|
}}
|
|
options={this.options}
|
|
/>
|
|
<small className="hint">What query format is used to fetch metrics from Prometheus</small>
|
|
</>
|
|
}
|
|
</section>
|
|
{this.canEditPrometheusPath && (
|
|
<>
|
|
<hr/>
|
|
<section>
|
|
<SubTitle title="Prometheus service address" />
|
|
<Input
|
|
value={this.path}
|
|
onChange={(value) => this.path = value}
|
|
onBlur={this.onSavePath}
|
|
placeholder="<namespace>/<service>:<port>"
|
|
/>
|
|
<small className="hint">
|
|
An address to an existing Prometheus installation{" "}
|
|
({"<namespace>/<service>:<port>"}). {productName} tries to auto-detect address if left empty.
|
|
</small>
|
|
</section>
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
}
|