Skip to content
Snippets Groups Projects
couchbase_eventing.js 4.39 KiB
var rp = require('request-promise');
var fs = require("fs");
var auth =  require('./config').auth;
var api =  require('./config').api;

//=========================================================
//utilities

let options = {uri: api,headers: {"Authorization":auth}};

var cstr = function(ob){console.log(JSON.stringify(ob,null,4))}

var reldir = "./functions/";
var getFuncs = function(funcName) {
	return new Promise(function(done,fail) {
		fs.readFile(reldir + funcName+ '.js','utf8', (err, file) => {
			if (err) {fail(err)}
			done(file);
		})
	})
};
//=========================================================

/**
 *  @method importDeploy
 *  @desc  Update an existing or create a new eventing function using the CB eventing API
 *  @param funcName Name of a function in <root>/functions
 *  @param update Boolean
 */

//function (and file) name, and flag for update versus create
var myArgs = process.argv.slice(2);
console.log('functionName: ', myArgs[0]);
console.log('update: ', myArgs[1]);

importDeploy(myArgs[0],myArgs[1])
	.then(r =>{console.log("importDeploy finished!");})
	.catch(e =>{
		console.error("importDeploy failed!");
		console.error(e);
	})



async function importDeploy(funcName,update) {

	//get the server cached functions
	//when we submit our import request, we need to submit
	//a object describing the function those being returned here (lots of settings and stuff)

	var op1 = Object.assign({},options);
	op1.uri += "/functions";op1.method = "GET";
	var funcs = await rp(op1);funcs = JSON.parse(funcs);
	console.log(funcs.length + " functions present");

	if(update){
		console.log("updating",funcName + ".js");

		//find the one we're updating
		var f = funcs.filter(fu =>{return fu.appname === funcName})

		//grab the contents of the file of the function we're updating
		//and replace just the code part of it
		f[0].appcode = await getFuncs(funcName)

		var op2 = Object.assign({},options)
		op2.uri += "/import";op2.method = "POST";

		//import expects an array of objects describing functions to import
		op2.json = [f[0]];

		/**
		 * @method waitStatus
		 * @desc Just keeps checking to see if your deployment or undeployment has finished
		 * @param funcName String
		 * @param operation Boolean
		 */
		var waitStatus =  function(funcName,operation){
			return new Promise(function(done, fail) {
				console.log("waitStatus resolving on a deployment_status of: ",operation);
				var id = setInterval(function(){
					//console.log("checking...");
					var op1 = Object.assign({},options);
					op1.uri += "/functions";op1.method = "GET";
					rp(op1).then(funcs =>{
						funcs = JSON.parse(funcs);
						var f = funcs.filter(fu =>{return fu.appname === funcName})
						var t = (f[0].settings.deployment_status) && (f[0].settings.processing_status);
						if(operation === t){
							clearInterval(id);
							done(true)
						}
					})
				},3000)
			})
		};

		//if we're currently deployed, stop that
		if(f[0].settings.deployment_status){

			var op3 = Object.assign({},options)
			op3.uri += "/functions/" +  f[0].appname + "/settings"; op3.method = "POST";
			op3.json = {"deployment_status":false,"processing_status":false};
			//console.log(op3);
			console.log("undeploy...");
			await rp(op3);
			//note: on successes, the response here is undefined?
			//this always works, but why don't I get a response here?
			//on failure we'll just catch it outside

			//var undeploy = await rp(op3);
			//console.log("undeploy:",undeploy === undefined);

			var newStatus = await waitStatus(funcName,false);
			console.log("undeployment complete");
		}

		console.log("posting import...",{appname:op2.json[0].appname,appcodeLength:op2.json[0].appcode.length});
		var postUpdate = await rp(op2);
		//console.log(postUpdate);

		//feature: check trip conditions
		//you can put trash in your functions, you can mis-label them...
		//not really sure what exactly could trigger a warning here yet
		if(postUpdate[0].info.warnings){
			var err = "import failure";
			console.log(err); throw new Error(err);
		}
		console.log("import success");

		var op4 = Object.assign({},options)
		op4.uri += "/functions/" +  f[0].appname + "/settings"; op4.method = "POST";
		op4.json = {"deployment_status":true,"processing_status":true};
		console.log("deploying...");
		await rp(op4);
		await waitStatus(funcName,true);
		console.log("deployment complete");
	}
	else{
		//todo: creation code
		//probably like just copy settings from the default config?
	}
}