<commit_before>'use strict';
var K8Api = require('kubernetes-client');
var async = require('async');

var path = require('path');
var fs = require('fs');
var exec = require('child_process').exec;
var soajs = require('soajs');
var request = require('request');

var config = require('./config.js');
var folder = config.folder;
delete require.cache[config.profile];
var profile = require(config.profile);
var mongo = new soajs.mongo(profile);

var utilLog = require('util');
var lib = {

    "loadCustomData": function (cb) {
        var dataDir = process.env.SOAJS_DATA_FOLDER;

        fs.exists(path.normalize(dataDir + "/../custom.js"), function (exists) {
            if (!exists) {
                return cb(null);
            }
            else {
                delete require.cache[require.resolve(path.normalize(dataDir + "/../custom.js"))];
                var customData = require(path.normalize(dataDir + "/../custom.js"));
                return cb(customData);
            }
        });
    },

    printProgress: function (message, counter) {
        process.stdout.clearLine();
        process.stdout.write(showTimestamp() + ' - ' + message + ' ' + showDots() + '\r');

        function showDots() {
            var output = '';
            var numOfDots = counter % 5;
            for (var i = 0; i < numOfDots; i++) { output += '.'; }
            return output;
        }

        function showTimestamp() {
            var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
            var now = new Date();
            return '' + now.getDate() + ' ' + months[now.getMonth()] + ' ' + now.getHours() + ':' +
                ((now.getMinutes().toString().length === 2) ? now.getMinutes() : '0' + now.getMinutes()) + ':' +
                ((now.getSeconds().toString().length === 2) ? now.getSeconds() : '0' + now.getSeconds());
        }
    },

    getDeployer: function (deployerConfig, cb) {
        if(!config.kubernetes.certsPath){
	        return cb(new Error('No certificates found for remote machine.'));
        }
        var deployer = {};

        var certsName = {
            "ca": '/ca.pem',
            "cert": '/apiserver.pem',
            "key": '/apiserver-key.pem'
        };
        lib.loadCustomData(function(body){
            if(body.deployment.deployDriver === 'container.kubernetes.local' && process.platform === 'darwin'){
                certsName = {
                    "ca": '/ca.crt',
                    "cert": '/apiserver.crt',
                    "key": '/apiserver.key'
                };
            }

            deployerConfig.ca = fs.readFileSync(config.kubernetes.certsPath + certsName.ca);
            deployerConfig.cert = fs.readFileSync(config.kubernetes.certsPath + certsName.cert);
            deployerConfig.key = fs.readFileSync(config.kubernetes.certsPath + certsName.key);

            deployerConfig.version = 'v1beta1';
            deployer.extensions = new K8Api.Extensions(deployerConfig);

            deployerConfig.version = 'v1';
            deployer.core = new K8Api.Core(deployerConfig);
            return cb(null, deployer);
        });
    },

    getContent: function (type, group, cb) {
        var path = config.services.path.dir + group + '/';
        fs.exists(path, function (exists) {
            if (!exists) {
                utilLog.log('Folder [' + path + '] does not exist, skipping ...');
                return cb(null, true);
            }

            fs.readdir(path, function (error, content) {
                if (error) return cb(error);

                var regex = new RegExp('[a-zA-Z0-9]*\.' + config.services.path.fileType, 'g');
                var loadContent, allContent = [];
                content.forEach(function (oneContent) {
                    if (oneContent.match(regex)) {
                        try {
                            loadContent = require(path + oneContent);
                        }
                        catch (e) {
                            return cb(e);
                        }
                        allContent.push(loadContent);
                    }
                });
                return cb(null, allContent);
            });
        });
    },

    deployGroup: function (type, services, deployer, cb) {
        if (services.length === 0) {
            utilLog.log('No services of type [' + type + '] found, skipping ...');
            return cb(null, true);
        }

        if (type === 'db' && config.mongo.external) {
            utilLog.log('External Mongo deployment detected, data containers will not be deployed ...');
            return cb(null, true);
        }

        async.eachSeries(services, function (oneService, callback) {
            lib.deployService(deployer, oneService, callback);
        }, cb);
    },

    importData: function (mongoInfo, cb) {
        utilLog.log('Importing provision data to:', profile.servers[0].host + ":" + profile.servers[0].port);
        var execString = "cd " + folder + " && mongo --host " + profile.servers[0].host + ":" + profile.servers[0].port;
        if (profile.credentials && profile.credentials.username && profile.credentials.password && profile.URLParam && profile.URLParam.authSource) {
            execString += " -u " + profile.credentials.username + " -p " + profile.credentials.password + " --authenticationDatabase " + profile.URLParam.authSource;
        }
        execString += " data.js";
        exec(execString, cb);
    },

    deployService: function (deployer, options, cb) {
        if (options.service) {
            deployer.core.namespaces.services.post({body: options.service}, function (error) {
                if (error) return cb(error);
                return createDeployment();
            });
        }
        else {
            return createDeployment();
        }

        function createDeployment() {
            deployer.extensions.namespaces.deployments.post({body: options.deployment}, function (error, result) {
                if (error) return cb(error);
                lib.registerContainers(deployer, options, cb);
            });
        }
    },

    deleteDeployments: function (deployer, options, cb) {
        deployer.extensions.namespaces.deployments.delete({}, cb);
    },

    deleteKubeServices: function (deployer, options, cb) {
        var filter = { labelSelector: 'type=soajs-service' };
        deployer.core.namespaces.services.get({qs: filter}, function (error, serviceList) {
            if (error) return cb(error);

            async.each(serviceList.items, function (oneService, callback) {
                deployer.core.namespaces.services.delete({ name: oneService.metadata.name }, callback);
            }, cb);
        });
    },

    deletePods: function (deployer, options, cb) {
        //force delete all pods for a better cleanup
        deployer.core.namespaces.pods.delete({}, cb);
    },

    deletePreviousServices: function (deployer, cb) {
    	//todo: need to provide --grace-period=0 using the javascript syntax
        lib.deleteDeployments(deployer, {}, function (error) {
            if (error) return cb(error);

            lib.deleteKubeServices(deployer, {}, function (error) {
                if (error) return cb(error);

                lib.deletePods(deployer, {}, cb);
            });
        });
    },

    getServiceIPs: function (serviceName, deployer, replicaCount, counter, cb) {
        if (typeof (counter) === 'function') {
            cb = counter; //counter wasn't passed as param
            counter = 0;
        }

        deployer.core.namespaces.pods.get({}, function (error, podList) {
            if (error) return cb(error);
            var onePod, ips = [];
            podList.items.forEach(function (onePod) {
                if (onePod.metadata.labels['soajs-app'] === serviceName && onePod.status.phase === 'Running') {
                    ips.push({
                        name: onePod.metadata.name,
                        ip: onePod.status.podIP
                    });
                }
            });

            if (ips.length !== replicaCount) {
                //pod containers may not be ready yet
                lib.printProgress('Waiting for ' + serviceName + ' containers to become available', counter++);
                setTimeout(function () {
                    return lib.getServiceIPs(serviceName, deployer, replicaCount, counter, cb);
                }, 1000);
            }
            else {
                utilLog.log(""); //intentional, to force writting a new line.
                return cb(null, ips);
            }
        });
    },

    addMongoInfo: function (services, mongoInfo, cb) {
        var mongoEnv = [];

	    if(config.mongo.prefix && config.mongo.prefix !== ""){
		    mongoEnv.push({name: 'SOAJS_MONGO_PREFIX', value: config.mongo.prefix});
	    }

        if (config.mongo.external) {
            // if (!config.dataLayer.mongo.url || !config.dataLayer.mongo.port) {
            if (!profile.servers[0].host || !profile.servers[0].port) {
                utilLog.log('ERROR: External Mongo information is missing URL or port, make sure SOAJS_MONGO_EXTERNAL_URL and SOAJS_MONGO_EXTERNAL_PORT are set ...');
                return cb('ERROR: missing mongo information');
            }

            mongoEnv.push({ name: 'SOAJS_MONGO_NB', value: profile.servers.length });
	        for(var i =1; i <= profile.servers.length; i++){
		        mongoEnv.push({name: 'SOAJS_MONGO_IP_' + i, value: profile.servers[i].host});
		        mongoEnv.push({name: 'SOAJS_MONGO_PORT_' + i, value: '' + profile.servers[i].port});
	        }

            if (profile.credentials && profile.credentials.username && profile.credentials.password) {
                mongoEnv.push({ name: 'SOAJS_MONGO_USERNAME', value: profile.credentials.username });
                mongoEnv.push({ name: 'SOAJS_MONGO_PASSWORD', value: profile.credentials.password });
	            mongoEnv.push({ name: 'SOAJS_MONGO_AUTH_DB', value: profile.URLParam.authSource });
            }

            if(profile.URLParam.ssl){
	            mongoEnv.push({ name: 'SOAJS_MONGO_SSL', value: profile.URLParam.ssl });
            }
        }
        else {
            mongoEnv.push({ name: 'SOAJS_MONGO_NB', value: '1' });
	        mongoEnv.push({ name: 'SOAJS_MONGO_IP_1', value: profile.servers[0].host});
	        mongoEnv.push({ name: 'SOAJS_MONGO_PORT_1', value: '27017'});
        }

        services.forEach(function (oneService) {
            oneService.deployment.spec.template.spec.containers[0].env = oneService.deployment.spec.template.spec.containers[0].env.concat(mongoEnv);
        });

        return cb(null, services);
    },

    registerNode: function (deployer, swarmConfig, cb) {
        deployer.core.nodes.get({}, function (error, nodeList) {
            if (error) return cb(error);

            async.map(nodeList.items, function (oneNode, callback) {
                var record = {
                    recordType: 'node',
                    id: oneNode.metadata.uid,
                    name: oneNode.metadata.name,
                    ip: getIP(oneNode.status.addresses),
                    kubePort: config.kubernetes.machinePort,
                    availability: ((!oneNode.spec.unschedulable) ? 'active' : 'drained'),
                    role: ((oneNode.metadata.labels['kubeadm.alpha.kubernetes.io/role'] === 'master') ? 'manager' : 'worker'),
                    resources: {
                        cpuCount: oneNode.status.capacity.cpu,
                        memory: calcMemory(oneNode.status.capacity.memory)
                    },
                    tokens: {}
                };

                return callback(null, record);
            }, function (error, nodeRecords) {
                if (error) return cb(error);

                for (var i = nodeRecords.length; i >= 0; i--) {
                    if (!nodeRecords[i]) {
                        nodeRecords.splice(i, 1);
                    }
                }

                mongo.insert(config.kubernetes.mongoCollection, nodeRecords, cb);
            });
        });

        function calcMemory (memory) {
			var value = memory.substring(0, memory.length - 2);
			var unit = memory.substring(memory.length - 2);

			if (unit === 'Ki') value += '000';
			else if (unit === 'Mi') value += '000000';

			return parseInt(value);
		}

        function getIP (addresses) {
			var ip = '';
			for (var i = 0; i < addresses.length; i++) {
				if (addresses[i].type === 'LegacyHostIP') {
					ip = addresses[i].address;
				}
			}

			return ip;
		}
    },

    configureEnvDeployer: function (cb) {
        var criteria = {role: 'manager'};
        mongo.find('docker', criteria, function (error, managerNodes) {
            if (error) return cb(error);

            async.map(managerNodes, function (oneNode, callback) {
                return callback(null, oneNode.name);
            }, function (error, nodeHostnames) {
                //get environments records
                mongo.find('environment', {}, function (error, envs) {
                    if (error) return cb(error);

                    async.each(envs, function (oneEnv, callback) {
                        oneEnv.deployer.container.kubernetes.remote.nodes = nodeHostnames;
                        mongo.save('environment', oneEnv, callback);
                    }, cb);
                });
            });
        });
    },

    registerContainers: function (deployer, serviceOptions, cb) {
        var info = {};
        var kubeServiceName = serviceOptions.deployment.metadata.name;
        var serviceGroup, serviceName, serviceEnv;

        if (serviceOptions.deployment.metadata.labels) {
            serviceGroup = serviceOptions.deployment.metadata.labels['soajs.service.group'];
            serviceName = serviceOptions.deployment.metadata.labels['soajs.service'];
            serviceEnv = serviceOptions.deployment.metadata.labels['soajs.env'];
        }

        if (serviceGroup === 'core') {
            info.type = (serviceName === 'controller') ? 'controller' : 'service';
        }
        else if (serviceGroup === 'nginx') {
            info.type = 'nginx';
        }
        else {
            return cb(null, true);
        }

        var replicaCount = serviceOptions.deployment.spec.replicas;

        utilLog.log ('Registering ' + serviceName + ' containers in docker collection ...');

        info.env = serviceEnv;
        info.running = true;
        info.recordType = 'container';

        lib.getServiceIPs(kubeServiceName, deployer, replicaCount, function (error, serviceIPs) {
            if (error) return cb(error);

            async.map(serviceIPs, function (oneServiceInfo, callback) {
                deployer.core.namespaces.pods.get({name: oneServiceInfo.name}, function (error, pod) {
                    if (error) return callback(error);
                    var record = JSON.parse(JSON.stringify(info));
                    record.taskName = oneServiceInfo.name;
                    record.serviceName = kubeServiceName;
                    delete pod.metadata.annotations;
                    record.info = pod;
                    return callback(null, record);
                });
            }, function (error, records) {
                if (error) return cb(error);
                mongo.insert(config.kubernetes.mongoCollection, records, cb);
            });
        });
    },

    closeDbCon: function (cb) {
        mongo.closeDb();
        return cb();
    }
};

