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:
parent
683ac4efcc
commit
8867f3a9e2
@ -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");
|
||||||
@ -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;
|
||||||
@ -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;
|
||||||
@ -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;
|
||||||
@ -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>
|
||||||
|
);
|
||||||
@ -16,6 +16,11 @@ import type { MetricProviderInfo, RequestMetricsProviders } from "../../../commo
|
|||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import requestMetricsProvidersInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-providers.injectable";
|
import requestMetricsProvidersInjectable from "../../../common/k8s-api/endpoints/metrics.api/request-providers.injectable";
|
||||||
import productNameInjectable from "../../../common/vars/product-name.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 {
|
export interface ClusterPrometheusSettingProps {
|
||||||
cluster: Cluster;
|
cluster: Cluster;
|
||||||
@ -28,6 +33,13 @@ type ProviderValue = typeof autoDetectPrometheus | string;
|
|||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
productName: string;
|
productName: string;
|
||||||
requestMetricsProviders: RequestMetricsProviders;
|
requestMetricsProviders: RequestMetricsProviders;
|
||||||
|
requestPrometheusDetails: (clusterId: string) => Promise<PrometheusDetailsData>;
|
||||||
|
logger: Logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PrometheusDetailsDataResult {
|
||||||
|
type: "success" | "error";
|
||||||
|
details?: PrometheusDetailsData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
@ -35,6 +47,7 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
|
|||||||
@observable path = "";
|
@observable path = "";
|
||||||
@observable selectedOption: ProviderValue = autoDetectPrometheus;
|
@observable selectedOption: ProviderValue = autoDetectPrometheus;
|
||||||
@observable loading = true;
|
@observable loading = true;
|
||||||
|
@observable prometheusDetails: PrometheusDetailsDataResult | null = null;
|
||||||
readonly loadedOptions = observable.map<string, MetricProviderInfo>();
|
readonly loadedOptions = observable.map<string, MetricProviderInfo>();
|
||||||
|
|
||||||
@computed get options(): SelectOption<ProviderValue>[] {
|
@computed get options(): SelectOption<ProviderValue>[] {
|
||||||
@ -91,6 +104,8 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.loadedOptions.replace(values.map(provider => [provider.id, provider]));
|
this.loadedOptions.replace(values.map(provider => [provider.id, provider]));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.loadPrometheusDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
parsePrometheusPath = () => {
|
parsePrometheusPath = () => {
|
||||||
@ -118,11 +133,31 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
|
|||||||
: undefined;
|
: 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 = () => {
|
onSavePath = () => {
|
||||||
this.props.cluster.preferences.prometheus = this.parsePrometheusPath();
|
this.props.cluster.preferences.prometheus = this.parsePrometheusPath();
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<section>
|
<section>
|
||||||
@ -138,6 +173,12 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
|
|||||||
onChange={option => {
|
onChange={option => {
|
||||||
this.selectedOption = option?.value ?? autoDetectPrometheus;
|
this.selectedOption = option?.value ?? autoDetectPrometheus;
|
||||||
this.onSaveProvider();
|
this.onSaveProvider();
|
||||||
|
|
||||||
|
// takes a while for the prometheus details to be available
|
||||||
|
// after saving the provider
|
||||||
|
setTimeout(() => {
|
||||||
|
void this.loadPrometheusDetails();
|
||||||
|
}, 100);
|
||||||
}}
|
}}
|
||||||
options={this.options}
|
options={this.options}
|
||||||
themeName="lens"
|
themeName="lens"
|
||||||
@ -147,6 +188,18 @@ class NonInjectedClusterPrometheusSetting extends React.Component<ClusterPrometh
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
</section>
|
</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 && (
|
{this.canEditPrometheusPath && (
|
||||||
<>
|
<>
|
||||||
<hr />
|
<hr />
|
||||||
@ -175,5 +228,7 @@ export const ClusterPrometheusSetting = withInjectables<Dependencies, ClusterPro
|
|||||||
...props,
|
...props,
|
||||||
productName: di.inject(productNameInjectable),
|
productName: di.inject(productNameInjectable),
|
||||||
requestMetricsProviders: di.inject(requestMetricsProvidersInjectable),
|
requestMetricsProviders: di.inject(requestMetricsProvidersInjectable),
|
||||||
|
requestPrometheusDetails: di.inject(getPrometheusDetailsRouteInjectable),
|
||||||
|
logger: di.inject(loggerInjectionToken),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user