232 lines
7.8 KiB
JavaScript
232 lines
7.8 KiB
JavaScript
const loginWithVmMSI = require("@azure/ms-rest-nodeauth").loginWithVmMSI;
|
|
const computeManagementClient = require("@azure/arm-compute").ComputeManagementClient;
|
|
const dnsManagementClient = require("@azure/arm-dns").DnsManagementClient;
|
|
const db = require("./mongo");
|
|
const utils = require("./utils");
|
|
|
|
const SUBSCRIPTION_ID = "62ebff8f-c40b-41be-9239-252d6c0c8ad9";
|
|
|
|
function _getRgName(provision) {
|
|
let rgName = provision.scenario.toUpperCase();
|
|
rgName = rgName.replace(/AZQMI/g, 'QMI');
|
|
rgName = rgName + "-" + provision._id.toString();
|
|
return rgName;
|
|
}
|
|
|
|
async function _getClient(scenarioName) {
|
|
var id = SUBSCRIPTION_ID;
|
|
if (scenarioName){
|
|
var scenario = await db.scenario.getOne({"name": scenarioName});
|
|
id = scenario.subscription? scenario.subscription.subsId : SUBSCRIPTION_ID;
|
|
}
|
|
var credentials = await loginWithVmMSI({ port: 50342 });
|
|
//console.log("AzureCLI# authenticated", credentials);
|
|
return new computeManagementClient(credentials, id);
|
|
}
|
|
async function _getDNSClient(scenarioName) {
|
|
var id = SUBSCRIPTION_ID;
|
|
if (scenarioName){
|
|
var scenario = await db.scenario.getOne({"name": scenarioName});
|
|
id = scenario.subscription? scenario.subscription.subsId : SUBSCRIPTION_ID;
|
|
}
|
|
var credentials = await loginWithVmMSI({ port: 50342 });
|
|
//console.log("AzureCLI# authenticated", credentials);
|
|
return new dnsManagementClient(credentials, id);
|
|
}
|
|
|
|
|
|
|
|
async function asyncForEach(array, callback) {
|
|
for (let index = 0; index < array.length; index++) {
|
|
await callback(array[index], index, array);
|
|
}
|
|
}
|
|
|
|
async function deallocate(provision, isSendEmailAfter ) {
|
|
|
|
let rgName = _getRgName(provision);
|
|
console.log("AzureCLI# Deallocating VMs for resource group: "+rgName);
|
|
|
|
var computeClient = await _getClient(provision.scenario);
|
|
let finalResult = await computeClient.virtualMachines.list(rgName);
|
|
if ( finalResult && finalResult.length > 0 ) {
|
|
db.provision.update(provision._id, {"statusVms": "Stopping"});
|
|
}
|
|
|
|
try {
|
|
await asyncForEach(finalResult, async function(vm) {
|
|
await computeClient.virtualMachines.deallocate(rgName, vm.name);
|
|
});
|
|
|
|
await utils.afterStopVms(provision, isSendEmailAfter);
|
|
|
|
console.log("AzureCLI# All VMs DEALLOCATED for resource group: "+rgName);
|
|
} catch ( error ) {
|
|
console.log("AzureCLI# ERROR stopping VMs: "+rgName, error);
|
|
await db.provision.update(provision._id.toString(), {"statusVms": "Running" });
|
|
}
|
|
}
|
|
|
|
async function start(provision){
|
|
|
|
let rgName = _getRgName(provision);
|
|
console.log("AzureCLI# Starting VMs for resource group: "+rgName);
|
|
|
|
var computeClient = await _getClient(provision.scenario);
|
|
let finalResult = await computeClient.virtualMachines.list(rgName);
|
|
|
|
if ( finalResult && finalResult.length > 0 ) {
|
|
db.provision.update(provision._id, {"statusVms": "Starting"});
|
|
}
|
|
|
|
try {
|
|
await asyncForEach(finalResult, async function(vm) {
|
|
await computeClient.virtualMachines.start(rgName, vm.name);
|
|
});
|
|
|
|
await utils.afterStartVms( provision );
|
|
|
|
} catch ( error ) {
|
|
console.log("AzureCLI# ERROR starting VMs: "+rgName, error);
|
|
await db.provision.update(provision._id.toString(), {"statusVms": "Stopped" });
|
|
}
|
|
|
|
|
|
}
|
|
|
|
async function getResourceGroupVms(rgName){
|
|
let computeClient = await _getClient();
|
|
return await computeClient.virtualMachines.list(rgName);
|
|
}
|
|
|
|
async function getAllVms(){
|
|
let computeClient = await _getClient();
|
|
console.log("AzureCLI# Retrieving all VMS from subscription");
|
|
return await computeClient.virtualMachines.listAll();
|
|
}
|
|
async function getAllVmsNext(nextLink){
|
|
let computeClient = await _getClient();
|
|
console.log("AzureCLI# Retrieving all VMS from subscription (next): " +nextLink);
|
|
return await computeClient.virtualMachines.listAllNext(nextLink)
|
|
}
|
|
|
|
async function updateVmsTags(provId, tagsEdit) {
|
|
|
|
if ( !tagsEdit ){ return {} ; }
|
|
let provision = await db.provision.getById(provId);
|
|
if ( !provision ){ return };
|
|
|
|
let rgName = _getRgName(provision);
|
|
console.log("AzureCLI# Updating TAGS in VMs for resource group: "+rgName);
|
|
|
|
|
|
var computeClient;
|
|
var finalResult;
|
|
try {
|
|
computeClient = await _getClient(provision.scenario);
|
|
finalResult = await computeClient.virtualMachines.list(rgName);
|
|
} catch (e2) {
|
|
console.log(`AzureCLI# ERROR: Resource group '${rgName}' could not be found`, e2);
|
|
return {};
|
|
}
|
|
|
|
if (finalResult && finalResult.length > 0) {
|
|
var toDelete = [];
|
|
var toAdd = [];
|
|
for(let tag in tagsEdit ) {
|
|
if ( !tagsEdit[tag] ) {
|
|
toDelete.push(tag);
|
|
} else {
|
|
toAdd.push({"key": tag, "value": tagsEdit[tag]});
|
|
}
|
|
}
|
|
var result = {};
|
|
if ( toDelete.length > 0 || toAdd.length > 0 ) {
|
|
|
|
await asyncForEach(finalResult, async function(vm) {
|
|
|
|
var vmActualTags = JSON.stringify(vm.tags);
|
|
var tags = vm.tags;
|
|
toDelete.forEach(t=>{
|
|
delete tags[t];
|
|
});
|
|
toAdd.forEach(t=>{
|
|
tags[t.key] = t.value;
|
|
});
|
|
tags["ProvId"] = provision._id.toString();
|
|
result[vm.name] = tags;
|
|
|
|
if ( JSON.stringify(tags) !== vmActualTags ) {
|
|
try {
|
|
console.log(`AzureCLI# setting new tags to VM ${vm.name} (${rgName})`);
|
|
await computeClient.virtualMachines.update(rgName, vm.name, {"tags": tags} );
|
|
} catch (e1) {
|
|
console.log(`AzureCLI# ERROR setting tags to VM ${vm.name} (${rgName})`, e1);
|
|
}
|
|
} else {
|
|
console.log(`AzureCLI# Same tags, no need to update tags for VM ${vm.name} (${rgName})`);
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
//db.event.add({ user: provision.user._id, provision: provision._id, type: 'provision.vms-tags-update' });
|
|
|
|
return result;
|
|
|
|
} else {
|
|
return {}
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* DNS Records
|
|
*/
|
|
|
|
const DNS_RESOURCE_GROUP = "QMI-Infra-DNS";
|
|
const DNS_ZONE_NAME = "qmi.qlik-poc.com";
|
|
|
|
async function getDNSRecords(type = "CNAME") {
|
|
let dnsClient = await _getDNSClient();
|
|
console.log(`AzureCLI# Retrieving '${type}' DNS records`);
|
|
return await dnsClient.recordSets.listByType(DNS_RESOURCE_GROUP, DNS_ZONE_NAME, type);
|
|
}
|
|
|
|
async function createDNSRecord(provision, cname, type = "CNAME"){
|
|
|
|
if ( !provision ) return;
|
|
|
|
let rgName = _getRgName(provision).toLowerCase();
|
|
|
|
let dnsClient = await _getDNSClient();
|
|
console.log(`AzureCLI# Creating '${type}' DNS record: ${rgName}.${DNS_ZONE_NAME} --> ${cname}`);
|
|
let parameters = {
|
|
"cnameRecord": {
|
|
"cname": cname
|
|
},
|
|
"tTL": 60
|
|
};
|
|
return await dnsClient.recordSets.createOrUpdate(DNS_RESOURCE_GROUP, DNS_ZONE_NAME, rgName, type, parameters );
|
|
}
|
|
|
|
async function deleteDNSRecord(provision, type = "CNAME"){
|
|
|
|
if ( !provision ) return;
|
|
|
|
let rgName = _getRgName(provision).toLowerCase();
|
|
let dnsClient = await _getDNSClient();
|
|
console.log(`AzureCLI# Deleting '${type}' DNS record: ${rgName}.${DNS_ZONE_NAME}`);
|
|
return await dnsClient.recordSets.deleteMethod(DNS_RESOURCE_GROUP, DNS_ZONE_NAME, rgName, type );
|
|
}
|
|
|
|
module.exports.start = start;
|
|
module.exports.deallocate = deallocate;
|
|
module.exports.getResourceGroupVms = getResourceGroupVms;
|
|
module.exports.getAllVms = getAllVms;
|
|
module.exports.getAllVmsNext = getAllVmsNext;
|
|
module.exports.updateVmsTags = updateVmsTags;
|
|
module.exports.getDNSRecords = getDNSRecords;
|
|
module.exports.createDNSRecord = createDNSRecord;
|
|
module.exports.deleteDNSRecord = deleteDNSRecord
|