module.exports = lib;
<commit_msg>registerNode() now sets role of node to manager by default<commit_after>'use strict';
var K8Api = require('kubernetes-client');
var async = require('async');

var path = require('path');
var fs = require('fs');
var exec = require('child_process').exec;
var soajs = require('soajs');
var request = require('request');

var config = require('./config.js');
var folder = config.folder;
delete require.cache[config.profile];
var profile = require(config.profile);
var mongo = new soajs.mongo(profile);

var utilLog = require('util');
var lib = {

    "loadCustomData": function (cb) {
        var dataDir = process.env.SOAJS_DATA_FOLDER;

        fs.exists(path.normalize(dataDir + "/../custom.js"), function (exists) {
            if (!exists) {
                return cb(null);
            }
            else {
                delete require.cache[require.resolve(path.normalize(dataDir + "/../custom.js"))];
                var customData = require(path.normalize(dataDir + "/../custom.js"));
                return cb(customData);
            }
        });
    },

    printProgress: function (message, counter) {
        process.stdout.clearLine();
        process.stdout.write(showTimestamp() + ' - ' + message + ' ' + showDots() + '\r');

        function showDots() {
            var output = '';
            var numOfDots = counter % 5;
            for (var i = 0; i < numOfDots; i++) { output += '.'; }
            return output;
        }

        function showTimestamp() {
            var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
            var now = new Date();
            return '' + now.getDate() + ' ' + months[now.getMonth()] + ' ' + now.getHours() + ':' +
                ((now.getMinutes().toString().length === 2) ? now.getMinutes() : '0' + now.getMinutes()) + ':' +
                ((now.getSeconds().toString().length === 2) ? now.getSeconds() : '0' + now.getSeconds());
        }
    },

    getDeployer: function (deployerConfig, cb) {
        if(!config.kubernetes.certsPath){
	        return cb(new Error('No certificates found for remote machine.'));
        }
        var deployer = {};

        var certsName = {
            "ca": '/ca.pem',
            "cert": '/apiserver.pem',
            "key": '/apiserver-key.pem'
        };
        lib.loadCustomData(function(body){
            if(body.deployment.deployDriver === 'container.kubernetes.local' && process.platform === 'darwin'){
                certsName = {
                    "ca": '/ca.crt',
                    "cert": '/apiserver.crt',
                    "key": '/apiserver.key'
                };
            }

            deployerConfig.ca = fs.readFileSync(config.kubernetes.certsPath + certsName.ca);
            deployerConfig.cert = fs.readFileSync(config.kubernetes.certsPath + certsName.cert);
            deployerConfig.key = fs.readFileSync(config.kubernetes.certsPath + certsName.key);

            deployerConfig.version = 'v1beta1';
            deployer.extensions = new K8Api.Extensions(deployerConfig);

            deployerConfig.version = 'v1';
            deployer.core = new K8Api.Core(deployerConfig);
            return cb(null, deployer);
        });
    },

    getContent: function (type, group, cb) {
        var path = config.services.path.dir + group + '/';
        fs.exists(path, function (exists) {
            if (!exists) {
                utilLog.log('Folder [' + path + '] does not exist, skipping ...');
                return cb(null, true);
            }

            fs.readdir(path, function (error, content) {
                if (error) return cb(error);

                var regex = new RegExp('[a-zA-Z0-9]*\.' + config.services.path.fileType, 'g');
                var loadContent, allContent = [];
                content.forEach(function (oneContent) {
                    if (oneContent.match(regex)) {
                        try {
                            loadContent = require(path + oneContent);
                        }
                        catch (e) {
                            return cb(e);
                        }
                        allContent.push(loadContent);
                    }
                });
                return cb(null, allContent);
            });
        });
    },

    deployGroup: function (type, services, deployer, cb) {
        if (services.length === 0) {
            utilLog.log('No services of type [' + type + '] found, skipping ...');
            return cb(null, true);
        }

        if (type === 'db' && config.mongo.external) {
            utilLog.log('External Mongo deployment detected, data containers will not be deployed ...');
            return cb(null, true);
        }

        async.eachSeries(services, function (oneService, callback) {
            lib.deployService(deployer, oneService, callback);
        }, cb);
    },

    importData: function (mongoInfo, cb) {
        utilLog.log('Importing provision data to:', profile.servers[0].host + ":" + profile.servers[0].port);
        var execString = "cd " + folder + " && mongo --host " + profile.servers[0].host + ":" + profile.servers[0].port;
        if (profile.credentials && profile.credentials.username && profile.credentials.password && profile.URLParam && profile.URLParam.authSource) {
            execString += " -u " + profile.credentials.username + " -p " + profile.credentials.password + " --authenticationDatabase " + profile.URLParam.authSource;
        }
        execString += " data.js";
        exec(execString, cb);
    },

    deployService: function (deployer, options, cb) {
        if (options.service) {
            deployer.core.namespaces.services.post({body: options.service}, function (error) {
                if (error) return cb(error);
                return createDeployment();
            });
        }
        else {
            return createDeployment();
        }

        function createDeployment() {
            deployer.extensions.namespaces.deployments.post({body: options.deployment}, function (error, result) {
                if (error) return cb(error);
                lib.registerContainers(deployer, options, cb);
            });
        }
    },

    deleteDeployments: function (deployer, options, cb) {
        deployer.extensions.namespaces.deployments.delete({}, cb);
    },

    deleteKubeServices: function (deployer, options, cb) {
        var filter = { labelSelector: 'type=soajs-service' };
        deployer.core.namespaces.services.get({qs: filter}, function (error, serviceList) {
            if (error) return cb(error);

            async.each(serviceList.items, function (oneService, callback) {
                deployer.core.namespaces.services.delete({ name: oneService.metadata.name }, callback);
            }, cb);
        });
    },

    deletePods: function (deployer, options, cb) {
        //force delete all pods for a better cleanup
        deployer.core.namespaces.pods.delete({}, cb);
    },

    deletePreviousServices: function (deployer, cb) {
    	//todo: need to provide --grace-period=0 using the javascript syntax
        lib.deleteDeployments(deployer, {}, function (error) {
            if (error) return cb(error);

            lib.deleteKubeServices(deployer, {}, function (error) {
                if (error) return cb(error);

                lib.deletePods(deployer, {}, cb);
            });
        });
    },

    getServiceIPs: function (serviceName, deployer, replicaCount, counter, cb) {
        if (typeof (counter) === 'function') {
            cb = counter; //counter wasn't passed as param
            counter = 0;
        }

        deployer.core.namespaces.pods.get({}, function (error, podList) {
            if (error) return cb(error);
            var onePod, ips = [];
            podList.items.forEach(function (onePod) {
                if (onePod.metadata.labels['soajs-app'] === serviceName && onePod.status.phase === 'Running') {
                    ips.push({
                        name: onePod.metadata.name,
                        ip: onePod.status.podIP
                    });
                }
            });

            if (ips.length !== replicaCount) {
                //pod containers may not be ready yet
                lib.printProgress('Waiting for ' + serviceName + ' containers to become available', counter++);
                setTimeout(function () {
                    return lib.getServiceIPs(serviceName, deployer, replicaCount, counter, cb);
                }, 1000);
            }
            else {
                utilLog.log(""); //intentional, to force writting a new line.
                return cb(null, ips);
            }
        });
    },

    addMongoInfo: function (services, mongoInfo, cb) {
        var mongoEnv = [];

	    if(config.mongo.prefix && config.mongo.prefix !== ""){
		    mongoEnv.push({name: 'SOAJS_MONGO_PREFIX', value: config.mongo.prefix});
	    }

        if (config.mongo.external) {
            // if (!config.dataLayer.mongo.url || !config.dataLayer.mongo.port) {
            if (!profile.servers[0].host || !profile.servers[0].port) {
                utilLog.log('ERROR: External Mongo information is missing URL or port, make sure SOAJS_MONGO_EXTERNAL_URL and SOAJS_MONGO_EXTERNAL_PORT are set ...');
                return cb('ERROR: missing mongo information');
            }

            mongoEnv.push({ name: 'SOAJS_MONGO_NB', value: profile.servers.length });
	        for(var i =1; i <= profile.servers.length; i++){
		        mongoEnv.push({name: 'SOAJS_MONGO_IP_' + i, value: profile.servers[i].host});
		        mongoEnv.push({name: 'SOAJS_MONGO_PORT_' + i, value: '' + profile.servers[i].port});
	        }

            if (profile.credentials && profile.credentials.username && profile.credentials.password) {
                mongoEnv.push({ name: 'SOAJS_MONGO_USERNAME', value: profile.credentials.username });
                mongoEnv.push({ name: 'SOAJS_MONGO_PASSWORD', value: profile.credentials.password });
	            mongoEnv.push({ name: 'SOAJS_MONGO_AUTH_DB', value: profile.URLParam.authSource });
            }

            if(profile.URLParam.ssl){
	            mongoEnv.push({ name: 'SOAJS_MONGO_SSL', value: profile.URLParam.ssl });
            }
        }
        else {
            mongoEnv.push({ name: 'SOAJS_MONGO_NB', value: '1' });
	        mongoEnv.push({ name: 'SOAJS_MONGO_IP_1', value: profile.servers[0].host});
	        mongoEnv.push({ name: 'SOAJS_MONGO_PORT_1', value: '27017'});
        }

        services.forEach(function (oneService) {
            oneService.deployment.spec.template.spec.containers[0].env = oneService.deployment.spec.template.spec.containers[0].env.concat(mongoEnv);
        });

        return cb(null, services);
    },

    registerNode: function (deployer, swarmConfig, cb) {
        deployer.core.nodes.get({}, function (error, nodeList) {
            if (error) return cb(error);

            async.map(nodeList.items, function (oneNode, callback) {
                var record = {
                    recordType: 'node',
                    id: oneNode.metadata.uid,
                    name: oneNode.metadata.name,
                    ip: getIP(oneNode.status.addresses),
                    kubePort: config.kubernetes.machinePort,
                    availability: ((!oneNode.spec.unschedulable) ? 'active' : 'drained'),
                    role: 'manager',
                    resources: {
                        cpuCount: oneNode.status.capacity.cpu,
                        memory: calcMemory(oneNode.status.capacity.memory)
                    },
                    tokens: {}
                };

                return callback(null, record);
            }, function (error, nodeRecords) {
                if (error) return cb(error);

                for (var i = nodeRecords.length; i >= 0; i--) {
                    if (!nodeRecords[i]) {
                        nodeRecords.splice(i, 1);
                    }
                }

                mongo.insert(config.kubernetes.mongoCollection, nodeRecords, cb);
            });
        });

        function calcMemory (memory) {
			var value = memory.substring(0, memory.length - 2);
			var unit = memory.substring(memory.length - 2);

			if (unit === 'Ki') value += '000';
			else if (unit === 'Mi') value += '000000';

			return parseInt(value);
		}

        function getIP (addresses) {
			var ip = '';
			for (var i = 0; i < addresses.length; i++) {
				if (addresses[i].type === 'LegacyHostIP') {
					ip = addresses[i].address;
				}
			}

			return ip;
		}
    },

    configureEnvDeployer: function (cb) {
        var criteria = {role: 'manager'};
        mongo.find('docker', criteria, function (error, managerNodes) {
            if (error) return cb(error);

            async.map(managerNodes, function (oneNode, callback) {
                return callback(null, oneNode.name);
            }, function (error, nodeHostnames) {
                //get environments records
                mongo.find('environment', {}, function (error, envs) {
                    if (error) return cb(error);

                    async.each(envs, function (oneEnv, callback) {
                        oneEnv.deployer.container.kubernetes.remote.nodes = nodeHostnames;
                        mongo.save('environment', oneEnv, callback);
                    }, cb);
                });
            });
        });
    },

    registerContainers: function (deployer, serviceOptions, cb) {
        var info = {};
        var kubeServiceName = serviceOptions.deployment.metadata.name;
        var serviceGroup, serviceName, serviceEnv;

        if (serviceOptions.deployment.metadata.labels) {
            serviceGroup = serviceOptions.deployment.metadata.labels['soajs.service.group'];
            serviceName = serviceOptions.deployment.metadata.labels['soajs.service'];
            serviceEnv = serviceOptions.deployment.metadata.labels['soajs.env'];
        }

        if (serviceGroup === 'core') {
            info.type = (serviceName === 'controller') ? 'controller' : 'service';
        }
        else if (serviceGroup === 'nginx') {
            info.type = 'nginx';
        }
        else {
            return cb(null, true);
        }

        var replicaCount = serviceOptions.deployment.spec.replicas;

        utilLog.log ('Registering ' + serviceName + ' containers in docker collection ...');

        info.env = serviceEnv;
        info.running = true;
        info.recordType = 'container';

        lib.getServiceIPs(kubeServiceName, deployer, replicaCount, function (error, serviceIPs) {
            if (error) return cb(error);

            async.map(serviceIPs, function (oneServiceInfo, callback) {
                deployer.core.namespaces.pods.get({name: oneServiceInfo.name}, function (error, pod) {
                    if (error) return callback(error);
                    var record = JSON.parse(JSON.stringify(info));
                    record.taskName = oneServiceInfo.name;
                    record.serviceName = kubeServiceName;
                    delete pod.metadata.annotations;
                    record.info = pod;
                    return callback(null, record);
                });
            }, function (error, records) {
                if (error) return cb(error);
                mongo.insert(config.kubernetes.mongoCollection, records, cb);
            });
        });
    },

    closeDbCon: function (cb) {
        mongo.closeDb();
        return cb();
    }
};

