226 lines
7.4 KiB
JavaScript
226 lines
7.4 KiB
JavaScript
const Docker = require('dockerode');
|
|
const docker = new Docker({
|
|
'socketPath': '/home/docker.sock'
|
|
});
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const PROJECT_PATH = process.env.PROJECT_PATH;
|
|
const DOCKERIMAGE = "qlikgear/terraform:1.0.0";
|
|
const SSHPATH = process.env.SSHPATH;
|
|
|
|
function hook_stdout(callback) {
|
|
var old_write = process.stdout.write
|
|
|
|
process.stdout.write = (function(write) {
|
|
return function(string, encoding, fd) {
|
|
write.apply(process.stdout, arguments)
|
|
callback(string, encoding, fd)
|
|
}
|
|
})(process.stdout.write)
|
|
|
|
return function() {
|
|
process.stdout.write = old_write
|
|
}
|
|
}
|
|
|
|
function _buildExec( exec, provision ) {
|
|
if (!provision.vmImage) {
|
|
//Old way
|
|
if ( provision.vmType ) {
|
|
exec.push('-var');
|
|
exec.push(`vm_type=${provision.vmType}`);
|
|
}
|
|
|
|
if ( provision.nodeCount) {
|
|
exec.push('-var');
|
|
exec.push(`agent_count=${provision.nodeCount}`);
|
|
}
|
|
} else if ( provision.vmImage ) {
|
|
//New way
|
|
for (let key in provision.vmImage) {
|
|
if (provision.vmImage[key].nodeCount) {
|
|
exec.push('-var');
|
|
exec.push(`agent_count_${key}=${provision[key].nodeCount}`);
|
|
}
|
|
|
|
if (provision.vmImage[key].vmType) {
|
|
exec.push('-var');
|
|
exec.push(`vm_type_${key}=${provision.vmImage[key].vmType}`);
|
|
}
|
|
|
|
if (provision.vmImage[key].version) {
|
|
exec.push('-var');
|
|
exec.push(`image_reference_${key}=${provision.vmImage[key].version.image}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
return exec;
|
|
}
|
|
|
|
const init = function( provMongo ) {
|
|
|
|
const templatePath = path.join(PROJECT_PATH, 'az-tf-templates', provMongo.scenario);
|
|
const name = `qmi-tf-init-${provMongo._id}`;
|
|
console.log(`Init: will spin up container: ${name}`);
|
|
var processStream = fs.createWriteStream(provMongo.logFile, {flags:'a'});
|
|
let exec = ['terraform', 'init', '-no-color', '-from-module=/template'];
|
|
console.log('Init: exec: '+exec.join(" "));
|
|
|
|
return docker.run(DOCKERIMAGE, exec, processStream, {
|
|
//"Env": ["VAR_ENV=whatever"],
|
|
"name": name,
|
|
"WorkingDir": "/app",
|
|
"HostConfig": {
|
|
"Binds": [
|
|
`${provMongo.path}:/app`,
|
|
`${templatePath}:/template`
|
|
]
|
|
}
|
|
}).then(function(data) {
|
|
var output = data[0];
|
|
var container = data[1];
|
|
console.log(`Init: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
|
return container.remove();
|
|
}).then(function() {
|
|
console.log(`Init: ${name} removed!`);
|
|
return provMongo;
|
|
});
|
|
};
|
|
|
|
const plan = function( provMongo, user ) {
|
|
|
|
const name = `qmi-tf-plan-${provMongo._id}`;
|
|
console.log(`Plan: will spin up container: ${name}`);
|
|
var processStream = fs.createWriteStream(provMongo.logFile, {flags:'a'});
|
|
//var processStream = process.stdout;
|
|
var exec = ['terraform', 'plan', '-no-color', '-input=false', '-out=tfplan', '-var-file=scenario.tfvars', '-var', `provision_id=${provMongo._id}`, '-var', `user_id=${user}`];
|
|
exec = _buildExec(exec, provMongo);
|
|
console.log('Plan: exec: '+exec.join(" "));
|
|
|
|
return docker.run(DOCKERIMAGE, exec, processStream, {
|
|
//"Env": ["VAR_ENV=whatever"],
|
|
"name": name,
|
|
"WorkingDir": "/app",
|
|
"HostConfig": {
|
|
"Binds": [
|
|
`${provMongo.path}:/app`,
|
|
`${SSHPATH}:/root/.ssh`
|
|
],
|
|
"NetworkMode": "host"
|
|
}
|
|
}).then(function(data){
|
|
var container = data[1];
|
|
console.log(`Plan: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
|
return container.remove();
|
|
}).then(function() {
|
|
console.log(`Plan: ${name} removed!`);
|
|
return fs.readFileSync(provMongo.logFile);
|
|
})
|
|
};
|
|
|
|
const apply = function( provMongo, user ) {
|
|
|
|
const name = `qmi-tf-apply-${provMongo._id}`;
|
|
console.log(`Apply: will spin up container: ${name}`);
|
|
var processStream = fs.createWriteStream(provMongo.logFile, {flags:'a'});
|
|
//var processStream = process.stdout;
|
|
|
|
var exec = ['terraform', 'apply', 'tfplan', '-no-color'];
|
|
console.log('Apply: exec: '+exec.join(" "));
|
|
|
|
return docker.run(DOCKERIMAGE, exec, processStream, {
|
|
//"Env": ["VAR_ENV=whatever"],
|
|
"name": name,
|
|
"WorkingDir": "/app",
|
|
"HostConfig": {
|
|
"Binds": [
|
|
`${provMongo.path}:/app`,
|
|
`${SSHPATH}:/root/.ssh`
|
|
],
|
|
"NetworkMode": "host"
|
|
}
|
|
}).then(function(data){
|
|
let container = data[1];
|
|
console.log(`Apply: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
|
return container.remove();
|
|
}).then(function() {
|
|
console.log(`Apply: ${name} removed!`);
|
|
return fs.readFileSync(provMongo.logFile);
|
|
})
|
|
}
|
|
|
|
const destroy = function(destroyMongo, provMongo) {
|
|
|
|
const name = `qmi-tf-destroy-${destroyMongo._id}`;
|
|
console.log(`Destroy: will spin up container: ${name}`);
|
|
var processStream = fs.createWriteStream(destroyMongo.logFile, {flags:'a'});
|
|
var exec = ['terraform', 'destroy', '-auto-approve', '-no-color', '-var-file=scenario.tfvars', "-var", `provision_id=${destroyMongo.provId}`];
|
|
exec = _buildExec(exec, provMongo);
|
|
console.log('Destroy: exec: '+exec.join(" "));
|
|
|
|
return docker.run(DOCKERIMAGE, exec, processStream, {
|
|
//"Env": ["VAR_ENV=whatever"],
|
|
"name": name,
|
|
"WorkingDir": "/app",
|
|
"HostConfig": {
|
|
"Binds": [
|
|
`${provMongo.path}:/app`,
|
|
`${SSHPATH}:/root/.ssh`
|
|
]
|
|
}
|
|
}).then(function(data) {
|
|
var container = data[1];
|
|
console.log(`Destroy: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
|
return container.remove();
|
|
}).then(async function(data) {
|
|
console.log(`Destroy: '${name}' removed!`);
|
|
return fs.readFileSync(destroyMongo.logFile);
|
|
});
|
|
};
|
|
|
|
const outputs = function(provMongo) {
|
|
|
|
const name = `qmi-tf-output-${provMongo._id}`;
|
|
console.log(`Output: will spin up container: ${name}`);
|
|
|
|
|
|
var exec = ['terraform', 'output', '-no-color', '-json'];
|
|
console.log('Output: exec: '+exec.join(" "));
|
|
|
|
var tfout = "";
|
|
var unhook = hook_stdout(function(string, encoding, fd) {
|
|
tfout += string.trim();
|
|
});
|
|
|
|
return docker.run(DOCKERIMAGE, exec, process.stdout, {
|
|
//"Env": ["VAR_ENV=whatever"],
|
|
"name": name,
|
|
"WorkingDir": "/app",
|
|
"HostConfig": {
|
|
"Binds": [
|
|
`${provMongo.path}:/app`
|
|
]
|
|
}
|
|
}).then(function(data) {
|
|
unhook();
|
|
var container = data[1];
|
|
console.log(`Output: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
|
return container.remove();
|
|
}).then(async function(data) {
|
|
console.log(`Output: '${name}' removed!`);
|
|
console.log("Output: tfout: " + tfout);
|
|
var out = JSON.parse(tfout);
|
|
var o = {};
|
|
for (var key in out) {
|
|
o[key] = out[key].value;
|
|
}
|
|
return o;
|
|
});
|
|
};
|
|
|
|
module.exports.init = init;
|
|
module.exports.plan = plan;
|
|
module.exports.apply = apply;
|
|
module.exports.destroy = destroy;
|
|
module.exports.outputs = outputs; |