1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Show auto detect prometheus info

Signed-off-by: Juho Heikka <juho.heikka@gmail.com>
This commit is contained in:
Juho Heikka 2023-06-01 09:48:19 +03:00
parent 683ac4efcc
commit 8867f3a9e2
6 changed files with 196 additions and 0 deletions

View File

@ -0,0 +1,17 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRequestChannel } from "@k8slens/messaging";
import type { PrometheusDetails } from "../../../../main/cluster/prometheus-handler/prometheus-handler";
import type { ClusterId } from "../../../cluster-types";
import type { PrometheusProvider } from "../../../../main/prometheus/provider";
type PrometheusProviderData = Pick<PrometheusProvider, "kind" | "name" | "isConfigurable">;
export type PrometheusDetailsData = Pick<PrometheusDetails, "prometheusPath"> & {
provider: PrometheusProviderData;
};
export const prometheusDetailsChannel = getRequestChannel<ClusterId, PrometheusDetailsData>("prometheus-details");

View File

@ -0,0 +1,21 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import apiBaseInjectable from "../../api-base.injectable";
import type { PrometheusDetails } from "../../../../main/cluster/prometheus-handler/prometheus-handler";
export type RequestPrometheusDetails = () => Promise<PrometheusDetails>;
const requestPrometheusDetailsInjectable = getInjectable({
id: "request-prometheus-details",
instantiate: (di): RequestPrometheusDetails => {
const apiBase = di.inject(apiBaseInjectable);
return () => apiBase.get("/prometheus/details");
},
});
export default requestPrometheusDetailsInjectable;

View File

@ -0,0 +1,39 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getRequestChannelListenerInjectable } from "@k8slens/messaging";
import { prometheusDetailsChannel } from "../../../common/k8s-api/endpoints/metrics.api/prometheus-details.channel";
import prometheusHandlerInjectable from "./prometheus-handler.injectable";
import clustersInjectable from "../../../features/cluster/storage/common/clusters.injectable";
const prometheusDetailsChannelListener =
getRequestChannelListenerInjectable({
id: "add-helm-repository-channel-listener",
channel: prometheusDetailsChannel,
getHandler: (di) => {
return async (clusterId) => {
const clusters = di.inject(clustersInjectable);
const cluster = clusters.get().find((c) => c.id === clusterId);
if (!cluster) {
throw new Error(`Cluster with id "${clusterId}" not found`);
}
const prometheusHandler = di.inject(prometheusHandlerInjectable, cluster);
const details = await prometheusHandler.getPrometheusDetails();
console.log(details);
return {
prometheusPath: details.prometheusPath,
provider: {
kind: details.provider.kind,
name: details.provider.name,
isConfigurable: details.provider.isConfigurable,
},
};
};
},
});
export default prometheusDetailsChannelListener;

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { logInfoInjectionToken } from "@k8slens/logger";
import { requestFromChannelInjectionToken } from "@k8slens/messaging";
import { prometheusDetailsChannel } from "../../../common/k8s-api/endpoints/metrics.api/prometheus-details.channel";
const getPrometheusDetailsRouteInjectable = getInjectable({
id: "get-prometheus-details-route",
instantiate: (di) => {
const logger = di.inject(logInfoInjectionToken);
const requestFromChannel = di.inject(requestFromChannelInjectionToken);
return (async (clusterId: string) => {
logger("requestFromChannel");
const prometheusDetails = await requestFromChannel(prometheusDetailsChannel, clusterId);
return prometheusDetails;
});
},
});
export default getPrometheusDetailsRouteInjectable;

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import { SubTitle } from "../layout/sub-title";
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
interface PrometheusDetailsProps {
providerName: string;
path: string;
}
export const PrometheusDetails = ({ providerName, path }: PrometheusDetailsProps) => (
<section>
<SubTitle title="Auto detected prometheus details" />
<div className="flex gaps align-center">
<div>
Prometheus provider name
</div>
<div>
{providerName}
</div>
</div>
<div className="flex gaps align-center">
<div>
Prometheus path
</div>
<div>
{path}
</div>
</div>
</section>
);

