diff --git a/extensions/metrics-cluster-feature/src/metrics-settings.tsx b/extensions/metrics-cluster-feature/src/metrics-settings.tsx index 34b88fa2cc..697f9a168d 100644 --- a/extensions/metrics-cluster-feature/src/metrics-settings.tsx +++ b/extensions/metrics-cluster-feature/src/metrics-settings.tsx @@ -1,7 +1,7 @@ import React from "react"; import { Component, Catalog, K8sApi } from "@k8slens/extensions"; import { observer } from "mobx-react"; -import { observable } from "mobx"; +import { computed, observable } from "mobx"; import { MetricsFeature, MetricsConfiguration } from "./metrics-feature"; interface Props { @@ -43,6 +43,22 @@ export class MetricsSettings extends React.Component { }; feature: MetricsFeature; + @computed get isTogglable() { + if (!this.props.cluster.status.active) return false; + if (this.canUpgrade) return false; + if (!this.isActiveMetricsProvider) return false; + + return true; + } + + get metricsProvider() { + return this.props.cluster.spec?.metrics?.prometheus?.type || ""; + } + + get isActiveMetricsProvider() { + return (!this.metricsProvider || this.metricsProvider === "lens"); + } + async componentDidMount() { this.feature = new MetricsFeature(this.props.cluster); @@ -148,6 +164,13 @@ export class MetricsSettings extends React.Component {

)} + { !this.isActiveMetricsProvider && ( +
+

+ Other metrics provider is currently active. See "Metrics" tab for details. +

+
+ )} { this.canUpgrade && (
@@ -155,7 +178,7 @@ export class MetricsSettings extends React.Component { this.updateStack() } waiting={this.upgrading} /> - An update is available for installed metrics components. + An update is available for enabled metrics components.
)} @@ -164,7 +187,7 @@ export class MetricsSettings extends React.Component { this.togglePrometheus(v.target.checked)} name="prometheus" @@ -182,7 +205,7 @@ export class MetricsSettings extends React.Component { this.toggleKubeStateMetrics(v.target.checked)} name="node-exporter" @@ -201,7 +224,7 @@ export class MetricsSettings extends React.Component { this.toggleNodeExporter(v.target.checked)} name="node-exporter" diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index 21400aa9bd..d138b05d12 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -6,9 +6,24 @@ import { requestMain } from "../ipc"; import { productName } from "../vars"; import { CatalogCategory, CatalogCategorySpec } from "../catalog"; + +export type KubernetesClusterPrometheusMetrics = { + address?: { + namespace: string; + service: string; + port: number; + prefix: string; + }; + type?: string; +}; + export type KubernetesClusterSpec = { kubeconfigPath: string; kubeconfigContext: string; + metrics?: { + source: string; + prometheus?: KubernetesClusterPrometheusMetrics; + } }; export interface KubernetesClusterStatus extends CatalogEntityStatus { diff --git a/src/extensions/registries/entity-setting-registry.ts b/src/extensions/registries/entity-setting-registry.ts index 444f816b0a..c63f01423b 100644 --- a/src/extensions/registries/entity-setting-registry.ts +++ b/src/extensions/registries/entity-setting-registry.ts @@ -11,13 +11,14 @@ export interface EntitySettingComponents { } export interface EntitySettingRegistration { - title: string; - kind: string; apiVersions: string[]; - source?: string; + kind: string; + title: string; components: EntitySettingComponents; + source?: string; id?: string; priority?: number; + group?: string; } export interface RegisteredEntitySetting extends EntitySettingRegistration { diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index 9b1b133749..c54f83825a 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -8,7 +8,7 @@ import logger from "./logger"; import { apiKubePrefix } from "../common/vars"; import { Singleton } from "../common/utils"; import { catalogEntityRegistry } from "../common/catalog"; -import { KubernetesCluster } from "../common/catalog-entities/kubernetes-cluster"; +import { KubernetesCluster, KubernetesClusterPrometheusMetrics } from "../common/catalog-entities/kubernetes-cluster"; export class ClusterManager extends Singleton { constructor() { @@ -47,7 +47,7 @@ export class ClusterManager extends Singleton { const index = catalogEntityRegistry.items.findIndex((entity) => entity.metadata.uid === cluster.id); if (index !== -1) { - const entity = catalogEntityRegistry.items[index]; + const entity = catalogEntityRegistry.items[index] as KubernetesCluster; entity.status.phase = cluster.disconnected ? "disconnected" : "connected"; entity.status.active = !cluster.disconnected; @@ -55,6 +55,17 @@ export class ClusterManager extends Singleton { if (cluster.preferences?.clusterName) { entity.metadata.name = cluster.preferences.clusterName; } + + entity.spec.metrics ||= { source: "local" }; + + if (entity.spec.metrics.source === "local") { + const prometheus: KubernetesClusterPrometheusMetrics = entity.spec?.metrics?.prometheus || {}; + + prometheus.type = cluster.preferences.prometheusProvider?.type; + prometheus.address = cluster.preferences.prometheus; + entity.spec.metrics.prometheus = prometheus; + } + catalogEntityRegistry.items.splice(index, 1, entity); } } diff --git a/src/renderer/components/+entity-settings/entity-settings.tsx b/src/renderer/components/+entity-settings/entity-settings.tsx index 3d0a8f26a3..fb2853f86f 100644 --- a/src/renderer/components/+entity-settings/entity-settings.tsx +++ b/src/renderer/components/+entity-settings/entity-settings.tsx @@ -11,6 +11,7 @@ import { CatalogEntity } from "../../api/catalog-entity"; import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; import { entitySettingRegistry } from "../../../extensions/registries"; import { EntitySettingsRouteParams } from "./entity-settings.route"; +import { groupBy } from "lodash"; interface Props extends RouteComponentProps { } @@ -52,18 +53,24 @@ export class EntitySettings extends React.Component { }; renderNavigation() { + const groups = Object.entries(groupBy(this.menuItems, (item) => item.group || "Extensions")); + return ( <>

{this.entity.metadata.name}

-
Settings
- { this.menuItems.map((setting) => ( - + { groups.map((group) => ( + <> +
{group[0]}
+ { group[1].map((setting) => ( + + ))} + ))}
diff --git a/src/renderer/components/cluster-settings/cluster-settings.tsx b/src/renderer/components/cluster-settings/cluster-settings.tsx index ba1aff0d9f..9498f1b089 100644 --- a/src/renderer/components/cluster-settings/cluster-settings.tsx +++ b/src/renderer/components/cluster-settings/cluster-settings.tsx @@ -22,6 +22,7 @@ entitySettingRegistry.add([ kind: "KubernetesCluster", source: "local", title: "General", + group: "Settings", components: { View: (props: { entity: CatalogEntity }) => { const cluster = getClusterForEntity(props.entity); @@ -47,6 +48,7 @@ entitySettingRegistry.add([ apiVersions: ["entity.k8slens.dev/v1alpha1"], kind: "KubernetesCluster", title: "Proxy", + group: "Settings", components: { View: (props: { entity: CatalogEntity }) => { const cluster = getClusterForEntity(props.entity); @@ -67,6 +69,7 @@ entitySettingRegistry.add([ apiVersions: ["entity.k8slens.dev/v1alpha1"], kind: "KubernetesCluster", title: "Terminal", + group: "Settings", components: { View: (props: { entity: CatalogEntity }) => { const cluster = getClusterForEntity(props.entity); @@ -87,6 +90,7 @@ entitySettingRegistry.add([ apiVersions: ["entity.k8slens.dev/v1alpha1"], kind: "KubernetesCluster", title: "Namespaces", + group: "Settings", components: { View: (props: { entity: CatalogEntity }) => { const cluster = getClusterForEntity(props.entity); @@ -107,6 +111,7 @@ entitySettingRegistry.add([ apiVersions: ["entity.k8slens.dev/v1alpha1"], kind: "KubernetesCluster", title: "Metrics", + group: "Settings", components: { View: (props: { entity: CatalogEntity }) => { const cluster = getClusterForEntity(props.entity); diff --git a/src/renderer/components/cluster-settings/components/cluster-metrics-setting.scss b/src/renderer/components/cluster-settings/components/cluster-metrics-setting.scss deleted file mode 100644 index eede36623e..0000000000 --- a/src/renderer/components/cluster-settings/components/cluster-metrics-setting.scss +++ /dev/null @@ -1,12 +0,0 @@ -.MetricsSelect { - $spacing: $padding; - --flex-gap: #{$spacing}; - - .Badge { - margin-top: $spacing; - } - - .Button { - margin-top: $spacing; - } -} diff --git a/src/renderer/components/cluster-settings/components/cluster-metrics-setting.tsx b/src/renderer/components/cluster-settings/components/cluster-metrics-setting.tsx index bc51ddf061..4a140dc4d0 100644 --- a/src/renderer/components/cluster-settings/components/cluster-metrics-setting.tsx +++ b/src/renderer/components/cluster-settings/components/cluster-metrics-setting.tsx @@ -1,5 +1,3 @@ -import "./cluster-metrics-setting.scss"; - import React from "react"; import { disposeOnUnmount, observer } from "mobx-react"; import { Select, SelectOption } from "../../select/select"; diff --git a/src/renderer/components/cluster-settings/components/cluster-prometheus-setting.tsx b/src/renderer/components/cluster-settings/components/cluster-prometheus-setting.tsx index f42ecbd321..73ba69ac43 100644 --- a/src/renderer/components/cluster-settings/components/cluster-prometheus-setting.tsx +++ b/src/renderer/components/cluster-settings/components/cluster-prometheus-setting.tsx @@ -6,6 +6,7 @@ import { SubTitle } from "../../layout/sub-title"; import { Select, SelectOption } from "../../select"; import { Input } from "../../input"; import { observable, computed, autorun } from "mobx"; +import { productName } from "../../../../common/vars"; const options: SelectOption[] = [ { value: "", label: "Auto detect" }, @@ -81,23 +82,20 @@ export class ClusterPrometheusSetting extends React.Component { render() { return ( <> - -

- Use pre-installed Prometheus service for metrics. Please refer to the{" "} - guide{" "} - for possible configuration changes. -

- { + this.provider = value; + this.onSaveProvider(); + }} + options={options} + /> + What query format is used to fetch metrics from Prometheus + {this.canEditPrometheusPath && ( - <> +

Prometheus service address.

{ /> An address to an existing Prometheus installation{" "} - ({"/:"}). Lens tries to auto-detect address if left empty. + ({"/:"}). {productName} tries to auto-detect address if left empty. - +
)} ); diff --git a/src/renderer/components/cluster-settings/components/show-metrics.tsx b/src/renderer/components/cluster-settings/components/show-metrics.tsx index a3e071182f..6c7b2c3897 100644 --- a/src/renderer/components/cluster-settings/components/show-metrics.tsx +++ b/src/renderer/components/cluster-settings/components/show-metrics.tsx @@ -1,5 +1,3 @@ -import "./cluster-metrics-setting.scss"; - import React from "react"; import { disposeOnUnmount, observer } from "mobx-react"; import { Cluster } from "../../../../main/cluster";