RackHD/on-tasks

View on GitHub
lib/services/base-obm-service.js

Summary

Maintainability
D
1 day
Test Coverage
// Copyright 2015, EMC, Inc.

'use strict';

var di = require('di');

module.exports = BaseObmServiceFactory;

di.annotate(BaseObmServiceFactory, new di.Provide('OBM.base'));
di.annotate(BaseObmServiceFactory,
    new di.Inject(
        'Assert', 'Promise', '_', 'Logger', 'ChildProcess'
    )
);

function BaseObmServiceFactory (assert, Promise, _, Logger, ChildProcess) {
    var logger = Logger.initialize(BaseObmServiceFactory);

    /**
     *
     * @param {Object} config
     * @constructor
     */
    function BaseObmService(options) {
        options = options || {};
        options.retries = options.retries || 0;
        options.delay = options.delay || 0;
        options.config = options.config || {};
        this.options = options;
    }

    BaseObmService.prototype.identifyOn = function() {
        var error = new Error('identifyOn not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };

    BaseObmService.prototype.identifyOff = function() {
        var error = new Error('identifyOff not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };
    
    BaseObmService.prototype.identifyBlink = function() {
        var error = new Error('identifyBlink not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };

    BaseObmService.prototype.reboot = function() {
        var error = new Error('reboot not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };

    BaseObmService.prototype.powerOn = function() {
        var error = new Error('powerOn not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };

    BaseObmService.prototype.powerOff = function() {
        var error = new Error('powerOff not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };

    BaseObmService.prototype.powerStatus = function() {
        var error = new Error('powerStatus not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };

    BaseObmService.prototype.setBootPxe = function() {
        var error = new Error('setBootPxe not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };

    BaseObmService.prototype.clearSEL = function() {
        var error = new Error('clearSEL not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };
    
    BaseObmService.prototype.NMI = function() {
        var error = new Error('NMI not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };
    
    BaseObmService.prototype.powerButton = function() {
        var error = new Error('powerButton not implemented');
        error.name = 'ObmCommandNotImplementedError';
        return Promise.reject(error);
    };


    // NOTE: makes updates to the config object via reference, because we all
    // miss coding in C, don't we?
    BaseObmService.prototype.validateAndSanitize = function() {
        var config = this.options.config;
        var missing = [];

        _.forEach(this.requiredKeys, function(key) {
            if (!_.has(config, key)) {
                missing.push(key);
            }
            if (!_.contains(['password', 'host', 'port'], key) && typeof config[key] === 'string') {
                // Sanitize any spaces the user decided to escape (e.g. copy/paste of a path)
                // These will get passed to us as '\\ ', meaning the slash is
                // escaped, which is obviously not good.
                config[key] = config[key].replace(/\\+\s/g, ' ');
            }
        });

        if (missing.length !== 0) {
            logger.error('Invalid OBM Configuration.', {
                missing: missing
            });
        }

        return missing.length === 0;
    };

    BaseObmService.prototype.run = function(options) {
        var self = this;
        assert.object(options);
        assert.string(options.command);
        return Promise.resolve()
        .then(function() {
            self.childProcess = new ChildProcess(
                    options.command, options.args, options.env, options.code);
            return self.childProcess.run({ retries: options.retries, delay: options.delay });
        });
    };

    BaseObmService.prototype.kill = function() {
        if (this.childProcess) {
            this.childProcess.killSafe();
        }
    };

    BaseObmService.create = function(Constructor, options) {
        assert.ok(Constructor);
        if (!(Constructor.prototype instanceof BaseObmService)) {
            throw new Error("Constructor " + Constructor.name + " is not " +
                    "an instance of BaseObmService");
        }
        var instance = new Constructor(options);
        if (instance.validateAndSanitize()) {
            return instance;
        } else {
            return null;
        }
    };

    return BaseObmService;
}