UNPKG

dce-dev-wizard

Version:

Wizard for managing development apps at Harvard DCE.

159 lines (138 loc) 4.99 kB
import clear from 'clear'; // Import helpers import showChooser from '../helpers/showChooser'; import getDeploymentConfig from '../operations/getDeploymentConfig'; import print from '../helpers/print'; import prompt from '../helpers/prompt'; import exec from '../helpers/exec'; import config from '../helpers/config'; // Import shared types import Deployment from '../types/Deployment'; import ChooserOption from '../types/ChooserOption'; /** * Show and/or modify related cluster status * @author Gabe Abrams * @param deployment the currently selected deployment */ const relatedClusters = async (deployment: Deployment) => { while (true) { // Show loading indicator clear(); console.log('Checking status of related instances...\n'); // Get related clusters const { relatedClusters } = config; if (!relatedClusters || relatedClusters.length === 0) { clear(); console.log('No related clusters. In your dceConfig.json file, add a "relatedClusters" array.'); return; } // Get the status on related clusters const relatedClustersWithStatus: { name: string, cluster: string, isOnline: boolean, }[] = []; for (let i = 0; i < relatedClusters.length; i += 1) { const relatedCluster = relatedClusters[i]; // Check if the related cluster is valid if (!relatedCluster.cluster || !relatedCluster.name) { console.log('Related clusters must be of form { name, cluster } where name is a human-readable name, cluster is the AWS cluster name.'); process.exit(0); } // Execute status command via aws cli const statusOutput = exec( `aws autoscaling describe-auto-scaling-groups --query "AutoScalingGroups[?contains(AutoScalingGroupName, '${relatedCluster.cluster}')] | [].Instances[] | length(@)"`, false, ); // Check if the output is a number if (Number.isNaN(Number.parseInt(statusOutput, 10))) { console.log(`Error getting status of ${relatedCluster.name} (${relatedCluster.cluster})`); console.log(`Got output: ${statusOutput} but expected a number.`); process.exit(0); } const isOnline = Number.parseInt(statusOutput, 10) >= 2; // Write to related cluster list relatedClustersWithStatus.push({ ...relatedCluster, isOnline, }); } // Show status clear(); const options: ChooserOption[] = relatedClustersWithStatus.map((cluster) => { return { description: `${cluster.name} (${cluster.isOnline ? 'ONLINE' : 'Offline'})`, }; }); // Option to refresh options.push({ description: '[Refresh Status]', tag: 'R', }); // Option to go back to main menu options.push({ description: '[Back to Main Menu]', tag: 'B', }); // Show chooser const option = showChooser({ question: 'Choose a cluster to turn on/off:', options, }); if (option.tag === 'B') { // Back to main menu return; } if (option.tag === 'R') { // Refresh status continue; } const cluster = relatedClustersWithStatus[option.index]; // Re-check status const statusOutput = exec( `aws autoscaling describe-auto-scaling-groups --query "AutoScalingGroups[?contains(AutoScalingGroupName, '${cluster.cluster}')] | [].Instances[] | length(@)"`, false, ); const nowIsOnline = Number.parseInt(statusOutput, 10) >= 2; if (nowIsOnline !== cluster.isOnline) { console.log('Status is out of date. Please continue to refresh.'); await print.enterToContinue(); continue; } // Ready to toggle! const newStatus = (cluster.isOnline ? 'off' : 'on'); const script = ` ON_OR_OFF="${newStatus}" CLUSTER_NAME="${cluster.cluster}" if ! command -v -- "aws" >/dev/null 2>&1; then echo "AWS CLI is not installed. Please install it first." exit 1 fi desiredCapacity=$([ "$ON_OR_OFF" == "on" ] && echo 1 || echo 0) asgs=$( aws autoscaling describe-auto-scaling-groups \ --query "AutoScalingGroups[?contains(AutoScalingGroupName, '$CLUSTER_NAME')].AutoScalingGroupName" \ --output text ) for asg in $asgs; do echo "Turning $ON_OR_OFF auto scaling group $asg" aws autoscaling set-desired-capacity \ --auto-scaling-group-name $asg \ --desired-capacity $desiredCapacity \ --no-honor-cooldown done `; clear(); print.title(`Turning ${newStatus}`); console.log(`\nTurning ${newStatus} ${cluster.name}...\n`); await exec(script, true); await new Promise((r) => { setTimeout(r, 3000); }); clear(); print.title('Cluster Updated'); console.log(`\n${cluster.name} is ${cluster.isOnline ? 'turning off' : 'turning on'}. This will take up to 15min.\n`); print.enterToContinue(); } }; export default relatedClusters;