mirror of
https://github.com/Azure/k8s-deploy.git
synced 2026-06-29 00:09:28 +08:00
added blue green strategy (#47)
* added blue green strategy * Addressed review comments * addressed pr comments * updated names in test * addressed final pr comments
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as canaryDeploymentHelper from './canary-deployment-helper';
|
||||
import * as KubernetesObjectUtility from '../resource-object-utility';
|
||||
@@ -13,30 +11,32 @@ import * as utils from '../manifest-utilities';
|
||||
import * as KubernetesManifestUtility from '../manifest-stability-utility';
|
||||
import * as KubernetesConstants from '../../constants';
|
||||
import { Kubectl, Resource } from '../../kubectl-object-model';
|
||||
|
||||
import { getUpdatedManifestFiles } from '../manifest-utilities';
|
||||
import { deployPodCanary } from './pod-canary-deployment-helper';
|
||||
import { deploySMICanary } from './smi-canary-deployment-helper';
|
||||
import { checkForErrors } from "../utility";
|
||||
|
||||
import { isBlueGreenDeploymentStrategy, isIngressRoute, isSMIRoute, routeBlueGreen } from './blue-green-helper';
|
||||
import { deployBlueGreenService } from './service-blue-green-helper';
|
||||
import { deployBlueGreenIngress } from './ingress-blue-green-helper';
|
||||
import { deployBlueGreenSMI } from './smi-blue-green-helper';
|
||||
|
||||
export async function deploy(kubectl: Kubectl, manifestFilePaths: string[], deploymentStrategy: string) {
|
||||
|
||||
// get manifest files
|
||||
let inputManifestFiles: string[] = getManifestFiles(manifestFilePaths);
|
||||
|
||||
// artifact substitution
|
||||
inputManifestFiles = updateContainerImagesInManifestFiles(inputManifestFiles, TaskInputParameters.containers);
|
||||
|
||||
// imagePullSecrets addition
|
||||
inputManifestFiles = updateImagePullSecretsInManifestFiles(inputManifestFiles, TaskInputParameters.imagePullSecrets);
|
||||
let inputManifestFiles: string[] = getUpdatedManifestFiles(manifestFilePaths);
|
||||
|
||||
// deployment
|
||||
const deployedManifestFiles = deployManifests(inputManifestFiles, kubectl, isCanaryDeploymentStrategy(deploymentStrategy));
|
||||
const deployedManifestFiles = deployManifests(inputManifestFiles, kubectl, isCanaryDeploymentStrategy(deploymentStrategy), isBlueGreenDeploymentStrategy());
|
||||
|
||||
// check manifest stability
|
||||
const resourceTypes: Resource[] = KubernetesObjectUtility.getResources(deployedManifestFiles, models.deploymentTypes.concat([KubernetesConstants.DiscoveryAndLoadBalancerResource.service]));
|
||||
await checkManifestStability(kubectl, resourceTypes);
|
||||
|
||||
// route blue-green deployments
|
||||
if (isBlueGreenDeploymentStrategy()) {
|
||||
await routeBlueGreen(kubectl, inputManifestFiles);
|
||||
}
|
||||
|
||||
// print ingress resources
|
||||
const ingressResources: Resource[] = KubernetesObjectUtility.getResources(deployedManifestFiles, [KubernetesConstants.DiscoveryAndLoadBalancerResource.ingress]);
|
||||
ingressResources.forEach(ingressResource => {
|
||||
@@ -44,7 +44,7 @@ export async function deploy(kubectl: Kubectl, manifestFilePaths: string[], depl
|
||||
});
|
||||
}
|
||||
|
||||
function getManifestFiles(manifestFilePaths: string[]): string[] {
|
||||
export function getManifestFiles(manifestFilePaths: string[]): string[] {
|
||||
const files: string[] = utils.getManifestFiles(manifestFilePaths);
|
||||
|
||||
if (files == null || files.length === 0) {
|
||||
@@ -54,7 +54,7 @@ function getManifestFiles(manifestFilePaths: string[]): string[] {
|
||||
return files;
|
||||
}
|
||||
|
||||
function deployManifests(files: string[], kubectl: Kubectl, isCanaryDeploymentStrategy: boolean): string[] {
|
||||
function deployManifests(files: string[], kubectl: Kubectl, isCanaryDeploymentStrategy: boolean, isBlueGreenDeploymentStrategy: boolean): string[] {
|
||||
let result;
|
||||
if (isCanaryDeploymentStrategy) {
|
||||
let canaryDeploymentOutput: any;
|
||||
@@ -65,6 +65,17 @@ function deployManifests(files: string[], kubectl: Kubectl, isCanaryDeploymentSt
|
||||
}
|
||||
result = canaryDeploymentOutput.result;
|
||||
files = canaryDeploymentOutput.newFilePaths;
|
||||
} else if (isBlueGreenDeploymentStrategy) {
|
||||
let blueGreenDeploymentOutput: any;
|
||||
if (isIngressRoute()) {
|
||||
blueGreenDeploymentOutput = deployBlueGreenIngress(kubectl, files);
|
||||
} else if (isSMIRoute()) {
|
||||
blueGreenDeploymentOutput = deployBlueGreenSMI(kubectl, files);
|
||||
} else {
|
||||
blueGreenDeploymentOutput = deployBlueGreenService(kubectl, files);
|
||||
}
|
||||
result = blueGreenDeploymentOutput.result;
|
||||
files = blueGreenDeploymentOutput.newFilePaths;
|
||||
} else {
|
||||
if (canaryDeploymentHelper.isSMICanaryStrategy()) {
|
||||
const updatedManifests = appendStableVersionLabelToResource(files, kubectl);
|
||||
@@ -104,58 +115,6 @@ async function checkManifestStability(kubectl: Kubectl, resources: Resource[]):
|
||||
await KubernetesManifestUtility.checkManifestStability(kubectl, resources);
|
||||
}
|
||||
|
||||
function updateContainerImagesInManifestFiles(filePaths: string[], containers: string[]): string[] {
|
||||
if (!!containers && containers.length > 0) {
|
||||
const newFilePaths = [];
|
||||
const tempDirectory = fileHelper.getTempDirectory();
|
||||
filePaths.forEach((filePath: string) => {
|
||||
let contents = fs.readFileSync(filePath).toString();
|
||||
containers.forEach((container: string) => {
|
||||
let imageName = container.split(':')[0];
|
||||
if (imageName.indexOf('@') > 0) {
|
||||
imageName = imageName.split('@')[0];
|
||||
}
|
||||
if (contents.indexOf(imageName) > 0) {
|
||||
contents = utils.substituteImageNameInSpecFile(contents, imageName, container);
|
||||
}
|
||||
});
|
||||
|
||||
const fileName = path.join(tempDirectory, path.basename(filePath));
|
||||
fs.writeFileSync(
|
||||
path.join(fileName),
|
||||
contents
|
||||
);
|
||||
newFilePaths.push(fileName);
|
||||
});
|
||||
|
||||
return newFilePaths;
|
||||
}
|
||||
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
function updateImagePullSecretsInManifestFiles(filePaths: string[], imagePullSecrets: string[]): string[] {
|
||||
if (!!imagePullSecrets && imagePullSecrets.length > 0) {
|
||||
const newObjectsList = [];
|
||||
filePaths.forEach((filePath: string) => {
|
||||
const fileContents = fs.readFileSync(filePath).toString();
|
||||
yaml.safeLoadAll(fileContents, function (inputObject: any) {
|
||||
if (!!inputObject && !!inputObject.kind) {
|
||||
const kind = inputObject.kind;
|
||||
if (KubernetesObjectUtility.isWorkloadEntity(kind)) {
|
||||
KubernetesObjectUtility.updateImagePullSecrets(inputObject, imagePullSecrets, false);
|
||||
}
|
||||
newObjectsList.push(inputObject);
|
||||
}
|
||||
});
|
||||
});
|
||||
core.debug('New K8s objects after addin imagePullSecrets are :' + JSON.stringify(newObjectsList));
|
||||
const newFilePaths = fileHelper.writeObjectsToFile(newObjectsList);
|
||||
return newFilePaths;
|
||||
}
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
function isCanaryDeploymentStrategy(deploymentStrategy: string): boolean {
|
||||
return deploymentStrategy != null && deploymentStrategy.toUpperCase() === canaryDeploymentHelper.CANARY_DEPLOYMENT_STRATEGY.toUpperCase();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user