UNPKG

@controlplane/cli

Version:

Control Plane Corporation CLI

182 lines 7.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.K8sWorkloadHandler = void 0; const pod_template_1 = require("../processors/pod-template"); const helper_1 = require("../../util/helper"); class K8sWorkloadHandler { constructor(filePath, k8sWorkload, mapper) { this.filePath = filePath; this.k8sWorkload = k8sWorkload; this.mapper = mapper; this.workload = { kind: 'workload', name: k8sWorkload.metadata.name, spec: { type: 'serverless', containers: [], defaultOptions: { autoscaling: { minScale: 1, maxScale: 1, }, capacityAI: false, }, }, }; } /*** Public Methods ***/ handle() { var _a; // Validate K8s workload this.validate(); // Process labels as tags if ((_a = this.k8sWorkload.spec.template.metadata) === null || _a === void 0 ? void 0 : _a.labels) { this.workload.tags = this.k8sWorkload.spec.template.metadata.labels; } if (!this.workload.tags || Object.keys(this.workload.tags).length == 0) { this.workload.tags = this.k8sWorkload.metadata.labels; } // Handle suspend if (this.k8sWorkload.spec.paused) { this.workload.spec.defaultOptions.suspend = true; } // Process template property const templateProcessor = new pod_template_1.K8sPodTemplateProcessor(this.filePath, 'spec.template', this.k8sWorkload, this.workload, this.k8sWorkload.spec.template, this.mapper); templateProcessor.process(); // Process autoscaling this.processAutoscaling(); // Process rollout options this.processRolloutOptions(); // Determine Workload Type this.determineWorkloadType(); return this.workload; } /*** Private Methods ***/ processAutoscaling() { // Process replicas first if (this.k8sWorkload.spec.replicas) { this.workload.spec.defaultOptions.autoscaling.minScale = this.k8sWorkload.spec.replicas; this.workload.spec.defaultOptions.autoscaling.maxScale = this.k8sWorkload.spec.replicas; } // Override the value set previously with HPA if it is specified this.processHpa(); } processHpa() { if (!this.mapper.k8sWorkloadNameToHpa[this.k8sWorkload.metadata.name]) { return; } const hpa = this.mapper.k8sWorkloadNameToHpa[this.workload.name]; // Handle min and max scales if (hpa.spec.minReplicas) { this.workload.spec.defaultOptions.autoscaling.minScale = hpa.spec.minReplicas; } if (hpa.spec.maxReplicas) { this.workload.spec.defaultOptions.autoscaling.maxScale = hpa.spec.maxReplicas; } // Handle scale to zero delay if (hpa.spec.behavior && hpa.spec.behavior.scaleDown && hpa.spec.behavior.scaleDown.stabilizationWindowSeconds) { this.workload.spec.defaultOptions.autoscaling.scaleToZeroDelay = hpa.spec.behavior.scaleDown.stabilizationWindowSeconds; } // Handle CPU Utilization target value if (hpa.spec.metrics) { for (const metric of hpa.spec.metrics) { if (metric.containerResource && metric.containerResource.name.toLowerCase() === 'cpu' && metric.containerResource.target.type.toLowerCase() === 'utilization') { // Take the first target value found this.workload.spec.defaultOptions.autoscaling.target = metric.containerResource.target.averageUtilization; break; } } } } processRolloutOptions() { if (!this.k8sWorkload.spec.minReadySeconds && !this.k8sWorkload.spec.podManagementPolicy && !this.k8sWorkload.spec.strategy && !this.k8sWorkload.spec.updateStrategy) { return; } const rolloutOptions = { minReadySeconds: this.k8sWorkload.spec.minReadySeconds || 0, maxUnavailableReplicas: '1', maxSurgeReplicas: '25%', scalingPolicy: 'OrderedReady', }; // Update strategy if (this.k8sWorkload.spec.strategy && this.k8sWorkload.spec.strategy.rollingUpdate) { // Set max surge replicas if (this.k8sWorkload.spec.strategy.rollingUpdate.maxSurge) { rolloutOptions.maxSurgeReplicas = this.k8sWorkload.spec.strategy.rollingUpdate.maxSurge.toString(); } // Set max unavailable replicas if (this.k8sWorkload.spec.strategy.rollingUpdate.maxUnavailable) { rolloutOptions.maxUnavailableReplicas = this.k8sWorkload.spec.strategy.rollingUpdate.maxUnavailable.toString(); } } if (this.k8sWorkload.spec.updateStrategy && this.k8sWorkload.spec.updateStrategy.rollingUpdate) { // Set max unavailable replicas if (this.k8sWorkload.spec.updateStrategy.rollingUpdate.maxUnavailable) { rolloutOptions.maxUnavailableReplicas = this.k8sWorkload.spec.updateStrategy.rollingUpdate.maxUnavailable.toString(); } } // Update scaling policy if (this.k8sWorkload.spec.podManagementPolicy) { rolloutOptions.scalingPolicy = this.k8sWorkload.spec.podManagementPolicy; } this.workload.spec.rolloutOptions = rolloutOptions; } determineWorkloadType() { // Check if workload type is 'standard' and/or 'stateful' let isStandard = false; let isStateful = false; // Iterate over each container for (const container of this.workload.spec.containers) { // Check if the container is mounting a volume set as a volume if (container.volumes) { for (const volume of container.volumes) { if (volume.uri.includes('cpln://volumeset')) { isStateful = true; break; } } } // Check if the container has many or no ports exposed if (!container.ports || container.ports.length == 0 || container.ports.length > 1) { isStandard = true; break; } // Check if liveness or readiness probes has grpc used if (container.livenessProbe && container.livenessProbe.grpc) { isStandard = true; break; } if (container.readinessProbe && container.readinessProbe.grpc) { isStandard = true; break; } } // Check if workload has rollout options if (this.workload.spec.rolloutOptions) { isStandard = true; } if (isStandard) { this.workload.spec.type = 'standard'; } // Type 'stateful' is stronger than type 'standard' if (isStateful) { this.workload.spec.type = 'stateful'; } } // Validators // validate() { if (!this.k8sWorkload.spec) { (0, helper_1.ensurePropertyPresence)('spec', this.filePath, this.k8sWorkload); } if (!this.k8sWorkload.spec.template) { (0, helper_1.ensurePropertyPresence)('spec.template', this.filePath, this.k8sWorkload); } } } exports.K8sWorkloadHandler = K8sWorkloadHandler; //# sourceMappingURL=workload.js.map