Blue/Green Refactor (#229)

* fresh new branch

* Added coverage to gitignore

Signed-off-by: Jaiveer Katariya <jaiveerkatariya@Jaiveers-MBP.lan>

* reverted package-lock.json

Signed-off-by: Jaiveer Katariya <jaiveerkatariya@Jaiveers-MBP.lan>
Co-authored-by: Jaiveer Katariya <jaiveerkatariya@Jaiveers-MBP.lan>
This commit is contained in:
Jaiveer Katariya
2022-08-12 15:47:05 -04:00
committed by GitHub
parent 531cfdcc3d
commit 01a65512ea
31 changed files with 1758 additions and 828 deletions
@@ -1,105 +1,18 @@
import * as core from '@actions/core'
import {K8sServiceObject} from '../../types/k8sObject'
import {Kubectl} from '../../types/kubectl'
import * as fileHelper from '../../utilities/fileUtils'
import {
addBlueGreenLabelsAndAnnotations,
BLUE_GREEN_VERSION_LABEL,
BlueGreenManifests,
createWorkloadsWithLabel,
deleteWorkloadsWithLabel,
fetchResource,
getManifestObjects,
GREEN_LABEL_VALUE,
NONE_LABEL_VALUE
GREEN_LABEL_VALUE
} from './blueGreenHelper'
export async function deployBlueGreenService(
kubectl: Kubectl,
filePaths: string[]
) {
const manifestObjects: BlueGreenManifests = getManifestObjects(filePaths)
// create deployments with green label value
const workloadDeployment = await createWorkloadsWithLabel(
kubectl,
manifestObjects.deploymentEntityList,
GREEN_LABEL_VALUE
)
const newObjectsList = manifestObjects.otherObjects
.concat(manifestObjects.ingressEntityList)
.concat(manifestObjects.unroutedServiceEntityList)
const manifestFiles = fileHelper.writeObjectsToFile(newObjectsList)
if (manifestFiles.length > 0) await kubectl.apply(manifestFiles)
// returning deployment details to check for rollout stability
return {workloadDeployment, newObjectsList}
}
export async function promoteBlueGreenService(
kubectl: Kubectl,
manifestObjects
) {
// checking if services are in the right state ie. targeting green deployments
if (
!(await validateServicesState(kubectl, manifestObjects.serviceEntityList))
) {
throw 'Not inP promote state'
}
// creating stable deployments with new configurations
return await createWorkloadsWithLabel(
kubectl,
manifestObjects.deploymentEntityList,
NONE_LABEL_VALUE
)
}
export async function rejectBlueGreenService(
kubectl: Kubectl,
filePaths: string[]
) {
// get all kubernetes objects defined in manifest files
const manifestObjects: BlueGreenManifests = getManifestObjects(filePaths)
// route to stable objects
await routeBlueGreenService(
kubectl,
NONE_LABEL_VALUE,
manifestObjects.serviceEntityList
)
// delete new deployments with green suffix
await deleteWorkloadsWithLabel(
kubectl,
GREEN_LABEL_VALUE,
manifestObjects.deploymentEntityList
)
}
export async function routeBlueGreenService(
kubectl: Kubectl,
nextLabel: string,
serviceEntityList: any[]
) {
const newObjectsList = []
serviceEntityList.forEach((serviceObject) => {
const newBlueGreenServiceObject = getUpdatedBlueGreenService(
serviceObject,
nextLabel
)
newObjectsList.push(newBlueGreenServiceObject)
})
// configures the services
const manifestFiles = fileHelper.writeObjectsToFile(newObjectsList)
await kubectl.apply(manifestFiles)
}
// add green labels to configure existing service
function getUpdatedBlueGreenService(
export function getUpdatedBlueGreenService(
inputObject: any,
labelValue: string
): object {
): K8sServiceObject {
const newObject = JSON.parse(JSON.stringify(inputObject))
// Adding labels and annotations.
@@ -121,25 +34,16 @@ export async function validateServicesState(
serviceObject.metadata.name
)
if (!!existingService) {
const currentLabel: string = getServiceSpecLabel(existingService)
if (currentLabel != GREEN_LABEL_VALUE) {
// service should be targeting deployments with green label
areServicesGreen = false
}
} else {
// service targeting deployment doesn't exist
areServicesGreen = false
}
let isServiceGreen =
!!existingService &&
getServiceSpecLabel(existingService as K8sServiceObject) ==
GREEN_LABEL_VALUE
areServicesGreen = areServicesGreen && isServiceGreen
}
return areServicesGreen
}
export function getServiceSpecLabel(inputObject: any): string {
if (inputObject?.spec?.selector[BLUE_GREEN_VERSION_LABEL]) {
return inputObject.spec.selector[BLUE_GREEN_VERSION_LABEL]
}
return ''
export function getServiceSpecLabel(inputObject: K8sServiceObject): string {
return inputObject.spec.selector[BLUE_GREEN_VERSION_LABEL]
}