Skip to content

Commit 12e6fc9

Browse files
authored
Hotfix for canary deployment issue (#12132)
1 parent e3e134b commit 12e6fc9

File tree

5 files changed

+107
-106
lines changed

5 files changed

+107
-106
lines changed

Tasks/KubernetesManifestV0/src/utils/DeploymentHelper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ function appendStableVersionLabelToResource(files: string[], kubectl: Kubectl):
114114
const updatedObject = canaryDeploymentHelper.markResourceAsStable(inputObject);
115115
newObjectsList.push(updatedObject);
116116
} else {
117-
manifestFiles.push(filePath);
117+
newObjectsList.push(inputObject);
118118
}
119119
});
120120
});

Tasks/KubernetesManifestV0/src/utils/PodCanaryDeploymentHelper.ts

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,37 @@ export function deployPodCanary(kubectl: Kubectl, filePaths: string[]) {
1717
filePaths.forEach((filePath: string) => {
1818
const fileContents = fs.readFileSync(filePath);
1919
yaml.safeLoadAll(fileContents, function (inputObject) {
20-
21-
const name = inputObject.metadata.name;
22-
const kind = inputObject.kind;
23-
if (helper.isDeploymentEntity(kind)) {
24-
tl.debug('Calculating replica count for canary');
25-
const canaryReplicaCount = calculateReplicaCountForCanary(inputObject, percentage);
26-
tl.debug('Replica count is ' + canaryReplicaCount);
27-
28-
// Get stable object
29-
tl.debug('Querying stable object');
30-
const stableObject = canaryDeploymentHelper.fetchResource(kubectl, kind, name);
31-
if (!stableObject) {
32-
tl.debug('Stable object not found. Creating only canary object');
33-
// If stable object not found, create canary deployment.
34-
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
35-
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
36-
newObjectsList.push(newCanaryObject);
20+
if (inputObject) {
21+
const name = inputObject.metadata.name;
22+
const kind = inputObject.kind;
23+
if (helper.isDeploymentEntity(kind)) {
24+
tl.debug('Calculating replica count for canary');
25+
const canaryReplicaCount = calculateReplicaCountForCanary(inputObject, percentage);
26+
tl.debug('Replica count is ' + canaryReplicaCount);
27+
28+
// Get stable object
29+
tl.debug('Querying stable object');
30+
const stableObject = canaryDeploymentHelper.fetchResource(kubectl, kind, name);
31+
if (!stableObject) {
32+
tl.debug('Stable object not found. Creating only canary object');
33+
// If stable object not found, create canary deployment.
34+
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
35+
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
36+
newObjectsList.push(newCanaryObject);
37+
} else {
38+
tl.debug('Stable object found. Creating canary and baseline objects');
39+
// If canary object not found, create canary and baseline object.
40+
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
41+
const newBaselineObject = canaryDeploymentHelper.getNewBaselineResource(stableObject, canaryReplicaCount);
42+
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
43+
tl.debug('New baseline object is: ' + JSON.stringify(newBaselineObject));
44+
newObjectsList.push(newCanaryObject);
45+
newObjectsList.push(newBaselineObject);
46+
}
3747
} else {
38-
tl.debug('Stable object found. Creating canary and baseline objects');
39-
// If canary object not found, create canary and baseline object.
40-
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
41-
const newBaselineObject = canaryDeploymentHelper.getNewBaselineResource(stableObject, canaryReplicaCount);
42-
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
43-
tl.debug('New baseline object is: ' + JSON.stringify(newBaselineObject));
44-
newObjectsList.push(newCanaryObject);
45-
newObjectsList.push(newBaselineObject);
48+
// Updating non deployment entity as it is.
49+
newObjectsList.push(inputObject);
4650
}
47-
} else {
48-
// Updating non deployment entity as it is.
49-
newObjectsList.push(inputObject);
5051
}
5152
});
5253
});

Tasks/KubernetesManifestV0/src/utils/SMICanaryDeploymentHelper.ts

Lines changed: 70 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,37 @@ export function deploySMICanary(kubectl: Kubectl, filePaths: string[]) {
2323
filePaths.forEach((filePath: string) => {
2424
const fileContents = fs.readFileSync(filePath);
2525
yaml.safeLoadAll(fileContents, function (inputObject) {
26-
const name = inputObject.metadata.name;
27-
const kind = inputObject.kind;
28-
if (helper.isDeploymentEntity(kind)) {
29-
// Get stable object
30-
tl.debug('Querying stable object');
31-
const stableObject = canaryDeploymentHelper.fetchResource(kubectl, kind, name);
32-
if (!stableObject) {
33-
tl.debug('Stable object not found. Creating only canary object');
34-
// If stable object not found, create canary deployment.
35-
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
36-
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
37-
newObjectsList.push(newCanaryObject);
38-
} else {
39-
if (!canaryDeploymentHelper.isResourceMarkedAsStable(stableObject)) {
40-
throw (tl.loc('StableSpecSelectorNotExist', name));
41-
}
26+
if (inputObject) {
27+
const name = inputObject.metadata.name;
28+
const kind = inputObject.kind;
29+
if (helper.isDeploymentEntity(kind)) {
30+
// Get stable object
31+
tl.debug('Querying stable object');
32+
const stableObject = canaryDeploymentHelper.fetchResource(kubectl, kind, name);
33+
if (!stableObject) {
34+
tl.debug('Stable object not found. Creating only canary object');
35+
// If stable object not found, create canary deployment.
36+
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
37+
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
38+
newObjectsList.push(newCanaryObject);
39+
} else {
40+
if (!canaryDeploymentHelper.isResourceMarkedAsStable(stableObject)) {
41+
throw (tl.loc('StableSpecSelectorNotExist', name));
42+
}
4243

43-
tl.debug('Stable object found. Creating canary and baseline objects');
44-
// If canary object not found, create canary and baseline object.
45-
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
46-
const newBaselineObject = canaryDeploymentHelper.getNewBaselineResource(stableObject, canaryReplicaCount);
47-
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
48-
tl.debug('New baseline object is: ' + JSON.stringify(newBaselineObject));
49-
newObjectsList.push(newCanaryObject);
50-
newObjectsList.push(newBaselineObject);
44+
tl.debug('Stable object found. Creating canary and baseline objects');
45+
// If canary object not found, create canary and baseline object.
46+
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(inputObject, canaryReplicaCount);
47+
const newBaselineObject = canaryDeploymentHelper.getNewBaselineResource(stableObject, canaryReplicaCount);
48+
tl.debug('New canary object is: ' + JSON.stringify(newCanaryObject));
49+
tl.debug('New baseline object is: ' + JSON.stringify(newBaselineObject));
50+
newObjectsList.push(newCanaryObject);
51+
newObjectsList.push(newBaselineObject);
52+
}
53+
} else {
54+
// Updating non deployment entity as it is.
55+
newObjectsList.push(inputObject);
5156
}
52-
} else {
53-
// Updating non deployment entity as it is.
54-
newObjectsList.push(inputObject);
5557
}
5658
});
5759
});
@@ -69,48 +71,49 @@ function createCanaryService(kubectl: Kubectl, filePaths: string[]) {
6971
filePaths.forEach((filePath: string) => {
7072
const fileContents = fs.readFileSync(filePath);
7173
yaml.safeLoadAll(fileContents, function (inputObject) {
74+
if (inputObject) {
75+
const name = inputObject.metadata.name;
76+
const kind = inputObject.kind;
77+
if (helper.isServiceEntity(kind)) {
78+
const newCanaryServiceObject = canaryDeploymentHelper.getNewCanaryResource(inputObject);
79+
tl.debug('New canary service object is: ' + JSON.stringify(newCanaryServiceObject));
80+
newObjectsList.push(newCanaryServiceObject);
81+
82+
const newBaselineServiceObject = canaryDeploymentHelper.getNewBaselineResource(inputObject);
83+
tl.debug('New baseline object is: ' + JSON.stringify(newBaselineServiceObject));
84+
newObjectsList.push(newBaselineServiceObject);
85+
86+
tl.debug('Querying for stable service object');
87+
const stableObject = canaryDeploymentHelper.fetchResource(kubectl, kind, canaryDeploymentHelper.getStableResourceName(name));
88+
if (!stableObject) {
89+
const newStableServiceObject = canaryDeploymentHelper.getStableResource(inputObject);
90+
tl.debug('New stable service object is: ' + JSON.stringify(newStableServiceObject));
91+
newObjectsList.push(newStableServiceObject);
92+
93+
tl.debug('Creating the traffic object for service: ' + name);
94+
const trafficObject = createTrafficSplitManifestFile(name, 0, 0, 1000);
95+
tl.debug('Creating the traffic object for service: ' + trafficObject);
96+
trafficObjectsList.push(trafficObject);
97+
} else {
98+
let updateTrafficObject = true;
99+
const trafficObject = canaryDeploymentHelper.fetchResource(kubectl, TRAFFIC_SPLIT_OBJECT, getTrafficSplitResourceName(name));
100+
if (trafficObject) {
101+
const trafficJObject = JSON.parse(JSON.stringify(trafficObject));
102+
if (trafficJObject && trafficJObject.spec && trafficJObject.spec.backends) {
103+
trafficJObject.spec.backends.forEach((s) => {
104+
if (s.service === canaryDeploymentHelper.getCanaryResourceName(name) && s.weight === "1000m") {
105+
tl.debug('Update traffic objcet not required');
106+
updateTrafficObject = false;
107+
}
108+
})
109+
}
110+
}
72111

73-
const name = inputObject.metadata.name;
74-
const kind = inputObject.kind;
75-
if (helper.isServiceEntity(kind)) {
76-
const newCanaryServiceObject = canaryDeploymentHelper.getNewCanaryResource(inputObject);
77-
tl.debug('New canary service object is: ' + JSON.stringify(newCanaryServiceObject));
78-
newObjectsList.push(newCanaryServiceObject);
79-
80-
const newBaselineServiceObject = canaryDeploymentHelper.getNewBaselineResource(inputObject);
81-
tl.debug('New baseline object is: ' + JSON.stringify(newBaselineServiceObject));
82-
newObjectsList.push(newBaselineServiceObject);
83-
84-
tl.debug('Querying for stable service object');
85-
const stableObject = canaryDeploymentHelper.fetchResource(kubectl, kind, canaryDeploymentHelper.getStableResourceName(name));
86-
if (!stableObject) {
87-
const newStableServiceObject = canaryDeploymentHelper.getStableResource(inputObject);
88-
tl.debug('New stable service object is: ' + JSON.stringify(newStableServiceObject));
89-
newObjectsList.push(newStableServiceObject);
90-
91-
tl.debug('Creating the traffic object for service: ' + name);
92-
const trafficObject = createTrafficSplitManifestFile(name, 0, 0, 1000);
93-
tl.debug('Creating the traffic object for service: ' + trafficObject);
94-
trafficObjectsList.push(trafficObject);
95-
} else {
96-
let updateTrafficObject = true;
97-
const trafficObject = canaryDeploymentHelper.fetchResource(kubectl, TRAFFIC_SPLIT_OBJECT, getTrafficSplitResourceName(name));
98-
if (trafficObject) {
99-
const trafficJObject = JSON.parse(JSON.stringify(trafficObject));
100-
if (trafficJObject && trafficJObject.spec && trafficJObject.spec.backends) {
101-
trafficJObject.spec.backends.forEach((s) => {
102-
if (s.service === canaryDeploymentHelper.getCanaryResourceName(name) && s.weight === "1000m") {
103-
tl.debug('Update traffic objcet not required');
104-
updateTrafficObject = false;
105-
}
106-
})
112+
if (updateTrafficObject) {
113+
tl.debug('Stable service object present so updating the traffic object for service: ' + name);
114+
trafficObjectsList.push(updateTrafficSplitObject(name));
107115
}
108116
}
109-
110-
if (updateTrafficObject) {
111-
tl.debug('Stable service object present so updating the traffic object for service: ' + name);
112-
trafficObjectsList.push(updateTrafficSplitObject(name));
113-
}
114117
}
115118
}
116119
});
@@ -152,7 +155,7 @@ function adjustTraffic(kubectl: Kubectl, manifestFilePaths: string[], stableWeig
152155
const inputManifestFiles: string[] = utils.getManifestFiles(manifestFilePaths);
153156

154157
if (inputManifestFiles == null || inputManifestFiles.length == 0) {
155-
return;
158+
return;
156159
}
157160

158161
const trafficSplitManifests = [];

Tasks/KubernetesManifestV0/task.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 162,
17-
"Patch": 1
17+
"Patch": 2
1818
},
1919
"demands": [],
2020
"groups": [],

Tasks/KubernetesManifestV0/task.loc.json

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 162,
17-
"Patch": 1
17+
"Patch": 2
1818
},
1919
"demands": [],
2020
"groups": [],
21-
"inputs": [
22-
{
21+
"inputs": [{
2322
"name": "action",
2423
"type": "pickList",
2524
"label": "ms-resource:loc.input.label.action",
@@ -329,12 +328,10 @@
329328
],
330329
"dataSourceBindings": [],
331330
"instanceNameFormat": "ms-resource:loc.instanceNameFormat",
332-
"outputVariables": [
333-
{
334-
"name": "manifestsBundle",
335-
"description": "The location of the manifest bundles created by bake action"
336-
}
337-
],
331+
"outputVariables": [{
332+
"name": "manifestsBundle",
333+
"description": "The location of the manifest bundles created by bake action"
334+
}],
338335
"execution": {
339336
"Node": {
340337
"target": "src//run.js"

0 commit comments

Comments
 (0)