From 8e1bc60780430e279b58d27020cc609e75a76ffb Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Mon, 19 Jul 2021 12:58:56 +0300 Subject: [PATCH] Introducing self-expanatory metric request functions Signed-off-by: Alex Andreev --- src/renderer/api/endpoints/cluster.api.ts | 20 +++++++++ src/renderer/api/endpoints/daemon-set.api.ts | 23 +++++++++- src/renderer/api/endpoints/deployment.api.ts | 17 ++++++++ src/renderer/api/endpoints/ingress.api.ts | 23 +++++----- src/renderer/api/endpoints/job.api.ts | 23 +++++++++- src/renderer/api/endpoints/metrics.api.ts | 9 ++++ src/renderer/api/endpoints/namespaces.api.ts | 21 +++++++++- src/renderer/api/endpoints/nodes.api.ts | 27 ++++++------ .../endpoints/persistent-volume-claims.api.ts | 17 ++++---- src/renderer/api/endpoints/pods.api.ts | 42 +++++++++---------- src/renderer/api/endpoints/replica-set.api.ts | 18 +++++++- .../api/endpoints/stateful-set.api.ts | 18 +++++++- 12 files changed, 198 insertions(+), 60 deletions(-) diff --git a/src/renderer/api/endpoints/cluster.api.ts b/src/renderer/api/endpoints/cluster.api.ts index 75f15b5a5b..aefaac07e9 100644 --- a/src/renderer/api/endpoints/cluster.api.ts +++ b/src/renderer/api/endpoints/cluster.api.ts @@ -52,6 +52,26 @@ export class ClusterApi extends KubeApi { } } +export function getMetricsByNodeNames(nodeNames: string[], params?: IMetricsReqParams): Promise { + const nodes = nodeNames.join("|"); + const opts = { category: "cluster", nodes }; + + return metricsApi.getMetrics({ + memoryUsage: opts, + memoryRequests: opts, + memoryLimits: opts, + memoryCapacity: opts, + cpuUsage: opts, + cpuRequests: opts, + cpuLimits: opts, + cpuCapacity: opts, + podUsage: opts, + podCapacity: opts, + fsSize: opts, + fsUsage: opts + }, params); +} + export enum ClusterStatus { ACTIVE = "Active", CREATING = "Creating", diff --git a/src/renderer/api/endpoints/daemon-set.api.ts b/src/renderer/api/endpoints/daemon-set.api.ts index 43419b5ac1..cb584806d4 100644 --- a/src/renderer/api/endpoints/daemon-set.api.ts +++ b/src/renderer/api/endpoints/daemon-set.api.ts @@ -20,11 +20,12 @@ */ import get from "lodash/get"; -import type { IPodContainer } from "./pods.api"; import { IAffinity, WorkloadKubeObject } from "../workload-kube-object"; import { autoBind } from "../../utils"; import { KubeApi } from "../kube-api"; +import { metricsApi } from "./metrics.api"; import type { KubeJsonApiData } from "../kube-json-api"; +import type { IPodContainer, IPodMetrics } from "./pods.api"; export class DaemonSet extends WorkloadKubeObject { static kind = "DaemonSet"; @@ -97,6 +98,24 @@ export class DaemonSet extends WorkloadKubeObject { } } -export const daemonSetApi = new KubeApi({ +export class DaemonSetApi extends KubeApi { +} + +export function getMetricsForDaemonSets(daemonsets: DaemonSet[], namespace: string, selector = ""): Promise { + const podSelector = daemonsets.map(daemonset => `${daemonset.getName()}-[[:alnum:]]{5}`).join("|"); + const opts = { category: "pods", pods: podSelector, namespace, selector }; + + return metricsApi.getMetrics({ + cpuUsage: opts, + memoryUsage: opts, + fsUsage: opts, + networkReceive: opts, + networkTransmit: opts, + }, { + namespace, + }); +} + +export const daemonSetApi = new DaemonSetApi({ objectConstructor: DaemonSet, }); diff --git a/src/renderer/api/endpoints/deployment.api.ts b/src/renderer/api/endpoints/deployment.api.ts index ef5b1c9ca7..0d5bef48dd 100644 --- a/src/renderer/api/endpoints/deployment.api.ts +++ b/src/renderer/api/endpoints/deployment.api.ts @@ -24,6 +24,8 @@ import moment from "moment"; import { IAffinity, WorkloadKubeObject } from "../workload-kube-object"; import { autoBind } from "../../utils"; import { KubeApi } from "../kube-api"; +import { metricsApi } from "./metrics.api"; +import type { IPodMetrics } from "./pods.api"; import type { KubeJsonApiData } from "../kube-json-api"; export class DeploymentApi extends KubeApi { @@ -68,6 +70,21 @@ export class DeploymentApi extends KubeApi { } } +export function getMetricsForDeployments(deployments: Deployment[], namespace: string, selector = ""): Promise { + const podSelector = deployments.map(deployment => `${deployment.getName()}-[[:alnum:]]{9,}-[[:alnum:]]{5}`).join("|"); + const opts = { category: "pods", pods: podSelector, namespace, selector }; + + return metricsApi.getMetrics({ + cpuUsage: opts, + memoryUsage: opts, + fsUsage: opts, + networkReceive: opts, + networkTransmit: opts, + }, { + namespace, + }); +} + interface IContainerProbe { httpGet?: { path?: string; diff --git a/src/renderer/api/endpoints/ingress.api.ts b/src/renderer/api/endpoints/ingress.api.ts index a65af0e326..31745f30c4 100644 --- a/src/renderer/api/endpoints/ingress.api.ts +++ b/src/renderer/api/endpoints/ingress.api.ts @@ -26,18 +26,19 @@ import { KubeApi } from "../kube-api"; import type { KubeJsonApiData } from "../kube-json-api"; export class IngressApi extends KubeApi { - getMetrics(ingress: string, namespace: string): Promise { - const opts = { category: "ingress", ingress, namespace }; +} - return metricsApi.getMetrics({ - bytesSentSuccess: opts, - bytesSentFailure: opts, - requestDurationSeconds: opts, - responseDurationSeconds: opts - }, { - namespace, - }); - } +export function getMetricsForIngress(ingress: string, namespace: string): Promise { + const opts = { category: "ingress", ingress }; + + return metricsApi.getMetrics({ + bytesSentSuccess: opts, + bytesSentFailure: opts, + requestDurationSeconds: opts, + responseDurationSeconds: opts + }, { + namespace, + }); } export interface IIngressMetrics { diff --git a/src/renderer/api/endpoints/job.api.ts b/src/renderer/api/endpoints/job.api.ts index f9e3188021..823a04bef9 100644 --- a/src/renderer/api/endpoints/job.api.ts +++ b/src/renderer/api/endpoints/job.api.ts @@ -22,10 +22,11 @@ import get from "lodash/get"; import { autoBind } from "../../utils"; import { IAffinity, WorkloadKubeObject } from "../workload-kube-object"; -import type { IPodContainer } from "./pods.api"; import { KubeApi } from "../kube-api"; +import { metricsApi } from "./metrics.api"; import type { JsonApiParams } from "../json-api"; import type { KubeJsonApiData } from "../kube-json-api"; +import type { IPodContainer, IPodMetrics } from "./pods.api"; export class Job extends WorkloadKubeObject { static kind = "Job"; @@ -129,6 +130,24 @@ export class Job extends WorkloadKubeObject { } } -export const jobApi = new KubeApi({ +export class JobApi extends KubeApi { +} + +export function getMetricsForJobs(jobs: Job[], namespace: string, selector = ""): Promise { + const podSelector = jobs.map(job => `${job.getName()}-[[:alnum:]]{5}`).join("|"); + const opts = { category: "pods", pods: podSelector, namespace, selector }; + + return metricsApi.getMetrics({ + cpuUsage: opts, + memoryUsage: opts, + fsUsage: opts, + networkReceive: opts, + networkTransmit: opts, + }, { + namespace, + }); +} + +export const jobApi = new JobApi({ objectConstructor: Job, }); diff --git a/src/renderer/api/endpoints/metrics.api.ts b/src/renderer/api/endpoints/metrics.api.ts index 3f5b6e66e7..c9b71faeb4 100644 --- a/src/renderer/api/endpoints/metrics.api.ts +++ b/src/renderer/api/endpoints/metrics.api.ts @@ -60,6 +60,15 @@ export interface IMetricsReqParams { namespace?: string; // rbac-proxy validation param } +export interface IResourceMetrics { + [metric: string]: T; + cpuUsage: T; + memoryUsage: T; + fsUsage: T; + networkReceive: T; + networkTransmit: T; +} + export const metricsApi = { async getMetrics(query: T, reqParams: IMetricsReqParams = {}): Promise { const { range = 3600, step = 60, namespace } = reqParams; diff --git a/src/renderer/api/endpoints/namespaces.api.ts b/src/renderer/api/endpoints/namespaces.api.ts index 63dd6a2ab0..208edb023f 100644 --- a/src/renderer/api/endpoints/namespaces.api.ts +++ b/src/renderer/api/endpoints/namespaces.api.ts @@ -22,6 +22,8 @@ import { KubeApi } from "../kube-api"; import { KubeObject } from "../kube-object"; import { autoBind } from "../../utils"; +import { metricsApi } from "./metrics.api"; +import type { IPodMetrics } from "./pods.api"; import type { KubeJsonApiData } from "../kube-json-api"; export enum NamespaceStatus { @@ -50,6 +52,23 @@ export class Namespace extends KubeObject { } } -export const namespacesApi = new KubeApi({ +export class NamespaceApi extends KubeApi { +} + +export function getMetricsForNamespace(namespace: string, selector = ""): Promise { + const opts = { category: "pods", pods: ".*", namespace, selector }; + + return metricsApi.getMetrics({ + cpuUsage: opts, + memoryUsage: opts, + fsUsage: opts, + networkReceive: opts, + networkTransmit: opts, + }, { + namespace, + }); +} + +export const namespacesApi = new NamespaceApi({ objectConstructor: Namespace, }); diff --git a/src/renderer/api/endpoints/nodes.api.ts b/src/renderer/api/endpoints/nodes.api.ts index 17a7571209..e74ca66b42 100644 --- a/src/renderer/api/endpoints/nodes.api.ts +++ b/src/renderer/api/endpoints/nodes.api.ts @@ -26,20 +26,21 @@ import { KubeApi } from "../kube-api"; import type { KubeJsonApiData } from "../kube-json-api"; export class NodesApi extends KubeApi { - getMetrics(): Promise { - const opts = { category: "nodes" }; +} - return metricsApi.getMetrics({ - memoryUsage: opts, - workloadMemoryUsage: opts, - memoryCapacity: opts, - memoryAllocatableCapacity: opts, - cpuUsage: opts, - cpuCapacity: opts, - fsSize: opts, - fsUsage: opts - }); - } +export function getMetricsForAllNodes(): Promise { + const opts = { category: "nodes"}; + + return metricsApi.getMetrics({ + memoryUsage: opts, + workloadMemoryUsage: opts, + memoryCapacity: opts, + memoryAllocatableCapacity: opts, + cpuUsage: opts, + cpuCapacity: opts, + fsSize: opts, + fsUsage: opts + }); } export interface INodeMetrics { diff --git a/src/renderer/api/endpoints/persistent-volume-claims.api.ts b/src/renderer/api/endpoints/persistent-volume-claims.api.ts index e8b50683c9..356122569a 100644 --- a/src/renderer/api/endpoints/persistent-volume-claims.api.ts +++ b/src/renderer/api/endpoints/persistent-volume-claims.api.ts @@ -27,14 +27,15 @@ import { KubeApi } from "../kube-api"; import type { KubeJsonApiData } from "../kube-json-api"; export class PersistentVolumeClaimsApi extends KubeApi { - getMetrics(pvcName: string, namespace: string): Promise { - return metricsApi.getMetrics({ - diskUsage: { category: "pvc", pvc: pvcName, namespace }, - diskCapacity: { category: "pvc", pvc: pvcName, namespace } - }, { - namespace - }); - } +} + +export function getMetricsForPvc(pvc: PersistentVolumeClaim): Promise { + return metricsApi.getMetrics({ + diskUsage: { category: "pvc", pvc: pvc.getName() }, + diskCapacity: { category: "pvc", pvc: pvc.getName() } + }, { + namespace: pvc.getNs() + }); } export interface IPvcMetrics { diff --git a/src/renderer/api/endpoints/pods.api.ts b/src/renderer/api/endpoints/pods.api.ts index 5b85a3d42b..e4d33c75bc 100644 --- a/src/renderer/api/endpoints/pods.api.ts +++ b/src/renderer/api/endpoints/pods.api.ts @@ -31,38 +31,38 @@ export class PodsApi extends KubeApi { return this.request.get(path, { query }); } +} - getMetrics(pods: Pod[], namespace: string, selector = "pod, namespace"): Promise { - const podSelector = pods.map(pod => pod.getName()).join("|"); - const opts = { category: "pods", pods: podSelector, namespace, selector }; +export function getMetricsForPods(pods: Pod[], namespace: string, selector = "pod, namespace"): Promise { + const podSelector = pods.map(pod => pod.getName()).join("|"); + const opts = { category: "pods", pods: podSelector, namespace, selector }; - return metricsApi.getMetrics({ - cpuUsage: opts, - cpuRequests: opts, - cpuLimits: opts, - memoryUsage: opts, - memoryRequests: opts, - memoryLimits: opts, - fsUsage: opts, - networkReceive: opts, - networkTransmit: opts, - }, { - namespace, - }); - } + return metricsApi.getMetrics({ + cpuUsage: opts, + cpuRequests: opts, + cpuLimits: opts, + memoryUsage: opts, + memoryRequests: opts, + memoryLimits: opts, + fsUsage: opts, + networkReceive: opts, + networkTransmit: opts, + }, { + namespace, + }); } export interface IPodMetrics { [metric: string]: T; cpuUsage: T; - cpuRequests: T; - cpuLimits: T; memoryUsage: T; - memoryRequests: T; - memoryLimits: T; fsUsage: T; networkReceive: T; networkTransmit: T; + cpuRequests?: T; + cpuLimits?: T; + memoryRequests?: T; + memoryLimits?: T; } // Reference: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#read-log-pod-v1-core diff --git a/src/renderer/api/endpoints/replica-set.api.ts b/src/renderer/api/endpoints/replica-set.api.ts index e2311c6b87..4632e1bfad 100644 --- a/src/renderer/api/endpoints/replica-set.api.ts +++ b/src/renderer/api/endpoints/replica-set.api.ts @@ -22,8 +22,9 @@ import get from "lodash/get"; import { autoBind } from "../../utils"; import { WorkloadKubeObject } from "../workload-kube-object"; -import type { IPodContainer, Pod } from "./pods.api"; import { KubeApi } from "../kube-api"; +import { metricsApi } from "./metrics.api"; +import type { IPodContainer, IPodMetrics, Pod } from "./pods.api"; import type { KubeJsonApiData } from "../kube-json-api"; export class ReplicaSetApi extends KubeApi { @@ -49,6 +50,21 @@ export class ReplicaSetApi extends KubeApi { } } +export function getMetricsForReplicaSets(replicasets: ReplicaSet[], namespace: string, selector = ""): Promise { + const podSelector = replicasets.map(replicaset => `${replicaset.getName()}-[[:alnum:]]{5}`).join("|"); + const opts = { category: "pods", pods: podSelector, namespace, selector }; + + return metricsApi.getMetrics({ + cpuUsage: opts, + memoryUsage: opts, + fsUsage: opts, + networkReceive: opts, + networkTransmit: opts, + }, { + namespace, + }); +} + export class ReplicaSet extends WorkloadKubeObject { static kind = "ReplicaSet"; static namespaced = true; diff --git a/src/renderer/api/endpoints/stateful-set.api.ts b/src/renderer/api/endpoints/stateful-set.api.ts index b91e06c25c..21f4c6e02e 100644 --- a/src/renderer/api/endpoints/stateful-set.api.ts +++ b/src/renderer/api/endpoints/stateful-set.api.ts @@ -20,10 +20,11 @@ */ import get from "lodash/get"; -import type { IPodContainer } from "./pods.api"; import { IAffinity, WorkloadKubeObject } from "../workload-kube-object"; import { autoBind } from "../../utils"; import { KubeApi } from "../kube-api"; +import { metricsApi } from "./metrics.api"; +import type { IPodContainer, IPodMetrics } from "./pods.api"; import type { KubeJsonApiData } from "../kube-json-api"; export class StatefulSetApi extends KubeApi { @@ -49,6 +50,21 @@ export class StatefulSetApi extends KubeApi { } } +export function getMetricsForStatefulSets(statefulSets: StatefulSet[], namespace: string, selector = ""): Promise { + const podSelector = statefulSets.map(statefulset => `${statefulset.getName()}-[[:digit:]]+`).join("|"); + const opts = { category: "pods", pods: podSelector, namespace, selector }; + + return metricsApi.getMetrics({ + cpuUsage: opts, + memoryUsage: opts, + fsUsage: opts, + networkReceive: opts, + networkTransmit: opts, + }, { + namespace, + }); +} + export class StatefulSet extends WorkloadKubeObject { static kind = "StatefulSet"; static namespaced = true;