on-http-y1
Version:
OnRack Http Server
1,223 lines (1,136 loc) • 71.6 kB
JavaScript
// Copyright 2016, EMC, Inc.
'use strict';
var injector = require('../../../index.js').injector;
var redfish = injector.get('Http.Api.Services.Redfish');
var waterline = injector.get('Services.Waterline');
var taskProtocol = injector.get('Protocol.Task');
var Promise = injector.get('Promise');
var _ = injector.get('_');
var nodeApi = injector.get('Http.Services.Api.Nodes');
var controller = injector.get('Http.Services.Swagger').controller;
var Errors = injector.get('Errors');
var moment = require('moment');
var racadm = injector.get('JobUtils.RacadmTool');
var wsman = injector.get('Http.Services.Wsman');
var configuration = injector.get('Services.Configuration');
var mktemp = require('mktemp');
var fs = require('fs');
var dataFactory = function(identifier, dataName) {
switch(dataName) {
case 'ohai':
case 'dmi':
case 'smart':
case 'hardware':
case 'boot':
case 'bios':
case 'nics':
case 'DeviceSummary':
return nodeApi.getNodeCatalogSourceById(identifier, dataName);
case 'catData':
return Promise.all([nodeApi.getNodeCatalogSourceById(identifier,'ohai'), nodeApi.getNodeCatalogSourceById(identifier,'dmi')])
.spread(function(ohai, dmi) {
var catData = _.merge(ohai.data, dmi.data);
return catData;
});
case 'chassis':
return nodeApi.getNodeById(identifier)
.then(function(node) {
return _.filter(node.relations, function(relation) {
return relation.relationType === 'enclosedBy';
}).map(function(relation) {
return relation.targets[0];
});
});
case 'chassisData':
return nodeApi.getPollersByNodeId(identifier)
.filter(function(poller) {
return poller.config.command === 'chassis';
}).spread(function(poller) {
return taskProtocol.requestPollerCache(poller.id, { latestOnly: true });
}).then(function(data) {
var chassisData = data[0].chassis;
chassisData.power = (chassisData.power) ? 'On' : 'Off';
var uidStatus = ['Off', 'Temporary On', 'On', 'Reserved'];
var validEnum = ['Off', 'Blinking', 'Lit', 'Unknown'];
chassisData.uid = validEnum[_.indexOf(uidStatus, chassisData.uid)];
return chassisData;
}).catch(function() {
return { power: "Unknown", uid: "Unknown"};
});
case 'selInfoData':
return nodeApi.getPollersByNodeId(identifier)
.filter(function(poller) {
return poller.config.command === 'selInformation';
}).spread(function(poller) {
return taskProtocol.requestPollerCache(poller.id, { latestOnly: true });
}).then(function(data) {
return data[0].selInformation;
});
case 'selData':
return nodeApi.getPollersByNodeId(identifier)
.filter(function(poller) {
return poller.config.command === 'sel';
}).spread(function(poller) {
return taskProtocol.requestPollerCache(poller.id, { latestOnly: true });
}).then(function(data) {
return data[0].sel;
});
}
};
//DCIM_View mappings to redfish equivalents
var autoNeg = {
"0": null, "2": true, "3": false };
var fullDuplex = {
"0": null, "1": true, "2": false };
var linkSpeed = {
"0": null, "1": 10, "2": 100, "3": 1000, "4": 2500, "5": 10000,
"6": 20000, "7": 40000, "8": 100000, "9": 25000, "10":50000 };
var selTranslator = function(selArray, identifier) {
var dateRegex = /(\d{1,2})\/(\d{1,2})\/(\d{4})/;
var timeRegex = /(\d{1,2}):(\d{1,2}):(\d{1,2})/;
var ipmiEventTypeMap = {
'Asserted': 'Assert',
'Deasserted': 'Deassert',
'Lower Non-critical going low': 'Lower Non-critical - going low',
'Lower Non-critical going high': 'Lower Non-critical - going high',
'Lower Critical going low': 'Lower Critical - going low',
'Lower Critical going high': 'Lower Critical - going high',
'Lower Non-recoverable going low': 'Lower Non-recoverable - going low',
'Lower Non-recoverable going high': 'Lower Non-recoverable - going high',
'Upper Non-critical going low': 'Upper Non-critical - going low',
'Upper Non-critical going high': 'Upper Non-critical - going high',
'Upper Critical going low': 'Upper Critical - going low',
'Upper Critical going high': 'Upper Critical - going high',
'Upper Non-recoverable going low': 'Upper Non-recoverable - going low',
'Upper Non-recoverable going high': 'Upper Non-recoverable - going high',
'Predictive Failure Deasserted': 'Predictive Failure deasserted',
'Predictive Failure Asserted': 'Predictive Failure asserted',
'Transition to Non-critical from OK': 'Transition to Non-Critical from OK',
'Device Absent': 'Device Removed / Device Absent',
'Device Present': 'Device Inserted / Device Present',
'Non-Redundant: Sufficient from Redundant': 'Non-redundant:Sufficient Resources from Redundant',
'Non-Redundant: Sufficient from Insufficient': 'Non-redundant:Sufficient Resources from Insufficient Resources',
'Non-Redundant: Insufficient Resources': 'Non-redundant:Insufficient Resources',
'Redundancy Degraded from Fully Redundant': 'Redundancy Degraded from Fully Redundant',
'Redundancy Degraded from Non-Redundant': 'Redundancy Degraded from Fully Redundant'
};
var ipmiSensorTypeMap = {
'Temperature': 'Temperature',
'Voltage': 'Voltage',
'Current': 'Current',
'Fan': 'Fan',
'Physical Security': 'Physical Chassis Security',
'Platform Security': 'Platform Security Violation Attempt',
'Processor': 'Processor',
'Power Supply': 'Power Supply / Converter',
'Power Unit': 'PowerUnit',
'Cooling Device': 'CoolingDevice',
'Memory': 'Memory',
'Drive Slot': 'Drive Slot/Bay',
'System Firmware Progress': 'System Firmware Progress',
'Event Logging Disabled': 'Event Logging Disabled',
'Watchdog 1': 'Watchdog',
'System Event': 'System Event',
'Critical Interrupt': 'Critical Interrupt',
'Button': 'Button/Switch',
'Module/Board': 'Module/Board',
'Microcontroller/Coprocessor': 'Microcontroller/Coprocessor',
'Add-in Card': 'Add-in Card',
'Chassis': 'Chassis',
'Chip Set': 'ChipSet',
'Other FRU': 'Other FRU',
'Cable/Interconnect': 'Cable/Interconnect',
'Terminator': 'Terminator',
'System Boot Initiated': 'SystemBoot/Restart',
'Boot Error': 'Boot Error',
'OS Boot': 'BaseOSBoot/InstallationStatus',
'OS Stop/Shutdown': 'OS Stop/Shutdown',
'Slot/Connector': 'Slot/Connector',
'System ACPI Power State': 'System ACPI PowerState',
'Watchdog 2': 'Watchdog',
'Platform Alert': 'Platform Alert',
'Entity Presence': 'Entity Presence',
'Monitor ASIC/IC': 'Monitor ASIC/IC',
'LAN': 'LAN',
'Management Subsystem Health': 'Management Subsystem Health',
'Battery': 'Battery',
'Version Change': 'Version Change',
'FRU State': 'FRUState'
};
var selTranslatorOrigin = function(sensorType, identifier) {
switch(sensorType) {
case 'Drive Slot':
return '/redfish/v1/Systems/' + identifier + '/SimpleStorage';
case 'Power Unit':
return dataFactory(identifier, 'chassis')
.then(function(chassis) {
return '/redfish/v1/Chassis/' + chassis + '/Power';
});
case 'Power Supply':
return dataFactory(identifier, 'chassis')
.then(function(chassis) {
return '/redfish/v1/Chassis/' + chassis + '/Power';
});
case 'Fan':
return dataFactory(identifier, 'chassis')
.then(function(chassis) {
return '/redfish/v1/Chassis/' + chassis + '/Thermal';
});
case 'Temperature':
return dataFactory(identifier, 'chassis')
.then(function(chassis) {
return '/redfish/v1/Chassis/' + chassis + '/Thermal';
});
}
return null;
};
return Promise.map(selArray, function(entry) {
var dates = dateRegex.exec(entry.date);
var times = timeRegex.exec(entry.time);
if(entry.sensorNumber.indexOf('#') !== 0) {
entry.sensorNumber = '#'+entry.sensorNumber;
}
return Promise.props({
logId: entry.logId,
// Month is zero indexed by moment so we must decrement
timestamp: moment.utc([dates[3], dates[1] - 1, dates[2], times[1], times[2], times[3]]).format(),
sensorType: _.get(ipmiSensorTypeMap, entry.sensorType, 'Other Units-based Sensor'),
value: _.get(ipmiEventTypeMap, entry.value, entry.value),
event: entry.event,
sensorNumber: parseInt(entry.sensorNumber.substr(1)),
origin: selTranslatorOrigin(entry.sensorType, identifier)
});
});
};
var getObmSettings = function(nodeId){
return waterline.obms.findByNode(nodeId, 'ipmi-obm-service', true)
.then(function (obmSettings) {
return obmSettings.config;
})
.catch(function(err) {
return (err);
});
};
/**
* Generate a list of systems managed by RackHD
* @param {Object} req
* @param {Object} res
*/
var listSystems = controller(function(req, res) {
var options = redfish.makeOptions(req, res);
return waterline.nodes.find({type: 'compute'}).then(function(nodes) {
options.nodes = nodes;
return redfish.render('redfish.1.0.0.computersystemcollection.json',
'ComputerSystemCollection.json#/definitions/ComputerSystemCollection',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate information about a specific system
* @param {Object} req
* @param {Object} res
*/
var getSystem = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
options.systemType = 'Physical';
return wsman.isDellSystem(identifier)
.then(function(result){
var node = result.node;
if(result.isDell){
return Promise.props({
hardware: dataFactory(identifier, 'hardware'),
boot: dataFactory(identifier, 'boot'),
chassis: dataFactory(identifier, 'chassis'),
chassisData: dataFactory(identifier, 'chassisData'),
obm: Promise.resolve(node)
.then(function(node) {
return _.map(node.obms, function(val, idx) {
return node.id + '.' + idx;
});
})
.then(function(obms) {
obms.push('RackHD');
return obms;
})
}).then(function(data) {
return redfish.render('redfish.2016.3.computersystem.1.3.0.json',
'ComputerSystem.v1_3_0.json#/definitions/ComputerSystem',
_.merge(options, data));
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return Promise.props({
catData: dataFactory(identifier, 'catData'),
chassis: dataFactory(identifier, 'chassis'),
chassisData: dataFactory(identifier, 'chassisData'),
obm: Promise.resolve(node)
.then(function(node) {
return _.map(node.obms, function(val, idx) {
return node.id + '.' + idx;
});
})
.then(function(obms) {
obms.push('RackHD');
return obms;
})
}).then(function(data) {
return redfish.render('redfish.1.0.0.computersystem.1.0.0.json',
'ComputerSystem.v1_3_0.json#/definitions/ComputerSystem',
_.merge(options, data));
}).catch(function(error) {
return redfish.handleError(error, res);
});
}
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate information about the bios of a specific system
* @param {Object} req
* @param {Object} res
*/
var listSystemBios = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return nodeApi.getNodeById(identifier)
.then(function(node){
// look for Dell service tag in identifiers list
var dellFound = false;
node.identifiers.forEach(function(ident) {
if(/^[0-9|A-Z]{7}$/.test(ident)){
dellFound=true;
}
});
if (dellFound) {
return dataFactory(identifier, 'bios').then(function(bios) {
options.bios = bios;
bios.attributes = [];
var key;
// create a single bios attribute list (not organized by type)
for(key in bios.data) {
if (bios.data.hasOwnProperty(key)) {
bios.attributes = bios.attributes.concat(bios.data[key]);
}
}
// normalize the currentValue field (some need value fields)
for(key in bios.attributes) {
if (bios.attributes[key].currentValue[0] === null) {
bios.attributes[key].currentValue[0] = {"value": null};
}
}
return options;
});
} else {
throw new Errors.NotFoundError('No BIOS found for node ' + identifier);
}
}).then(function(options) {
return redfish.render('redfish.1.0.0.bios.1.0.0.json',
'Bios.v1_0_1.json#/definitions/Bios',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate information about the bios settings data of a specific system
* @param {Object} req
* @param {Object} res
*/
var listSystemBiosSettings = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return nodeApi.getNodeById(identifier).then(function(node){
var dellFound = false;
node.identifiers.forEach(function(ident) {
if(/^[0-9|A-Z]{7}$/.test(ident)){
dellFound = true;
}
});
if (dellFound) {
return dataFactory(identifier, 'bios').then(function(bios) {
options.bios = bios;
bios.attributes = [];
var key;
// create a single bios attribute list (not organized by type)
for(key in bios.data) {
if (bios.data.hasOwnProperty(key)) {
bios.attributes = bios.attributes.concat(bios.data[key]);
}
}
for (key = bios.attributes.length - 1; key >= 0; key -= 1) {
// remove entries that are readOnly
if (bios.attributes[key].isReadOnly.value === "true") {
bios.attributes.splice(key, 1);
continue;
}
// normalize the currentValue field (some need value fields)
if (bios.attributes[key].currentValue[0] === null) {
bios.attributes[key].currentValue[0] = {"value": null};
}
}
return options;
});
} else {
/* TODO: Not implemented? */
throw new Errors.NotFoundError(
'No BIOS found for node ' + identifier
);
}
}).then(function(options) {
return redfish.render('redfish.1.0.0.bios.1.0.0.settings.json',
'Bios.v1_0_1.json#/definitions/Bios',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Patch information about the bios settings data of a specific system
* @param {Object} req
* @param {Object} res
*/
var patchSystemBiosSettings = controller({success: 202}, function(req, res) {
var identifier = req.swagger.params.identifier.value;
redfish.makeOptions(req, res, identifier);
var payload = req.swagger.params.payload.value;
var southboundApiRouter = _.filter(configuration.get('httpEndpoints', []),
_.matches({routers:'southbound-api-router'}))[0];
return nodeApi.getNodeById(identifier)
.then(function(node){
var dellFound = false;
node.identifiers.forEach(function(ident) {
if(/^[0-9|A-Z]{7}$/.test(ident)){
dellFound = true;
}
});
if(dellFound){
var results = { name: "Graph.Dell.Wsman.UpdateSystemComponents", options: {} };
return dataFactory(identifier, 'DeviceSummary').then(function(summary) {
results.options = {
defaults: {
serverIP: summary.data.id,
fileName: "",
shareType: 0,
shareAddress: southboundApiRouter.address,
shareName: "/nfs",
shutdownType: 0,
serverUsername: "",
serverPassword: "",
serverComponents: [{fqdd: "BIOS.Setup.1-1", attributes: []}]
}
};
for (var key in payload.Attributes) {
if (payload.Attributes.hasOwnProperty(key)) {
results.options.defaults.serverComponents[0].attributes.push(
{name: key, value: payload.Attributes[key]});
}
}
return results;
});
} else {
/* TODO: Not implemented? */
throw new Errors.NotFoundError(
'Update Bios is not implemented for node ' + identifier
);
}
}).then(function(results) {
return nodeApi.setNodeWorkflowById(results, identifier);
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Change Bios password of a specific system
* @param {Object} req
* @param {Object} res
*/
var changeSystemBiosPassword = controller({success: 202}, function(req, res) {
var identifier = req.swagger.params.identifier.value;
redfish.makeOptions(req, res, identifier);
var payload = req.swagger.params.payload.value;
var southboundApiRouter = _.filter(configuration.get('httpEndpoints', []),
_.matches({routers:'southbound-api-router'}))[0];
var xmlData = `<SystemConfiguration Model=" " ServiceTag=" " TimeStamp=" ">
<Component FQDD="BIOS.Setup.1-1">
<Attribute Name="OldSetupPassword">xxxx</Attribute>
<Attribute Name="NewSetupPassword">xxxx</Attribute>
<Attribute Name="PasswordStatus">Unlocked</Attribute>
</Component>
</SystemConfiguration>`;
return nodeApi.getNodeById(identifier)
.then(function(node){
var dellFound = false;
node.identifiers.forEach(function(ident) {
if(/^[0-9|A-Z]{7}$/.test(ident)){
dellFound = true;
}
});
if(dellFound){
var results = { name: "Graph.Dell.Wsman.UpdateSystemComponents", options: {} };
return mktemp
.createFile('/nfs/XXXXXX.xml')
.then(function(path) {
fs.writeFile(path, xmlData,function() {});
return dataFactory(identifier, 'DeviceSummary').then(function(summary) {
results.options = {
defaults: {
serverIP: summary.data.id,
fileName: path.split('/')[2],
shareType: 0,
shareAddress: southboundApiRouter.address,
shareName: "/nfs",
shutdownType: 0,
serverUsername: "",
serverPassword: "",
serverComponents: [{fqdd: "BIOS.Setup.1-1", attributes: []}],
cleanup: true
}
};
if (payload.PasswordName === "SysPassword") {
results.options.defaults.serverComponents[0].attributes.push(
{name: 'PasswordStatus', value: 'Unlocked'});
results.options.defaults.serverComponents[0].attributes.push(
{name: 'OldSysPassword', value: payload.OldPassword});
results.options.defaults.serverComponents[0].attributes.push(
{name: 'NewSysPassword', value: payload.NewPassword});
}
else if (payload.PasswordName ==="SetupPassword") {
results.options.defaults.serverComponents[0].attributes.push(
{name: 'OldSetupPassword', value: payload.OldPassword});
results.options.defaults.serverComponents[0].attributes.push(
{name: 'NewSetupPassword', value: payload.NewPassword});
}
else {
throw new Errors.BadRequestError('Invalid PasswordName: ' + payload.PasswordName);
}
return results;
});
});
} else {
/* TODO: Not implemented? */
throw new Errors.NotFoundError(
'Update Bios is not implemented for node ' + identifier
);
}
}).then(function(results) {
return nodeApi.setNodeWorkflowById(results, identifier);
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate information about the processors of a specific system
* @param {Object} req
* @param {Object} res
*/
var listSystemProcessors = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return dataFactory(identifier, 'hardware').then(function(hardware) {
options.hardware = hardware;
}).then(function(){
return redfish.render('wsman.1.0.0.processorcollection.json',
'ProcessorCollection.json#/definitions/ProcessorCollection',
options);
});
} else {
return dataFactory(identifier, 'dmi').then(function(dmi) {
options.dmi = dmi;
options.dmi.data['Processor Information'].forEach(function(element,index){
if(element.Status.indexOf('Unpopulated') !== -1){
options.dmi.data['Processor Information'].splice(index,1);
}
});
if(options.dmi.data['Processor Information'].length === 0){
throw new Errors.NotFoundError('no valid processor found');
}
return redfish.render('redfish.1.0.0.processorcollection.json',
'ProcessorCollection.json#/definitions/ProcessorCollection',
options);
});
}
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate specific information about the processors of a specific system
* @param {Object} req
* @param {Object} res
*/
var getSystemProcessor = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.props({
socketId: req.swagger.params.socket.value,
hardware: dataFactory(identifier, 'hardware')
}).then(function(data) {
if(data.hardware.data.cpus.length <= data.socketId) {
throw new Errors.NotFoundError('invalid socketId');
}
return redfish.render('wsman.1.0.0.processor.1.0.0.json',
'Processor.v1_0_3.json#/definitions/Processor',
_.merge(options, data));
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return Promise.props({
socketId: req.swagger.params.socket.value,
catData: dataFactory(identifier, 'catData')
}).then(function(data) {
if(!_.has(data.catData.cpu, data.socketId)) {
throw new Errors.NotFoundError('invalid socketId');
}
return redfish.render('redfish.1.0.0.processor.1.0.0.json',
'Processor.v1_0_3.json#/definitions/Processor',
_.merge(options, data));
}).catch(function(error) {
return redfish.handleError(error, res);
});
}
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate information about the storage adapters of a specific system
* @param {Object} req
* @param {Object} res
*/
var listSimpleStorage = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.resolve(dataFactory(identifier, 'hardware'))
.then(function(hardware) {
options.hardware = hardware;
var controllers = {};
_.forEach(hardware.data.storage.controllers, function(ele) {
var id = ele.fQDD.replace(/[:.]/g, '_'); // jshint ignore: line
if(!(id in controllers)) {
controllers[id] = [];
}
controllers[id].push(ele);
});
var ids = [];
_.forOwn(controllers, function(val, key) { ids.push(key); });
options.controllers = ids;
return redfish.render('redfish.1.0.0.simplestoragecollection.json',
'SimpleStorageCollection.json#/definitions/SimpleStorageCollection',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return Promise.all([ dataFactory(identifier, 'dmi'),
dataFactory(identifier, 'smart') ])
.spread(function(dmi, smart) {
options.dmi = dmi;
var controllers = {};
_.forEach(smart.data, function(ele) {
var id = ele.Controller.controller_PCI_BDF.replace(/[:.]/g, '_');
if(!(id in controllers)) {
controllers[id] = [];
}
controllers[id].push(ele);
});
var ids = [];
_.forOwn(controllers, function(val, key) { ids.push(key); });
options.controllers = ids;
return redfish.render('redfish.1.0.0.simplestoragecollection.json',
'SimpleStorageCollection.json#/definitions/SimpleStorageCollection',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
}
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate information about the storage devices on an adapter of a specific system
* @param {Object} req
* @param {Object} res
*/
var getSimpleStorage = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var index = req.swagger.params.index.value;
var options = redfish.makeOptions(req, res, identifier);
options.index = index;
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.resolve(dataFactory(identifier, 'hardware'))
.then(function(hardware) {
options.hardware = hardware;
var controllers = {};
_.forEach(hardware.data.storage.controllers, function(ele) {
var id = ele.fQDD.replace(/[:.]/g, '_'); // jshint ignore: line
if(!(id in controllers)) {
controllers[id] = [];
}
controllers[id].push(ele);
});
options.controller = controllers[index][0];
options.devices = [];
_.forEach(hardware.data.storage.physicalDisks, function(ele) {
if(ele.fqdd.indexOf(options.controller.fqdd) !== -1) {
ele.size = ele.size.replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " bytes";
options.devices.push(ele);
}
});
return redfish.render('wsman.1.0.0.simplestorage.1.0.0.json',
'SimpleStorage.v1_1_1.json#/definitions/SimpleStorage',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return Promise.all([ dataFactory(identifier, 'dmi'),
dataFactory(identifier, 'smart') ])
.spread(function(dmi, smart) {
options.dmi = dmi;
var controllers = {};
_.forEach(smart.data, function(ele) {
var id = ele.Controller.controller_PCI_BDF.replace(/[:.]/g, '_');
if(!(id in controllers)) {
controllers[id] = [];
}
controllers[id].push(ele);
});
options.controller = controllers[index][0].Controller;
options.devices = [];
_.forEach(controllers[index], function(ele) {
if(ele.SMART.Identity){
options.devices.push(ele.SMART);
}
});
return redfish.render('redfish.1.0.0.simplestorage.1.0.0.json',
'SimpleStorage.v1_1_1.json#/definitions/SimpleStorage',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
}
}).catch(function(error) {
return redfish.handleError(error, res);
});
});
/**
* Generate information about the storage adapters of a specific system
* @param {Object} req
* @param {Object} res
*/
var listStorage = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.resolve(dataFactory(identifier, 'hardware'))
.then(function(hardware) {
options.hardware = hardware;
var controllers = {};
_.forEach(hardware.data.storage.controllers, function(ele) {
var id = ele.fQDD.replace(/[:.]/g, '_'); // jshint ignore: line
if(!(id in controllers)) {
controllers[id] = [];
}
controllers[id].push(ele);
});
var ids = [];
_.forOwn(controllers, function(val, key) { ids.push(key); });
options.controllers = ids;
return redfish.render('redfish.2016.3.storagecollection.json',
'StorageCollection.json#/definitions/StorageCollection',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return redfish.handleError("Not implemented for non-Dell hardware.", res, null, 501);
}
});
});
/**
* Generate information about the storage devices on an adapter of a specific system
* @param {Object} req
* @param {Object} res
*/
var getStorage = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var index = req.swagger.params.index.value;
var options = redfish.makeOptions(req, res, identifier);
options.index = index;
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.resolve(dataFactory(identifier, 'hardware'))
.then(function(hardware) {
options.hardware = hardware;
var controllers = {};
_.forEach(hardware.data.storage.controllers, function(ele) {
var id = ele.fQDD.replace(/[:.]/g, '_'); // jshint ignore: line
if(!(id in controllers)) {
controllers[id] = [];
}
controllers[id].push(ele);
});
options.controllers = [];
_.forEach(hardware.data.storage.controllers, function(ele) {
var speed = ele.possibleSpeed; //possibleSpeed format is X_X_GBS or X_GBS, convert to decimal
var speedInDecimal;
if (speed){
speed = speed.split('_');
speed.splice(speed.length - 1, 1);
speedInDecimal = speed[0];
if (speed.length > 1){
speedInDecimal += "." + speed[1];
}
}
else {
speedInDecimal = 0;
}
ele.possibleSpeed = speedInDecimal;
options.controllers.push(ele);
});
options.drives = [];
_.forEach(hardware.data.storage.physicalDisks, function(ele) {
options.drives.push(ele);
});
return redfish.render('redfish.2016.3.storage.1.1.1.json',
'Storage.v1_1_1.json#/definitions/Storage',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return redfish.handleError("Not implemented for non-Dell hardware.", res, null, 501);
}
});
});
/**
* Generate information about the storage devices on an adapter of a specific system
* @param {Object} req
* @param {Object} res
*/
var getDrive = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var index = req.swagger.params.index.value;
var driveIndex = req.swagger.params.driveIndex.value;
var options = redfish.makeOptions(req, res, identifier);
options.driveIndex = driveIndex;
options.identifier = identifier;
options.index = index;
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.resolve(dataFactory(identifier, 'hardware'))
.then(function(hardware) {
options.hardware = hardware;
options.drive = hardware.data.storage.physicalDisks[driveIndex];
options.volumeIds = [];
//get redfish ids of all volumes related to this drive
var currFqdd = hardware.data.storage.physicalDisks[driveIndex].fqdd;
for(var i = 0; i < hardware.data.storage.virtualDisks.length; i+=1){
if (hardware.data.storage.virtualDisks[i].physicalDiskIds.indexOf(currFqdd) > -1){
options.volumeIds.push(i);
}
}
return redfish.render('redfish.2016.3.drive.1.1.1.json',
'Drive.v1_1_1.json#/definitions/Drive',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return redfish.handleError("Not implemented for non-Dell hardware.", res, null, 501);
}
});
});
var listVolume = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var index = req.swagger.params.index.value;
var options = redfish.makeOptions(req, res, identifier);
options.identifier = identifier;
options.index = index;
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.resolve(dataFactory(identifier, 'hardware'))
.then(function(hardware) {
options.hardware = hardware;
options.virtualDisks = [];
_.forEach(hardware.data.storage.virtualDisks, function(ele) {
options.virtualDisks.push(ele);
});
return redfish.render('redfish.2016.3.volumecollection.json',
'VolumeCollection.json#/definitions/VolumeCollection',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return redfish.handleError("Not implemented for non-Dell hardware.", res, null, 501);
}
});
});
/**
* Generate information about the storage devices on an adapter of a specific system
* @param {Object} req
* @param {Object} res
*/
var getVolume = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var index = req.swagger.params.index.value;
var volumeIndex = req.swagger.params.volumeIndex.value;
var options = redfish.makeOptions(req, res, identifier);
options.volumeIndex = volumeIndex;
options.identifier = identifier;
options.index = index;
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
return Promise.resolve(dataFactory(identifier, 'hardware'))
.then(function(hardware) {
options.hardware = hardware;
options.volume = hardware.data.storage.virtualDisks[volumeIndex];
options.driveIds = [];
//convert drive fqdds into the ids used for redfish
_.forEach(hardware.data.storage.virtualDisks[volumeIndex].physicalDiskIds, function(ele){
for(var i = 0; i < ele.length; i+=1){
if (ele === hardware.data.storage.physicalDisks[i].fqdd){
options.driveIds.push(i);
break;
}
}
});
return redfish.render('redfish.2016.3.volume.1.0.2.json',
'Volume.v1_0_2.json#/definitions/Volume',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return redfish.handleError("Not implemented for non-Dell hardware.", res, null, 501);
}
});
});
/**
* Generate information about the log services available for a system
* @param {Object} req
* @param {Object} res
*/
var listLogService = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return wsman.isDellSystem(identifier)
.then(function(result){
if(result.isDell){
options.logSource = ['sel', 'lc'];
} else {
options.logSource = ['sel'];
}
return redfish.render('redfish.1.0.0.logservicecollection.json',
'LogServiceCollection.json#/definitions/LogServiceCollection',
options)
.catch(function(error) {
return redfish.handleError(error, res);
});
});
});
/**
* Generate information about the log service provider for a system
* @param {Object} req
* @param {Object} res
*/
var getSelLogService = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return wsman.isDellSystem(identifier)
.then(function(result){
var node = result.node;
if(result.isDell){
options.type = 'SEL';
options.description = 'iDRAC System Event Log';
options.name = 'idrac-sel-information';
options.log = {};
return wsman.getLog(node, options.type)
.then(function(sel) {
options.log.size = sel.length || 0;
options.log.policy = 'WrapsWhenFull';
options.log.lastWriteDate = sel.length > 0 ? sel[0].creationTimeStamp : 'Unknown';
return redfish.render('redfish.1.0.0.logservice.1.0.0.json',
'LogService.v1_0_3.json#/definitions/LogService',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
options.type = 'SEL';
options.description = 'IPMI System Event Log';
options.name = 'ipmi-sel-information';
options.log = {};
return dataFactory(identifier, 'selInfoData')
.then(function(sel) {
options.log.size = sel['# of Alloc Units'] || 0;
options.log.policy = sel.Overflow && sel.Overflow === 'false' ?
'WrapsWhenFull' :
'NeverOverWrites';
options.log.lastWriteDate = sel['Last Add Time'] || 'Unknown';
return redfish.render('redfish.1.0.0.logservice.1.0.0.json',
'LogService.v1_0_3.json#/definitions/LogService',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
}
});
});
/**
* Generate information about the log entries of a log service for a system
* @param {Object} req
* @param {Object} res
*/
var listSelLogServiceEntries = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
options.type = 'SEL';
return wsman.isDellSystem(identifier)
.then(function(result){
var node = result.node;
if(result.isDell){
return wsman.getLog(node, options.type)
.then(function(selData) {
options.logEntries = selData;
return redfish.render('wsman.1.0.0.logentrycollection.json',
'LogEntryCollection.json#/definitions/LogEntryCollection',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return dataFactory(identifier, 'selData')
.then(function(selData) {
if(selData) {
return selTranslator(selData, identifier);
}
return [];
})
.then(function(selData) {
options.logEntries = selData;
return redfish.render('redfish.1.0.0.logentrycollection.json',
'LogEntryCollection.json#/definitions/LogEntryCollection',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
}
});
});
/**
* Generate information about a specific log entry for a system
* @param {Object} req
* @param {Object} res
*/
var getSelLogServiceEntry = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var entryId = req.swagger.params.entryId.value;
var options = redfish.makeOptions(req, res, identifier);
options.type = 'SEL';
options.description = 'IPMI System Event Log';
options.name = 'ipmi-sel-information';
options.log = {};
return wsman.isDellSystem(identifier)
.then(function(result){
var node = result.node;
if(result.isDell){
return wsman.getLog(node, options.type)
.then(function(selData) {
options.entries = _.filter(selData, function(entry) {
return entry.recordID === entryId;
});
if(!options.entries.length) {
throw new Errors.NotFoundError('sel entry ' + entryId + ' was not found');
}
options.entry = options.entries[0];
return redfish.render('wsman.1.0.0.logentry.1.0.0.json',
'LogEntry.v1_1_1.json#/definitions/LogEntry',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return dataFactory(identifier, 'selData')
.then(function(selData) {
options.entries = _.filter(selData, function(entry) {
return entry.logId === entryId;
});
if(!options.entries.length) {
throw new Errors.NotFoundError('SEL entry ' + entryId + ' was not found');
}
return selTranslator(options.entries, identifier);
})
.then(function(selData) {
options.entries = selData;
options.entry = options.entries[0];
return redfish.render('redfish.1.0.0.logentry.1.0.0.json',
'LogEntry.v1_1_1.json#/definitions/LogEntry',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
}
});
});
/**
* Generate information about the log service provider for a system
* @param {Object} req
* @param {Object} res
*/
var getLcLogService = controller(function(req, res) {
var identifier = req.swagger.params.identifier.value;
var options = redfish.makeOptions(req, res, identifier);
return wsman.isDellSystem(identifier)
.then(function(result){
var node = result.node;
if(result.isDell){
options.type = 'LC';
options.description = 'iDRAC Lifecycle Controller Log';
options.name = 'idrac-lc-information';
options.log = {};
return wsman.getLog(node, options.type)
.then(function(lc) {
options.log.size = lc.length || 0;
options.log.policy = 'WrapsWhenFull';
options.log.lastWriteDate = lc.length > 0 ? lc[0].creationTimeStamp : 'Unknown';
return redfish.render('redfish.1.0.0.logservice.1.0.0.json',
'LogService.v1_0_3.json#/definitions/LogService',
options);
}).catch(function(error) {
return redfish.handleError(error, res);
});
} else {
return redfish.handleError("Not implemented for non-Dell hardware.", res, null, 501);
}
});
});
/**
* Generate information about the log entries of a log service for a system
* @param {Object} req
* @param {Obje