const AWS = require("aws-sdk"); const db = require("./mongo"); const utils = require("./utils"); function _getRgName(provision) { let rgName = provision.scenario.toUpperCase(); rgName = rgName.replace(/AZQMI/g, 'QMI'); rgName = rgName + "-" + provision._id.toString(); return rgName; } function _getRegion(provision) { let region = "eu-west-1"; if ( provision.deployOpts.location === 'East US') { region = "us-east-1"; } else if ( provision.deployOpts.location === 'Southeast Asia' ) { region = "ap-southeast-1"; } return region; } function _getDbIndentifier(provision) { var out; if ( provision.outputs['db_instance_id'] ) { out = provision.outputs['db_instance_id']; } else if (provision.outputs['db_instance_endpoint']) { out = provision.outputs['db_instance_endpoint'].split(".")[0]; } return out; } async function stopDbInstance(provision, triggerUserId, isSendEmailAfter) { if (provision.statusVms === 'Stopped' || provision.statusVms === 'Stopping'){ return; } var identifier = _getDbIndentifier(provision); if ( !identifier ) { return; } await db.provision.update(provision._id.toString(), {"statusVms": "Stopping" }); db.event.add({ user: triggerUserId, provision: provision._id, type: `db.stopping` }); return new Promise((resolve, reject) => { let region = _getRegion(provision); var rds = new AWS.RDS({apiVersion: '2014-10-31', region: region}); var params = { DBInstanceIdentifier: identifier }; console.log(`AWSCLI# DB (${identifier}) stopping...`); rds.stopDBInstance(params, async function(err, data) { if (err) { console.log("AWSCLI# ERROR stopping DB: "+identifier, err.stack); await db.provision.update(provision._id.toString(), {"statusVms": "Running" }); reject(err); } else { console.log(`AWSCLI# DB (${identifier}) stopped!`); resolve(data); } }); }); } async function startDbInstance(provision, triggerUserId) { if (provision.statusVms === 'Running' || provision.statusVms === 'Starting'){ return; } var identifier = _getDbIndentifier(provision); if ( !identifier ) { return; } await db.provision.update(provision._id.toString(), {"statusVms": "Starting" }); db.event.add({ user: triggerUserId, provision: provision._id, type: `db.starting` }); return new Promise((resolve, reject) => { let region = _getRegion(provision); var rds = new AWS.RDS({apiVersion: '2014-10-31', region: region}); var params = { DBInstanceIdentifier: identifier }; console.log(`AWSCLI# DB (${identifier}) starting...`); rds.startDBInstance(params, async function(err, data) { if (err) { console.log("AWSCLI# ERROR starting DB: "+identifier, err.stack); await db.provision.update(provision._id.toString(), {"statusVms": "Stopped" }); reject(err); } else { console.log(`AWSCLI# DB (${identifier}) starting (2)...`); rds.waitFor('dBInstanceAvailable', params, async function(err, data) { if (err) { console.log("AWSCLI# ERROR waiting for DB to become available: "+identifier, err.stack); reject(err); } else { console.log(`AWSCLI# DB (${identifier}) started!`); await utils.afterStartVms( provision, triggerUserId, "db" ); } }); resolve(data); } }); }); } function deallocate(provision, triggerUserId, isSendEmailAfter) { let rgName = _getRgName(provision); let region = _getRegion(provision); console.log("AWSCLI# Stopping EC2s for resource group: "+rgName); return new Promise((resolve, reject) => { var ec2 = new AWS.EC2({apiVersion: '2016-11-15', region: region}); var params = { DryRun: false, Filters: [ { Name: 'tag:Name', Values: [ `fort-${provision._id}` ] }, ] }; ec2.describeInstances(params, async function (err, data) { if (err) { console.log("AWSCLI# ERROR describing EC2s: "+rgName, err.stack); await db.provision.update(provision._id.toString(), {"statusVms": "Running" }); reject(err); } else if (data && data.Reservations && data.Reservations.length) { var ec2Ids = data.Reservations[0].Instances.map(ec2=> ec2.InstanceId); console.log("AWSCLI# Stopping Ec2s ids...", ec2Ids); params = { DryRun: false, InstanceIds: ec2Ids }; ec2.stopInstances(params, async function(err1, data) { if (err1) { console.log("AWSCLI# ERROR stopping EC2s: "+rgName, err1.stack); await db.provision.update(provision._id.toString(), {"statusVms": "Running" }); reject(err1); } else { console.log("AWSCLI# Ec2s stopped!"); await utils.afterStopVms( provision, triggerUserId, isSendEmailAfter ); resolve(data); } }); } else { console.log("AWSCLI# No Ec2 Instances found: "+rgName); resolve(data); } }); }); } function start(provision, triggerUserId) { let rgName = _getRgName(provision); let region = _getRegion(provision); console.log("AWSCLI# Stopping EC2s for resource group: "+rgName); return new Promise((resolve, reject) => { var ec2 = new AWS.EC2({apiVersion: '2016-11-15', region: region}); var params = { DryRun: false, Filters: [ { Name: 'tag:Name', Values: [ `fort-${provision._id}` ] }, ] }; ec2.describeInstances(params, async function (err, data) { if (err) { console.log("AWSCLI# ERROR describing EC2s: "+rgName, err.stack); await db.provision.update(provision._id.toString(), {"statusVms": "Stopped" }); reject(err); } else if (data && data.Reservations && data.Reservations.length) { var ec2Ids = data.Reservations[0].Instances.map(ec2=> ec2.InstanceId); console.log("AWSCLI# Starting Ec2s ids...", ec2Ids); params = { DryRun: false, InstanceIds: ec2Ids }; ec2.startInstances(params, async function(err1, data) { if (err1) { console.log("AWSCLI# ERROR starting EC2s: "+rgName, err1.stack); await db.provision.update(provision._id.toString(), {"statusVms": "Stopped" }); reject(err1); } else { console.log("AWSCLI# Ec2s started!"); await utils.afterStartVms( provision, triggerUserId ); resolve(data); } }); } else { console.log("AWSCLI# No Ec2 Instances found: "+rgName); resolve(data); } }); }); } module.exports.deallocate = deallocate; module.exports.start = start; module.exports.stopDbInstance = stopDbInstance; module.exports.startDbInstance = startDbInstance;