Skip to content

Commit ac0b58c

Browse files
benjaminbob21davidgamerobosesuneha
authored
Add timeout to the rollout status (Azure#425)
* Added timeout to the rollout status and tests for it * Fixed integration test errors * Fix for blue green integration test * Probable fix for integration errors * No jobs run error fixed * Changed timeout to file level constant * Added parsing logic for timeout * Made tests more concise * implemented timeout validation check in an extracted utils mod * Changed function name to parseDuration * Removed timeout parameter from getResource --------- Co-authored-by: David Gamero <david340804@gmail.com> Co-authored-by: Suneha Bose <123775811+bosesuneha@users.noreply.github.com>
1 parent e207ec4 commit ac0b58c

28 files changed

+1678
-210
lines changed

.github/workflows/run-integration-tests-canary-smi.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ jobs:
4242
kubernetes-version: 1.31.0
4343
driver: 'none'
4444
timeout-minutes: 3
45+
46+
- name: Install Linkerd and SMI
47+
run: |
4548
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install-edge | sh
4649
export PATH=$PATH:/home/runner/.linkerd2/bin
4750
curl -sL https://linkerd.github.io/linkerd-smi/install | sh

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ inputs:
8484
skip-tls-verify:
8585
description: True if the insecure-skip-tls-verify option should be used. Input should be 'true' or 'false'.
8686
default: false
87+
timeout:
88+
description: 'Timeout for the rollout status'
89+
required: false
90+
default: 10m
8791
resource-type:
8892
description: Either Microsoft.ContainerService/managedClusters or Microsoft.ContainerService/fleets'.
8993
required: false

src/actions/deploy.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ export async function deploy(
2121
kubectl: Kubectl,
2222
manifestFilePaths: string[],
2323
deploymentStrategy: DeploymentStrategy,
24-
resourceType: ClusterType
24+
resourceType: ClusterType,
25+
timeout?: string
2526
) {
2627
// update manifests
2728
const inputManifestFiles: string[] = updateManifestFiles(manifestFilePaths)
@@ -36,7 +37,8 @@ export async function deploy(
3637
inputManifestFiles,
3738
deploymentStrategy,
3839
kubectl,
39-
trafficSplitMethod
40+
trafficSplitMethod,
41+
timeout
4042
)
4143
core.debug(`Deployed manifest files: ${deployedManifestFiles}`)
4244
core.endGroup()
@@ -50,7 +52,7 @@ export async function deploy(
5052
])
5153
)
5254

53-
await checkManifestStability(kubectl, resourceTypes, resourceType)
55+
await checkManifestStability(kubectl, resourceTypes, resourceType, timeout)
5456
core.endGroup()
5557

5658
// print ingresses

src/actions/promote.ts

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,26 @@ export async function promote(
4444
kubectl: Kubectl,
4545
manifests: string[],
4646
deploymentStrategy: DeploymentStrategy,
47-
resourceType: ClusterType
47+
resourceType: ClusterType,
48+
timeout?: string
4849
) {
4950
switch (deploymentStrategy) {
5051
case DeploymentStrategy.CANARY:
51-
await promoteCanary(kubectl, manifests)
52+
await promoteCanary(kubectl, manifests, timeout)
5253
break
5354
case DeploymentStrategy.BLUE_GREEN:
54-
await promoteBlueGreen(kubectl, manifests, resourceType)
55+
await promoteBlueGreen(kubectl, manifests, resourceType, timeout)
5556
break
5657
default:
5758
throw Error('Invalid promote deployment strategy')
5859
}
5960
}
6061

