From de58523fc431857d846d6acda93f088a15c11879 Mon Sep 17 00:00:00 2001 From: Jamie Zhuang Date: Wed, 13 Dec 2017 02:14:18 -0500 Subject: [PATCH] Port Graph.Dell.Configure.Redfish.Alerting to use WSMAN API --- .../dell-wsman-configure-redfish-alert.js | 181 ++++++++++++++++++ .../dell-wsman-configure-redfish-alert.js | 13 ++ .../dell-wsman-configure-redfish-alert.json | 23 +++ .../dell-wsman-configure-redfish-alert.js | 13 ++ ...dell-wsman-configure-redfish-alert-spec.js | 161 ++++++++++++++++ ...dell-wsman-configure-redfish-alert-spec.js | 19 ++ ...dell-wsman-configure-redfish-alert-spec.js | 36 ++++ ...dell-wsman-configure-redfish-alert-spec.js | 19 ++ 8 files changed, 465 insertions(+) create mode 100644 lib/jobs/dell-wsman-configure-redfish-alert.js create mode 100644 lib/task-data/base-tasks/dell-wsman-configure-redfish-alert.js create mode 100644 lib/task-data/schemas/dell-wsman-configure-redfish-alert.json create mode 100644 lib/task-data/tasks/dell-wsman-configure-redfish-alert.js create mode 100644 spec/lib/jobs/dell-wsman-configure-redfish-alert-spec.js create mode 100644 spec/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert-spec.js create mode 100644 spec/lib/task-data/schemas/dell-wsman-configure-redfish-alert-spec.js create mode 100644 spec/lib/task-data/tasks/dell-wsman-configure-redfish-alert-spec.js diff --git a/lib/jobs/dell-wsman-configure-redfish-alert.js b/lib/jobs/dell-wsman-configure-redfish-alert.js new file mode 100644 index 00000000..5704eab3 --- /dev/null +++ b/lib/jobs/dell-wsman-configure-redfish-alert.js @@ -0,0 +1,181 @@ +// Copyright 2017, Dell EMC, Inc. + +'use strict'; + +var di = require('di'); + +module.exports = DellWsmanConfigureRedfishAlertFactory; +di.annotate(DellWsmanConfigureRedfishAlertFactory, new di.Provide('Job.Dell.Wsman.Configure.Redfish.Alert')); +di.annotate(DellWsmanConfigureRedfishAlertFactory, new di.Inject( + 'Job.Dell.Wsman.Base', + 'JobUtils.WsmanTool', + 'Logger', + 'Promise', + 'Assert', + 'Util', + 'Services.Waterline', + 'Services.Configuration', + '_', + 'Errors', + 'Services.Encryption' +)); + +function DellWsmanConfigureRedfishAlertFactory( + BaseJob, + WsmanTool, + Logger, + Promise, + assert, + util, + waterline, + configuration, + _, + errors, + encryption +) { + var logger = Logger.initialize(DellWsmanConfigureRedfishAlertFactory); + + function DellWsmanConfigureRedfishAlertJob(options, context, taskId) { + DellWsmanConfigureRedfishAlertJob.super_.call(this, logger, options, context, taskId); + assert.object(this.options); + this.nodeId = this.context.target; + } + + util.inherits(DellWsmanConfigureRedfishAlertJob, BaseJob); + + DellWsmanConfigureRedfishAlertJob.prototype._initJob = function () { + var self = this; + self.dell = configuration.get('dell'); + + var updateComponents = _.get(self.dell, 'services.configuration.updateComponents'); + if (!updateComponents) { + throw new errors.NotFoundError('Dell SCP UpdateComponents web service is not defined in smiConfig.json.'); + } + + var shareFolder = _.get(self.dell, 'shareFolder'); + if(!shareFolder) { + throw new errors.NotFoundError('The shareFolder is not defined in smiConfig.json.'); + } + }; + + DellWsmanConfigureRedfishAlertJob.prototype._handleSyncRequest = function () { + var self = this; + return Promise.all([ + self.checkOBM('SCP UpdateComponents'), + self.getServerComponents() + ]) + .spread(function(obm, serverComponents){ + return self.updateComponents(obm, serverComponents); + }); + }; + + DellWsmanConfigureRedfishAlertJob.prototype._handleSyncResponse = function (response) { + var body = _.get(response, 'body'); + var status = _.get(body, 'status'); + var message = _.get(body, 'message'); + logger.info('Response from SCP Microservice for UpdateComponents: ' + body); + if(status === "OK") { + return response; + } else { + throw new errors.InternalServerError(message); + } + }; + + /** + * generate components based on the following rule: + * all components prefixed by fqddPrefix and attributes postfixed by attrPostfix + * are Enabled except those prefixed by disableFqddPrefix and attributes postfixed by + * disableAttrPostfix, which are Disalbed. + * @param {Object} components the base components used to generate required components + * @param {String} fqddPrefix the fqddPrefix + * @param {String} attrPostfix the attrPostfix + * @param {String} disableFqddPrefix the disableFqddPrefix + * @param {String} disableAttrPostfix the disableAttrPostfix + * @return {Object} the generated components + */ + DellWsmanConfigureRedfishAlertJob.prototype.generateComponents = function( + components, + fqddPrefix, + attrPostfix, + disableFqddPrefix, + disableAttrPostfix + ) { + var filteredComponents = _.filter(components, function(component) { + return _.startsWith(component.fqdd, fqddPrefix); + }); + + return _.map(filteredComponents, function(component) { + var newComponent = {}; + newComponent.fqdd = component.fqdd; + var filteredAttrs = _.filter(component.attributes, function(attr) { + return _.endsWith(attr.name, attrPostfix); + }); + newComponent.attributes = _.map(filteredAttrs, function(attr) { + var value = "Enabled"; + if(disableFqddPrefix && + disableAttrPostfix && + _.startsWith(component.fqdd, disableFqddPrefix) && + _.endsWith(attr.name, disableAttrPostfix) + ) { + value = "Disabled"; + } + return { + "name": attr.name, + "value": value + }; + }); + return newComponent; + }); + }; + + DellWsmanConfigureRedfishAlertJob.prototype.getServerComponents = function() { + var self = this; + return waterline.catalogs.findLatestCatalogOfSource( + self.nodeId, + 'idrac-wsman-systemconfiguration-components' + ) + .then(function(catalogs) { + var components = _.get(catalogs, 'data.serverComponents'); + var idrac = self.generateComponents(components, 'iDRAC.Embedded', '#AlertEnable'); + var eventfilters = self.generateComponents( + components, + 'EventFilters', + '#Alert#RedfishEventing', + 'EventFilters.Audit', + '4_3#Alert#RedfishEventing' + ); + return idrac.concat(eventfilters); + }); + }; + + DellWsmanConfigureRedfishAlertJob.prototype.updateComponents = function(obm, serverComponents) { + var self = this; + var data = { + "serverAndNetworkShareRequest": { + "serverIP": obm.config.host, + "serverUsername": obm.config.user, + "serverPassword": encryption.decrypt(obm.config.password), + "shareAddress": self.dell.shareFolder.address, + "shareName": self.dell.shareFolder.shareName, + "shareUsername": self.dell.shareFolder.username, + "sharePassword": self.dell.shareFolder.password, + "shareType": self.dell.shareFolder.shareType, + "shutdownType": self.options.shutdownType + }, + "serverComponents": serverComponents, + "forceUpdate": self.options.forceUpdate + }; + + var wsman = new WsmanTool(self.dell.gateway, { + verifySSl: false, + recvTimeoutMs: 1800000 + }); + return wsman.clientRequest( + self.dell.services.configuration.updateComponents, + "POST", + data + ); + }; + + return DellWsmanConfigureRedfishAlertJob; +} diff --git a/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert.js b/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert.js new file mode 100644 index 00000000..b7645f11 --- /dev/null +++ b/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert.js @@ -0,0 +1,13 @@ +// Copyright 2017, Dell EMC, Inc. + +'use strict'; + +module.exports = { + friendlyName: 'Dell Wsman Configure Redfish Alert', + injectableName: 'Task.Base.Dell.Wsman.Configure.Redfish.Alert', + runJob: 'Job.Dell.Wsman.Configure.Redfish.Alert', + requiredOptions: [ + ], + requiredProperties: {}, + properties:{} +}; diff --git a/lib/task-data/schemas/dell-wsman-configure-redfish-alert.json b/lib/task-data/schemas/dell-wsman-configure-redfish-alert.json new file mode 100644 index 00000000..7ea7ca93 --- /dev/null +++ b/lib/task-data/schemas/dell-wsman-configure-redfish-alert.json @@ -0,0 +1,23 @@ +{ + "copyright": "Copyright 2017, Dell EMC, Inc.", + "definitions": { + "shutdownType": { + "description": "Specify the type of system shutdown: Graceful(0), Forced(1), default value:0", + "type": "integer", + "enum": [0, 1] + }, + "forceUpdate": { + "description": "Specify the forceUpdate", + "type": "boolean" + } + }, + "properties": { + "shutdownType": { + "$ref": "#/definitions/shutdownType" + }, + "forceUpdate": { + "$ref": "#/definitions/forceUpdate" + } + }, + "required": ["shutdownType", "forceUpdate"] +} diff --git a/lib/task-data/tasks/dell-wsman-configure-redfish-alert.js b/lib/task-data/tasks/dell-wsman-configure-redfish-alert.js new file mode 100644 index 00000000..4c2664da --- /dev/null +++ b/lib/task-data/tasks/dell-wsman-configure-redfish-alert.js @@ -0,0 +1,13 @@ +// Copyright 2017, Dell EMC, Inc. + +'use strict'; + +module.exports = { + friendlyName: 'Dell Wsman Configure Redfish Alert', + injectableName: 'Task.Dell.Wsman.Configure.Redfish.Alert', + implementsTask: 'Task.Base.Dell.Wsman.Configure.Redfish.Alert', + optionsSchema: 'dell-wsman-configure-redfish-alert.json', + options: { + }, + properties: {} +}; diff --git a/spec/lib/jobs/dell-wsman-configure-redfish-alert-spec.js b/spec/lib/jobs/dell-wsman-configure-redfish-alert-spec.js new file mode 100644 index 00000000..e5f35e00 --- /dev/null +++ b/spec/lib/jobs/dell-wsman-configure-redfish-alert-spec.js @@ -0,0 +1,161 @@ +// Copyright 2017, Dell EMC, Inc. + +'use strict'; + +describe('Dell Wsman Configure Redfish Alert Job', function() { + var WsmanJob; + var uuid; + var job; + var sandbox = sinon.sandbox.create(); + var configuration; + var BaseJob; + var WsmanTool; + var waterline = {}; + + before(function(){ + helper.setupInjector([ + helper.require('/spec/mocks/logger.js'), + helper.require('/lib/jobs/base-job.js'), + helper.require('/lib/jobs/dell-wsman-base-job.js'), + helper.require('/lib/jobs/dell-wsman-configure-redfish-alert.js'), + helper.require('/lib/utils/job-utils/wsman-tool.js'), + helper.di.simpleWrapper(waterline, 'Services.Waterline') + ]); + WsmanJob = helper.injector.get('Job.Dell.Wsman.Configure.Redfish.Alert'); + uuid = helper.injector.get('uuid'); + configuration = helper.injector.get('Services.Configuration'); + BaseJob = helper.injector.get('Job.Dell.Wsman.Base'); + WsmanTool = helper.injector.get('JobUtils.WsmanTool'); + waterline.catalogs = { + findLatestCatalogOfSource: sandbox.stub() + }; + }); + + var dellConfigs = { + "services": { + "configuration": { + "updateComponents": "/api/1.0/server/configuration/updateComponents" + }, + }, + "shareFolder": { + "address": "192.168.128.33", + "username": "admin", + "password": "admin", + "shareName": "testShareName", + "shareType": 2 + }, + "gateway": "http://localhost:46020" + }; + + var obm = { + "service" : "dell-wsman-obm-service", + "config" : { + "user" : "admin", + "password" : "admin", + "host" : "192.168.188.13" + }, + "node" : "59db1dc1423ad2cc0650f8bc" + }; + + beforeEach(function(){ + job = new WsmanJob({}, {"nodeId": uuid.v4()}, uuid.v4()); + sandbox.stub(configuration, 'get').returns(dellConfigs); + sandbox.stub(WsmanTool.prototype, 'clientRequest'); + sandbox.stub(job, 'checkOBM').resolves(obm); + }); + + afterEach(function(){ + sandbox.restore(); + }); + + it('Should _run succesfully', function(){ + WsmanTool.prototype.clientRequest.resolves({ + body: { + status: 'OK', + message: 'test message' + } + }); + waterline.catalogs.findLatestCatalogOfSource.resolves(); + return job._run().then(function() { + expect(job.checkOBM).to.be.calledOnce; + expect(waterline.catalogs.findLatestCatalogOfSource).to.be.calledOnce; + expect(WsmanTool.prototype.clientRequest).to.be.calledOnce; + }); + }); + + it('Should _initJob throw an error if SCP service is missing', function(){ + configuration.get.returns({}); + return expect(job._run()) + .to.be.rejectedWith( + 'Dell SCP UpdateComponents web service is not defined in smiConfig.json.' + ); + }); + + it('Should _initJob throw an error if shareFolder is missing', function(){ + configuration.get.returns({ + "services": { + "configuration": { + "updateComponents": "/api/1.0/server/configuration/updateComponents" + }, + }, + "gateway": "http://localhost:46020" + }); + return expect(job._run()) + .to.be.rejectedWith('The shareFolder is not defined in smiConfig.json.'); + }); + + it('Should getServerComponent succesfully', function(){ + waterline.catalogs.findLatestCatalogOfSource.resolves({ + "data": { + "serverComponents": [ + { + "fqdd": "iDRAC.Embedded.1", + "attributes": [ + { + "name": "IPMILan.1#AlertEnable", + "value" : "Disabled" + } + ] + }, + { + "fqdd": "EventFilters.SystemHealth.1", + "attributes": [ + { + "name": "NIC_1_2#Alert#RedfishEventing", + "value" : "Disabled" + } + ] + }, + { + "fqdd": "EventFilters.Audit.1", + "attributes": [ + { + "name": "FSD_4_3#Alert#RedfishEventing", + "value" : "Disabled" + } + ] + } + ] + } + }); + + return job.getServerComponents().then(function(serverComponents) { + expect(serverComponents).to.be.an.array; + expect(serverComponents[0]).to.be.an.object; + expect(serverComponents[0].fqdd).to.equal("iDRAC.Embedded.1"); + expect(serverComponents[0].attributes).to.be.an.array; + expect(serverComponents[0].attributes[0]).to.be.an.object; + expect(serverComponents[0].attributes[0].value).to.equal("Enabled"); + expect(serverComponents[1]).to.be.an.object; + expect(serverComponents[1].fqdd).to.equal("EventFilters.SystemHealth.1"); + expect(serverComponents[1].attributes).to.be.an.array; + expect(serverComponents[1].attributes[0]).to.be.an.object; + expect(serverComponents[1].attributes[0].value).to.equal("Enabled"); + expect(serverComponents[2]).to.be.an.object; + expect(serverComponents[2].fqdd).to.equal("EventFilters.Audit.1"); + expect(serverComponents[2].attributes).to.be.an.array; + expect(serverComponents[2].attributes[0]).to.be.an.object; + expect(serverComponents[2].attributes[0].value).to.equal("Disabled"); + }); + }); +}); diff --git a/spec/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert-spec.js b/spec/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert-spec.js new file mode 100644 index 00000000..5faa96c0 --- /dev/null +++ b/spec/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert-spec.js @@ -0,0 +1,19 @@ +// Copyright 2017, Dell EMC, Inc. +/* jshint node:true */ + +'use strict'; + +describe(require('path').basename(__filename), function () { + var base = require('./base-task-data-spec'); + + base.before(function (context) { + context.taskdefinition = helper.require( + '/lib/task-data/base-tasks/dell-wsman-configure-redfish-alert.js' + ); + }); + + describe('task-data', function () { + base.examples(); + }); + +}); diff --git a/spec/lib/task-data/schemas/dell-wsman-configure-redfish-alert-spec.js b/spec/lib/task-data/schemas/dell-wsman-configure-redfish-alert-spec.js new file mode 100644 index 00000000..f269e677 --- /dev/null +++ b/spec/lib/task-data/schemas/dell-wsman-configure-redfish-alert-spec.js @@ -0,0 +1,36 @@ +// Copyright 2017, Dell EMC, Inc. +/* jshint node: true */ + +'use strict'; + +describe(require('path').basename(__filename), function() { + var schemaFileName = 'dell-wsman-configure-redfish-alert.json'; + + var canonical = { + shutdownType: 0, + forceUpdate: true + }; + + var positiveSetParam = { + shutdownType: [0, 1], + forceUpdate: [true, false] + }; + + var negativeSetParam = { + shutdownType: [2, -1, "0", "1"], + forceUpdate: ["true", "false"] + }; + + var positiveUnsetParam = [ + ]; + + var negativeUnsetParam = [ + 'shutdownType', + 'forceUpdate' + ]; + + var SchemaUtHelper = require('./schema-ut-helper'); + new SchemaUtHelper(schemaFileName, canonical).batchTest( + positiveSetParam, negativeSetParam, positiveUnsetParam, negativeUnsetParam + ); +}); diff --git a/spec/lib/task-data/tasks/dell-wsman-configure-redfish-alert-spec.js b/spec/lib/task-data/tasks/dell-wsman-configure-redfish-alert-spec.js new file mode 100644 index 00000000..d185bd96 --- /dev/null +++ b/spec/lib/task-data/tasks/dell-wsman-configure-redfish-alert-spec.js @@ -0,0 +1,19 @@ +// Copyright 2017, Dell EMC, Inc. +/* jshint node:true */ + +'use strict'; + +describe(require('path').basename(__filename), function () { + var base = require('./base-tasks-spec'); + + base.before(function (context) { + context.taskdefinition = helper.require( + '/lib/task-data/tasks/dell-wsman-configure-redfish-alert.js' + ); + }); + + describe('task-data', function () { + base.examples(); + }); + +});