From de95c8416c7b4bd5a3bd4984cf94154e804f8e54 Mon Sep 17 00:00:00 2001 From: Jari Kolehmainen Date: Wed, 22 Apr 2020 18:56:14 +0300 Subject: [PATCH] update metrics feature Signed-off-by: Jari Kolehmainen --- src/features/metrics.ts | 10 +- src/features/metrics/03-statefulset.yml.hb | 2 +- src/features/metrics/05-clusterrole.yml | 3 + .../metrics/10-node-exporter-ds.yml.hb | 4 +- .../12-kube-state-metrics-clusterrole.yml | 155 ++++++++++++------ .../14-kube-state-metrics-deployment.yml.hb | 2 +- src/features/user-mode.ts | 4 + src/main/cluster-manager.ts | 11 ++ src/main/cluster.ts | 5 + src/main/feature-manager.ts | 6 +- src/main/feature.ts | 4 +- .../Features/Components/Metrics.vue | 43 +++-- .../Features/Components/UserMode.vue | 3 - src/renderer/store/modules/clusters.ts | 13 ++ 14 files changed, 187 insertions(+), 78 deletions(-) diff --git a/src/features/metrics.ts b/src/features/metrics.ts index 2be5ae6a8ba1..8cbd10080f7b 100644 --- a/src/features/metrics.ts +++ b/src/features/metrics.ts @@ -28,7 +28,7 @@ export interface MetricsConfiguration { export class MetricsFeature extends Feature { name = 'metrics'; - latestVersion = "v2.11.1" + latestVersion = "v2.17.2-lens1" config: MetricsConfiguration = { persistence: { @@ -40,7 +40,7 @@ export class MetricsFeature extends Feature { enabled: true, }, retention: { - time: "7d", + time: "2d", size: "5GB", }, kubeStateMetrics: { @@ -65,6 +65,10 @@ export class MetricsFeature extends Feature { return super.install(cluster) } + async upgrade(cluster: Cluster): Promise { + return this.install(cluster) + } + async featureStatus(kc: KubeConfig): Promise { return new Promise( async (resolve, reject) => { const client = kc.makeApiClient(AppsV1Api) @@ -79,7 +83,7 @@ export class MetricsFeature extends Feature { const prometheus = (await client.readNamespacedStatefulSet('prometheus', 'lens-metrics')).body; status.installed = true; status.currentVersion = prometheus.spec.template.spec.containers[0].image.split(":")[1]; - status.canUpgrade = semver.lt(status.currentVersion, this.latestVersion) + status.canUpgrade = semver.lt(status.currentVersion, this.latestVersion, true); resolve(status) } catch(error) { resolve(status) diff --git a/src/features/metrics/03-statefulset.yml.hb b/src/features/metrics/03-statefulset.yml.hb index ef568ae9fb0e..8a28acd480e7 100644 --- a/src/features/metrics/03-statefulset.yml.hb +++ b/src/features/metrics/03-statefulset.yml.hb @@ -53,7 +53,7 @@ spec: mountPath: /var/lib/prometheus containers: - name: prometheus - image: docker.io/kontenapharos/prometheus:v2.11.1 + image: docker.io/prom/prometheus:v2.17.2 args: - --web.listen-address=0.0.0.0:9090 - --config.file=/etc/prometheus/prometheus.yaml diff --git a/src/features/metrics/05-clusterrole.yml b/src/features/metrics/05-clusterrole.yml index 91c12c4c989d..9b23edc84b8d 100644 --- a/src/features/metrics/05-clusterrole.yml +++ b/src/features/metrics/05-clusterrole.yml @@ -6,10 +6,13 @@ rules: - apiGroups: [""] resources: - nodes + - nodes/proxy - nodes/metrics - services - endpoints - pods + - ingresses + - configmaps verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"] verbs: ["get"] diff --git a/src/features/metrics/10-node-exporter-ds.yml.hb b/src/features/metrics/10-node-exporter-ds.yml.hb index 631e9ae8a768..d78437275fd6 100644 --- a/src/features/metrics/10-node-exporter-ds.yml.hb +++ b/src/features/metrics/10-node-exporter-ds.yml.hb @@ -41,7 +41,7 @@ spec: hostPID: true containers: - name: node-exporter - image: docker.io/kontenapharos/prometheus-node-exporter:v0.18.0 + image: docker.io/prom/node-exporter:v1.0.0-rc.0 args: - --path.procfs=/host/proc - --path.sysfs=/host/sys @@ -54,7 +54,7 @@ spec: resources: requests: cpu: 10m - memory: 50Mi + memory: 24Mi limits: cpu: 200m memory: 100Mi diff --git a/src/features/metrics/12-kube-state-metrics-clusterrole.yml b/src/features/metrics/12-kube-state-metrics-clusterrole.yml index 4c7a5338afcf..b74e08fc5721 100644 --- a/src/features/metrics/12-kube-state-metrics-clusterrole.yml +++ b/src/features/metrics/12-kube-state-metrics-clusterrole.yml @@ -3,49 +3,112 @@ kind: ClusterRole metadata: name: lens-kube-state-metrics rules: -- apiGroups: [""] - resources: - - configmaps - - secrets - - nodes - - pods - - services - - resourcequotas - - replicationcontrollers - - limitranges - - persistentvolumeclaims - - persistentvolumes - - namespaces - - endpoints - verbs: ["list", "watch"] -- apiGroups: ["extensions"] - resources: - - daemonsets - - deployments - - replicasets - - ingresses - verbs: ["list", "watch"] -- apiGroups: ["apps"] - resources: - - daemonsets - - deployments - - replicasets - - statefulsets - verbs: ["list", "watch"] -- apiGroups: ["batch"] - resources: - - cronjobs - - jobs - verbs: ["list", "watch"] -- apiGroups: ["autoscaling"] - resources: - - horizontalpodautoscalers - verbs: ["list", "watch"] -- apiGroups: ["policy"] - resources: - - poddisruptionbudgets - verbs: ["list", "watch"] -- apiGroups: ["certificates.k8s.io"] - resources: - - certificatesigningrequests - verbs: ["list", "watch"] + - apiGroups: + - "" + resources: + - configmaps + - secrets + - nodes + - pods + - services + - resourcequotas + - replicationcontrollers + - limitranges + - persistentvolumeclaims + - persistentvolumes + - namespaces + - endpoints + verbs: + - list + - watch + - apiGroups: + - extensions + resources: + - daemonsets + - deployments + - replicasets + - ingresses + verbs: + - list + - watch + - apiGroups: + - apps + resources: + - statefulsets + - daemonsets + - deployments + - replicasets + verbs: + - list + - watch + - apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - list + - watch + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - list + - watch + - apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - list + - watch + - apiGroups: + - storage.k8s.io + resources: + - storageclasses + - volumeattachments + verbs: + - list + - watch + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - networkpolicies + verbs: + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch diff --git a/src/features/metrics/14-kube-state-metrics-deployment.yml.hb b/src/features/metrics/14-kube-state-metrics-deployment.yml.hb index 09857b3611a6..575eb41e95b1 100644 --- a/src/features/metrics/14-kube-state-metrics-deployment.yml.hb +++ b/src/features/metrics/14-kube-state-metrics-deployment.yml.hb @@ -31,7 +31,7 @@ spec: serviceAccountName: kube-state-metrics containers: - name: kube-state-metrics - image: docker.io/kontenapharos/prometheus-kube-state-metrics:v1.6.0 + image: quay.io/coreos/kube-state-metrics:v1.9.5 ports: - name: metrics containerPort: 8080 diff --git a/src/features/user-mode.ts b/src/features/user-mode.ts index 69aa963ad98e..eea957a6b401 100644 --- a/src/features/user-mode.ts +++ b/src/features/user-mode.ts @@ -10,6 +10,10 @@ export class UserModeFeature extends Feature { return super.install(cluster) } + async upgrade(cluster: Cluster): Promise { + return true + } + async featureStatus(kc: KubeConfig): Promise { return new Promise( async (resolve, reject) => { const client = kc.makeApiClient(RbacAuthorizationV1Api) diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index ed5793242731..882604fcc271 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -150,6 +150,17 @@ export class ClusterManager { } }); + this.promiseIpc.on("upgradeFeature", async (installReq: FeatureInstallRequest) => { + logger.debug(`IPC: upgradeFeature for ${installReq.name}`) + const cluster = this.clusters.get(installReq.clusterId) + try { + await cluster.upgradeFeature(installReq.name, installReq.config) + return {success: true, message: ""} + } catch(error) { + return {success: false, message: error} + } + }); + this.promiseIpc.on("uninstallFeature", async (installReq: FeatureInstallRequest) => { logger.debug(`IPC: uninstallFeature for ${installReq.name}`) const cluster = this.clusters.get(installReq.clusterId) diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 5f4372997e23..cb603e62720c 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -105,6 +105,11 @@ export class Cluster implements ClusterInfo { return this.refreshCluster() } + public async upgradeFeature(name: string, config: any) { + await fm.upgradeFeature(name, this, config) + return this.refreshCluster() + } + public async uninstallFeature(name: string) { await fm.uninstallFeature(name, this) return this.refreshCluster() diff --git a/src/main/feature-manager.ts b/src/main/feature-manager.ts index 6895727e1c77..4f6a7fb72b0a 100644 --- a/src/main/feature-manager.ts +++ b/src/main/feature-manager.ts @@ -40,7 +40,11 @@ export async function installFeature(name: string, cluster: Cluster, config: any await feature.install(cluster) } - +export async function upgradeFeature(name: string, cluster: Cluster, config: any) { + const feature = ALL_FEATURES[name] as Feature + // TODO Figure out how to handle config stuff + await feature.upgrade(cluster) +} export async function uninstallFeature(name: string, cluster: Cluster) { const feature = ALL_FEATURES[name] as Feature diff --git a/src/main/feature.ts b/src/main/feature.ts index 799973310441..03d85454c711 100644 --- a/src/main/feature.ts +++ b/src/main/feature.ts @@ -48,9 +48,7 @@ export abstract class Feature { }); } - upgrade(): boolean { - return true; - } + abstract async upgrade(cluster: Cluster): Promise; abstract async uninstall(cluster: Cluster): Promise; diff --git a/src/renderer/components/ClusterSettings/Features/Components/Metrics.vue b/src/renderer/components/ClusterSettings/Features/Components/Metrics.vue index 252dde7697d1..ff1b8fd64a92 100644 --- a/src/renderer/components/ClusterSettings/Features/Components/Metrics.vue +++ b/src/renderer/components/ClusterSettings/Features/Components/Metrics.vue @@ -9,13 +9,14 @@ Install - + + + Upgrade + + Uninstall - - Upgrade - {{ errorMsg }} @@ -54,16 +55,14 @@ export default { }, computed:{ isUpgradeAvailable: function() { - if(!this.settings.installed) return false; - if(!this.settings.currentVersion) return false; - if(!this.settings.latestVersion) return false; - let currentVersion = (this.settings.currentVersion.charAt(0) === "v") ? this.settings.currentVersion.substr(1) : this.settings.currentVersion; - let latestVersion = (this.settings.latestVersion.charAt(0) === "v") ? this.settings.latestVersion.substr(1) : this.settings.latestVersion; - return semver.gt(latestVersion, currentVersion) + return this.cluster.features.metrics.canUpgrade; }, isProcessing: function() { return this.status === "PROCESSING"; }, + isUpgrading: function() { + return this.status === "UPGRADING"; + }, canInstall: function() { return !this.cluster.preferences.prometheus } @@ -99,7 +98,7 @@ export default { } }, uninstall: async function(){ - this.status="PROCESSING"; + this.status = "PROCESSING"; let error = null; try { let result = await this.$store.dispatch("uninstallClusterFeature", { @@ -108,7 +107,7 @@ export default { }) console.log("uninstall result:", result); this.$store.dispatch("refineCluster", this.cluster.id); - this.status="SUCCESS"; + this.status = "SUCCESS"; this.errorMsg = ""; } catch(error) { this.status = "ERROR" @@ -117,16 +116,24 @@ export default { } return true; - }, upgrade: async function(){ - // todo + this.status = "UPGRADING"; + try { + let result = await this.$store.dispatch("upgradeClusterFeature", { + name: this.feature, + clusterId: this.cluster.id, + config: null, + }) + this.$store.dispatch("refineCluster", this.cluster.id); + this.status = ""; + this.errorMsg = ""; + } catch(error) { + this.status = "ERROR" + this.errorMsg = error.message + } return true; - }, - }, - mounted: function(){ - console.log(this.settings); } } diff --git a/src/renderer/components/ClusterSettings/Features/Components/UserMode.vue b/src/renderer/components/ClusterSettings/Features/Components/UserMode.vue index 0096bb65ce97..0c520d0caca7 100644 --- a/src/renderer/components/ClusterSettings/Features/Components/UserMode.vue +++ b/src/renderer/components/ClusterSettings/Features/Components/UserMode.vue @@ -121,9 +121,6 @@ export default { return true; }, - }, - mounted: function(){ - console.log(this.settings); } } diff --git a/src/renderer/store/modules/clusters.ts b/src/renderer/store/modules/clusters.ts index 4abf0fc14850..cb2b8caaf8ed 100644 --- a/src/renderer/store/modules/clusters.ts +++ b/src/renderer/store/modules/clusters.ts @@ -140,6 +140,19 @@ const actions: ActionTree = { return response }, // For data structure see: cluster-manager.ts / FeatureInstallRequest + async upgradeClusterFeature({commit}, data) { + // Custom no timeout IPC as install can take very variable time + const ipc = new PromiseIpc(); + const response = await ipc.send('upgradeFeature', data) + console.log("upgrade result:", response); + const cluster = await ipc.send('refreshCluster', data.clusterId) + + + tracker.event("cluster", "upgrade-feature") + commit("updateCluster", cluster) + return response + }, + // For data structure see: cluster-manager.ts / FeatureInstallRequest async uninstallClusterFeature({commit}, data) { // Custom no timeout IPC as uninstall can take very variable time const ipc = new PromiseIpc();