import {Component, EventEmitter, Inject} from 'ng-metadata/core'; const templateUrl = require('./kube-deploy-modal.component.html'); const styleUrl = require('./kube-deploy-modal.css'); // The response from the API about deployment rollout status type DeploymentRollout = { status: 'available' | 'progressing' | 'failed', message: string }; @Component({ selector: 'kube-deploy-modal', templateUrl, styleUrls: [ styleUrl ], }) export class KubeDeployModalComponent { private state : 'loadingDeployments' | 'readyToDeploy' | 'deployingConfiguration' | 'cyclingDeployments' | 'deployed' | 'error'; private errorMessage: string; private deploymentsStatus: { name: string, numPods: number, message?: string }[] = []; private deploymentsCycled: number = 0; constructor(@Inject('ApiService') private ApiService) { this.state = 'loadingDeployments'; ApiService.scGetNumDeployments().then(resp => { this.deploymentsStatus = resp.items.map(dep => ({ name: dep.metadata.name, numPods: dep.spec.replicas })); this.state = 'readyToDeploy'; }).catch(err => { this.state = 'error'; this.errorMessage = `There are no Quay deployments active in this namespace. \ Please check that you are running this \ tool in the same namespace as the Quay Enterprise application\ Associated error message: ${err.toString()}`; }) } deployConfiguration(): void { this.ApiService.scDeployConfiguration().then(() => { this.state = 'deployingConfiguration'; const deploymentNames: string[] = this.deploymentsStatus.map(dep => dep.name); this.ApiService.scCycleQEDeployments({ deploymentNames }).then(() => { this.state = 'cyclingDeployments'; this.watchDeployments(); }).catch(err => { this.state = 'error'; this.errorMessage = `Could not cycle the deployments with the new configuration. Error: ${err.toString()}`; }) }).catch(err => { this.state = 'error'; this.errorMessage = `Could not deploy the configuration. Error: ${err.toString()}`; }) } watchDeployments(): void { this.deploymentsStatus.forEach(deployment => { // Query each deployment every 500ms, and stop polling once it's either available or failed const id: number = window.setInterval(() => { const params = { 'deployment': deployment.name }; this.ApiService.scGetDeploymentRolloutStatus(null, params).then((deploymentRollout: DeploymentRollout) => { if (deploymentRollout.status === 'available') { window.clearInterval(id); this.deploymentsCycled++; if (this.deploymentsCycled === this.deploymentsStatus.length) { this.state = 'deployed'; } } else if (deploymentRollout.status === 'progressing') { deployment.message = deploymentRollout.message; } else { // deployment rollout failed window.clearInterval(id); deployment.message = deploymentRollout.message; } }).catch(err => { window.clearInterval(id); this.state = 'error'; this.errorMessage = `Could not cycle the deployments with the new configuration. Error: ${err.toString()}`; }); }, 500); }); } }