Compare commits

..

8 Commits

Author SHA1 Message Date
asgayle 0b282a825d Added support message 2022-10-17 11:15:16 -04:00
Jaiveer Katariya d64c205796 Resolved issue with Canary deploy (#247) 2022-10-14 12:25:27 -04:00
Kenta Nakase c8f050230d Fix description about baseline-and-canary-replicas (#241) 2022-09-28 14:21:08 -04:00
Kenta Nakase a0b037b13e Fix issue form (#238) 2022-09-15 11:23:38 -04:00
Vidya Reddy 7fd0e52a8b Add the bug report and feature request form (#237)
* Added the bug report and feature request form

* updated the url
2022-09-06 13:10:29 -04:00
Oliver King 659bbb3802 Add permissions to README.md (#236)
* Add permissions to README.md

* remove space

* prettier

* remove extra changes

* fix spacing
2022-08-31 10:19:52 -04:00
dependabot[bot] 3c0579b484 Bump @actions/core from 1.9.0 to 1.9.1 (#233)
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-22 14:00:31 -04:00
Oliver King b11eda66ea Fix README.md typo (#235) 2022-08-22 11:07:47 -04:00
12 changed files with 247 additions and 113 deletions
+36
View File
@@ -0,0 +1,36 @@
name: Bug Report
description: File a bug report specifying all inputs you provided for the action, we will respond to this thread with any questions.
title: 'Bug: '
labels: ['bug', 'triage']
assignees: '@Azure/aks-atlanta'
body:
- type: textarea
id: What-happened
attributes:
label: What happened?
description: Tell us what happened and how is it different from the expected?
placeholder: Tell us what you see!
validations:
required: true
- type: checkboxes
id: Version
attributes:
label: Version
options:
- label: I am using the latest version
required: true
- type: input
id: Runner
attributes:
label: Runner
description: What runner are you using?
placeholder: Mention the runner info (self-hosted, operating system)
validations:
required: true
- type: textarea
id: Logs
attributes:
label: Relevant log output
description: Run in debug mode for the most verbose logs. Please feel free to attach a screenshot of the logs
validations:
required: true
+6
View File
@@ -0,0 +1,6 @@
blank_issues_enabled: false
contact_links:
- name: GitHub Action "k8s-deploy" Support
url: https://github.com/Azure/k8s-deploy
security: https://github.com/Azure/k8s-deploy/blob/main/SECURITY.md
about: Please ask and answer questions here.
@@ -0,0 +1,13 @@
name: Feature Request
description: File a Feature Request form, we will respond to this thread with any questions.
title: 'Feature Request: '
labels: ['Feature']
assignees: '@Azure/aks-atlanta'
body:
- type: textarea
id: Feature_request
attributes:
label: Feature request
description: Provide example functionality and links to relevant docs
validations:
required: true
+15 -2
View File
@@ -4,6 +4,15 @@ This action is used to deploy manifests to Kubernetes clusters. It requires that
If you are looking to automate your workflows to deploy to [Azure Web Apps](https://azure.microsoft.com/en-us/services/app-service/web/) and [Azure Web App for Containers](https://azure.microsoft.com/en-us/services/app-service/containers/), consider using [`Azure/webapps-deploy`](https://github.com/Azure/webapps-deploy) action.
This action requires the following permissions from your workflow:
```yaml
permissions:
id-token: write
contents: read
actions: read
```
## Action capabilities
Following are the key capabilities of this action:
@@ -82,8 +91,8 @@ Following are the key capabilities of this action:
<td>Used to compute the number of replicas of &#39;-baseline&#39; and &#39;-canary&#39; variants of the workloads found in manifest files. For the specified percentage input, if (percentage * numberOfDesirerdReplicas)/100 is not a round number, the floor of this number is used while creating &#39;-baseline&#39; and &#39;-canary&#39;.<br/><br/>For example, if Deployment hello-world was found in the input manifest file with &#39;replicas: 4&#39; and if &#39;strategy: canary&#39; and &#39;percentage: 25&#39; are given as inputs to the action, then the Deployments hello-world-baseline and hello-world-canary are created with 1 replica each. The &#39;-baseline&#39; variant is created with the same image and tag as the stable version (4 replica variant prior to deployment) while the &#39;-canary&#39; variant is created with the image and tag corresponding to the new changes being deployed</td>
</tr>
<tr>
<td>baseline-and-canary-replicas </br></br> (Optional and relevant only if traffic-split-method is canary)</td>
<td>The number of baseline and canary replicas. Percentage traffic split is controlled in the service mesh plane, the actual number of replicas for canary and baseline variants could be controlled independently of the traffic split. For example, assume that the input Deployment manifest desired 30 replicas to be used for stable and that the following inputs were specified for the action </br></br><code>&nbsp;&nbsp;&nbsp;&nbsp;strategy: canary<br>&nbsp;&nbsp;&nbsp;&nbsp;trafficSplitMethod: smi<br>&nbsp;&nbsp;&nbsp;&nbsp;percentage: 20<br>&nbsp;&nbsp;&nbsp;&nbsp;baselineAndCanaryReplicas: 1</code></br></br> In this case, stable variant will receive 80% traffic while baseline and canary variants will receive 10% each (20% split equally between baseline and canary). However, instead of creating baseline and canary with 3 replicas, the explicit count of baseline and canary replicas is honored. That is, only 1 replica each is created for baseline and canary variants.</td>
<td>baseline-and-canary-replicas </br></br> (Optional and relevant only if strategy is canary and traffic-split-method is smi)</td>
<td>The number of baseline and canary replicas. Percentage traffic split is controlled in the service mesh plane, the actual number of replicas for canary and baseline variants could be controlled independently of the traffic split. For example, assume that the input Deployment manifest desired 30 replicas to be used for stable and that the following inputs were specified for the action </br></br><code>&nbsp;&nbsp;&nbsp;&nbsp;strategy: canary<br>&nbsp;&nbsp;&nbsp;&nbsp;trafficSplitMethod: smi<br>&nbsp;&nbsp;&nbsp;&nbsp;percentage: 20<br>&nbsp;&nbsp;&nbsp;&nbsp;baselineAndCanaryReplicas: 1</code></br></br> In this case, stable variant will receive 80% traffic while baseline and canary variants will receive 10% each (20% split equally between baseline and canary). However, instead of creating baseline and canary with 3 replicas each, the explicit count of baseline and canary replicas is honored. That is, only 1 replica each is created for baseline and canary variants.</td>
</tr>
<tr>
<td>route-method </br></br>(Optional and relevant only if strategy is blue-green)</td>
@@ -462,3 +471,7 @@ provided by the bot. You will only need to do this once across all repos using o
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Support
k8s-deploy is an open source project that is [**not** covered by the Microsoft Azure support policy](https://support.microsoft.com/en-us/help/2941892/support-for-linux-and-open-source-technology-in-azure). [Please search open issues here](https://github.com/Azure/k8s-deploy/issues), and if your issue isn't already represented please [open a new one](https://github.com/Azure/k8s-deploy/issues/new/choose). The project maintainers will respond to the best of their abilities.
+1 -1
View File
@@ -41,7 +41,7 @@ inputs:
baseline-and-canary-replicas:
description: 'Baseline and canary replicas count. Valid value between 0 to 100 (inclusive)'
required: false
default: 0
default: ''
percentage:
description: 'Percentage of traffic redirect to canary deployment'
required: false
+26 -15
View File
@@ -9,7 +9,7 @@
"version": "0.0.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/core": "^1.9.1",
"@actions/exec": "^1.0.0",
"@actions/io": "^1.0.0",
"@actions/tool-cache": "1.1.2",
@@ -29,11 +29,20 @@
}
},
"node_modules/@actions/core": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.0.tgz",
"integrity": "sha512-5pbM693Ih59ZdUhgk+fts+bUWTnIdHV3kwOSr+QIoFHMLg7Gzhwm0cifDY/AG68ekEJAkHnQVpcy4f6GjmzBCA==",
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"dependencies": {
"@actions/http-client": "^2.0.1"
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/core/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/@actions/exec": {
@@ -6407,11 +6416,19 @@
},
"dependencies": {
"@actions/core": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.0.tgz",
"integrity": "sha512-5pbM693Ih59ZdUhgk+fts+bUWTnIdHV3kwOSr+QIoFHMLg7Gzhwm0cifDY/AG68ekEJAkHnQVpcy4f6GjmzBCA==",
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
"requires": {
"@actions/http-client": "^2.0.1"
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
},
"dependencies": {
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}
}
},
"@actions/exec": {
@@ -7363,12 +7380,6 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
"dev": true
},
"@vercel/ncc": {
"version": "0.34.0",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
"dev": true
},
"abab": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
+1 -1
View File
@@ -11,7 +11,7 @@
"format-check": "prettier --check ."
},
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/core": "^1.9.1",
"@actions/exec": "^1.0.0",
"@actions/io": "^1.0.0",
"@actions/tool-cache": "1.1.2",
+17 -5
View File
@@ -1,7 +1,7 @@
import * as core from '@actions/core'
import * as deploy from './deploy'
import * as canaryDeploymentHelper from '../strategyHelpers/canary/canaryHelper'
import * as SMICanaryDeploymentHelper from '../strategyHelpers/canary/smiCanaryHelper'
import * as PodCanaryHelper from '../strategyHelpers/canary/podCanaryHelper'
import {
getResources,
updateManifestFiles
@@ -57,6 +57,8 @@ export async function promote(
async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
let includeServices = false
const manifestFilesForDeployment: string[] = updateManifestFiles(manifests)
const trafficSplitMethod = parseTrafficSplitMethod(
core.getInput('traffic-split-method', {required: true})
)
@@ -72,8 +74,14 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
)
core.endGroup()
core.startGroup('Deploying input manifests with SMI canary strategy')
await deploy.deploy(kubectl, manifests, DeploymentStrategy.CANARY)
core.startGroup(
'Deploying input manifests with SMI canary strategy from promote'
)
await SMICanaryDeploymentHelper.deploySMICanary(
manifestFilesForDeployment,
kubectl,
true
)
core.endGroup()
core.startGroup('Redirecting traffic to stable deployment')
@@ -83,8 +91,12 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
)
core.endGroup()
} else {
core.startGroup('Deploying input manifests')
await deploy.deploy(kubectl, manifests, DeploymentStrategy.CANARY)
core.startGroup('Deploying input manifests from promote')
await PodCanaryHelper.deployPodCanary(
manifestFilesForDeployment,
kubectl,
true
)
core.endGroup()
}
+30 -4
View File
@@ -2,6 +2,7 @@ import {Kubectl} from '../../types/kubectl'
import * as fs from 'fs'
import * as yaml from 'js-yaml'
import * as core from '@actions/core'
import {ExecOutput} from '@actions/exec'
import {
isDeploymentEntity,
isServiceEntity,
@@ -30,7 +31,7 @@ export async function deleteCanaryDeployment(
includeServices: boolean
) {
if (manifestFilePaths == null || manifestFilePaths.length == 0) {
throw new Error('Manifest file not found')
throw new Error('Manifest files for deleting canary deployment not found')
}
await cleanUpCanary(kubectl, manifestFilePaths, includeServices)
@@ -54,7 +55,7 @@ export function isResourceMarkedAsStable(inputObject: any): boolean {
export function getStableResource(inputObject: any): object {
const replicaCount = specContainsReplicas(inputObject.kind)
? inputObject.metadata.replicas
? inputObject.spec.replicas
: 0
return getNewCanaryObject(inputObject, replicaCount, STABLE_LABEL_VALUE)
@@ -79,7 +80,12 @@ export async function fetchResource(
kind: string,
name: string
) {
const result = await kubectl.getResource(kind, name)
let result: ExecOutput
try {
result = await kubectl.getResource(kind, name)
} catch (e) {
core.debug(`detected error while fetching resources: ${e}`)
}
if (!result || result?.stderr) {
return null
@@ -93,7 +99,7 @@ export async function fetchResource(
return resource
} catch (ex) {
core.debug(
`Exception occurred while Parsing ${resource} in JSON object: ${ex}`
`Exception occurred while parsing ${resource} in JSON object: ${ex}`
)
}
}
@@ -111,6 +117,26 @@ export function getStableResourceName(name: string) {
return name + STABLE_SUFFIX
}
export function getBaselineDeploymentFromStableDeployment(
inputObject: any,
replicaCount: number
): object {
// TODO: REFACTOR TO MAKE EVERYTHING TYPE SAFE
const oldName = inputObject.metadata.name
const newName =
oldName.substring(0, oldName.length - STABLE_SUFFIX.length) +
BASELINE_SUFFIX
const newObject = getNewCanaryObject(
inputObject,
replicaCount,
BASELINE_LABEL_VALUE
) as any
newObject.metadata.name = newName
return newObject
}
function getNewCanaryObject(
inputObject: any,
replicas: number,
+22 -32
View File
@@ -8,9 +8,13 @@ import * as canaryDeploymentHelper from './canaryHelper'
import {isDeploymentEntity} from '../../types/kubernetesTypes'
import {getReplicaCount} from '../../utilities/manifestUpdateUtils'
export async function deployPodCanary(filePaths: string[], kubectl: Kubectl) {
export async function deployPodCanary(
filePaths: string[],
kubectl: Kubectl,
onlyDeployStable: boolean = false
) {
const newObjectsList = []
const percentage = parseInt(core.getInput('percentage'))
const percentage = parseInt(core.getInput('percentage', {required: true}))
if (percentage < 0 || percentage > 100)
throw Error('Percentage must be between 0 and 100')
@@ -22,7 +26,7 @@ export async function deployPodCanary(filePaths: string[], kubectl: Kubectl) {
const name = inputObject.metadata.name
const kind = inputObject.kind
if (isDeploymentEntity(kind)) {
if (!onlyDeployStable && isDeploymentEntity(kind)) {
core.debug('Calculating replica count for canary')
const canaryReplicaCount = calculateReplicaCountForCanary(
inputObject,
@@ -30,37 +34,22 @@ export async function deployPodCanary(filePaths: string[], kubectl: Kubectl) {
)
core.debug('Replica count is ' + canaryReplicaCount)
// Get stable object
core.debug('Querying stable object')
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(
inputObject,
canaryReplicaCount
)
newObjectsList.push(newCanaryObject)
// if there's already a stable object, deploy baseline as well
const stableObject = await canaryDeploymentHelper.fetchResource(
kubectl,
kind,
name
)
if (!stableObject) {
core.debug('Stable object not found. Creating canary object')
const newCanaryObject =
canaryDeploymentHelper.getNewCanaryResource(
inputObject,
canaryReplicaCount
)
newObjectsList.push(newCanaryObject)
} else {
if (stableObject) {
core.debug(
'Creating canary and baseline objects. Stable object found: ' +
JSON.stringify(stableObject)
`Stable object found for ${kind} ${name}. Creating baseline objects`
)
const newCanaryObject =
canaryDeploymentHelper.getNewCanaryResource(
inputObject,
canaryReplicaCount
)
core.debug(
'New canary object: ' + JSON.stringify(newCanaryObject)
)
const newBaselineObject =
canaryDeploymentHelper.getNewBaselineResource(
stableObject,
@@ -69,12 +58,10 @@ export async function deployPodCanary(filePaths: string[], kubectl: Kubectl) {
core.debug(
'New baseline object: ' + JSON.stringify(newBaselineObject)
)
newObjectsList.push(newCanaryObject)
newObjectsList.push(newBaselineObject)
}
} else {
// update non deployment entity as it is
// deploy non deployment entity or regular deployments for promote as they are
newObjectsList.push(inputObject)
}
}
@@ -88,7 +75,10 @@ export async function deployPodCanary(filePaths: string[], kubectl: Kubectl) {
return {result, newFilePaths: manifestFiles}
}
function calculateReplicaCountForCanary(inputObject: any, percentage: number) {
export function calculateReplicaCountForCanary(
inputObject: any,
percentage: number
) {
const inputReplicaCount = getReplicaCount(inputObject)
return Math.round((inputReplicaCount * percentage) / 100)
return Math.max(1, Math.round((inputReplicaCount * percentage) / 100))
}
+66 -45
View File
@@ -6,6 +6,7 @@ import * as yaml from 'js-yaml'
import * as fileHelper from '../../utilities/fileUtils'
import * as kubectlUtils from '../../utilities/trafficSplitUtils'
import * as canaryDeploymentHelper from './canaryHelper'
import * as podCanaryHelper from './podCanaryHelper'
import {isDeploymentEntity, isServiceEntity} from '../../types/kubernetesTypes'
import {checkForErrors} from '../../utilities/kubectlUtils'
import {inputAnnotations} from '../../inputUtils'
@@ -13,67 +14,86 @@ import {inputAnnotations} from '../../inputUtils'
const TRAFFIC_SPLIT_OBJECT_NAME_SUFFIX = '-workflow-rollout'
const TRAFFIC_SPLIT_OBJECT = 'TrafficSplit'
export async function deploySMICanary(filePaths: string[], kubectl: Kubectl) {
const canaryReplicaCount = parseInt(
core.getInput('baseline-and-canary-replicas')
)
if (canaryReplicaCount < 0 || canaryReplicaCount > 100)
export async function deploySMICanary(
filePaths: string[],
kubectl: Kubectl,
onlyDeployStable: boolean = false
) {
const canaryReplicasInput = core.getInput('baseline-and-canary-replicas')
let canaryReplicaCount
let calculateReplicas = true
if (canaryReplicasInput !== '') {
canaryReplicaCount = parseInt(canaryReplicasInput)
calculateReplicas = false
core.debug(
`read replica count ${canaryReplicaCount} from input: ${canaryReplicasInput}`
)
}
if (canaryReplicaCount < 0 && canaryReplicaCount > 100)
throw Error('Baseline-and-canary-replicas must be between 0 and 100')
const newObjectsList = []
filePaths.forEach((filePath: string) => {
for await (const filePath of filePaths) {
const fileContents = fs.readFileSync(filePath).toString()
yaml.safeLoadAll(fileContents, (inputObject) => {
const inputObjects = yaml.safeLoadAll(fileContents)
for (const inputObject of inputObjects) {
const name = inputObject.metadata.name
const kind = inputObject.kind
if (isDeploymentEntity(kind)) {
const stableObject = canaryDeploymentHelper.fetchResource(
if (!onlyDeployStable && isDeploymentEntity(kind)) {
if (calculateReplicas) {
// calculate for each object
const percentage = parseInt(
core.getInput('percentage', {required: true})
)
canaryReplicaCount =
podCanaryHelper.calculateReplicaCountForCanary(
inputObject,
percentage
)
core.debug(`calculated replica count ${canaryReplicaCount}`)
}
core.debug('Creating canary object')
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource(
inputObject,
canaryReplicaCount
)
newObjectsList.push(newCanaryObject)
const stableObject = await canaryDeploymentHelper.fetchResource(
kubectl,
kind,
name
canaryDeploymentHelper.getStableResourceName(name)
)
if (!stableObject) {
if (stableObject) {
core.debug(
'Stable object not found. Creating only canary object'
`Stable object found for ${kind} ${name}. Creating baseline objects`
)
const newCanaryObject =
canaryDeploymentHelper.getNewCanaryResource(
inputObject,
canaryReplicaCount
)
newObjectsList.push(newCanaryObject)
} else {
if (
!canaryDeploymentHelper.isResourceMarkedAsStable(stableObject)
) {
throw Error(`StableSpecSelectorNotExist : ${name}`)
}
core.debug(
'Stable object found. Creating canary and baseline objects'
)
const newCanaryObject =
canaryDeploymentHelper.getNewCanaryResource(
inputObject,
canaryReplicaCount
)
const newBaselineObject =
canaryDeploymentHelper.getNewBaselineResource(
canaryDeploymentHelper.getBaselineDeploymentFromStableDeployment(
stableObject,
canaryReplicaCount
)
newObjectsList.push(newCanaryObject)
newObjectsList.push(newBaselineObject)
}
} else if (isDeploymentEntity(kind)) {
core.debug(
`creating stable deployment with ${inputObject.spec.replicas} replicas`
)
const stableDeployment =
canaryDeploymentHelper.getStableResource(inputObject)
newObjectsList.push(stableDeployment)
} else {
// Update non deployment entity as it is
// Update non deployment entity or stable deployment as it is
newObjectsList.push(inputObject)
}
})
})
}
}
core.debug(
`deploying canary objects with SMI: \n ${JSON.stringify(newObjectsList)}`
)
const newFilePaths = fileHelper.writeObjectsToFile(newObjectsList)
const forceDeployment = core.getInput('force').toLowerCase() === 'true'
const result = await kubectl.apply(newFilePaths, forceDeployment)
@@ -83,7 +103,7 @@ export async function deploySMICanary(filePaths: string[], kubectl: Kubectl) {
async function createCanaryService(kubectl: Kubectl, filePaths: string[]) {
const newObjectsList = []
const trafficObjectsList = []
const trafficObjectsList: string[] = []
for (const filePath of filePaths) {
const fileContents = fs.readFileSync(filePath).toString()
@@ -93,6 +113,7 @@ async function createCanaryService(kubectl: Kubectl, filePaths: string[]) {
const kind = inputObject.kind
if (isServiceEntity(kind)) {
core.debug(`Creating services for ${kind} ${name}`)
const newCanaryServiceObject =
canaryDeploymentHelper.getNewCanaryResource(inputObject)
newObjectsList.push(newCanaryServiceObject)
@@ -155,7 +176,7 @@ async function createCanaryService(kubectl: Kubectl, filePaths: string[]) {
name
)
trafficObjectsList.push(
updateTrafficSplitObject(kubectl, name)
await updateTrafficSplitObject(kubectl, name)
)
}
}
@@ -230,7 +251,7 @@ async function updateTrafficSplitObject(
kubectl: Kubectl,
serviceName: string
): Promise<string> {
const percentage = parseInt(core.getInput('percentage'))
const percentage = parseInt(core.getInput('percentage', {required: true}))
if (percentage < 0 || percentage > 100)
throw Error('Percentage must be between 0 and 100')
@@ -241,9 +262,9 @@ async function updateTrafficSplitObject(
core.debug(
'Creating the traffic object with canary weight: ' +
baselineAndCanaryWeight +
',baseling weight: ' +
', baseline weight: ' +
baselineAndCanaryWeight +
',stable: ' +
', stable weight: ' +
stableDeploymentWeight
)
return await createTrafficSplitManifestFile(
+14 -8
View File
@@ -3,6 +3,7 @@ import {createInlineArray} from '../utilities/arrayUtils'
import * as core from '@actions/core'
import * as toolCache from '@actions/tool-cache'
import * as io from '@actions/io'
import {exec} from 'child_process'
export interface Resource {
name: string
@@ -142,14 +143,16 @@ export class Kubectl {
public async getResource(
resourceType: string,
name: string
name: string,
silentFailure: boolean = false
): Promise<ExecOutput> {
return await this.execute([
'get',
`${resourceType}/${name}`,
'-o',
'json'
])
core.debug(
'fetching resource of type ' + resourceType + ' and name ' + name
)
return await this.execute(
['get', `${resourceType}/${name}`, '-o', 'json'],
silentFailure
)
}
public executeCommand(command: string, args?: string) {
@@ -170,7 +173,10 @@ export class Kubectl {
args = args.concat(['--namespace', this.namespace])
}
core.debug(`Kubectl run with command: ${this.kubectlPath} ${args}`)
return await getExecOutput(this.kubectlPath, args, {silent})
return await getExecOutput(this.kubectlPath, args, {
silent
})
}
}