mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Update metrics feature components (#301)
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
b8fd4040a1
commit
260de08c72
@ -28,7 +28,7 @@ export interface MetricsConfiguration {
|
|||||||
|
|
||||||
export class MetricsFeature extends Feature {
|
export class MetricsFeature extends Feature {
|
||||||
name = 'metrics';
|
name = 'metrics';
|
||||||
latestVersion = "v2.11.1"
|
latestVersion = "v2.17.2-lens1"
|
||||||
|
|
||||||
config: MetricsConfiguration = {
|
config: MetricsConfiguration = {
|
||||||
persistence: {
|
persistence: {
|
||||||
@ -40,7 +40,7 @@ export class MetricsFeature extends Feature {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
retention: {
|
retention: {
|
||||||
time: "7d",
|
time: "2d",
|
||||||
size: "5GB",
|
size: "5GB",
|
||||||
},
|
},
|
||||||
kubeStateMetrics: {
|
kubeStateMetrics: {
|
||||||
@ -65,6 +65,10 @@ export class MetricsFeature extends Feature {
|
|||||||
return super.install(cluster)
|
return super.install(cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async upgrade(cluster: Cluster): Promise<boolean> {
|
||||||
|
return this.install(cluster)
|
||||||
|
}
|
||||||
|
|
||||||
async featureStatus(kc: KubeConfig): Promise<FeatureStatus> {
|
async featureStatus(kc: KubeConfig): Promise<FeatureStatus> {
|
||||||
return new Promise<FeatureStatus>( async (resolve, reject) => {
|
return new Promise<FeatureStatus>( async (resolve, reject) => {
|
||||||
const client = kc.makeApiClient(AppsV1Api)
|
const client = kc.makeApiClient(AppsV1Api)
|
||||||
@ -79,7 +83,7 @@ export class MetricsFeature extends Feature {
|
|||||||
const prometheus = (await client.readNamespacedStatefulSet('prometheus', 'lens-metrics')).body;
|
const prometheus = (await client.readNamespacedStatefulSet('prometheus', 'lens-metrics')).body;
|
||||||
status.installed = true;
|
status.installed = true;
|
||||||
status.currentVersion = prometheus.spec.template.spec.containers[0].image.split(":")[1];
|
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)
|
resolve(status)
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
resolve(status)
|
resolve(status)
|
||||||
|
|||||||
@ -53,7 +53,7 @@ spec:
|
|||||||
mountPath: /var/lib/prometheus
|
mountPath: /var/lib/prometheus
|
||||||
containers:
|
containers:
|
||||||
- name: prometheus
|
- name: prometheus
|
||||||
image: docker.io/kontenapharos/prometheus:v2.11.1
|
image: docker.io/prom/prometheus:v2.17.2
|
||||||
args:
|
args:
|
||||||
- --web.listen-address=0.0.0.0:9090
|
- --web.listen-address=0.0.0.0:9090
|
||||||
- --config.file=/etc/prometheus/prometheus.yaml
|
- --config.file=/etc/prometheus/prometheus.yaml
|
||||||
|
|||||||
@ -6,10 +6,13 @@ rules:
|
|||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources:
|
resources:
|
||||||
- nodes
|
- nodes
|
||||||
|
- nodes/proxy
|
||||||
- nodes/metrics
|
- nodes/metrics
|
||||||
- services
|
- services
|
||||||
- endpoints
|
- endpoints
|
||||||
- pods
|
- pods
|
||||||
|
- ingresses
|
||||||
|
- configmaps
|
||||||
verbs: ["get", "list", "watch"]
|
verbs: ["get", "list", "watch"]
|
||||||
- nonResourceURLs: ["/metrics"]
|
- nonResourceURLs: ["/metrics"]
|
||||||
verbs: ["get"]
|
verbs: ["get"]
|
||||||
|
|||||||
@ -41,7 +41,7 @@ spec:
|
|||||||
hostPID: true
|
hostPID: true
|
||||||
containers:
|
containers:
|
||||||
- name: node-exporter
|
- 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:
|
args:
|
||||||
- --path.procfs=/host/proc
|
- --path.procfs=/host/proc
|
||||||
- --path.sysfs=/host/sys
|
- --path.sysfs=/host/sys
|
||||||
@ -54,7 +54,7 @@ spec:
|
|||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 50Mi
|
memory: 24Mi
|
||||||
limits:
|
limits:
|
||||||
cpu: 200m
|
cpu: 200m
|
||||||
memory: 100Mi
|
memory: 100Mi
|
||||||
|
|||||||
@ -3,49 +3,112 @@ kind: ClusterRole
|
|||||||
metadata:
|
metadata:
|
||||||
name: lens-kube-state-metrics
|
name: lens-kube-state-metrics
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: [""]
|
- apiGroups:
|
||||||
resources:
|
- ""
|
||||||
- configmaps
|
resources:
|
||||||
- secrets
|
- configmaps
|
||||||
- nodes
|
- secrets
|
||||||
- pods
|
- nodes
|
||||||
- services
|
- pods
|
||||||
- resourcequotas
|
- services
|
||||||
- replicationcontrollers
|
- resourcequotas
|
||||||
- limitranges
|
- replicationcontrollers
|
||||||
- persistentvolumeclaims
|
- limitranges
|
||||||
- persistentvolumes
|
- persistentvolumeclaims
|
||||||
- namespaces
|
- persistentvolumes
|
||||||
- endpoints
|
- namespaces
|
||||||
verbs: ["list", "watch"]
|
- endpoints
|
||||||
- apiGroups: ["extensions"]
|
verbs:
|
||||||
resources:
|
- list
|
||||||
- daemonsets
|
- watch
|
||||||
- deployments
|
- apiGroups:
|
||||||
- replicasets
|
- extensions
|
||||||
- ingresses
|
resources:
|
||||||
verbs: ["list", "watch"]
|
- daemonsets
|
||||||
- apiGroups: ["apps"]
|
- deployments
|
||||||
resources:
|
- replicasets
|
||||||
- daemonsets
|
- ingresses
|
||||||
- deployments
|
verbs:
|
||||||
- replicasets
|
- list
|
||||||
- statefulsets
|
- watch
|
||||||
verbs: ["list", "watch"]
|
- apiGroups:
|
||||||
- apiGroups: ["batch"]
|
- apps
|
||||||
resources:
|
resources:
|
||||||
- cronjobs
|
- statefulsets
|
||||||
- jobs
|
- daemonsets
|
||||||
verbs: ["list", "watch"]
|
- deployments
|
||||||
- apiGroups: ["autoscaling"]
|
- replicasets
|
||||||
resources:
|
verbs:
|
||||||
- horizontalpodautoscalers
|
- list
|
||||||
verbs: ["list", "watch"]
|
- watch
|
||||||
- apiGroups: ["policy"]
|
- apiGroups:
|
||||||
resources:
|
- batch
|
||||||
- poddisruptionbudgets
|
resources:
|
||||||
verbs: ["list", "watch"]
|
- cronjobs
|
||||||
- apiGroups: ["certificates.k8s.io"]
|
- jobs
|
||||||
resources:
|
verbs:
|
||||||
- certificatesigningrequests
|
- list
|
||||||
verbs: ["list", "watch"]
|
- 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
|
||||||
|
|||||||
@ -31,7 +31,7 @@ spec:
|
|||||||
serviceAccountName: kube-state-metrics
|
serviceAccountName: kube-state-metrics
|
||||||
containers:
|
containers:
|
||||||
- name: kube-state-metrics
|
- 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:
|
ports:
|
||||||
- name: metrics
|
- name: metrics
|
||||||
containerPort: 8080
|
containerPort: 8080
|
||||||
|
|||||||
@ -10,6 +10,10 @@ export class UserModeFeature extends Feature {
|
|||||||
return super.install(cluster)
|
return super.install(cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async upgrade(cluster: Cluster): Promise<boolean> {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
async featureStatus(kc: KubeConfig): Promise<FeatureStatus> {
|
async featureStatus(kc: KubeConfig): Promise<FeatureStatus> {
|
||||||
return new Promise<FeatureStatus>( async (resolve, reject) => {
|
return new Promise<FeatureStatus>( async (resolve, reject) => {
|
||||||
const client = kc.makeApiClient(RbacAuthorizationV1Api)
|
const client = kc.makeApiClient(RbacAuthorizationV1Api)
|
||||||
|
|||||||
@ -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) => {
|
this.promiseIpc.on("uninstallFeature", async (installReq: FeatureInstallRequest) => {
|
||||||
logger.debug(`IPC: uninstallFeature for ${installReq.name}`)
|
logger.debug(`IPC: uninstallFeature for ${installReq.name}`)
|
||||||
const cluster = this.clusters.get(installReq.clusterId)
|
const cluster = this.clusters.get(installReq.clusterId)
|
||||||
|
|||||||
@ -105,6 +105,11 @@ export class Cluster implements ClusterInfo {
|
|||||||
return this.refreshCluster()
|
return this.refreshCluster()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async upgradeFeature(name: string, config: any) {
|
||||||
|
await fm.upgradeFeature(name, this, config)
|
||||||
|
return this.refreshCluster()
|
||||||
|
}
|
||||||
|
|
||||||
public async uninstallFeature(name: string) {
|
public async uninstallFeature(name: string) {
|
||||||
await fm.uninstallFeature(name, this)
|
await fm.uninstallFeature(name, this)
|
||||||
return this.refreshCluster()
|
return this.refreshCluster()
|
||||||
|
|||||||
@ -40,7 +40,11 @@ export async function installFeature(name: string, cluster: Cluster, config: any
|
|||||||
await feature.install(cluster)
|
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) {
|
export async function uninstallFeature(name: string, cluster: Cluster) {
|
||||||
const feature = ALL_FEATURES[name] as Feature
|
const feature = ALL_FEATURES[name] as Feature
|
||||||
|
|||||||
@ -48,9 +48,7 @@ export abstract class Feature {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
upgrade(): boolean {
|
abstract async upgrade(cluster: Cluster): Promise<boolean>;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract async uninstall(cluster: Cluster): Promise<boolean>;
|
abstract async uninstall(cluster: Cluster): Promise<boolean>;
|
||||||
|
|
||||||
|
|||||||
@ -9,13 +9,14 @@
|
|||||||
<b-spinner small v-if="isProcessing" label="Small Spinner" />
|
<b-spinner small v-if="isProcessing" label="Small Spinner" />
|
||||||
Install
|
Install
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button @click="uninstall" v-if="settings.installed" :disabled="!cluster.isAdmin || isProcessing" variant="danger">
|
<b-button @click="upgrade" v-if="isUpgradeAvailable" :disabled="!cluster.isAdmin || isProcessing || isUpgrading" variant="primary">
|
||||||
|
<b-spinner small v-if="isUpgrading" label="Small Spinner" />
|
||||||
|
Upgrade
|
||||||
|
</b-button>
|
||||||
|
<b-button @click="uninstall" v-if="settings.installed" :disabled="!cluster.isAdmin || isProcessing || isUpgrading" variant="danger">
|
||||||
<b-spinner small v-if="isProcessing" label="Small Spinner" />
|
<b-spinner small v-if="isProcessing" label="Small Spinner" />
|
||||||
Uninstall
|
Uninstall
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button @click="upgrade" v-if="isUpgradeAvailable" :disabled="!cluster.isAdmin" variant="primary">
|
|
||||||
Upgrade
|
|
||||||
</b-button>
|
|
||||||
<b-alert show variant="danger" v-if="status === 'ERROR'">
|
<b-alert show variant="danger" v-if="status === 'ERROR'">
|
||||||
{{ errorMsg }}
|
{{ errorMsg }}
|
||||||
</b-alert>
|
</b-alert>
|
||||||
@ -54,16 +55,14 @@ export default {
|
|||||||
},
|
},
|
||||||
computed:{
|
computed:{
|
||||||
isUpgradeAvailable: function() {
|
isUpgradeAvailable: function() {
|
||||||
if(!this.settings.installed) return false;
|
return this.cluster.features.metrics.canUpgrade;
|
||||||
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)
|
|
||||||
},
|
},
|
||||||
isProcessing: function() {
|
isProcessing: function() {
|
||||||
return this.status === "PROCESSING";
|
return this.status === "PROCESSING";
|
||||||
},
|
},
|
||||||
|
isUpgrading: function() {
|
||||||
|
return this.status === "UPGRADING";
|
||||||
|
},
|
||||||
canInstall: function() {
|
canInstall: function() {
|
||||||
return !this.cluster.preferences.prometheus
|
return !this.cluster.preferences.prometheus
|
||||||
}
|
}
|
||||||
@ -99,7 +98,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
uninstall: async function(){
|
uninstall: async function(){
|
||||||
this.status="PROCESSING";
|
this.status = "PROCESSING";
|
||||||
let error = null;
|
let error = null;
|
||||||
try {
|
try {
|
||||||
let result = await this.$store.dispatch("uninstallClusterFeature", {
|
let result = await this.$store.dispatch("uninstallClusterFeature", {
|
||||||
@ -108,7 +107,7 @@ export default {
|
|||||||
})
|
})
|
||||||
console.log("uninstall result:", result);
|
console.log("uninstall result:", result);
|
||||||
this.$store.dispatch("refineCluster", this.cluster.id);
|
this.$store.dispatch("refineCluster", this.cluster.id);
|
||||||
this.status="SUCCESS";
|
this.status = "SUCCESS";
|
||||||
this.errorMsg = "";
|
this.errorMsg = "";
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
this.status = "ERROR"
|
this.status = "ERROR"
|
||||||
@ -117,16 +116,24 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
},
|
},
|
||||||
upgrade: async function(){
|
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;
|
return true;
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
|
||||||
mounted: function(){
|
|
||||||
console.log(this.settings);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -121,9 +121,6 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
|
||||||
mounted: function(){
|
|
||||||
console.log(this.settings);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -140,6 +140,19 @@ const actions: ActionTree<ClusterState, any> = {
|
|||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
// For data structure see: cluster-manager.ts / FeatureInstallRequest
|
// 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) {
|
async uninstallClusterFeature({commit}, data) {
|
||||||
// Custom no timeout IPC as uninstall can take very variable time
|
// Custom no timeout IPC as uninstall can take very variable time
|
||||||
const ipc = new PromiseIpc();
|
const ipc = new PromiseIpc();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user