mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
dedicated action button
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
b3da20c425
commit
4b983ae5bd
@ -2,3 +2,5 @@ apiVersion: v1
|
|||||||
kind: Namespace
|
kind: Namespace
|
||||||
metadata:
|
metadata:
|
||||||
name: lens-metrics
|
name: lens-metrics
|
||||||
|
annotations:
|
||||||
|
extensionVersion: "{{ version }}"
|
||||||
@ -46,6 +46,7 @@ export interface MetricsConfiguration {
|
|||||||
alertManagers: string[];
|
alertManagers: string[];
|
||||||
replicas: number;
|
replicas: number;
|
||||||
storageClass: string;
|
storageClass: string;
|
||||||
|
version?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MetricsStatus {
|
export interface MetricsStatus {
|
||||||
@ -77,6 +78,8 @@ export class MetricsFeature {
|
|||||||
sc.metadata?.annotations?.["storageclass.beta.kubernetes.io/is-default-class"] === "true"
|
sc.metadata?.annotations?.["storageclass.beta.kubernetes.io/is-default-class"] === "true"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
config.version = this.latestVersion;
|
||||||
|
|
||||||
return this.stack.kubectlApplyFolder(this.resourceFolder, config, ["--prune"]);
|
return this.stack.kubectlApplyFolder(this.resourceFolder, config, ["--prune"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,11 +91,11 @@ export class MetricsFeature {
|
|||||||
const status: MetricsStatus = { installed: false, canUpgrade: false};
|
const status: MetricsStatus = { installed: false, canUpgrade: false};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const statefulSet = K8sApi.forCluster(this.cluster, K8sApi.StatefulSet);
|
const namespaceApi = K8sApi.forCluster(this.cluster, K8sApi.Namespace);
|
||||||
const prometheus = await statefulSet.get({name: "prometheus", namespace: "lens-metrics"});
|
const namespace = await namespaceApi.get({name: "lens-metrics"});
|
||||||
|
|
||||||
if (prometheus?.kind) {
|
if (namespace?.kind) {
|
||||||
const currentVersion = prometheus.spec.template.spec.containers[0].image.split(":")[1];
|
const currentVersion = namespace.metadata.annotations?.extensionVersion || "0.0.0";
|
||||||
|
|
||||||
status.installed = true;
|
status.installed = true;
|
||||||
status.canUpgrade = semver.lt(currentVersion, this.latestVersion, true);
|
status.canUpgrade = semver.lt(currentVersion, this.latestVersion, true);
|
||||||
|
|||||||
@ -17,6 +17,8 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
};
|
};
|
||||||
@observable canUpgrade = false;
|
@observable canUpgrade = false;
|
||||||
@observable upgrading = false;
|
@observable upgrading = false;
|
||||||
|
@observable changed = false;
|
||||||
|
@observable inProgress = false;
|
||||||
|
|
||||||
config: MetricsConfiguration = {
|
config: MetricsConfiguration = {
|
||||||
prometheus: {
|
prometheus: {
|
||||||
@ -44,6 +46,7 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
feature: MetricsFeature;
|
feature: MetricsFeature;
|
||||||
|
|
||||||
@computed get isTogglable() {
|
@computed get isTogglable() {
|
||||||
|
if (this.inProgress) return false;
|
||||||
if (!this.props.cluster.status.active) return false;
|
if (!this.props.cluster.status.active) return false;
|
||||||
if (this.canUpgrade) return false;
|
if (this.canUpgrade) return false;
|
||||||
if (!this.isActiveMetricsProvider) return false;
|
if (!this.isActiveMetricsProvider) return false;
|
||||||
@ -69,7 +72,23 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
const status = await this.feature.getStatus();
|
const status = await this.feature.getStatus();
|
||||||
|
|
||||||
this.canUpgrade = status.canUpgrade;
|
this.canUpgrade = status.canUpgrade;
|
||||||
this.featureStates.prometheus = status.installed;
|
|
||||||
|
if (this.canUpgrade) {
|
||||||
|
this.changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statefulSet = K8sApi.forCluster(this.props.cluster, K8sApi.StatefulSet);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await statefulSet.get({name: "prometheus", namespace: "lens-metrics"});
|
||||||
|
this.featureStates.prometheus = true;
|
||||||
|
} catch(e) {
|
||||||
|
if (e?.error?.code === 404) {
|
||||||
|
this.featureStates.prometheus = false;
|
||||||
|
} else {
|
||||||
|
this.featureStates.prometheus = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const deployment = K8sApi.forCluster(this.props.cluster, K8sApi.Deployment);
|
const deployment = K8sApi.forCluster(this.props.cluster, K8sApi.Deployment);
|
||||||
|
|
||||||
@ -103,55 +122,47 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
this.config.kubeStateMetrics.enabled = !!this.featureStates.kubeStateMetrics;
|
this.config.kubeStateMetrics.enabled = !!this.featureStates.kubeStateMetrics;
|
||||||
this.config.nodeExporter.enabled = !!this.featureStates.nodeExporter;
|
this.config.nodeExporter.enabled = !!this.featureStates.nodeExporter;
|
||||||
|
|
||||||
|
this.inProgress = true;
|
||||||
|
|
||||||
|
try {
|
||||||
if (!this.config.prometheus.enabled && !this.config.kubeStateMetrics.enabled && !this.config.nodeExporter.enabled) {
|
if (!this.config.prometheus.enabled && !this.config.kubeStateMetrics.enabled && !this.config.nodeExporter.enabled) {
|
||||||
await this.feature.uninstall(this.config);
|
await this.feature.uninstall(this.config);
|
||||||
} else {
|
} else {
|
||||||
await this.feature.install(this.config);
|
await this.feature.install(this.config);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
this.inProgress = false;
|
||||||
|
this.changed = false;
|
||||||
|
|
||||||
|
await this.updateFeatureStates();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async togglePrometheus(enabled: boolean) {
|
async togglePrometheus(enabled: boolean) {
|
||||||
this.featureStates.prometheus = enabled;
|
this.featureStates.prometheus = enabled;
|
||||||
|
this.changed = true;
|
||||||
try {
|
|
||||||
await this.save();
|
|
||||||
} catch(error) {
|
|
||||||
this.featureStates.prometheus = !enabled;
|
|
||||||
Component.Notifications.error(`Failed to ${enabled ? "enable" : "disable"} Prometheus: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleKubeStateMetrics(enabled: boolean) {
|
async toggleKubeStateMetrics(enabled: boolean) {
|
||||||
this.featureStates.kubeStateMetrics = enabled;
|
this.featureStates.kubeStateMetrics = enabled;
|
||||||
|
this.changed = true;
|
||||||
try {
|
|
||||||
await this.save();
|
|
||||||
} catch(error) {
|
|
||||||
this.featureStates.kubeStateMetrics = !enabled;
|
|
||||||
Component.Notifications.error(`Failed to ${enabled ? "enable" : "disable"} kube-state-metrics: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleNodeExporter(enabled: boolean) {
|
async toggleNodeExporter(enabled: boolean) {
|
||||||
this.featureStates.nodeExporter = enabled;
|
this.featureStates.nodeExporter = enabled;
|
||||||
|
this.changed = true;
|
||||||
try {
|
|
||||||
await this.save();
|
|
||||||
} catch(error) {
|
|
||||||
this.featureStates.nodeExporter = !enabled;
|
|
||||||
Component.Notifications.error(`Failed to ${enabled ? "enable" : "disable"} node-exporter: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateStack() {
|
@computed get buttonLabel() {
|
||||||
this.upgrading = true;
|
if (this.inProgress && this.canUpgrade) return "Upgrading ...";
|
||||||
|
if (this.inProgress) return "Applying ...";
|
||||||
|
if (this.canUpgrade) return "Upgrade";
|
||||||
|
|
||||||
await this.save();
|
if (this.changed && !this.featureStates.kubeStateMetrics && !this.featureStates.nodeExporter && !this.featureStates.prometheus) {
|
||||||
setTimeout(() => {
|
return "Uninstall";
|
||||||
Component.Notifications.info("Lens Metrics stack updated!", {timeout: 5_000});
|
}
|
||||||
this.upgrading = false;
|
|
||||||
this.canUpgrade = false;
|
return "Apply";
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -171,17 +182,6 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
{ this.canUpgrade && (
|
|
||||||
<section>
|
|
||||||
<Component.SubTitle title="Software Update" />
|
|
||||||
|
|
||||||
<Component.Button label={this.upgrading ? "Updating ..." : "Update Now"} primary onClick={() => this.updateStack() } waiting={this.upgrading} />
|
|
||||||
|
|
||||||
<small className="hint">
|
|
||||||
An update is available for enabled metrics components.
|
|
||||||
</small>
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
<section>
|
<section>
|
||||||
<Component.SubTitle title="Prometheus" />
|
<Component.SubTitle title="Prometheus" />
|
||||||
<Component.FormSwitch
|
<Component.FormSwitch
|
||||||
@ -193,7 +193,7 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
name="prometheus"
|
name="prometheus"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Install bundled Prometheus metrics stack"
|
label="Enable bundled Prometheus metrics stack"
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
Enable timeseries data visualization (Prometheus stack) for your cluster.
|
Enable timeseries data visualization (Prometheus stack) for your cluster.
|
||||||
@ -211,11 +211,11 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
name="node-exporter"
|
name="node-exporter"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Install bundled kube-state-metrics stack"
|
label="Enable bundled kube-state-metrics stack"
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
Enable Kubernetes API object metrics for your cluster.
|
Enable Kubernetes API object metrics for your cluster.
|
||||||
Install this only if you don't have existing kube-state-metrics stack installed.
|
Enable this only if you don't have existing kube-state-metrics stack installed.
|
||||||
</small>
|
</small>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -230,13 +230,26 @@ export class MetricsSettings extends React.Component<Props> {
|
|||||||
name="node-exporter"
|
name="node-exporter"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Install bundled node-exporter stack"
|
label="Enable bundled node-exporter stack"
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
Enable node level metrics for your cluster.
|
Enable node level metrics for your cluster.
|
||||||
Install this only if you don't have existing node-exporter stack installed.
|
Enable this only if you don't have existing node-exporter stack installed.
|
||||||
</small>
|
</small>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<Component.Button
|
||||||
|
label={this.buttonLabel}
|
||||||
|
waiting={this.inProgress}
|
||||||
|
onClick={() => this.save()}
|
||||||
|
primary
|
||||||
|
disabled={!this.changed} />
|
||||||
|
|
||||||
|
{this.canUpgrade && (<small className="hint">
|
||||||
|
An update is available for enabled metrics components.
|
||||||
|
</small>)}
|
||||||
|
</section>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user