61-
async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
62+
async function promoteCanary(
63+
kubectl: Kubectl,
64+
manifests: string[],
65+
timeout?: string
66+
) {
6267
let includeServices = false
6368

6469
const manifestFilesForDeployment: string[] = updateManifestFiles(manifests)
@@ -76,7 +81,8 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
7681
core.startGroup('Redirecting traffic to canary deployment')
7782
await SMICanaryDeploymentHelper.redirectTrafficToCanaryDeployment(
7883
kubectl,
79-
manifests
84+
manifests,
85+
timeout
8086
)
8187
core.endGroup()
8288

@@ -87,7 +93,8 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
8793
promoteResult = await SMICanaryDeploymentHelper.deploySMICanary(
8894
manifestFilesForDeployment,
8995
kubectl,
90-
true
96+
true,
97+
timeout
9198
)
9299

93100
core.endGroup()
@@ -96,7 +103,8 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
96103
const stableRedirectManifests =
97104
await SMICanaryDeploymentHelper.redirectTrafficToStableDeployment(
98105
kubectl,
99-
manifests
106+
manifests,
107+
timeout
100108
)
101109

102110
filesToAnnotate = promoteResult.manifestFiles.concat(
@@ -109,7 +117,8 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
109117
promoteResult = await PodCanaryHelper.deployPodCanary(
110118
manifestFilesForDeployment,
111119
kubectl,
112-
true
120+
true,
121+
timeout
113122
)
114123
filesToAnnotate = promoteResult.manifestFiles
115124
core.endGroup()
@@ -144,7 +153,8 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
144153
async function promoteBlueGreen(
145154
kubectl: Kubectl,
146155
manifests: string[],
147-
resourceType: ClusterType
156+
resourceType: ClusterType,
157+
timeout?: string
148158
) {
149159
// update container images and pull secrets
150160
const inputManifestFiles: string[] = updateManifestFiles(manifests)
@@ -160,11 +170,19 @@ async function promoteBlueGreen(
160170
const {deployResult} = await (async () => {
161171
switch (routeStrategy) {
162172
case RouteStrategy.INGRESS:
163-
return await promoteBlueGreenIngress(kubectl, manifestObjects)
173+
return await promoteBlueGreenIngress(
174+
kubectl,
175+
manifestObjects,
176+
timeout
177+
)
164178
case RouteStrategy.SMI:
165-
return await promoteBlueGreenSMI(kubectl, manifestObjects)
179+
return await promoteBlueGreenSMI(kubectl, manifestObjects, timeout)
166180
default:
167-
return await promoteBlueGreenService(kubectl, manifestObjects)
181+
return await promoteBlueGreenService(
182+
kubectl,
183+
manifestObjects,
184+
timeout
185+
)
168186
}
169187
})()
170188

@@ -182,7 +200,8 @@ async function promoteBlueGreen(
182200
await KubernetesManifestUtility.checkManifestStability(
183201
kubectl,
184202
resources,
185-
resourceType
203+
resourceType,
204+
timeout
186205
)
187206
core.endGroup()
188207

@@ -201,23 +220,32 @@ async function promoteBlueGreen(
201220
[].concat(
202221
manifestObjects.deploymentEntityList,
203222
manifestObjects.serviceEntityList
204-
)
223+
),
224+
timeout
205225
)
206226
} else if (routeStrategy == RouteStrategy.SMI) {
207227
await routeBlueGreenSMI(
208228
kubectl,
209229
NONE_LABEL_VALUE,
210230
manifestObjects.serviceEntityList
211231
)
212-
await deleteGreenObjects(kubectl, manifestObjects.deploymentEntityList)
213-
await cleanupSMI(kubectl, manifestObjects.serviceEntityList)
232+
await deleteGreenObjects(
233+
kubectl,
234+
manifestObjects.deploymentEntityList,
235+
timeout
236+
)
237+
await cleanupSMI(kubectl, manifestObjects.serviceEntityList, timeout)
214238
} else {
215239
await routeBlueGreenService(
216240
kubectl,
217241
NONE_LABEL_VALUE,
218242
manifestObjects.serviceEntityList
219243
)
220-
await deleteGreenObjects(kubectl, manifestObjects.deploymentEntityList)
244+
await deleteGreenObjects(
245+
kubectl,
246+
manifestObjects.deploymentEntityList,
247+
timeout
248+
)
221249
}
222250
core.endGroup()
223251

src/actions/reject.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,26 @@ import {parseRouteStrategy, RouteStrategy} from '../types/routeStrategy'
1919
export async function reject(
2020
kubectl: Kubectl,
2121
manifests: string[],
22-
deploymentStrategy: DeploymentStrategy
22+
deploymentStrategy: DeploymentStrategy,
23+
timeout?: string
2324
) {
2425
switch (deploymentStrategy) {
2526
case DeploymentStrategy.CANARY:
26-
await rejectCanary(kubectl, manifests)
27+
await rejectCanary(kubectl, manifests, timeout)
2728
break
2829
case DeploymentStrategy.BLUE_GREEN:
29-
await rejectBlueGreen(kubectl, manifests)
30+
await rejectBlueGreen(kubectl, manifests, timeout)
3031
break
3132
default:
3233
throw 'Invalid delete deployment strategy'
3334
}
3435
}
3536

36-
async function rejectCanary(kubectl: Kubectl, manifests: string[]) {
37+
async function rejectCanary(
38+
kubectl: Kubectl,
39+
manifests: string[],
40+
timeout?: string
41+
) {
3742
let includeServices = false
3843

3944
const trafficSplitMethod = parseTrafficSplitMethod(
@@ -44,7 +49,8 @@ async function rejectCanary(kubectl: Kubectl, manifests: string[]) {
4449
includeServices = true
4550
await SMICanaryDeploymentHelper.redirectTrafficToStableDeployment(
4651
kubectl,
47-
manifests
52+
manifests,
53+
timeout
4854
)
4955
core.endGroup()
5056
}
@@ -53,12 +59,17 @@ async function rejectCanary(kubectl: Kubectl, manifests: string[]) {
5359
await canaryDeploymentHelper.deleteCanaryDeployment(
5460
kubectl,
5561
manifests,
56-
includeServices
62+
includeServices,
63+
timeout
5764
)
5865
core.endGroup()
5966
}
6067

61-
async function rejectBlueGreen(kubectl: Kubectl, manifests: string[]) {
68+
async function rejectBlueGreen(
69+
kubectl: Kubectl,
70+
manifests: string[],
71+
timeout?: string
72+
) {
6273
const routeStrategy = parseRouteStrategy(
6374
core.getInput('route-method', {required: true})
6475
)
@@ -67,11 +78,11 @@ async function rejectBlueGreen(kubectl: Kubectl, manifests: string[]) {
6778
const manifestObjects: BlueGreenManifests = getManifestObjects(manifests)
6879

6980
if (routeStrategy == RouteStrategy.INGRESS) {
70-
await rejectBlueGreenIngress(kubectl, manifestObjects)
81+
await rejectBlueGreenIngress(kubectl, manifestObjects, timeout)
7182
} else if (routeStrategy == RouteStrategy.SMI) {
72-
await rejectBlueGreenSMI(kubectl, manifestObjects)
83+
await rejectBlueGreenSMI(kubectl, manifestObjects, timeout)
7384
} else {
74-
await rejectBlueGreenService(kubectl, manifestObjects)
85+
await rejectBlueGreenService(kubectl, manifestObjects, timeout)
7586
}
7687
core.endGroup()
7788
}

src/run.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {parseDeploymentStrategy} from './types/deploymentStrategy'
1313
import {getFilesFromDirectoriesAndURLs} from './utilities/fileUtils'
1414
import {PrivateKubectl} from './types/privatekubectl'
1515
import {parseResourceTypeInput} from './inputUtils'
16+
import {parseDuration} from './utilities/durationUtils'
1617

1718
export async function run() {
1819
// verify kubeconfig is set
@@ -52,6 +53,17 @@ export async function run() {
5253
return
5354
}
5455

56+
// Parse and validate timeout using extracted utility
57+
let timeout: string
58+
try {
59+
const timeoutInput = core.getInput('timeout') || '10m'
60+
timeout = parseDuration(timeoutInput)
61+
core.debug(`Using timeout: ${timeout}`)
62+
} catch (e) {
63+
core.setFailed(`Invalid timeout parameter: ${e.message}`)
64+
return
65+
}
66+
5567
const kubectl = isPrivateCluster
5668
? new PrivateKubectl(
5769
kubectlPath,
@@ -65,15 +77,27 @@ export async function run() {
6577
// run action
6678
switch (action) {
6779
case Action.DEPLOY: {
68-
await deploy(kubectl, fullManifestFilePaths, strategy, resourceType)
80+
await deploy(
81+
kubectl,
82+
fullManifestFilePaths,
83+
strategy,
84+
resourceType,
85+
timeout
86+
)
6987
break
7088
}
7189
case Action.PROMOTE: {
72-
await promote(kubectl, fullManifestFilePaths, strategy, resourceType)
90+
await promote(
91+
kubectl,
92+
fullManifestFilePaths,
93+
strategy,
94+
resourceType,
95+
timeout
96+
)
7397
break
7498
}
7599
case Action.REJECT: {
76-
await reject(kubectl, fullManifestFilePaths, strategy)
100+
await reject(kubectl, fullManifestFilePaths, strategy, timeout)
77101
break
78102
}
79103
default: {

0 commit comments

Comments
 (0)