RackHD/on-tasks

View on GitHub
lib/jobs/dell-wsman-post-discovery.js

Summary

Maintainability
F
3 days
Test Coverage
// Copyright 2016, DELL, Inc.

'use strict';

var di = require('di');

module.exports = DellWsmanPostDiscoveryJobFactory;
di.annotate(DellWsmanPostDiscoveryJobFactory, new di.Provide('Job.Dell.Wsman.PostDiscovery'));
di.annotate(DellWsmanPostDiscoveryJobFactory, new di.Inject(
    'Job.Base',
    'Logger',
    'Promise',
    'Assert',
    'Util',
    'Services.Waterline',
    'Services.Lookup',
    'Services.Configuration',
    '_',
    'Errors',
    'JobUtils.WorkflowTool',
    'Protocol.Events',
    'validator',
    'JobUtils.RedfishTool'
));

function DellWsmanPostDiscoveryJobFactory(
    BaseJob,
    Logger,
    Promise,
    assert,
    util,
    waterline,
    lookup,
    configuration,
    _,
    errors,
    workflowTool,
    eventsProtocol,
    validator,
    RedfishTool
) {
    var logger = Logger.initialize(DellWsmanPostDiscoveryJobFactory);

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

        assert.object(this.options);
        this.user = options.credentials.userName;
        this.password = options.credentials.password;
        this.nodeId = this.context.target || undefined;
        this.nodeData = options.data || undefined;
        this.redfish = new RedfishTool();

    }

    util.inherits(DellWsmanPostDiscoveryJob, BaseJob);


    /**
     * @memberOf DellWsmanPostDiscoveryJob
     */
    DellWsmanPostDiscoveryJob.prototype._run = function () {
        var self = this;

        self.dell = configuration.get('dell');
        if (!self.dell || !self.dell.services || !self.dell.services.discovery) {
            throw new errors.NotFoundError('Dell Discovery web service is not defined in smiConfig.json.');
        }
        if(!self.nodeId) {
            throw new Error('Node ID is required.');
        }
        if(self.validateNodeData() === false) {
            throw new Error('Invalid node data.');
        }
        return Promise.resolve(self.processNode())
       .then(function(){
            return self._done();
       })
        .catch(function(err){
            self._done(err);
        });
    };


    /**
     * @memberOf DellWsmanPostDiscoveryJob
     */
    DellWsmanPostDiscoveryJob.prototype.validateNodeData = function () {

        if(!this.nodeData){
            return false;
        }
        var data = this.nodeData;
        if(data.status !== 'SUCCESS'){
            return false;
        }
//        var type = data.deviceType;
//        if( type === 'IDRAC7' || type === 'IDRAC8' || type === 'CMC_FX2' || type === 'CMC'){
//            if(!data.summary || !data.summary.serviceTag) {
//                logger.error('Node data is invalid for node ID: ' + this.nodeId);
//                return false;
//            }
//        } else {
//            return false
//        }
        return true;
    };


    DellWsmanPostDiscoveryJob.prototype.processNode = function() {

        var self = this;
        var computeNode = null;
        var nodeType = self.nodeData.deviceType;

        return waterline.nodes.getNodeById(self.context.target)
        .then(function(node){
            computeNode = node;
            logger.debug('Creating WSman OBM for ' + nodeType + ' node ID: ' + computeNode.id);
            return self.createWsmanObm(computeNode, self.nodeData.summary.id);
        })
        .then(function(){
            if(nodeType === 'CMC_FX2' || nodeType === 'CMC') {
                logger.info('Node is: ' + nodeType + ', no Redfish OBM will be created.');
                return Promise.resolve();
            } else {
                logger.debug('Creating Redfish OBM for ' + nodeType + ' node ID: ' + computeNode.id);
                return self.createRedfishObm(computeNode, self.nodeData.summary.id);
            }
        })
        .then(function(){
            if(nodeType === 'CMC_FX2' || nodeType === 'CMC') {
                logger.info('Node is: ' + nodeType + ', no enclosure will be created.');
                return Promise.resolve();
            } else {
                logger.debug('Creating Enclosure for node ID: ' + computeNode.id);
                return self.createEnclosure(computeNode, self.nodeData.summary.id);
            }
        })
        .then(function(enclosureNode){
            if(enclosureNode){
                logger.debug('Setting relationships for nodes ID: ' + computeNode.id + ' - ' + enclosureNode.id);
                return Promise.resolve(self.setRelationships(computeNode, enclosureNode));
            } else {
                return Promise.resolve();
            }
        });
    };

    DellWsmanPostDiscoveryJob.prototype.createEnclosure = function(node, ipAddr) {

        var self = this;

        var newNode = {
            name: node.name + '_Enclosure',
            type: 'enclosure',
            identifiers: [node.name + '_Enclosure'],
            relations: []
        };
        return waterline.nodes.create(newNode)
        .then(function (node_) {
            return Promise.resolve(self.createRedfishObm(node_, ipAddr))
            .then(function(){
                logger.debug("Creating default Redfish Chassis pollers for node " + node_.id);
                return workflowTool.runGraph(node_.id, 'Graph.Redfish.Chassis.Poller.Create')
                .then(function(){
                    return node_;
                });
            });
        });
    };

    DellWsmanPostDiscoveryJob.prototype.createWsmanObm = function(node, ipAddr){
        var self = this;

        var settings = {
            "service": "dell-wsman-obm-service",
            "config": {"userName": self.user || self.dell.credentials.userName,
                        "password": self.password || self.dell.credentials.password,
                        "host": ipAddr
            }
        };
        return waterline.obms.upsertByNode(node.id, settings);
    };

    /**
     * @function createRedfishObm
     */
    DellWsmanPostDiscoveryJob.prototype.createRedfishObm = function (node, ipAddr) {
        var self = this;
        var redfishType = 'Systems';
        if(node.type === 'enclosure'){
            redfishType = 'Chassis';
        }

        var uri = 'https://' + ipAddr + '/redfish/v1';

        var settings = {
            uri: uri,
            host: ipAddr,
            root: '/redfish/v1/',
            port: '',
            protocol: 'https',
            username: this.user || this.dell.credentials.userName,
            password: this.password || this.dell.credentials.password,
            verifySSL: true
        };
        this.redfish.settings = settings;

        var rootPath = settings.root;
        return this.redfish.clientRequest(rootPath)
        .then(function(root) {
            if (!_.has(root.body, redfishType)) {
                logger.warning('No ' + redfishType + ' Members Found');
                return Promise.resolve();
            }
            var path = redfishType === 'Systems' ? root.body.Systems['@odata.id'] : root.body.Chassis['@odata.id'];
            return self.redfish.clientRequest(path)
            .then(function(res) {
                assert.object(res);
                settings.root = res.body.Members[0]['@odata.id'];
                return Promise.resolve({
                    config: settings,
                    service: 'redfish-obm-service'
                });
            });
        })
        .then(function(redfishObm){
            if(redfishObm) {
                return waterline.obms.upsertByNode(node.id, redfishObm);
            } else {
                return Promise.resolve();
            }
        })
        .catch(function(err) {
            logger.error("Redfish call failed. No OBM settings created for " + ipAddr);
            return undefined;
        });
    };


    /**
     * @memberOf DellWsmanPostDiscoveryJob
     */
    DellWsmanPostDiscoveryJob.prototype.setRelationships = function (n1, n2) {
//        logger.debug('setRelationships: NODE: '+ JSON.stringify(n1, null, 4));
//        logger.debug('setRelationships: ENCL: '+ JSON.stringify(n2, null, 4));
        n1.relations.push({
            relationType: 'enclosedBy',
            targets: [n2.id]
        });
        return waterline.nodes.updateByIdentifier(
            n1.id,
            {relations: n1.relations}
        )
        .then(function(){
            if(_.isEmpty(n2.relations)){
                n2.relations.push({
                    relationType: 'encloses',
                    targets: [n1.id]
                });
            } else {
                var encloses = _.find(n2.relations, { 'relationType': 'encloses' } );
                encloses.targets.push(n1.id);
            }
        })
        .then(function(){
            return waterline.nodes.updateByIdentifier(
                n2.id,
                {relations: n2.relations}
            );
        });
    };

    return DellWsmanPostDiscoveryJob;
}