import { KubeObject } from "../kube-object"; import { KubeApi } from "../kube-api"; export enum HpaMetricType { Resource = "Resource", Pods = "Pods", Object = "Object", External = "External", } export type IHpaMetricData = T & { target?: { kind: string; name: string; apiVersion: string; }; name?: string; metricName?: string; currentAverageUtilization?: number; currentAverageValue?: string; targetAverageUtilization?: number; targetAverageValue?: string; }; export interface IHpaMetric { [kind: string]: IHpaMetricData; type: HpaMetricType; resource?: IHpaMetricData<{ name: string }>; pods?: IHpaMetricData; external?: IHpaMetricData; object?: IHpaMetricData<{ describedObject: { apiVersion: string; kind: string; name: string; }; }>; } export class HorizontalPodAutoscaler extends KubeObject { static kind = "HorizontalPodAutoscaler"; static namespaced = true; static apiBase = "/apis/autoscaling/v2beta1/horizontalpodautoscalers"; spec: { scaleTargetRef: { kind: string; name: string; apiVersion: string; }; minReplicas: number; maxReplicas: number; metrics: IHpaMetric[]; }; status: { currentReplicas: number; desiredReplicas: number; currentMetrics: IHpaMetric[]; conditions: { lastTransitionTime: string; message: string; reason: string; status: string; type: string; }[]; }; getMaxPods() { return this.spec.maxReplicas || 0; } getMinPods() { return this.spec.minReplicas || 0; } getReplicas() { return this.status.currentReplicas; } getConditions() { if (!this.status.conditions) return []; return this.status.conditions.map(condition => { const { message, reason, lastTransitionTime, status } = condition; return { ...condition, isReady: status === "True", tooltip: `${message || reason} (${lastTransitionTime})` }; }); } getMetrics() { return this.spec.metrics || []; } getCurrentMetrics() { return this.status.currentMetrics || []; } protected getMetricName(metric: IHpaMetric): string { const { type, resource, pods, object, external } = metric; switch (type) { case HpaMetricType.Resource: return resource.name; case HpaMetricType.Pods: return pods.metricName; case HpaMetricType.Object: return object.metricName; case HpaMetricType.External: return external.metricName; } } // todo: refactor getMetricValues(metric: IHpaMetric): string { const metricType = metric.type.toLowerCase(); const currentMetric = this.getCurrentMetrics().find(current => metric.type == current.type && this.getMetricName(metric) == this.getMetricName(current) ); const current = currentMetric ? currentMetric[metricType] : null; const target = metric[metricType]; let currentValue = "unknown"; let targetValue = "unknown"; if (current) { currentValue = current.currentAverageUtilization || current.currentAverageValue || current.currentValue; if (current.currentAverageUtilization) currentValue += "%"; } if (target) { targetValue = target.targetAverageUtilization || target.targetAverageValue || target.targetValue; if (target.targetAverageUtilization) targetValue += "%"; } return `${currentValue} / ${targetValue}`; } } export const hpaApi = new KubeApi({ objectConstructor: HorizontalPodAutoscaler, });