const db = require('qmi-cloud-common/mongo'); const path = require('path'); const PROJECT_PATH = process.env.PROJECT_PATH; const tf = require("./docker/tf"); const azure = require("./docker/azure"); const sendEmail = require("qmi-cloud-common/send-email"); const barracuda = require("qmi-cloud-common/barracuda"); module.exports = async function(job) { var prov = await db.provision.update(job.data.id, { "status": "initializing", "jobId": job.id, "logFile": path.join('/logs', 'provision', `${job.data.id}.log`), "path": path.join(PROJECT_PATH, '..', 'qmi-cloud-provisions', `${job.data.scenario}_${job.data.id}`) }); if ( !prov ) { console.log(`ProcessorApply# Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` ); return Promise.reject({"success": false, "err": "Not found Provision object in Worker"}); } var idProv = prov._id.toString(); db.event.add({ user: prov.user._id, provision: prov._id, type: 'provision.init' }); // TERRAFORM INIT return tf.init(prov) .then(async function(res) { if ( res.statusCode === 1 ) { console.log(`ProcessorApply# Error at Terraform INIT for provision (${idProv})`); return Promise.reject({"success": false, "error": "Error at Terraform Init", provStatus: "error_init"}); } else { // TERRAFORM PLAN return tf.plan(prov, job.data._scenario); } } ) .then( async function(res) { if ( res.statusCode === 1 ) { console.log(`ProcessorApply# Error at Terraform PLAN for provision (${idProv}) `); return Promise.reject({"success": false, "error": "Error at Terraform Plan", provStatus: "error_plan"}); } else { const dateNow = new Date(); let patch = { "status": "provisioning", "statusVms": (prov.vmImage && prov.vmImage.vm1)? "Running" : "N/A", "runningFrom": dateNow, "runningTime": 0, "countExtend": 0 }; if ( prov.schedule && !prov.schedule.is24x7 ) { patch["startDateOnSchedule"] = dateNow; patch["endDateOnSchedule"] = dateNow; } return await db.provision.update(prov._id, patch); } } ).then( function(prov) { // TERRAFORM APPLY return tf.apply(prov); } ).then( async function(res) { if ( res.statusCode === 1 ) { console.log(`ProcessorApply# Error at Terraform APPLY for provision (${idProv})`); } else if ( res.statusCode === 137 ){ console.log(`ProcessorApply# Apply container must have been killed!`); return Promise.reject({"success": false, "error": "Apply container must have been killed", provStatus: "aborted"}); } var status = ( res.output.indexOf("Error:") !== -1 )? "error" : "provisioned"; return await db.provision.update(prov._id, {"status": status}); } ).then( async function(prov) { return tf.outputs(prov).then( async function(outputs){ if ( outputs.barracudaAzureFqdn ) { let fqdn = outputs.barracudaAzureFqdn; delete outputs['barracudaAzureFqdn']; return await db.provision.update(prov._id, {"barracudaAzureFqdn": fqdn, "outputs": outputs}); } else { return await db.provision.update(prov._id, {"outputs": outputs}); } }); } ).then( async function(prov) { if ( prov.isExternalAccess && prov.barracudaAzureFqdn ) { console.log(`ProcessorApply# Calling Barracuda service to create App and DNS CName for provision (${prov._id})`); barracuda.createApp(prov); } return prov; } ).then( async function(prov) { // Application Gateway assign policy return azure.appgateway(prov, job.data._scenario); } ).then( async function(prov) { // Create Image return azure.createimage(prov, job.data._scenario); } ).then( function(prov) { if (prov.status === "provisioned") { sendEmail.sendProvisionSuccess(prov, job.data._scenario); } else { sendEmail.sendProvisionError(prov, job.data._scenario); } db.event.add({ user: prov.user._id, provision: prov._id, type: 'provision.finished' }); return Promise.resolve({"success": true, provMongo: prov}); } ).catch( function(err) { console.log("ProcessorApply# Provision: error", err); var errormsg = err.provStatus? err.provStatus : 'error' db.provision.update(prov._id, {"status": errormsg}); db.event.add({ user: prov.user._id, provision: prov._id, type: 'provision.'+errormsg }); if ( errormsg !== "aborted") { sendEmail.sendProvisionError(prov, job.data._scenario); } return Promise.reject({"success": false, "error": err}); } ); }