module.exports = lib;
<|endoftext|>


<commit_before>'use strict';

// ------------------------------------------------------------------------------------------ Test Dependencies

var _ = require('lodash');
var sinon = require('sinon');
var should = require('chai').should();
var filesize = require('filesize');
var path = require('path');
var errors = require('../../lib/errors');

// ------------------------------------------------------------------------------------------ Mock Dependencies

// ------------------------------------------------------------------------------------------ Test Definition

describe('Errors module', function() {
	var sandbox;

	beforeEach(function() {
		sandbox = sinon.sandbox.create();
	});

	afterEach(function() {
		sandbox.restore();
	})

	// -------------------------------------------------------------------------------------- Testing register

	it('should be possible to register errors using an Array', function() {

		var req = {},
			array = [{
				code: 'MYERROR',
				message: 'My Error'
			}]

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an associative Array', function() {

		var req = {},
			array = [];

		array['MYERROR'] = {
			message: 'My Error'
		}

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Array of Errors', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';
		var array = [ error ];

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Array of Objects', function() {

		var req = {};

		var array = [{
			code: 'MYERROR',
			message: 'My Error'
		}];

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an associative Array of Objects', function() {

		var req = {};

		var array = [];
		array['MYERROR'] = {
			message: 'My Error'
		};

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Error', function() {

		var req = {};
		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var result = req.errors.register(error);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Object', function() {

		var req = {}

		errors(req, null, function() {});
		var result = req.errors.register({
			code: 'MYERROR',
			message: 'My Error'
		});

		result.should.equals(true);

	});

	it('should be possible to register errors using an Object and a separate argument for the error code', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			message: 'My Error'
		}, 'MYERROR');

		result.should.equals(true);

	});

	it('should be possible to register errors using an Error and a separate argument for the error code', function() {

		var req = {},
			error = new Error('My Error');

		errors(req, null, function() {});
		var result = req.errors.register(error, 'MYERROR');
		result.should.equals(true);

	});

	it('should be possible to register errors using a separate argument for the error code, but providing the code in the error Object', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			code: 'MYERROR',
			message: 'My Error'
		}, null);

		result.should.equals(true);

	});

	it('should be possible to register default error using an Array', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register([{
			message: 'My Error'
		}]);

		result.should.equals(true);

	});

	it('should be possible to register default error using an Object', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			message: 'My Error'
		});

		result.should.equals(true);

	});

	it('should be possible to register default error using an Error', function() {

		var req = {},
			error = new Error('My Error');

		errors(req, null, function() {});
		var result = req.errors.register(error);
		result.should.equals(true);

	});

	it('should be possible to register default error using a separate argument for the error code', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			message: 'My Error'
		}, null);

		result.should.equals(true);

	});

	it('should not be possible to register errors using an Array of strings', function() {

		var req = {};

		try {
			errors(req, null, function() {});
			var result = req.errors.register(["Error1", "Error2", "Error3"]);
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	it('should not be possible to register errors using a String', function() {

		var req = {};

		try {
			errors(req, null, function() {});
			var result = req.errors.register("My Error");
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	it('should not be possible to register errors using an invalid type for the error and a separate argument for the error code', function() {

		var req = {};

		try {
			errors(req, null, function() {});
			var result = req.errors.register("My Error",100);
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	it('should not be possible to register errors using more than two arguments', function() {

		var req ={};

		try {
			errors(req, null, function() {});
			var result = req.errors.register("My Error","is","awesome");
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	// -------------------------------------------------------------------------------------- Testing parse & get

	it('should be possible to retrieve registered error message from system error', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		var otherError = new Error('My Other Error');
		otherError.code = 'MYERROR';

		var parsed = req.errors.parse(otherError);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(error);

	});

	it('should return the default error message if there was no matching error registered', function() {

		var req = {};

		var defaultError = new Error('default');
		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register([ error, defaultError ]);
		registered.should.equals(true);

		delete error.code
		var parsed = req.errors.parse(error);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(defaultError);

	});

	it('should return the original error object if there was no matching error nor any default error registered', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		error.code = 'MYOTHERERROR'
		var parsed = req.errors.parse(error);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(error);

	});

	it('should be possible to parse an error with null value', function() {

		var req = {};

		errors(req, null, function() {});
		var parsed = req.errors.parse(null);
		parsed.should.equals(true);
		req.errors.exist().should.equals(false);

	});

	// -------------------------------------------------------------------------------------- Testing purge & reset

	it('should be possible to purge all registered errors', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		req.errors.purge();

		var otherError = new Error('My Other Error');
		otherError.code = 'MYERROR';

		var parsed = req.errors.parse(otherError);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(otherError);

	});

	it('should be possible to reset all registered and parsed errors', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		var otherError = new Error('My Other Error');
		otherError.code = 'MYERROR';

		var parsed = req.errors.parse(otherError);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		req.errors.reset();
		var result = req.errors.get();
		result.length.should.equals(0);

	});

});

<commit_msg>fixes #105 : Add ACL with login screen - Adding missing unit tests for Errors module<commit_after>'use strict';

// ------------------------------------------------------------------------------------------ Test Dependencies

var _ = require('lodash');
var sinon = require('sinon');
var should = require('chai').should();
var filesize = require('filesize');
var path = require('path');
var errors = require('../../lib/errors');

// ------------------------------------------------------------------------------------------ Mock Dependencies

// ------------------------------------------------------------------------------------------ Test Definition

describe('Errors module', function() {
	var sandbox;

	beforeEach(function() {
		sandbox = sinon.sandbox.create();
	});

	afterEach(function() {
		sandbox.restore();
	})

	// -------------------------------------------------------------------------------------- Testing register

	it('should be possible to register errors using an Array', function() {

		var req = {},
			array = [{
				code: 'MYERROR',
				message: 'My Error'
			}]

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an associative Array', function() {

		var req = {},
			array = [];

		array['MYERROR'] = {
			message: 'My Error'
		}

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Array of Errors', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';
		var array = [ error ];

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Array of Objects', function() {

		var req = {};

		var array = [{
			code: 'MYERROR',
			message: 'My Error'
		}];

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an associative Array of Objects', function() {

		var req = {};

		var array = [];
		array['MYERROR'] = {
			message: 'My Error'
		};

		errors(req, null, function() {});
		var result = req.errors.register(array);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Error', function() {

		var req = {};
		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var result = req.errors.register(error);
		result.should.equals(true);

	});

	it('should be possible to register errors using an Object', function() {

		var req = {}

		errors(req, null, function() {});
		var result = req.errors.register({
			code: 'MYERROR',
			message: 'My Error'
		});

		result.should.equals(true);

	});

	it('should be possible to register errors using an Object and a separate argument for the error code', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			message: 'My Error'
		}, 'MYERROR');

		result.should.equals(true);

	});

	it('should be possible to register errors using an Error and a separate argument for the error code', function() {

		var req = {},
			error = new Error('My Error');

		errors(req, null, function() {});
		var result = req.errors.register(error, 'MYERROR');
		result.should.equals(true);

	});

	it('should be possible to register errors using a separate argument for the error code, but providing the code in the error Object', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			code: 'MYERROR',
			message: 'My Error'
		}, null);

		result.should.equals(true);

	});

	it('should be possible to register default error using an Array', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register([{
			message: 'My Error'
		}]);

		result.should.equals(true);

	});

	it('should be possible to register default error using an Object', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			message: 'My Error'
		});

		result.should.equals(true);

	});

	it('should be possible to register default error using an Error', function() {

		var req = {},
			error = new Error('My Error');

		errors(req, null, function() {});
		var result = req.errors.register(error);
		result.should.equals(true);

	});

	it('should be possible to register default error using a separate argument for the error code', function() {

		var req = {};

		errors(req, null, function() {});
		var result = req.errors.register({
			message: 'My Error'
		}, null);

		result.should.equals(true);

	});

	it('should not be possible to register errors using an Array of strings', function() {

		var req = {};

		try {
			errors(req, null, function() {});
			var result = req.errors.register(["Error1", "Error2", "Error3"]);
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	it('should not be possible to register errors using a String', function() {

		var req = {};

		try {
			errors(req, null, function() {});
			var result = req.errors.register("My Error");
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	it('should not be possible to register errors using an invalid type for the error and a separate argument for the error code', function() {

		var req = {};

		try {
			errors(req, null, function() {});
			var result = req.errors.register("My Error",100);
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	it('should not be possible to register errors using more than two arguments', function() {

		var req ={};

		try {
			errors(req, null, function() {});
			var result = req.errors.register("My Error","is","awesome");
			result.should.equals(false);
		} catch(err) {
			should.exist(err);
			err.message.should.equals("Invalid argument exception");
		}

	});

	// -------------------------------------------------------------------------------------- Testing parse & get

	it('should be possible to retrieve registered error message from system error', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		var otherError = new Error('My Other Error');
		otherError.code = 'MYERROR';

		var parsed = req.errors.parse(otherError);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(error);
	});

	it('should return the default error message if there was no matching error registered', function() {

		var req = {};

		var defaultError = new Error('default');
		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register([ error, defaultError ]);
		registered.should.equals(true);

		delete error.code
		var parsed = req.errors.parse(error);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(defaultError);

	});

	it('should return the original error object if there was no matching error nor any default error registered', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		error.code = 'MYOTHERERROR'
		var parsed = req.errors.parse(error);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(error);

	});

	it('should be possible to parse an error with null value', function() {

		var req = {};

		errors(req, null, function() {});
		var parsed = req.errors.parse(null);
		parsed.should.equals(true);
		req.errors.exist().should.equals(false);

	});

	// -------------------------------------------------------------------------------------- Testing purge & reset

	it('should be possible to purge all registered errors', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		req.errors.purge();

		var otherError = new Error('My Other Error');
		otherError.code = 'MYERROR';

		var parsed = req.errors.parse(otherError);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		var result = req.errors.get();
		result.length.should.equals(1);
		result[0].should.equals(otherError);

	});

	it('should be possible to reset all registered and parsed errors', function() {

		var req = {};

		var error = new Error('My Error');
		error.code = 'MYERROR';

		errors(req, null, function() {});
		var registered = req.errors.register(error);
		registered.should.equals(true);

		var otherError = new Error('My Other Error');
		otherError.code = 'MYERROR';

		var parsed = req.errors.parse(otherError);
		parsed.should.equals(true);
		req.errors.exist().should.equals(true);

		req.errors.reset();
		var result = req.errors.get();
		result.length.should.equals(0);

	});

	// -------------------------------------------------------------------------------------- Testing custom errors

	it('should be possible to create a custom error', function(done) {

		var req = {};

		errors(req, null, function() {

			should.exist(req.errors);
			var error = req.errors.custom('code', 'message');
			should.exist(error);
			error.code.should.equals('code');
			error.message.should.equals('message');
			done();

		});

	});

});

<|endoftext|>


<commit_before>/*
 * Korganic
 *
 * By Joshua Lawson - SphyrixNetworks
 *
 * ----------------
 *
 * HTML5 Animation software built for use with KGE (Koron Game Engine) for building
 * 2D Animations and Menus for games built with KGE. For information about KGE
 * please visit http://www.kge.com.au for information about Korganic visit
 * http://kge.com.au/tools/korganic or for any information about the author of
 * either of the mentioned software please visit http://joshualawson.com.au or
 * http://sphyrix.net
 *
 * ----------------
 *
 * e-mail: josh@sphyrix.net
 * twitter: jlawson1988
 *
 * ----------------
 * This software is licensed under the MIT License
 */

var Circle = function(context, settings)
{
    this.context = context;

    this.settings =
    {
        width: settings.width || 0,
        height: settings.height || 0,
        x: settings.x || 0,
        y: settings.y || 0,
        fill: settings.fill || false,
        fill_opacity: settings.fill_opacity || 1,
        stroke: settings.stroke || false,
        stroke_width: settings.stroke_width || 1,
        stroke_opacity: settings.stroke_opacity || 1,
        opacity: settings.opacity || 100
    };

    //Draw Elipse or Circle
    var kappa = .5522848,

    x = this.getX(),
    y = this.getY(),
    ox = (this.getWidth() / 2) * kappa, // control point offset horizontal
    oy = (this.getHeight() / 2) * kappa, // control point offset vertical
    xe = this.getX() + this.getWidth(),           // x-end
    ye = this.getY() + this.getHeight(),           // y-end
    xm = this.getX() + this.getWidth() / 2,       // x-middle
    ym = this.getY() + this.getHeight() / 2;       // y-middle

    this.context.beginPath();
    this.context.moveTo(this.getX(), ym);
    this.context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
    this.context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
    this.context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
    this.context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);

    //Check if there is an overall opacity, if there is adjust the individual opacitys to include the overall opacity
    if(this.getOpacity() !== 100)
    {
        this.setStrokeOpacity(this.getStrokeOpacity() * (1 - (parseFloat(this.getOpacity()) / 100.0)));
        this.setFillOpacity(this.getFillOpacity() * (1 - (parseFloat(this.getOpacity()) / 100.0)));
    }

    //If fill is set or stroke is set
    if(this.getFill() !== false)
    {
        this.context.fillStyle = "rgba(" + hexToRgb(this.getFill()).r + ", " + hexToRgb(this.getFill()).g + ", " + hexToRgb(this.getFill()).b + ", " + this.getFillOpacity() + ")";
        this.context.fill();
    }
    if(this.getStroke !== false)
    {
        this.context.strokeStyle = "rgba(" + hexToRgb(this.getStroke()).r + ", " + hexToRgb(this.getStroke()).g + ", " + hexToRgb(this.getStroke()).b + ", " + this.getStrokeOpacity() + ")";
        this.context.lineWidth = this.getStrokeWidth();
        this.context.stroke();
    }

    this.context.closePath();

};

Circle.prototype = {
    constructor: Circle,

    getWidth: function(){
        return this.settings.width;
    },

    setWidth: function(width){
        this.settings.width = width;
    },

    getHeight: function(){
        return this.settings.height;
    },

    setHeight: function(height){
        this.settings.height = height;
    },

    getX: function(){
        return this.settings.x;
    },

    setX: function(x){
        this.settings.x = x;
    },

    getY: function(){
        return this.settings.y;
    },

    setY: function(y){
        this.settings.y = y;
    },

    getFill: function(){
        return this.settings.fill;
    },

    setFill: function(fill){
        this.settings.fill = fill;
    },

    getFillOpacity: function(){
        return this.settings.fill_opacity;
    },

    setFillOpacity: function(fill_opacity){
        this.settings.fill_opacity = fill_opacity;
    },

    getStroke: function(){
        return this.settings.stroke;
    },

    setStroke: function(stroke){
        this.settings.stroke = stroke;
    },

    getStrokeOpacity: function(){
        return this.settings.stroke_opacity;
    },

    setStrokeOpacity: function(stroke_opacity){
        this.settings.stroke_opacity = stroke_opacity;
    },

    getOpacity: function(){
        return this.settings.opacity;
    },

    setOpacity: function(opacity){
        this.settings.opacity = opacity;
    },

    getStrokeWidth: function(){
        return this.settings.stroke_width;
    },

    setStrokeWidth: function(stroke_width){
        this.settings.stroke_width = stroke_width;
    }

};<commit_msg>Changed the way Circle Draws<commit_after>/*
 * Korganic
 *
 * By Joshua Lawson - SphyrixNetworks
 *
 * ----------------
 *
 * HTML5 Animation software built for use with KGE (Koron Game Engine) for building
 * 2D Animations and Menus for games built with KGE. For information about KGE
 * please visit http://www.kge.com.au for information about Korganic visit
 * http://kge.com.au/tools/korganic or for any information about the author of
 * either of the mentioned software please visit http://joshualawson.com.au or
 * http://sphyrix.net
 *
 * ----------------
 *
 * e-mail: josh@sphyrix.net
 * twitter: jlawson1988
 *
 * ----------------
 * This software is licensed under the MIT License
 */

var Circle = function(context, settings)
{
    this.context = context;

    this.settings =
    {
        width: settings.width || 0,
        height: settings.height || 0,
        x: settings.x || 0,
        y: settings.y || 0,
        fill: settings.fill || false,
        fill_opacity: settings.fill_opacity || 1,
        stroke: settings.stroke || false,
        stroke_width: settings.stroke_width || 1,
        stroke_opacity: settings.stroke_opacity || 1,
        opacity: settings.opacity || 100,
        rotation: settings.rotation || 0
    };

    this.draw();

};

Circle.prototype = {
    constructor: Circle,

    getWidth: function(){
        return this.settings.width;
    },

    setWidth: function(width){
        this.settings.width = width;
    },

    getHeight: function(){
        return this.settings.height;
    },

    setHeight: function(height){
        this.settings.height = height;
    },

    getX: function(){
        return this.settings.x;
    },

    setX: function(x){
        this.settings.x = x;
    },

    getY: function(){
        return this.settings.y;
    },

    setY: function(y){
        this.settings.y = y;
    },

    getFill: function(){
        return this.settings.fill;
    },

    setFill: function(fill){
        this.settings.fill = fill;
    },

    getFillOpacity: function(){
        return this.settings.fill_opacity;
    },

    setFillOpacity: function(fill_opacity){
        this.settings.fill_opacity = fill_opacity;
    },

    getStroke: function(){
        return this.settings.stroke;
    },

    setStroke: function(stroke){
        this.settings.stroke = stroke;
    },

    getStrokeOpacity: function(){
        return this.settings.stroke_opacity;
    },

    setStrokeOpacity: function(stroke_opacity){
        this.settings.stroke_opacity = stroke_opacity;
    },

    getOpacity: function(){
        return this.settings.opacity;
    },

    setOpacity: function(opacity){
        this.settings.opacity = opacity;
    },

    getStrokeWidth: function(){
        return this.settings.stroke_width;
    },

    setStrokeWidth: function(stroke_width){
        this.settings.stroke_width = stroke_width;
    },

    getRotation: function()
    {
        return this.settings.rotation;
    },

    setRotation: function(rotation)
    {
        this.settings.rotation = rotation;
    },

    draw: function()
    {
        //Draw Elipse or Circle
        var kappa = .5522848,

        x = this.getX(),
        y = this.getY(),
        ox = (this.getWidth() / 2) * kappa, // control point offset horizontal
        oy = (this.getHeight() / 2) * kappa, // control point offset vertical
        xe = this.getX() + this.getWidth(),           // x-end
        ye = this.getY() + this.getHeight(),           // y-end
        xm = this.getX() + this.getWidth() / 2,       // x-middle
        ym = this.getY() + this.getHeight() / 2;       // y-middle

        this.context.beginPath();
        this.context.moveTo(this.getX(), ym);
        this.context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
        this.context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
        this.context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
        this.context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);

        //Check if there is an overall opacity, if there is adjust the individual opacitys to include the overall opacity
        if(this.getOpacity() !== 100)
        {
            this.setStrokeOpacity(this.getStrokeOpacity() * (1 - (parseFloat(this.getOpacity()) / 100.0)));
            this.setFillOpacity(this.getFillOpacity() * (1 - (parseFloat(this.getOpacity()) / 100.0)));
        }

        //If fill is set or stroke is set
        if(this.getFill() !== false)
        {
            this.context.fillStyle = "rgba(" + hexToRgb(this.getFill()).r + ", " + hexToRgb(this.getFill()).g + ", " + hexToRgb(this.getFill()).b + ", " + this.getFillOpacity() + ")";
            this.context.fill();
        }
        if(this.getStroke !== false)
        {
            this.context.strokeStyle = "rgba(" + hexToRgb(this.getStroke()).r + ", " + hexToRgb(this.getStroke()).g + ", " + hexToRgb(this.getStroke()).b + ", " + this.getStrokeOpacity() + ")";
            this.context.lineWidth = this.getStrokeWidth();
            this.context.stroke();
        }

        this.context.closePath();

    }

};<|endoftext|>


<commit_before>/*global describe, require, it, expect, beforeEach, afterEach, console, jasmine */
var underTest = require('../src/commands/add-scheduled-event'),
	create = require('../src/commands/create'),
	shell = require('shelljs'),
	tmppath = require('../src/util/tmppath'),
	fs = require('fs'),
	path = require('path'),
	aws = require('aws-sdk'),
	Promise = require('bluebird'),
	awsRegion = 'us-east-1';
describe('addScheduledEvent', function () {
	'use strict';
	var workingdir, testRunName, newObjects, s3, config, events, lambda, eventConfig;
	beforeEach(function () {
		var eventFile;
		workingdir = tmppath();
		s3 = Promise.promisifyAll(new aws.S3());
		events = Promise.promisifyAll(new aws.CloudWatchEvents({region: awsRegion}));
		lambda = Promise.promisifyAll(new aws.Lambda({region: awsRegion}), {suffix: 'Promise'});
		testRunName = 'test' + Date.now();
		newObjects = {workingdir: workingdir};
		jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
		shell.mkdir(workingdir);
		eventFile = path.join(workingdir, 'test-event.json');
		eventConfig = {
			name: 'Mike'
		};
		fs.writeFileSync(eventFile, JSON.stringify(eventConfig), 'utf8');
		config = {
			event: eventFile,
			source: workingdir,
			name: testRunName + '-scheduled-event',
			schedule: 'rate(5 minutes)'
		};

	});
	afterEach(function (done) {
		this.destroyObjects(newObjects).catch(function (err) {
			console.log('error cleaning up', err);
		}).finally(done);
	});
	it('fails when the event file is not defined in options', function (done) {
		config.event = '';
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('event file not specified. please provide it with --event');
			done();
		});
	});
	it('fails when the event name is not defined in options', function (done) {
		config.name = '';
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('event name not specified. please provide it with --name');
			done();
		});
	});
	it('fails when the event schedule is not defined in options', function (done) {
		config.schedule = '';
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('event schedule not specified. please provide it with --schedule');
			done();
		});
	});

	it('fails when the source dir does not contain the project config file', function (done) {
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('claudia.json does not exist in the source folder');
			done();
		});
	});
	it('fails when the project config file does not contain the lambda name', function (done) {
		fs.writeFileSync(path.join(workingdir, 'claudia.json'), '{}', 'utf8');
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('invalid configuration -- lambda.name missing from claudia.json');
			done();
		});
	});
	it('fails when the project config file does not contain the lambda region', function (done) {
		fs.writeFileSync(path.join(workingdir, 'claudia.json'), JSON.stringify({lambda: {name: 'xxx'}}), 'utf8');
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('invalid configuration -- lambda.region missing from claudia.json');
			done();
		});
	});
	it('fails when the project config file does not contain the lambda role', function (done) {
		fs.writeFileSync(path.join(workingdir, 'claudia.json'), JSON.stringify({lambda: {name: 'xxx', region: 'abc'}}), 'utf8');
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('invalid configuration -- lambda.role missing from claudia.json');
			done();
		});
	});

	describe('when params are valid', function () {
		var createConfig,
			createLambda = function () {
				return create(createConfig).then(function (result) {
					newObjects.lambdaRole = result.lambda && result.lambda.role;
					newObjects.lambdaFunction = result.lambda && result.lambda.name;
					newObjects.eventRule = testRunName + '-scheduled-event';
				});
			};
		beforeEach(function () {
			createConfig = {name: testRunName, region: awsRegion, source: workingdir, handler: 'main.handler'};
			shell.cp('-r', 'spec/test-projects/echo/*', workingdir);
		});
		it('uses the schedule expression to configure the rule', function (done) {
			createLambda()
			.then(function () {
				return underTest(config);
			}).then(function () {
				return events.describeRuleAsync({
					Name: newObjects.eventRule
				});
			}).then(function (eventConfig) {
				expect(eventConfig.State).toEqual('ENABLED');
				expect(eventConfig.ScheduleExpression).toEqual('rate(5 minutes)');
			}).then(done, done.fail);
		});
		it('uses the rate argument as a shorthand for the schedule expression', function (done) {
			config.schedule = '';
			config.rate = '10 minutes';
			createLambda()
			.then(function () {
				return underTest(config);
			}).then(function () {
				return events.describeRuleAsync({
					Name: newObjects.eventRule
				});
			}).then(function (eventConfig) {
				expect(eventConfig.State).toEqual('ENABLED');
				expect(eventConfig.ScheduleExpression).toEqual('rate(10 minutes)');
			}).then(done, done.fail);
		});
		it('uses the cron argument as a shorthand for the schedule expression', function (done) {
			config.schedule = '';
			config.cron = '0 8 1 * ? *';
			createLambda()
			.then(function () {
				return underTest(config);
			}).then(function () {
				return events.describeRuleAsync({
					Name: newObjects.eventRule
				});
			}).then(function (eventConfig) {
				expect(eventConfig.State).toEqual('ENABLED');
				expect(eventConfig.ScheduleExpression).toEqual('cron(0 8 1 * ? *)');
			}).then(done, done.fail);
		});
		it('sets up privileges and rule notifications', function (done) {
			var functionArn;

			createLambda()
			.then(function () {
				return lambda.getFunctionConfigurationPromise({
					FunctionName: testRunName
				});
			}).then(function (lambdaResult) {
				functionArn = lambdaResult.FunctionArn;
			}).then(function () {
				return underTest(config);
			}).then(function () {
				return events.listTargetsByRuleAsync({Rule: config.name});
			}).then(function (config) {
				expect(config.Targets.length).toBe(1);
				expect(config.Targets[0].Arn).toEqual(functionArn);
				expect(eventConfig).toEqual(JSON.parse(config.Targets[0].Input));
			}).then(done, done.fail);
		});
		it('binds to an alias, if the version is provided', function (done) {
			var functionArn;
			createConfig.version = 'special';
			config.version = 'special';

			createLambda()
			.then(function () {
				return lambda.getFunctionConfigurationPromise({
					FunctionName: testRunName,
					Qualifier: 'special'
				});
			}).then(function (lambdaResult) {
				functionArn = lambdaResult.FunctionArn;
				console.log(functionArn);
			}).then(function () {
				return underTest(config);
			}).then(function () {
				return events.listTargetsByRuleAsync({Rule: config.name});
			}).then(function (config) {
				expect(config.Targets.length).toBe(1);
				expect(config.Targets[0].Arn).toEqual(functionArn);
				expect(eventConfig).toEqual(JSON.parse(config.Targets[0].Input));
			}).then(done, done.fail);
		});
	});
});
<commit_msg>Updated test for role check in addScheduledEvent.<commit_after>/*global describe, require, it, expect, beforeEach, afterEach, console, jasmine */
var underTest = require('../src/commands/add-scheduled-event'),
	create = require('../src/commands/create'),
	shell = require('shelljs'),
	tmppath = require('../src/util/tmppath'),
	fs = require('fs'),
	path = require('path'),
	aws = require('aws-sdk'),
	Promise = require('bluebird'),
	awsRegion = 'us-east-1';
