1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/renderer/components/cluster-settings/components/cluster-prometheus-setting.tsx
Alex Andreev 2fbad87fbd Use light theme for all dialog inputs
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
2022-02-01 14:54:16 +03:00

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>
</>
)}
</>
);
}
}