1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Move metrics parsing from HPA object to separate injectable

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
Alex Andreev 2023-01-18 09:38:28 +03:00
parent 25b594de7e
commit 674833fb4c
2 changed files with 95 additions and 156 deletions

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { BaseKubeObjectCondition, LabelSelector, NamespaceScopedMetadata } from "../kube-object";
import { KubeObject } from "../kube-object";
import type { OptionVarient } from "../../utils";
import type { DerivedKubeApiOptions, KubeApiDependencies } from "../kube-api";
import { KubeApi } from "../kube-api";
import type { OptionVarient } from "../../utils";
import type { BaseKubeObjectCondition, LabelSelector, NamespaceScopedMetadata } from "../kube-object";
import { KubeObject } from "../kube-object";
export enum HpaMetricType {
Resource = "Resource",
@ -28,10 +28,9 @@ export interface ContainerResourceMetricSource {
name: string;
targetAverageUtilization?: number;
targetAverageValue?: string;
// autscaling/v2
target?: {
averageUtilization?: number;
averageValue?: string;
type?: string;
}
}
@ -41,8 +40,6 @@ export interface ExternalMetricSource {
metricSelector?: LabelSelector;
targetAverageValue?: string;
targetValue?: string;
// autoscaling/v2
metric?: {
name?: string;
selector?: LabelSelector;
@ -59,24 +56,21 @@ export interface ObjectMetricSource {
metricName?: string;
selector?: LabelSelector;
targetValue?: string;
// autoscaling/v2
metric?: {
name?: string;
},
target: {
target?: {
type?: string;
value?: string;
averageValue?: string;
};
describedObject?: CrossVersionObjectReference;
describedObject?: CrossVersionObjectReference
}
export interface PodsMetricSource {
metricName?: string;
selector?: LabelSelector;
targetAverageValue?: string;
// autoscaling/v2
metric?: {
name?: string;
}
@ -90,8 +84,6 @@ export interface ResourceMetricSource {
name: string;
targetAverageUtilization?: number;
targetAverageValue?: string;
// autoscaling/v2
target?: {
averageUtilization?: number;
averageValue?: string;
@ -136,17 +128,29 @@ interface HPAScalingPolicy {
type HPAScalingPolicyType = string;
export interface ContainerResourceMetricStatus {
container: string;
container?: string;
currentAverageUtilization?: number;
currentAverageValue: string;
currentAverageValue?: string;
name: string;
current?: {
averageUtilization?: number;
averageValue?: string;
}
}
export interface ExternalMetricStatus {
currentAverageValue?: string;
currentValue: string;
metricName: string;
currentValue?: string;
metricName?: string;
metricSelector?: LabelSelector;
metric?: {
name?: string;
selector?: LabelSelector;
},
current?: {
averageValue?: string;
value?: string;
}
}
export interface ObjectMetricStatus {
@ -154,30 +158,34 @@ export interface ObjectMetricStatus {
currentValue?: string;
metricName?: string;
selector?: LabelSelector;
// autoscaling/v2
metric?: {
name?: string;
selector?: LabelSelector;
},
current: {
current?: {
type?: string;
value?: string;
averageValue?: string;
};
describedObject?: CrossVersionObjectReference;
}
export interface PodsMetricStatus {
currentAverageValue: string;
metricName: string;
currentAverageValue?: string;
metricName?: string;
selector?: LabelSelector;
metric?: {
name?: string;
}
current?: {
averageValue?: string;
}
}
export interface ResourceMetricStatus {
currentAverageUtilization?: number;
currentAverageValue?: string;
name: string;
// autoscaling/v2
current?: {
averageUtilization?: number;
averageValue?: string;
@ -220,11 +228,6 @@ export interface HorizontalPodAutoscalerStatus {
currentMetrics?: HorizontalPodAutoscalerMetricStatus[];
}
interface MetricCurrentTarget {
current?: string;
target?: string;
}
export class HorizontalPodAutoscaler extends KubeObject<
NamespaceScopedMetadata,
HorizontalPodAutoscalerStatus,
@ -263,48 +266,12 @@ export class HorizontalPodAutoscaler extends KubeObject<
}
getMetrics() {
// console.log(this.spec)
return this.spec.metrics ?? [];
}
getCurrentMetrics() {
// console.log(this.status)
return this.status?.currentMetrics ?? [];
}
getMetricValues(metric: HorizontalPodAutoscalerMetricSpec): string {
const {
current = "unknown",
target = "unknown",
} = this.getMetricsCurrentAndTarget(metric);
return `${current} / ${target}`;
}
getMetricsCurrentAndTarget(spec: HorizontalPodAutoscalerMetricSpec): MetricCurrentTarget {
const currentMetrics = this.getCurrentMetrics();
const currentMetric = currentMetrics.find(m => (
m.type === spec.type
&& getMetricName(m) === getMetricName(spec)
));
console.log(spec, currentMetrics)
switch (spec.type) {
case HpaMetricType.Resource:
return getResourceMetricValue(currentMetric?.resource, spec.resource);
case HpaMetricType.Pods:
return getPodsMetricValue(currentMetric?.pods, spec.pods);
case HpaMetricType.Object:
return getObjectMetricValue(currentMetric?.object, spec.object);
case HpaMetricType.External:
return getExternalMetricValue(currentMetric?.external, spec.external);
case HpaMetricType.ContainerResource:
return getContainerResourceMetricValue(currentMetric?.containerResource, spec.containerResource);
default:
return {};
}
}
}
export class HorizontalPodAutoscalerApi extends KubeApi<HorizontalPodAutoscaler> {
@ -322,92 +289,3 @@ export class HorizontalPodAutoscalerApi extends KubeApi<HorizontalPodAutoscaler>
});
}
}
function getMetricName(metric: HorizontalPodAutoscalerMetricSpec | HorizontalPodAutoscalerMetricStatus): string | undefined {
switch (metric.type) {
case HpaMetricType.Resource:
return metric.resource.name;
case HpaMetricType.Pods:
return metric.pods.metricName;
case HpaMetricType.Object:
return metric.object.metricName;
case HpaMetricType.External:
return metric.external.metricName;
case HpaMetricType.ContainerResource:
return metric.containerResource.name;
default:
return undefined;
}
}
function getResourceMetricValue(currentMetric: ResourceMetricStatus | undefined, targetMetric: ResourceMetricSource): MetricCurrentTarget {
return {
current: (
typeof currentMetric?.current?.averageUtilization === "number"
? `${currentMetric.current?.averageUtilization}%`
: currentMetric?.current?.averageValue
),
target: typeof targetMetric?.target?.averageUtilization === "number"
? `${targetMetric.target.averageUtilization}%`
: targetMetric?.target?.averageValue ?? "unknown"
};
}
function getPodsMetricValue(currentMetric: PodsMetricStatus | undefined, targetMetric: PodsMetricSource): MetricCurrentTarget {
return {
current: currentMetric?.currentAverageValue,
target: targetMetric?.target?.averageValue,
}
// v1
// return {
// current: currentMetric?.currentAverageValue,
// target: targetMetric?.targetAverageValue,
// };
}
function getObjectMetricValue(currentMetric: ObjectMetricStatus | undefined, targetMetric: ObjectMetricSource): MetricCurrentTarget {
return {
current: (
currentMetric?.currentValue
?? currentMetric?.averageValue
),
target: targetMetric?.target?.value
};
}
function getExternalMetricValue(currentMetric: ExternalMetricStatus | undefined, targetMetric: ExternalMetricSource): MetricCurrentTarget {
return {
current: (
currentMetric?.currentValue
?? currentMetric?.currentAverageValue
),
target: (
targetMetric?.target?.value
?? `${targetMetric?.target?.averageValue} (avg)`
),
};
}
function getContainerResourceMetricValue(currentMetric: ContainerResourceMetricStatus | undefined, targetMetric: ContainerResourceMetricSource): MetricCurrentTarget {
let target = "unknown";
if (targetMetric.target) {
// v2
target = targetMetric.target.averageUtilization ? `${targetMetric.target.averageUtilization}%` : "unknown";
} else {
target = typeof targetMetric?.targetAverageUtilization === "number"
? `${targetMetric.targetAverageUtilization}%`
: targetMetric?.targetAverageValue ?? "unknown";
}
return {
current: (
typeof currentMetric?.currentAverageUtilization === "number"
? `${currentMetric.currentAverageUtilization}%`
: currentMetric?.currentAverageValue
),
target,
};
}

View File

@ -0,0 +1,61 @@
import { getInjectable } from "@ogre-tools/injectable";
import { HorizontalPodAutoscaler, HorizontalPodAutoscalerMetricSpec, HorizontalPodAutoscalerMetricStatus, HpaMetricType } from "../../../common/k8s-api/endpoints";
import type { HorizontalPodAutoscalerV2MetricParser } from "./hpa-v2-metric-parser";
import horizonalPodAutoscalerV2MetricParser from "./hpa-v2-metric-parser.injectable";
const getHorizontalPodAutoscalerMetrics = getInjectable({
id: "get-horizontal-pod-autoscaler-metrics",
instantiate: (di) => (hpa: HorizontalPodAutoscaler) => {
const hpaV2Parser = di.inject(horizonalPodAutoscalerV2MetricParser);
const metrics = hpa.spec?.metrics ?? [];
const currentMetrics = hpa.status?.currentMetrics ?? [];
return metrics.map((metric) => {
const currentMetric = currentMetrics.find(current =>
current.type === metric.type
&& getMetricName(current) === getMetricName(metric)
);
const parser = hpa.apiVersion.includes("v2") ? hpaV2Parser : hpaV2Parser;
const values = getMetricValues(parser, currentMetric, metric);
return `${values.current ?? "unknown"} / ${values.target ?? "unknown"}`;
});
},
})
function getMetricValues(parser: HorizontalPodAutoscalerV2MetricParser, current: HorizontalPodAutoscalerMetricStatus | undefined, target: HorizontalPodAutoscalerMetricSpec) {
switch (target.type) {
case HpaMetricType.Resource:
return parser.getResource({ current: current?.resource, target: target.resource});
case HpaMetricType.Pods:
return parser.getPods({ current: current?.pods, target: target.pods });
case HpaMetricType.Object:
return parser.getObject({ current: current?.object, target: target.object });
case HpaMetricType.External:
return parser.getExternal({ current: current?.external, target: target.external });
case HpaMetricType.ContainerResource:
return parser.getContainerResource({ current: current?.containerResource, target: target.containerResource });
default:
return {};
}
}
function getMetricName(metric: HorizontalPodAutoscalerMetricSpec | HorizontalPodAutoscalerMetricStatus): string | undefined {
switch (metric.type) {
case HpaMetricType.Resource:
return metric.resource.name;
case HpaMetricType.Pods:
return metric.pods.metricName || metric.pods.metric?.name;
case HpaMetricType.Object:
return metric.object.metricName || metric.object.metric?.name;
case HpaMetricType.External:
return metric.external.metricName || metric.external.metric?.name;
case HpaMetricType.ContainerResource:
return metric.containerResource.name;
default:
return undefined;
}
}
export default getHorizontalPodAutoscalerMetrics;