describe('addScheduledEvent', function () {
	'use strict';
	var workingdir, testRunName, newObjects, s3, config, events, lambda, eventConfig;
	beforeEach(function () {
		var eventFile;
		workingdir = tmppath();
		s3 = Promise.promisifyAll(new aws.S3());
		events = Promise.promisifyAll(new aws.CloudWatchEvents({region: awsRegion}));
		lambda = Promise.promisifyAll(new aws.Lambda({region: awsRegion}), {suffix: 'Promise'});
		testRunName = 'test' + Date.now();
		newObjects = {workingdir: workingdir};
		jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
		shell.mkdir(workingdir);
		eventFile = path.join(workingdir, 'test-event.json');
		eventConfig = {
			name: 'Mike'
		};
		fs.writeFileSync(eventFile, JSON.stringify(eventConfig), 'utf8');
		config = {
			event: eventFile,
			source: workingdir,
			name: testRunName + '-scheduled-event',
			schedule: 'rate(5 minutes)'
		};

	});
	afterEach(function (done) {
		this.destroyObjects(newObjects).catch(function (err) {
			console.log('error cleaning up', err);
		}).finally(done);
	});
	it('fails when the event file is not defined in options', function (done) {
		config.event = '';
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('event file not specified. please provide it with --event');
			done();
		});
	});
	it('fails when the event name is not defined in options', function (done) {
		config.name = '';
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('event name not specified. please provide it with --name');
			done();
		});
	});
	it('fails when the event schedule is not defined in options', function (done) {
		config.schedule = '';
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('event schedule not specified. please provide it with --schedule');
			done();
		});
	});

	it('fails when the source dir does not contain the project config file', function (done) {
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('claudia.json does not exist in the source folder');
			done();
		});
	});
	it('fails when the project config file does not contain the lambda name', function (done) {
		fs.writeFileSync(path.join(workingdir, 'claudia.json'), '{}', 'utf8');
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('invalid configuration -- lambda.name missing from claudia.json');
			done();
		});
	});
	it('fails when the project config file does not contain the lambda region', function (done) {
		fs.writeFileSync(path.join(workingdir, 'claudia.json'), JSON.stringify({lambda: {name: 'xxx'}}), 'utf8');
		underTest(config).then(done.fail, function (reason) {
			expect(reason).toEqual('invalid configuration -- lambda.region missing from claudia.json');
			done();
		});
	});
	it('does not fail when the project config file does not contain the lambda role', function (done) {
		fs.writeFileSync(path.join(workingdir, 'claudia.json'), JSON.stringify({lambda: {name: 'xxx', region: 'abc'}}), 'utf8');
		underTest(config).then(done, done.fail);
	});

	describe('when params are valid', function () {
		var createConfig,
			createLambda = function () {
				return create(createConfig).then(function (result) {
					newObjects.lambdaRole = result.lambda && result.lambda.role;
					newObjects.lambdaFunction = result.lambda && result.lambda.name;
					newObjects.eventRule = testRunName + '-scheduled-event';
				});
			};
		beforeEach(function () {
			createConfig = {name: testRunName, region: awsRegion, source: workingdir, handler: 'main.handler'};
			shell.cp('-r', 'spec/test-projects/echo/*', workingdir);
		});
		it('uses the schedule expression to configure the rule', function (done) {
			createLambda()
			.then(function () {
				return underTest(config);
			}).then(function () {
				return events.describeRuleAsync({
					Name: newObjects.eventRule
				});
			}).then(function (eventConfig) {
				expect(eventConfig.State).toEqual('ENABLED');
				expect(eventConfig.ScheduleExpression).toEqual('rate(5 minutes)');
			}).then(done, done.fail);
		});
		it('uses the rate argument as a shorthand for the schedule expression', function (done) {
			config.schedule = '';
			config.rate = '10 minutes';
			createLambda()
			.then(function () {
				return underTest(config);
			}).then(function () {
				return events.describeRuleAsync({
					Name: newObjects.eventRule
				});
			}).then(function (eventConfig) {
				expect(eventConfig.State).toEqual('ENABLED');
				expect(eventConfig.ScheduleExpression).toEqual('rate(10 minutes)');
			}).then(done, done.fail);
		});
		it('uses the cron argument as a shorthand for the schedule expression', function (done) {
			config.schedule = '';
			config.cron = '0 8 1 * ? *';
			createLambda()
			.then(function () {
				return underTest(config);
			}).then(function () {
				return events.describeRuleAsync({
					Name: newObjects.eventRule
				});
			}).then(function (eventConfig) {
				expect(eventConfig.State).toEqual('ENABLED');
				expect(eventConfig.ScheduleExpression).toEqual('cron(0 8 1 * ? *)');
			}).then(done, done.fail);
		});
		it('sets up privileges and rule notifications', function (done) {
			var functionArn;

			createLambda()
			.then(function () {
				return lambda.getFunctionConfigurationPromise({
					FunctionName: testRunName
				});
			}).then(function (lambdaResult) {
				functionArn = lambdaResult.FunctionArn;
			}).then(function () {
				return underTest(config);
			}).then(function () {
				return events.listTargetsByRuleAsync({Rule: config.name});
			}).then(function (config) {
				expect(config.Targets.length).toBe(1);
				expect(config.Targets[0].Arn).toEqual(functionArn);
				expect(eventConfig).toEqual(JSON.parse(config.Targets[0].Input));
			}).then(done, done.fail);
		});
		it('binds to an alias, if the version is provided', function (done) {
			var functionArn;
			createConfig.version = 'special';
			config.version = 'special';

			createLambda()
			.then(function () {
				return lambda.getFunctionConfigurationPromise({
					FunctionName: testRunName,
					Qualifier: 'special'
				});
			}).then(function (lambdaResult) {
				functionArn = lambdaResult.FunctionArn;
				console.log(functionArn);
			}).then(function () {
				return underTest(config);
			}).then(function () {
				return events.listTargetsByRuleAsync({Rule: config.name});
			}).then(function (config) {
				expect(config.Targets.length).toBe(1);
				expect(config.Targets[0].Arn).toEqual(functionArn);
				expect(eventConfig).toEqual(JSON.parse(config.Targets[0].Input));
			}).then(done, done.fail);
		});
	});
});
<|endoftext|>


