RackHD/on-tasks

View on GitHub
lib/jobs/ucs-service-profile-discovery.js

Summary

Maintainability
F
3 days
Test Coverage
//Copyright 2017, Dell EMC, Inc.

'use strict';

var di = require('di'),
    urlParse = require('url-parse');

module.exports = UcsServiceProfileDiscoveryJobFactory;
di.annotate(UcsServiceProfileDiscoveryJobFactory,
    new di.Provide('Job.Ucs.Service.Profile.Discovery'));
di.annotate(UcsServiceProfileDiscoveryJobFactory, new di.Inject(
    'Job.Base',
    'Logger',
    'Promise',
    'Assert',
    'Util',
    'Services.Waterline',
    'Services.Encryption',
    '_',
    'JobUtils.UcsTool',
    'Constants'
));

function UcsServiceProfileDiscoveryJobFactory(
    BaseJob,
    Logger,
    Promise,
    assert,
    util,
    waterline,
    encryption,
    _,
    UcsTool,
    Constants
) {
    var logger = Logger.initialize(UcsServiceProfileDiscoveryJobFactory);

    /**
     * @param {Object} options task options object
     * @param {Object} context graph context object
     * @param {String} taskId running task identifier
     * @constructor
     */
    function UcsServiceProfileDiscoveryJob(options, context, taskId) {
        UcsServiceProfileDiscoveryJob.super_.call(this,
                                   logger,
                                   options,
                                   context,
                                   taskId);

        assert.object(this.options);
        assert.string(this.options.uri);
        assert.string(this.options.username);
        assert.string(this.options.password);
        assert.string(this.options.ucs);
        var parse = urlParse(this.options.uri);
        var protocol = parse.protocol.replace(':','').trim();
        this.settings = {
            uri: parse.href,
            host: parse.host.split(':')[0],
            root: parse.pathname,
            port: parse.port,
            protocol: protocol,
            ucsUser: this.options.username,
            ucsPassword: this.options.password,
            ucsHost: this.options.ucs,
            verifySSL: this.options.verifySSL || false
        };
        this.ucs = new UcsTool();
        this.ucs.settings = this.settings;
    }
    
    util.inherits(UcsServiceProfileDiscoveryJob, BaseJob);

    /**
     * @memberOf UcsServiceProfileDiscoveryJob
     */
    UcsServiceProfileDiscoveryJob.prototype._run = function() {
        var self = this;
        
        return self.getRoot()
            .then(function(root) {
                return self.createServiceProfile(root);
            })
            .then(function(logicalServers) {
                self.context.logicalNodeList = (self.context.logicalNodeList || []).concat(
                    _.map(logicalServers, _.property('id')));
                self._done();
            })
            .catch(function(err) {
                self._done(err);
            });
    };

    /**
     * @function getRoot
     * @description return all the elements from the Cisco UCS Manager that RackHD cares about
     */
    UcsServiceProfileDiscoveryJob.prototype.getRoot = function () {
        var url = "/serviceProfile";
        return this.ucs.clientRequest(url)
            .then(function(response) {
                return response.body;
            });
    };

    /**
     * @function createServiceProfile
     * @description discovers all the service profiles in the Cisco UCS
     */
    UcsServiceProfileDiscoveryJob.prototype.createServiceProfile = function (root) {
        var self = this;
        var url = "/serviceProfile";
        return Promise.try(function () {
            if (_.has(root, 'ServiceProfile')) {
                return self.ucs.clientRequest(url)
                    .then(function(res) {
                        assert.object(res);
                        return res.body;
                    })
                    .then(function(data) {
                        assert.object(data);
                        return data['ServiceProfile']['members'];
                    })
                    .map(function(members){
                        return self.createUpdateNode(members, Constants.NodeTypes.Compute)
                        .spread(function(newNode){
                            var relations = [{
                                relationType: 'associatedTo',
                                targets: [newNode.associatedServer]
                            }];
                            return self.updateRelations(newNode.id, relations);
                        });
                    });
            }else{
                logger.warning('No Logical Servers found');
                return;
            }
        });
    };

    UcsServiceProfileDiscoveryJob.prototype.updateRelations = function(nodeId, relations) {
        // Update existing node with new relations or create one
        return waterline.nodes.needOneById(nodeId)
            .then(function(curNode) {
                relations = _.uniq(relations.concat(curNode.relations), 'relationType');
                return waterline.nodes.updateOne(
                    { id: curNode.id },
                    { relations: relations });
            });
    };

    UcsServiceProfileDiscoveryJob.prototype.createUpdateNode = function(data, type) {

        var self = this;
        var config = Object.assign({}, self.settings);

        assert.string(data.name);
        assert.string(data.path);
        var ids = [ config.ucsHost + ':' + data.path ];

        var obm = {
            config: config,
            service: 'ucs-obm-service'
        };
        var node = {
            type: type,
            name: data.name,
            identifiers: ids,
            relations : []
        };
        // Update existing node  or create a new one
        return waterline.nodes.needOne({identifiers:ids})
            .then(function(curNode) {
                return waterline.nodes.updateOne(
                    { id: curNode.id },
                    node
                );
            })
            .catch(function(error) {
                if (error.name === 'NotFoundError') {
                    return waterline.nodes.create(node);
                }
                throw error;
            })
            .then(function(data){
                return [data, waterline.obms.upsertByNode(data.id,obm)];
            });
    };

    return UcsServiceProfileDiscoveryJob;
}