From 1cae8dfe8b6485cf29c5699565ba557165b600b0 Mon Sep 17 00:00:00 2001 From: Deepak Sattiraju Date: Thu, 5 Mar 2020 17:10:12 +0530 Subject: [PATCH] Updating replacement logic (#25) --- lib/actions/promote.js | 3 +- lib/actions/reject.js | 3 +- lib/constants.js | 6 +- lib/utilities/kubectl-util.js | 164 +++++++++--------- lib/utilities/resource-object-utility.js | 55 ++++++ .../strategy-helpers/deployment-helper.js | 75 ++++---- src/utilities/resource-object-utility.ts | 61 +++++++ .../strategy-helpers/deployment-helper.ts | 79 ++++----- 8 files changed, 265 insertions(+), 181 deletions(-) diff --git a/lib/actions/promote.js b/lib/actions/promote.js index f0cabc49..2bdf58c9 100644 --- a/lib/actions/promote.js +++ b/lib/actions/promote.js @@ -1,9 +1,10 @@ 'use strict'; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; diff --git a/lib/actions/reject.js b/lib/actions/reject.js index 6710e5c9..d3177ef6 100644 --- a/lib/actions/reject.js +++ b/lib/actions/reject.js @@ -1,9 +1,10 @@ 'use strict'; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; diff --git a/lib/constants.js b/lib/constants.js index 4d3283c2..50919389 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -2,6 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); class KubernetesWorkload { } +exports.KubernetesWorkload = KubernetesWorkload; KubernetesWorkload.pod = 'Pod'; KubernetesWorkload.replicaset = 'Replicaset'; KubernetesWorkload.deployment = 'Deployment'; @@ -9,18 +10,17 @@ KubernetesWorkload.statefulSet = 'StatefulSet'; KubernetesWorkload.daemonSet = 'DaemonSet'; KubernetesWorkload.job = 'job'; KubernetesWorkload.cronjob = 'cronjob'; -exports.KubernetesWorkload = KubernetesWorkload; class DiscoveryAndLoadBalancerResource { } +exports.DiscoveryAndLoadBalancerResource = DiscoveryAndLoadBalancerResource; DiscoveryAndLoadBalancerResource.service = 'service'; DiscoveryAndLoadBalancerResource.ingress = 'ingress'; -exports.DiscoveryAndLoadBalancerResource = DiscoveryAndLoadBalancerResource; class ServiceTypes { } +exports.ServiceTypes = ServiceTypes; ServiceTypes.loadBalancer = 'LoadBalancer'; ServiceTypes.nodePort = 'NodePort'; ServiceTypes.clusterIP = 'ClusterIP'; -exports.ServiceTypes = ServiceTypes; exports.deploymentTypes = ['deployment', 'replicaset', 'daemonset', 'pod', 'statefulset']; exports.workloadTypes = ['deployment', 'replicaset', 'daemonset', 'pod', 'statefulset', 'job', 'cronjob']; exports.workloadTypesWithRolloutStatus = ['deployment', 'daemonset', 'statefulset']; diff --git a/lib/utilities/kubectl-util.js b/lib/utilities/kubectl-util.js index ca9ee6a6..720f3589 100644 --- a/lib/utilities/kubectl-util.js +++ b/lib/utilities/kubectl-util.js @@ -1,82 +1,82 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const os = require("os"); -const path = require("path"); -const util = require("util"); -const fs = require("fs"); -const toolCache = require("@actions/tool-cache"); -const core = require("@actions/core"); -const kubectlToolName = 'kubectl'; -const stableKubectlVersion = 'v1.15.0'; -const stableVersionUrl = 'https://storage.googleapis.com/kubernetes-release/release/stable.txt'; -const trafficSplitAPIVersionPrefix = 'split.smi-spec.io'; -function getExecutableExtension() { - if (os.type().match(/^Win/)) { - return '.exe'; - } - return ''; -} -function getkubectlDownloadURL(version) { - switch (os.type()) { - case 'Linux': - return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/amd64/kubectl', version); - case 'Darwin': - return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/darwin/amd64/kubectl', version); - case 'Windows_NT': - default: - return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/windows/amd64/kubectl.exe', version); - } -} -function getStableKubectlVersion() { - return __awaiter(this, void 0, void 0, function* () { - return toolCache.downloadTool(stableVersionUrl).then((downloadPath) => { - let version = fs.readFileSync(downloadPath, 'utf8').toString().trim(); - if (!version) { - version = stableKubectlVersion; - } - return version; - }, (error) => { - core.debug(error); - core.warning('GetStableVersionFailed'); - return stableKubectlVersion; - }); - }); -} -exports.getStableKubectlVersion = getStableKubectlVersion; -function downloadKubectl(version) { - return __awaiter(this, void 0, void 0, function* () { - let cachedToolpath = toolCache.find(kubectlToolName, version); - let kubectlDownloadPath = ''; - if (!cachedToolpath) { - try { - kubectlDownloadPath = yield toolCache.downloadTool(getkubectlDownloadURL(version)); - } - catch (exception) { - throw new Error('DownloadKubectlFailed'); - } - cachedToolpath = yield toolCache.cacheFile(kubectlDownloadPath, kubectlToolName + getExecutableExtension(), kubectlToolName, version); - } - const kubectlPath = path.join(cachedToolpath, kubectlToolName + getExecutableExtension()); - fs.chmodSync(kubectlPath, '777'); - return kubectlPath; - }); -} -exports.downloadKubectl = downloadKubectl; -function getTrafficSplitAPIVersion(kubectl) { - const result = kubectl.executeCommand('api-versions'); - const trafficSplitAPIVersion = result.stdout.split('\n').find(version => version.startsWith(trafficSplitAPIVersionPrefix)); - if (!trafficSplitAPIVersion) { - throw new Error('UnableToCreateTrafficSplitManifestFile'); - } - return trafficSplitAPIVersion; -} -exports.getTrafficSplitAPIVersion = getTrafficSplitAPIVersion; +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const os = require("os"); +const path = require("path"); +const util = require("util"); +const fs = require("fs"); +const toolCache = require("@actions/tool-cache"); +const core = require("@actions/core"); +const kubectlToolName = 'kubectl'; +const stableKubectlVersion = 'v1.15.0'; +const stableVersionUrl = 'https://storage.googleapis.com/kubernetes-release/release/stable.txt'; +const trafficSplitAPIVersionPrefix = 'split.smi-spec.io'; +function getExecutableExtension() { + if (os.type().match(/^Win/)) { + return '.exe'; + } + return ''; +} +function getkubectlDownloadURL(version) { + switch (os.type()) { + case 'Linux': + return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/amd64/kubectl', version); + case 'Darwin': + return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/darwin/amd64/kubectl', version); + case 'Windows_NT': + default: + return util.format('https://storage.googleapis.com/kubernetes-release/release/%s/bin/windows/amd64/kubectl.exe', version); + } +} +function getStableKubectlVersion() { + return __awaiter(this, void 0, void 0, function* () { + return toolCache.downloadTool(stableVersionUrl).then((downloadPath) => { + let version = fs.readFileSync(downloadPath, 'utf8').toString().trim(); + if (!version) { + version = stableKubectlVersion; + } + return version; + }, (error) => { + core.debug(error); + core.warning('GetStableVersionFailed'); + return stableKubectlVersion; + }); + }); +} +exports.getStableKubectlVersion = getStableKubectlVersion; +function downloadKubectl(version) { + return __awaiter(this, void 0, void 0, function* () { + let cachedToolpath = toolCache.find(kubectlToolName, version); + let kubectlDownloadPath = ''; + if (!cachedToolpath) { + try { + kubectlDownloadPath = yield toolCache.downloadTool(getkubectlDownloadURL(version)); + } + catch (exception) { + throw new Error('DownloadKubectlFailed'); + } + cachedToolpath = yield toolCache.cacheFile(kubectlDownloadPath, kubectlToolName + getExecutableExtension(), kubectlToolName, version); + } + const kubectlPath = path.join(cachedToolpath, kubectlToolName + getExecutableExtension()); + fs.chmodSync(kubectlPath, '777'); + return kubectlPath; + }); +} +exports.downloadKubectl = downloadKubectl; +function getTrafficSplitAPIVersion(kubectl) { + const result = kubectl.executeCommand('api-versions'); + const trafficSplitAPIVersion = result.stdout.split('\n').find(version => version.startsWith(trafficSplitAPIVersionPrefix)); + if (!trafficSplitAPIVersion) { + throw new Error('UnableToCreateTrafficSplitManifestFile'); + } + return trafficSplitAPIVersion; +} +exports.getTrafficSplitAPIVersion = getTrafficSplitAPIVersion; diff --git a/lib/utilities/resource-object-utility.js b/lib/utilities/resource-object-utility.js index 533b1aec..14c7f740 100644 --- a/lib/utilities/resource-object-utility.js +++ b/lib/utilities/resource-object-utility.js @@ -87,6 +87,61 @@ function updateImagePullSecrets(inputObject, newImagePullSecrets, override) { setImagePullSecrets(inputObject, existingImagePullSecretObjects); } exports.updateImagePullSecrets = updateImagePullSecrets; +function updateImageDetails(inputObject, containers) { + if (!inputObject || !inputObject.spec || !containers) { + return; + } + if (inputObject.spec.template && !!inputObject.spec.template.spec) { + if (inputObject.spec.template.spec.containers) { + updateContainers(inputObject.spec.template.spec.containers, containers); + } + if (inputObject.spec.template.spec.initContainers) { + updateContainers(inputObject.spec.template.spec.initContainers, containers); + } + return; + } + if (inputObject.spec.jobTemplate && inputObject.spec.jobTemplate.spec && inputObject.spec.jobTemplate.spec.template && inputObject.spec.jobTemplate.spec.template.spec) { + if (inputObject.spec.jobTemplate.spec.template.spec.containers) { + updateContainers(inputObject.spec.jobTemplate.spec.template.spec.containers, containers); + } + if (inputObject.spec.jobTemplate.spec.template.spec.initContainers) { + updateContainers(inputObject.spec.jobTemplate.spec.template.spec.initContainers, containers); + } + return; + } + if (inputObject.spec.containers) { + updateContainers(inputObject.spec.containers, containers); + } + if (inputObject.spec.initContainers) { + updateContainers(inputObject.spec.initContainers, containers); + } +} +exports.updateImageDetails = updateImageDetails; +function updateContainers(containers, images) { + if (!containers || containers.length === 0) { + return containers; + } + containers.forEach((container) => { + const imageName = extractImageName(container.image.trim()); + images.forEach(image => { + if (extractImageName(image) === imageName) { + container.image = image; + } + }); + }); +} +function extractImageName(imageName) { + let img = ''; + if (imageName.indexOf('/') > 0) { + const registry = imageName.substring(0, imageName.indexOf('/')); + const imgName = imageName.substring(imageName.indexOf('/') + 1).split(':')[0]; + img = `${registry}/${imgName}`; + } + else { + img = imageName.split(':')[0]; + } + return img; +} function updateSpecLabels(inputObject, newLabels, override) { if (!inputObject) { throw ('NullInputObject'); diff --git a/lib/utilities/strategy-helpers/deployment-helper.js b/lib/utilities/strategy-helpers/deployment-helper.js index 7f340941..219dfd27 100644 --- a/lib/utilities/strategy-helpers/deployment-helper.js +++ b/lib/utilities/strategy-helpers/deployment-helper.js @@ -1,15 +1,15 @@ 'use strict'; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); -const path = require("path"); const core = require("@actions/core"); const yaml = require("js-yaml"); const canaryDeploymentHelper = require("./canary-deployment-helper"); @@ -20,6 +20,7 @@ const fileHelper = require("../files-helper"); const utils = require("../manifest-utilities"); const KubernetesManifestUtility = require("../manifest-stability-utility"); const KubernetesConstants = require("../../constants"); +const string_comparison_1 = require("./../string-comparison"); const pod_canary_deployment_helper_1 = require("./pod-canary-deployment-helper"); const smi_canary_deployment_helper_1 = require("./smi-canary-deployment-helper"); const utility_1 = require("../utility"); @@ -28,9 +29,7 @@ function deploy(kubectl, manifestFilePaths, deploymentStrategy) { // get manifest files let inputManifestFiles = getManifestFiles(manifestFilePaths); // artifact substitution - inputManifestFiles = updateContainerImagesInManifestFiles(inputManifestFiles, TaskInputParameters.containers); - // imagePullSecrets addition - inputManifestFiles = updateImagePullSecretsInManifestFiles(inputManifestFiles, TaskInputParameters.imagePullSecrets); + inputManifestFiles = updateResourceObjects(inputManifestFiles, TaskInputParameters.containers, TaskInputParameters.imagePullSecrets); // deployment const deployedManifestFiles = deployManifests(inputManifestFiles, kubectl, isCanaryDeploymentStrategy(deploymentStrategy)); // check manifest stability @@ -101,49 +100,37 @@ function checkManifestStability(kubectl, resources) { yield KubernetesManifestUtility.checkManifestStability(kubectl, resources); }); } -function updateContainerImagesInManifestFiles(filePaths, containers) { - if (!!containers && containers.length > 0) { - const newFilePaths = []; - const tempDirectory = fileHelper.getTempDirectory(); - filePaths.forEach((filePath) => { - let contents = fs.readFileSync(filePath).toString(); - containers.forEach((container) => { - let imageName = container.split(':')[0]; - if (imageName.indexOf('@') > 0) { - imageName = imageName.split('@')[0]; +function updateResourceObjects(filePaths, imagePullSecrets, containers) { + const newObjectsList = []; + const updateResourceObject = (inputObject) => { + if (!!imagePullSecrets && imagePullSecrets.length > 0) { + KubernetesObjectUtility.updateImagePullSecrets(inputObject, imagePullSecrets, false); + } + if (!!containers && containers.length > 0) { + KubernetesObjectUtility.updateImageDetails(inputObject, containers); + } + }; + filePaths.forEach((filePath) => { + const fileContents = fs.readFileSync(filePath).toString(); + yaml.safeLoadAll(fileContents, function (inputObject) { + if (inputObject && inputObject.kind) { + const kind = inputObject.kind; + if (KubernetesObjectUtility.isWorkloadEntity(kind)) { + updateResourceObject(inputObject); } - 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, imagePullSecrets) { - if (!!imagePullSecrets && imagePullSecrets.length > 0) { - const newObjectsList = []; - filePaths.forEach((filePath) => { - const fileContents = fs.readFileSync(filePath).toString(); - yaml.safeLoadAll(fileContents, function (inputObject) { - if (!!inputObject && !!inputObject.kind) { - const kind = inputObject.kind; - if (KubernetesObjectUtility.isWorkloadEntity(kind)) { - KubernetesObjectUtility.updateImagePullSecrets(inputObject, imagePullSecrets, false); + else if (string_comparison_1.isEqual(kind, 'list', string_comparison_1.StringComparer.OrdinalIgnoreCase)) { + let items = inputObject.items; + if (items.length > 0) { + items.forEach((item) => updateResourceObject(item)); } - newObjectsList.push(inputObject); } - }); + newObjectsList.push(inputObject); + } }); - core.debug('New K8s objects after addin imagePullSecrets are :' + JSON.stringify(newObjectsList)); - const newFilePaths = fileHelper.writeObjectsToFile(newObjectsList); - return newFilePaths; - } - return filePaths; + }); + core.debug('New K8s objects after addin imagePullSecrets are :' + JSON.stringify(newObjectsList)); + const newFilePaths = fileHelper.writeObjectsToFile(newObjectsList); + return newFilePaths; } function isCanaryDeploymentStrategy(deploymentStrategy) { return deploymentStrategy != null && deploymentStrategy.toUpperCase() === canaryDeploymentHelper.CANARY_DEPLOYMENT_STRATEGY.toUpperCase(); diff --git a/src/utilities/resource-object-utility.ts b/src/utilities/resource-object-utility.ts index c5b41c49..343b7e7c 100644 --- a/src/utilities/resource-object-utility.ts +++ b/src/utilities/resource-object-utility.ts @@ -102,6 +102,67 @@ export function updateImagePullSecrets(inputObject: any, newImagePullSecrets: st setImagePullSecrets(inputObject, existingImagePullSecretObjects); } +export function updateImageDetails(inputObject: any, containers: string[]) { + if (!inputObject || !inputObject.spec || !containers) { + return; + } + + if (inputObject.spec.template && !!inputObject.spec.template.spec) { + if (inputObject.spec.template.spec.containers) { + updateContainers(inputObject.spec.template.spec.containers, containers); + } + if (inputObject.spec.template.spec.initContainers) { + updateContainers(inputObject.spec.template.spec.initContainers, containers); + } + return; + } + + if (inputObject.spec.jobTemplate && inputObject.spec.jobTemplate.spec && inputObject.spec.jobTemplate.spec.template && inputObject.spec.jobTemplate.spec.template.spec) { + if (inputObject.spec.jobTemplate.spec.template.spec.containers) { + updateContainers(inputObject.spec.jobTemplate.spec.template.spec.containers, containers); + } + + if (inputObject.spec.jobTemplate.spec.template.spec.initContainers) { + updateContainers(inputObject.spec.jobTemplate.spec.template.spec.initContainers, containers); + } + return; + } + + if (inputObject.spec.containers) { + updateContainers(inputObject.spec.containers, containers); + } + + if (inputObject.spec.initContainers) { + updateContainers(inputObject.spec.initContainers, containers); + } +} + +function updateContainers(containers: any[], images: string[]) { + if (!containers || containers.length === 0) { + return containers; + } + containers.forEach((container) => { + const imageName: string = extractImageName(container.image.trim()); + images.forEach(image => { + if (extractImageName(image) === imageName) { + container.image = image; + } + }); + }); +} + +function extractImageName(imageName) { + let img = ''; + if (imageName.indexOf('/') > 0) { + const registry = imageName.substring(0, imageName.indexOf('/')); + const imgName = imageName.substring(imageName.indexOf('/') + 1).split(':')[0]; + img = `${registry}/${imgName}`; + } else { + img = imageName.split(':')[0]; + } + return img; +} + export function updateSpecLabels(inputObject: any, newLabels: Map, override: boolean) { if (!inputObject) { throw ('NullInputObject'); diff --git a/src/utilities/strategy-helpers/deployment-helper.ts b/src/utilities/strategy-helpers/deployment-helper.ts index 34c547c7..bdf3b9cc 100644 --- a/src/utilities/strategy-helpers/deployment-helper.ts +++ b/src/utilities/strategy-helpers/deployment-helper.ts @@ -13,6 +13,7 @@ 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 { StringComparer, isEqual } from './../string-comparison'; import { deployPodCanary } from './pod-canary-deployment-helper'; import { deploySMICanary } from './smi-canary-deployment-helper'; @@ -25,10 +26,7 @@ export async function deploy(kubectl: Kubectl, manifestFilePaths: string[], depl let inputManifestFiles: string[] = getManifestFiles(manifestFilePaths); // artifact substitution - inputManifestFiles = updateContainerImagesInManifestFiles(inputManifestFiles, TaskInputParameters.containers); - - // imagePullSecrets addition - inputManifestFiles = updateImagePullSecretsInManifestFiles(inputManifestFiles, TaskInputParameters.imagePullSecrets); + inputManifestFiles = updateResourceObjects(inputManifestFiles, TaskInputParameters.containers, TaskInputParameters.imagePullSecrets); // deployment const deployedManifestFiles = deployManifests(inputManifestFiles, kubectl, isCanaryDeploymentStrategy(deploymentStrategy)); @@ -104,56 +102,37 @@ 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; +function updateResourceObjects(filePaths: string[], imagePullSecrets: string[], containers: string[]): string[] { + const newObjectsList = []; + const updateResourceObject = (inputObject) => { + if (!!imagePullSecrets && imagePullSecrets.length > 0) { + KubernetesObjectUtility.updateImagePullSecrets(inputObject, imagePullSecrets, false); + } + if (!!containers && containers.length > 0) { + KubernetesObjectUtility.updateImageDetails(inputObject, containers); + } } - - 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); + 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)) { + updateResourceObject(inputObject); + } + else if (isEqual(kind, 'list', StringComparer.OrdinalIgnoreCase)) { + let items = inputObject.items; + if (items.length > 0) { + items.forEach((item) => updateResourceObject(item)); } - newObjectsList.push(inputObject); } - }); + newObjectsList.push(inputObject); + } }); - core.debug('New K8s objects after addin imagePullSecrets are :' + JSON.stringify(newObjectsList)); - const newFilePaths = fileHelper.writeObjectsToFile(newObjectsList); - return newFilePaths; - } - return filePaths; + }); + core.debug('New K8s objects after addin imagePullSecrets are :' + JSON.stringify(newObjectsList)); + const newFilePaths = fileHelper.writeObjectsToFile(newObjectsList); + return newFilePaths; } function isCanaryDeploymentStrategy(deploymentStrategy: string): boolean {