<commit_before>(function(){
  'use strict';
  var module = angular.module('app', ['onsen']);

  module.controller('AppController', function($scope) {
    $scope.doSomething = function() {
      setTimeout(function() {
        alert('Soon you can use this sick new feature!');
      }, 100);
    };

    document.addEventListener('deviceready', onDeviceReady, false);

    var onSuccess = function(acceleration) {
      if (Math.abs(acceleration.x) > 1 ||
          Math.abs(acceleration.y) > 1 ||
          Math.abs(acceleration.z) > 1) {
            var newSurvey = {
              title: accelerometer.timestamp,
              desc: 'Triggered by shaking the device.',
              label: '[General Health]',
              questions: [
                          {
                            type: 'radio',
                            question: 'What is you favourite CS course?',
                            options: ['CS91','CS21','CS97']
                          },
                          {
                            type: 'text',
                            question: 'Is this a super cool project?'

                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:'
                          }
              ]
            };
            alert(JSON.stringify(this));
      }
    };
    var onS = onSuccess.bind($scope);

    function onError() {
        alert('onError!');
    }

    var options = { frequency: 3000 };

    function onDeviceReady() {
      var watchID = navigator.accelerometer.watchAcceleration(onS, onError, options);
    }

  });

  module.controller('DetailController', function($scope, $surveys) {
    $scope.item = $surveys.selectedItem;
  });

  module.controller('MasterController', function($scope, $surveys) {
    $scope.items = $surveys.items;

    $scope.showDetail = function(index) {
      var selectedItem = $scope.items[index];
      $surveys.selectedItem = selectedItem;
      $scope.ons.navigator.pushPage('detail.html', {title : selectedItem.title});
    };

    $scope.addSurvey = function() {
      setTimeout(function() {
        $scope.items = [
          {
              title: 'Survey I',
              desc: 'This could be the coolest, most relevant survey ever.',
              label: '[Mental Health]',
              questions: [
                          {
                            type: 'radio',
                            question: 'What is you favourite CS course?',
                            options: ['CS91','CS21','CS97']
                          },
                          {
                            type: 'text',
                            question: 'Is this a super cool project?'

                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:',
                            max: 100,
                            min: 0
                          }
              ]
          },
          {
              title: 'Survey II',
              desc: 'This could be the second coolest, most relevant survey ever.',
              label: '[Physical Health]',
              questions: [
                          {
                            type: 'radio',
                            question: 'What is you favourite CS course?',
                            options: ['CS91','CS21','CS97']
                          },
                          {
                            type: 'text',
                            question: 'Is this a super cool project?'

                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:',
                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:',
                          }
              ]
          }
        ];
        $scope.$apply();
      }, 2000);
    };

    $scope.addSurvey();

  });

  module.factory('$surveys', function() {
      var surveys = {};
      surveys.items = [];
      return surveys;
  });
})();<commit_msg>Fixed acceleration errors. Aslo, important to note what certificates for android apps are different between computers. You have to uninstall the old app prior to adding your own local copy.<commit_after>(function(){
  'use strict';
  var module = angular.module('app', ['onsen']);

  module.controller('AppController', function($scope) {
    $scope.doSomething = function() {
      setTimeout(function() {
        alert('Soon you can use this sick new feature!');
      }, 100);
    };

    document.addEventListener('deviceready', onDeviceReady, false);

    var onSuccess = function(acceleration) {
      if (Math.abs(acceleration.x) > 10 ||
          Math.abs(acceleration.y) > 10 ||
          Math.abs(acceleration.z) > 10) {
            var newSurvey = {
              title: acceleration.timestamp,
              desc: 'Triggered by shaking the device.',
              label: '[General Health]',
              questions: [
                          {
                            type: 'radio',
                            question: 'What is you favourite CS course?',
                            options: ['CS91','CS21','CS97']
                          },
                          {
                            type: 'text',
                            question: 'Is this a super cool project?'

                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:'
                          }
              ]
            };
            alert("WE ARE ACCELERATING WEEEEEEE");
      }
    };

    function onError() {
        alert('onError!');
    }

    var options = { frequency: 3000 };

    function onDeviceReady() {
      console.log(navigator.accelerometer);
      var watchID = navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
    }

  });

  module.controller('DetailController', function($scope, $surveys) {
    $scope.item = $surveys.selectedItem;
  });

  module.controller('MasterController', function($scope, $surveys) {
    $scope.items = $surveys.items;

    $scope.showDetail = function(index) {
      var selectedItem = $scope.items[index];
      $surveys.selectedItem = selectedItem;
      $scope.ons.navigator.pushPage('detail.html', {title : selectedItem.title});
    };

    $scope.addSurvey = function() {
      setTimeout(function() {
        $scope.items = [
          {
              title: 'Survey I',
              desc: 'This could be the coolest, most relevant survey ever.',
              label: '[Mental Health]',
              questions: [
                          {
                            type: 'radio',
                            question: 'What is you favourite CS course?',
                            options: ['CS91','CS21','CS97']
                          },
                          {
                            type: 'text',
                            question: 'Is this a super cool project?'

                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:',
                            max: 100,
                            min: 0
                          }
              ]
          },
          {
              title: 'Survey II',
              desc: 'This could be the second coolest, most relevant survey ever.',
              label: '[Physical Health]',
              questions: [
                          {
                            type: 'radio',
                            question: 'What is you favourite CS course?',
                            options: ['CS91','CS21','CS97']
                          },
                          {
                            type: 'text',
                            question: 'Is this a super cool project?'

                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:',
                          },
                          {
                            type: 'range',
                            question: 'Drag the thing to do the stuff based on your feelings:',
                          }
              ]
          }
        ];
        $scope.$apply();
      }, 2000);
    };

    $scope.addSurvey();

  });

  module.factory('$surveys', function() {
      var surveys = {};
      surveys.items = [];
      return surveys;
  });
})();<|endoftext|>