View File

@ -16,6 +16,11 @@ import type { MetricProviderInfo, RequestMetricsProviders } from "../../../commo
import { withInjectables } from "@ogre-tools/injectable-react";
import requestMetricsProvidersInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-providers.injectable";
import productNameInjectable from "../../../common/vars/product-name.injectable";
import getPrometheusDetailsRouteInjectable from "./get-prometheus-details.injectable";
import type { PrometheusDetailsData } from "../../../common/k8s-api/endpoints/metrics.api/prometheus-details.channel";
import { loggerInjectionToken } from "@k8slens/logger";
import type { Logger } from "@k8slens/logger";
import { PrometheusDetails } from "./prometheus-details";
export interface ClusterPrometheusSettingProps {
cluster: Cluster;
@ -28,6 +33,13 @@ type ProviderValue = typeof autoDetectPrometheus | string;
interface Dependencies {
productName: string;
requestMetricsProviders: RequestMetricsProviders;
requestPrometheusDetails: (clusterId: string) => Promise<PrometheusDetailsData>;
logger: Logger;
}
interface PrometheusDetailsDataResult {
type: "success" | "error";
details?: PrometheusDetailsData;
}
@observer
@ -35,6 +47,7 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
@observable path = "";
@observable selectedOption: ProviderValue = autoDetectPrometheus;
@observable loading = true;
@observable prometheusDetails: PrometheusDetailsDataResult | null = null;
readonly loadedOptions = observable.map<string, MetricProviderInfo>();
@computed get options(): SelectOption<ProviderValue>[] {
@ -91,6 +104,8 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
this.loading = false;
this.loadedOptions.replace(values.map(provider => [provider.id, provider]));
});
this.loadPrometheusDetails();
}
parsePrometheusPath = () => {
@ -118,11 +133,31 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
: undefined;
};
loadPrometheusDetails = async () => {
try {
const details = await this.props.requestPrometheusDetails(this.props.cluster.id);
this.prometheusDetails = {
type: "success",
details,
};
this.props.logger.info(`[CLUSTER-SETTINGS]: Prometheus details loaded: ${JSON.stringify(this.prometheusDetails)}`);
} catch (error) {
this.props.logger.error(`[CLUSTER-SETTINGS]: Failed to load prometheus details: ${error}`);
this.prometheusDetails = {
type: "error",
details: undefined,
};
}
};
onSavePath = () => {
this.props.cluster.preferences.prometheus = this.parsePrometheusPath();
};
render() {
return (
<>
<section>
@ -138,6 +173,12 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
onChange={option => {
this.selectedOption = option?.value ?? autoDetectPrometheus;
this.onSaveProvider();
// takes a while for the prometheus details to be available
// after saving the provider
setTimeout(() => {
void this.loadPrometheusDetails();
}, 100);
}}
options={this.options}
themeName="lens"
@ -147,6 +188,18 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
)
}
</section>
{this.prometheusDetails?.details && this.prometheusDetails?.type === "success" /*&& this.selectedOption === autoDetectPrometheus */ && (
<>
<hr />
<PrometheusDetails
providerName={this.prometheusDetails.details.provider.name}
path={this.prometheusDetails.details.prometheusPath}
/>
</>
)}
{this.prometheusDetails?.type === "error" && (
<div>auto detection did not find a prometheus provider</div>
)}
{this.canEditPrometheusPath && (
<>
<hr />
@ -175,5 +228,7 @@ export const ClusterPrometheusSetting = withInjectables<Dependencies, ClusterPro
...props,
productName: di.inject(productNameInjectable),
requestMetricsProviders: di.inject(requestMetricsProvidersInjectable),
requestPrometheusDetails: di.inject(getPrometheusDetailsRouteInjectable),
logger: di.inject(loggerInjectionToken),
}),
});