UNPKG

@apigeeks/fbl-k8s-plugin

Version:

fbl wrapper plugin for helm and kubectl cli utilities

495 lines 23.7 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const assert = require("assert"); const chai = require("chai"); const chaiAsPromised = require("chai-as-promised"); const mocha_typescript_1 = require("mocha-typescript"); const typedi_1 = require("typedi"); const fbl_1 = require("fbl"); const handlers_1 = require("../../src/handlers"); const kubectl_1 = require("../../src/handlers/kubectl"); const services_1 = require("../../src/services"); const path_1 = require("path"); const K8sBaseHandlerTestSuite_1 = require("./K8sBaseHandlerTestSuite"); chai.use(chaiAsPromised); let K8sCleanupActionHandlerTestSuite = class K8sCleanupActionHandlerTestSuite extends K8sBaseHandlerTestSuite_1.K8sBaseHandlerTestSuite { failValidation() { return __awaiter(this, void 0, void 0, function* () { const actionHandler = new handlers_1.K8sCleanupActionHandler(); const context = fbl_1.ContextUtil.generateEmptyContext(); const snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); yield chai.expect(actionHandler.validate([], context, snapshot, {})).to.be.rejected; yield chai.expect(actionHandler.validate({ dryRun: true, }, context, snapshot, {})).to.be.rejected; yield chai.expect(actionHandler.validate({ namespace: 'default', ignored: { storageClasses: [], }, }, context, snapshot, {})).to.be.rejected; }); } passValidation() { return __awaiter(this, void 0, void 0, function* () { const actionHandler = new handlers_1.K8sCleanupActionHandler(); const context = fbl_1.ContextUtil.generateEmptyContext(); const snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); yield actionHandler.validate({ namespace: 'CustomObject', }, context, snapshot, {}); }); } cleanupHelms() { return __awaiter(this, void 0, void 0, function* () { const assetsDir = path_1.join(process.cwd(), 'test/assets'); const context = fbl_1.ContextUtil.generateEmptyContext(); const snapshot = new fbl_1.ActionSnapshot('.', {}, assetsDir, 0, {}); const helmUpgradeOrInstallActionHandler = new handlers_1.K8sHelmUpgradeOrInstallActionHandler(); const optionsHelmDeployed = { chart: 'helm/sample', name: 'helm-cleanup-deployed', }; const optionsHelmCluster = { chart: 'helm/cleanup', name: 'helm-cleanup-cluster', }; yield helmUpgradeOrInstallActionHandler.validate(optionsHelmDeployed, context, snapshot, {}); yield helmUpgradeOrInstallActionHandler.execute(optionsHelmDeployed, context, snapshot, {}); yield helmUpgradeOrInstallActionHandler.validate(optionsHelmCluster, context, snapshot, {}); yield helmUpgradeOrInstallActionHandler.execute(optionsHelmCluster, context, snapshot, {}); context.entities.registered.splice(-1, 1); assert.strictEqual(context.entities.registered.length, 1); const actionHandler = new handlers_1.K8sCleanupActionHandler(); const cleanupOptions = { namespace: 'default', }; yield actionHandler.validate(cleanupOptions, context, snapshot, {}); yield actionHandler.execute(cleanupOptions, context, snapshot, {}); const objectsAfterCleanup = yield typedi_1.Container.get(services_1.K8sHelmService).listInstalledHelms(); chai.expect(objectsAfterCleanup) .to.be.an('array') .that.not.includes('helm-cleanup-cluster'); chai.expect(objectsAfterCleanup) .to.be.an('array') .that.includes('helm-cleanup-deployed'); context.entities.registered.splice(-1, 1); yield actionHandler.execute(cleanupOptions, context, snapshot, {}); }); } cleanupConfigMap() { return __awaiter(this, void 0, void 0, function* () { yield this.cleanupConfigMapAndSecret('ConfigMap'); }); } cleanupSecret() { return __awaiter(this, void 0, void 0, function* () { yield this.cleanupConfigMapAndSecret('Secret'); }); } cleanupStorageClass() { return __awaiter(this, void 0, void 0, function* () { yield this.applyTestObjects({ kind: 'StorageClass', apiVersion: 'storage.k8s.io/v1', metadata: { namespace: 'default', name: 'config-deployed', }, provisioner: 'kubernetes.io/aws-ebs', parameters: { type: 'gp2', }, volumeBindingMode: 'Immediate', }, { kind: 'StorageClass', apiVersion: 'storage.k8s.io/v1', metadata: { namespace: 'default', name: 'config-cluster', }, provisioner: 'kubernetes.io/aws-ebs', parameters: { type: 'gp2', }, volumeBindingMode: 'Immediate', }, 'StorageClass'); }); } cleanupPersistentVolumeClaim() { return __awaiter(this, void 0, void 0, function* () { const applyK8sObjectActionHandler = new kubectl_1.K8sApplyObjectActionHandler(); const context = fbl_1.ContextUtil.generateEmptyContext(); const snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); const k8sObject = { kind: 'StorageClass', apiVersion: 'storage.k8s.io/v1', metadata: { namespace: 'default', name: 'test-storage-class', }, provisioner: 'kubernetes.io/aws-ebs', parameters: { type: 'gp2', }, volumeBindingMode: 'Immediate', }; yield applyK8sObjectActionHandler.validate(k8sObject, context, snapshot, {}); yield applyK8sObjectActionHandler.execute(k8sObject, context, snapshot, {}); yield this.applyTestObjects({ apiVersion: 'v1', kind: 'PersistentVolumeClaim', metadata: { namespace: 'default', name: 'config-deployed', }, spec: { volumeMode: 'Filesystem', resources: { requests: { storage: '8Gi', }, }, accessModes: ['ReadWriteOnce'], storageClassName: 'test-storage-class', }, }, { apiVersion: 'v1', kind: 'PersistentVolumeClaim', metadata: { namespace: 'default', name: 'config-cluster', }, spec: { volumeMode: 'Filesystem', resources: { requests: { storage: '8Gi', }, }, accessModes: ['ReadWriteOnce'], storageClassName: 'test-storage-class', }, }, 'pvc'); }); } dryRunK8sObject() { return __awaiter(this, void 0, void 0, function* () { typedi_1.Container.get(fbl_1.FlowService).debug = true; const applyK8sObjectActionHandler = new kubectl_1.K8sApplyObjectActionHandler(); const actionHandler = new handlers_1.K8sCleanupActionHandler(); const context = fbl_1.ContextUtil.generateEmptyContext(); const k8sObject = { apiVersion: 'v1', kind: 'ConfigMap', metadata: { name: 'dry-run-test-config-map', }, data: {}, }; let snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); yield applyK8sObjectActionHandler.validate(k8sObject, context, snapshot, {}); yield applyK8sObjectActionHandler.execute(k8sObject, context, snapshot, {}); snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); const cleanupOptionSecret = { dryRun: true, namespace: 'default', kinds: ['ConfigMap'], }; yield actionHandler.execute(cleanupOptionSecret, context, snapshot, {}); const logs = yield snapshot .getSteps() .filter((step) => step.type === 'log') .map(log => log.payload); const lastLog = logs.pop(); assert(lastLog.indexOf(`Found following ConfigMaps to be cleaned up: ${k8sObject.metadata.name}`) >= 0); }); } dryRunHelm() { return __awaiter(this, void 0, void 0, function* () { typedi_1.Container.get(fbl_1.FlowService).debug = true; const assetsDir = path_1.join(process.cwd(), 'test/assets'); const context = fbl_1.ContextUtil.generateEmptyContext(); let snapshot = new fbl_1.ActionSnapshot('.', {}, assetsDir, 0, {}); const helmUpgradeOrInstallActionHandler = new handlers_1.K8sHelmUpgradeOrInstallActionHandler(); const optionsHelm = { chart: 'helm/sample', name: 'helm-cleanup-dry-run', }; yield helmUpgradeOrInstallActionHandler.validate(optionsHelm, context, snapshot, {}); yield helmUpgradeOrInstallActionHandler.execute(optionsHelm, context, snapshot, {}); context.entities.registered.pop(); const actionHandler = new handlers_1.K8sCleanupActionHandler(); snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); const cleanupOptions = { dryRun: true, namespace: 'default', }; yield actionHandler.validate(cleanupOptions, context, snapshot, {}); yield actionHandler.execute(cleanupOptions, context, snapshot, {}); const logs = yield snapshot .getSteps() .filter((step) => step.type === 'log') .map(log => log.payload); assert(logs[0].indexOf(`Found following helm releases to be cleaned up: ${optionsHelm.name}`) >= 0); }); } checkIgnoredHelm() { return __awaiter(this, void 0, void 0, function* () { const helmUpgradeOrInstallActionHandler = new handlers_1.K8sHelmUpgradeOrInstallActionHandler(); const cleanupService = typedi_1.Container.get(services_1.K8sCleanupService); const assetsDir = path_1.join(process.cwd(), 'test/assets'); const context = fbl_1.ContextUtil.generateEmptyContext(); const snapshot = new fbl_1.ActionSnapshot('.', {}, assetsDir, 0, {}); const helmOptions = { chart: 'helm/cleanup', name: 'helm-ignored-test', }; yield helmUpgradeOrInstallActionHandler.validate(helmOptions, context, snapshot, {}); yield helmUpgradeOrInstallActionHandler.execute(helmOptions, context, snapshot, {}); const cleanupOptions = { dryRun: false, namespace: 'default', }; yield cleanupService.cleanup(cleanupOptions, context, snapshot); const listOfHelmsAfterCleanupSameContext = yield typedi_1.Container.get(services_1.K8sHelmService).listInstalledHelms(); chai.expect(listOfHelmsAfterCleanupSameContext) .to.be.an('array') .that.includes(helmOptions.name); context.entities.registered.pop(); const cleanupOptionsIgnored = { dryRun: false, namespace: 'default', ignored: { objects: {}, helms: ['helm-ignored-test'], }, }; yield cleanupService.cleanup(cleanupOptionsIgnored, context, snapshot); const listOfHelmsAfterCleanUpIgnored = yield typedi_1.Container.get(services_1.K8sHelmService).listInstalledHelms(); chai.expect(listOfHelmsAfterCleanUpIgnored) .to.be.an('array') .that.includes(helmOptions.name); yield cleanupService.cleanup(cleanupOptions, context, snapshot); const listOfHelmsAfterCleanup = yield typedi_1.Container.get(services_1.K8sHelmService).listInstalledHelms(); chai.expect(listOfHelmsAfterCleanup) .to.be.an('array') .that.not.includes(helmOptions.name); }); } checkIgnoredK8sObject() { return __awaiter(this, void 0, void 0, function* () { const applyK8sObjectActionHandler = new kubectl_1.K8sApplyObjectActionHandler(); const cleanupService = typedi_1.Container.get(services_1.K8sCleanupService); const context = fbl_1.ContextUtil.generateEmptyContext(); const snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); const k8sConfigMapObject = { kind: 'ConfigMap', apiVersion: 'v1', metadata: { namespace: 'default', name: 'configmap-ignored-test', }, }; yield applyK8sObjectActionHandler.validate(k8sConfigMapObject, context, snapshot, {}); yield applyK8sObjectActionHandler.execute(k8sConfigMapObject, context, snapshot, {}); const cleanupOptions = { dryRun: false, namespace: 'default', }; yield cleanupService.cleanup(cleanupOptions, context, snapshot); const listConfigMapsAfterCleanUpSameContext = yield typedi_1.Container.get(services_1.K8sKubectlService).listObjects('ConfigMap', 'default'); chai.expect(listConfigMapsAfterCleanUpSameContext) .to.be.an('array') .that.includes(k8sConfigMapObject.metadata.name); context.entities.registered.pop(); const cleanupOptionsIgnored = { dryRun: false, namespace: 'default', ignored: { objects: { ConfigMap: ['configmap-ignored-test'], }, helms: [''], }, }; yield cleanupService.cleanup(cleanupOptionsIgnored, context, snapshot); const listConfigMapsAfterCleanUpIgnored = yield typedi_1.Container.get(services_1.K8sKubectlService).listObjects('ConfigMap', 'default'); chai.expect(listConfigMapsAfterCleanUpIgnored) .to.be.an('array') .that.includes(k8sConfigMapObject.metadata.name); yield cleanupService.cleanup(cleanupOptions, context, snapshot); const listConfigMapsAfterCleanUp = yield typedi_1.Container.get(services_1.K8sKubectlService).listObjects('ConfigMap', 'default'); chai.expect(listConfigMapsAfterCleanUp) .to.be.an('array') .that.not.includes(k8sConfigMapObject.metadata.name); }); } applyTestObjects(deployedObject, clusterObject, kind) { return __awaiter(this, void 0, void 0, function* () { const assetsDir = path_1.join(process.cwd(), 'test/assets'); const applyK8sObjectActionHandler = new kubectl_1.K8sApplyObjectActionHandler(); const context = fbl_1.ContextUtil.generateEmptyContext(); const snapshot = new fbl_1.ActionSnapshot('.', {}, '', 0, {}); const snapshotHelm = new fbl_1.ActionSnapshot('.', {}, assetsDir, 0, {}); yield applyK8sObjectActionHandler.validate(deployedObject, context, snapshot, {}); yield applyK8sObjectActionHandler.execute(deployedObject, context, snapshot, {}); yield applyK8sObjectActionHandler.validate(clusterObject, context, snapshot, {}); yield applyK8sObjectActionHandler.execute(clusterObject, context, snapshot, {}); context.entities.registered.splice(-1, 1); assert.strictEqual(context.entities.registered.length, 1); // install helm const helmUpgradeOrInstallActionHandler = new handlers_1.K8sHelmUpgradeOrInstallActionHandler(); const options = { chart: 'helm/cleanup', name: 'helm-cleanup-test', }; yield helmUpgradeOrInstallActionHandler.validate(options, context, snapshotHelm, {}); yield helmUpgradeOrInstallActionHandler.execute(options, context, snapshotHelm, {}); const configMaps = yield typedi_1.Container.get(services_1.K8sKubectlService).listObjects(kind, 'default'); chai.expect(configMaps) .to.be.an('array') .that.includes('config-cluster'); chai.expect(configMaps) .to.be.an('array') .that.includes('config-deployed'); chai.expect(configMaps) .to.be.an('array') .that.includes('helm-cleanup'); const actionHandler = new handlers_1.K8sCleanupActionHandler(); const cleanupOptions = { namespace: 'default', ignored: { objects: { ConfigMap: ['foo-*'], }, }, }; yield actionHandler.validate(cleanupOptions, context, snapshot, {}); yield actionHandler.execute(cleanupOptions, context, snapshot, {}); const objectsAfterCleanup = yield typedi_1.Container.get(services_1.K8sKubectlService).listObjects(kind, 'default'); chai.expect(objectsAfterCleanup) .to.be.an('array') .that.not.includes('config-cluster'); chai.expect(objectsAfterCleanup) .to.be.an('array') .that.includes('config-deployed'); chai.expect(objectsAfterCleanup) .to.be.an('array') .that.includes('helm-cleanup'); }); } cleanupConfigMapAndSecret(kind) { return __awaiter(this, void 0, void 0, function* () { yield this.applyTestObjects({ kind: kind, apiVersion: 'v1', data: { test: 'true', }, metadata: { namespace: 'default', name: 'config-deployed', }, }, { kind: kind, apiVersion: 'v1', data: { test: 'true', }, metadata: { namespace: 'default', name: 'config-cluster', }, }, kind); }); } }; __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "failValidation", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "passValidation", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "cleanupHelms", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "cleanupConfigMap", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "cleanupSecret", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "cleanupStorageClass", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "cleanupPersistentVolumeClaim", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "dryRunK8sObject", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "dryRunHelm", null); __decorate([ mocha_typescript_1.test(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "checkIgnoredHelm", null); __decorate([ mocha_typescript_1.test, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], K8sCleanupActionHandlerTestSuite.prototype, "checkIgnoredK8sObject", null); K8sCleanupActionHandlerTestSuite = __decorate([ mocha_typescript_1.suite() ], K8sCleanupActionHandlerTestSuite); exports.K8sCleanupActionHandlerTestSuite = K8sCleanupActionHandlerTestSuite; //# sourceMappingURL=K8sCleanupActionHandlerTestSuite.js.map