Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5f373e3
Add IBMs route for ssh along with unit-test and fix for 2.0
srinia6 Oct 6, 2016
e1f6af3
Modified 1.1 to handle new SSH model
dalebremner Oct 11, 2016
19b4fea
misc unit-test fix
srinia6 Oct 19, 2016
4ce2f49
Address review comments
srinia6 Nov 4, 2016
0667de2
Merge pull request #505 from srinia6/ssh-obm-service
Nov 7, 2016
6628471
Merge remote-tracking branch 'origin/master' into feature/ibms
Jan 17, 2017
452070c
adding snmp support for ibms
Jan 18, 2017
bfd0260
Merge pull request #565 from brianparry/feature/ibms
Jan 19, 2017
4b5d23b
addressing comments
Jan 19, 2017
6433f56
Merge pull request #568 from BillyAbildgaard/feature/ibms
Jan 25, 2017
2fca55d
fixing unit tests
Jan 26, 2017
bda7e13
Merge pull request #574 from BillyAbildgaard/feature/ibms
geoff-reid Jan 27, 2017
e7f90c4
Update monorail-2.0.yaml
Jan 29, 2017
862a60c
Merge pull request #575 from BillyAbildgaard/feature/ibms
Jan 30, 2017
5e4e019
updating postNode w/ new snmpSettings
Feb 2, 2017
7857f37
Render all ibm services into node settings property.
Feb 7, 2017
0eb3d87
Update unit tests
dalebremner Feb 8, 2017
204b98f
Merge pull request #580 from BillyAbildgaard/feature/ibms
Feb 9, 2017
92a4e80
Merge remote-tracking branch 'origin/master' into feature/ibms
dalebremner Feb 9, 2017
8f1073c
Merge pull request #586 from dalebremner/feature/ibms
Feb 10, 2017
e9bbccd
Fix redfish/manager/id to return data, when no nodes are discovered
srinia6 Feb 15, 2017
2c98a77
Merge pull request #589 from srinia6/master
yyscamper Feb 16, 2017
af9ab3b
Merge pull request #570 from RackHD/feature/ibms
Feb 16, 2017
b88186d
Before, it's not so easy to implement both showing status when workflow
lanchongyizu Feb 16, 2017
6db3115
Rename Progress to GraphProgress, and change the interfaces.
lanchongyizu Feb 16, 2017
acc7398
Merge pull request #590 from lanchongyizu/feature/workflow_progress
anhou Feb 21, 2017
686affa
Refactor OS installation progress
Feb 17, 2017
48d6b10
fix some style suggestion
Feb 21, 2017
b8103ba
Add assertion for /notification/progress to screen invalid request
Feb 21, 2017
7d3a816
Merge pull request #591 from yyscamper/refactor-os-progress
anhou Feb 22, 2017
6016cf5
pulling in latest commits from master
Feb 22, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions data/profiles/install-centos.ipxe
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
echo Starting CentOS/RHEL <%=version%> installer for ${hostidentifier}

# The progress notification is just something nice-to-have, so progress notification failure should
# never impact the normal installation process
<% if( typeof progressMilestones !== 'undefined' && progressMilestones.enterProfileUri ) { %>
# since there is no curl like http client in ipxe, so use imgfetch instead
# note: the progress milestones uri must be wrapped in unescaped format, otherwise imgfetch will fail
imgfetch --name fakedimage http://<%=server%>:<%=port%><%-progressMilestones.enterProfileUri%> ||
imgfree fakedimage ||
<% } %>

set base-url <%=repo%>/images/pxeboot
set params initrd=initrd.img ks=<%=installScriptUri%> hostname=<%=hostname%> ksdevice=bootif BOOTIF=01-${netX/mac} console=<%=comport%>,115200n8 console=tty0
kernel ${base-url}/vmlinuz repo=<%=repo%> ${params}
initrd ${base-url}/initrd.img

imgfetch --name fakedimage http://<%=server%>:<%=port%>/api/current/notification/progress?taskId=<%=taskId%>&totalSteps=<%=totalSteps%>&currentStep=2&description=kernel+download+done%2C+starting+initiating+installer
imgfree fakedimage
<% if( typeof progressMilestones !== 'undefined' && progressMilestones.startInstallerUri ) { %>
imgfetch --name fakedimage http://<%=server%>:<%=port%><%-progressMilestones.startInstallerUri%> ||
imgfree fakedimage ||
<% } %>

boot || prompt --key 0x197e --timeout 2000 Press F12 to investigate || exit shell

13 changes: 12 additions & 1 deletion data/templates/centos-ks
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,22 @@ net-tools
%end

%pre
/usr/bin/curl -X POST -H 'Content-Type:application/json' -d "{\"taskId\": \"<%=taskId%>\", \"progress\": { \"description\": \"Installer started, starting OS installtion\", \"maximum\": \"<%=totalSteps%>\", \"value\": 3}}" http://<%=server%>:<%=port%>/api/current/notification;
# The progress notification is just something nice-to-have, so progress notification failure should
# never impact the normal installation process
<% if( typeof progressMilestones !== 'undefined' && progressMilestones.preConfigUri ) { %>
# the url may contain query, the symbol '&' will mess the command line logic, so the whole url need be wrapped in quotation marks
/usr/bin/curl -X POST -H 'Content-Type:application/json' "http://<%=server%>:<%=port%><%-progressMilestones.preConfigUri%>" || true
<% } %>
%end

%post --log=/root/install-post.log
(
#notify the current progress
<% if( typeof progressMilestones !== 'undefined' && progressMilestones.postConfigUri ) { %>
# the url may contain query, the symbol '&' will mess the command line logic, so the whole url need be wrapped in quotation marks
/usr/bin/curl -X POST -H 'Content-Type:application/json' "http://<%=server%>:<%=port%><%-progressMilestones.postConfigUri%>" || true
<% } %>

# PLACE YOUR POST DIRECTIVES HERE
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
Expand Down
8 changes: 8 additions & 0 deletions data/views/ibms.2.0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id" : "<%=id%>",
<% if (node !== null) { %>
"node": "<%=basepath%>/nodes/<%=node%>",
<% } %>
"service": "<%= service %>",
"config": <%- JSON.stringify(config) %>
}
16 changes: 15 additions & 1 deletion data/views/node.2.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,19 @@
<% } %>
<% } %>
"type": "<%=type%>",
"workflows": "<%=basepath %>/nodes/<%=id%>/workflows"
"workflows": "<%=basepath %>/nodes/<%=id%>/workflows",
<% if (ibms === null) { %>
"ibms": null,
<% } else { %>
"ibms":[
<% ibms.forEach(function (value, i, arr){ %>
{
"service": "<%=value.service%>",
"ref":"<%=basepath %>/ibms/<%=value.id%>"
}
<%= ( arr.length > 0 && i < arr.length-1 ) ? ',': '' %>
<% }); %>
]
<% } %>

}
81 changes: 58 additions & 23 deletions lib/api/1.1/northbound/nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ di.annotate(nodesRouterFactory, new di.Inject(
'Logger',
'Promise',
'_',
'Assert'
'Assert',
'Errors'
)
);

Expand All @@ -30,28 +31,41 @@ function nodesRouterFactory (
Logger,
Promise,
_,
assert
assert,
Errors
) {
var router = express.Router();

/**
* Renders obmSettings property into a node.
* Renders obmSettings and sshSettings properties into a node.
*
* @param {object} node - node model instance
* @return {object} Promise that fulfills to the rendered node
*/
function _renderNodeObmSettings(node) {
function _renderNodeMgmtSettings(node) {
// This function exists to allow backward compatibility of the 1.1 API
// with 2.0 API OBM resources.
// with 2.0 API OBM and SSH resources.
assert.object(node, 'node should be a node model instance.');
assert.ok(!node.obmSettings, 'node should not have obmSettings property');

node = _.omit(node.toJSON(), 'obms');
return Promise.map(waterline.obms.find({node: node.id}), function(obm) {
return _.pick(obm.toJSON(), 'service', 'config');
})
.then(function(obms) {
node = _.omit(node.toJSON(), ['obms', 'ibms']);

var obms = Promise.map(waterline.obms.find({node: node.id}), function(obm) {
return _.pick(obm.toJSON(), 'service', 'config');
});

var ibms = Promise.map(waterline.ibms.find({node: node.id}), function(ibm) {
return _.pick(ibm.toJSON(), 'service', 'config');
});

return Promise.all([obms, ibms])
.spread(function(obms, ibms) {
node.obmSettings = obms;

_.forEach(ibms, function(ibm) {
var settingKey = ibm.service.split('-')[0] + 'Settings';
node[settingKey] = ibm.config;
});
return node;
});
}
Expand All @@ -69,7 +83,7 @@ function nodesRouterFactory (
return nodeApiService.getAllNodes(req.query)
.then(function (nodes){
return Promise.map(nodes, function(node) {
return _renderNodeObmSettings(node);
return _renderNodeMgmtSettings(node);
});
});
}));
Expand Down Expand Up @@ -136,7 +150,7 @@ function nodesRouterFactory (
router.get('/nodes/:identifier', rest(function (req) {
return nodeApiService.getNodeById(req.params.identifier)
.then(function (node){
return _renderNodeObmSettings(node);
return _renderNodeMgmtSettings(node);
});
}));

Expand Down Expand Up @@ -180,7 +194,7 @@ function nodesRouterFactory (
})
.then(function() {
// lastly render obmSettings into the node.
return _renderNodeObmSettings(node);
return _renderNodeMgmtSettings(node);
});
}));

Expand Down Expand Up @@ -229,7 +243,7 @@ function nodesRouterFactory (
router.get('/nodes/:identifier/obm', rest(function (req) {
return nodeApiService.getNodeObmById(req.params.identifier)
.then(function (node){
return _renderNodeObmSettings(node)
return _renderNodeMgmtSettings(node)
.then(function (retNode){
return retNode.obmSettings;
});
Expand Down Expand Up @@ -280,7 +294,7 @@ function nodesRouterFactory (
});
})
.then(function() {
return _renderNodeObmSettings(node);
return _renderNodeMgmtSettings(node);
});
}));

Expand Down Expand Up @@ -324,10 +338,13 @@ function nodesRouterFactory (
*/

router.get('/nodes/:identifier/ssh', rest(function (req) {
return nodeApiService.getNodeSshById(req.params.identifier);
}, {
serializer: 'Serializables.V1.Ssh',
isObject: true
return nodeApiService.getNodeById(req.params.identifier)
.then(function(node) {
return _renderNodeMgmtSettings(node)
.then(function (retNode){
return retNode.sshSettings;
});
});
}));


Expand All @@ -349,14 +366,32 @@ function nodesRouterFactory (
*/

router.post('/nodes/:identifier/ssh', rest(function (req) {
return nodeApiService.postNodeSshById(req.params.identifier, req.body);
var node;
var newBody;

return Promise.try(function() {
if (req.body.host && req.body.user && req.body.password) {
return waterline.nodes.needByIdentifier(req.params.identifier);
} else {
throw new Errors.BadRequestError('Invalid SSH body');
}
})
.then(function(queryNode) {
node = queryNode;
newBody = {
nodeId: req.params.identifier,
service: 'ssh-ibm-service',
config: req.body
};
return waterline.ibms.upsertByNode(req.params.identifier, newBody);
})
.then(function() {
return _renderNodeMgmtSettings(node);
});
}, {
deserializer: 'Serializables.V1.Ssh',
serializer: 'Serializables.V1.Node',
renderOptions: { success: 201 }
}));


/**
* @api {get} /api/1.1/nodes/:identifier/catalogs GET /:id/catalogs
* @apiVersion 1.1.0
Expand Down
118 changes: 118 additions & 0 deletions lib/api/2.0/ibms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright 2016, EMC, Inc.

'use strict';

var injector = require('../../../index.js').injector;
var controller = injector.get('Http.Services.Swagger').controller;
var schemaApiService = injector.get('Http.Api.Services.Schema');
var nameSpace = '/api/2.0/ibms/definitions/';
var waterline = injector.get('Services.Waterline');
var eventsProtocol = injector.get('Protocol.Events');
var Errors = injector.get('Errors');
var _ = injector.get('_'); // jshint ignore:line


// GET /api/2.0/ibms
var ibmsGet = controller(function(req) {
return waterline.ibms.find(req.query);
});

// PUT /api/2.0/ibms
var ibmsPut = controller({success: 201}, function(req) {
var nodeId = req.swagger.params.body.value.nodeId;
delete req.swagger.params.body.value.nodeId;
return waterline.ibms.upsertByNode(nodeId, req.swagger.params.body.value);
});

// GET /api/2.0/ibms/identifier
var ibmsGetById = controller(function(req) {
return waterline.ibms.needByIdentifier(req.swagger.params.identifier.value);
});

// PATCH /api/2.0/ibms/identifier
var ibmsPatchById = controller( function(req) {
var ibmId = req.swagger.params.identifier.value;
var values = req.swagger.params.body.value;
return waterline.ibms.needByIdentifier(ibmId)
.then(function(oldIbm) {
/* Get nodes that need to publish events */
if (oldIbm.node && !values.nodeId) {
return Promise.all([waterline.nodes.getNodeById(oldIbm.node)]);
} else if (!oldIbm.node && values.nodeId) {
return Promise.all([waterline.nodes.getNodeById(values.node)]);
} else if (oldIbm.node && values.nodeId && oldIbm.node === values.nodeId) {
return Promise.all([waterline.nodes.getNodeById(oldIbm.node)]);
} else if (oldIbm.node && values.nodeId && oldIbm.node !== values.nodeId) {
return Promise.all([waterline.nodes.getNodeById(oldIbm.node),
waterline.nodes.getNodeById(values.nodeId)]);
}
})
.then(function(oldNodes) {
return waterline.ibms.updateByIdentifier(ibmId, values)
.tap(function() {
/* Publish events of nodes got beofre update */
_.forEach(oldNodes, function(oldNode) {
if (oldNode) {
/* asynchronous, don't wait promise return for performance*/
return waterline.nodes.getNodeById(oldNode.id)
.then(function(newNode) {
return eventsProtocol.publishNodeAttrEvent(oldNode, newNode, 'ibms');
})
.catch(function (error) {
throw new Errors.BaseError('Error Occured', error.message);
});
}
});
});
});
});

// DELETE /api/2.0/ibms/identifier
var ibmsDeleteById = controller({success: 204}, function(req) {
var ibmId = req.swagger.params.identifier.value;
return waterline.ibms.needByIdentifier(ibmId)
.then(function (ibm) {
return waterline.nodes.getNodeById(ibm.node);
})
.then(function (oldNode) {
return waterline.ibms.destroyByIdentifier(ibmId)
.tap(function () {
if (oldNode) {
/* asynchronous, don't wait promise return for performance*/
waterline.nodes.getNodeById(oldNode.id)
.then(function (newNode) {
return eventsProtocol.publishNodeAttrEvent(oldNode, newNode, 'ibms');
})
.catch(function (error) {
throw new Errors.BaseError('Error Occured', error.message);
});
}
});
});

});

// GET /ibms/definitions
var ibmsDefinitionsGetAll = controller(function() {
return schemaApiService.getNamespace(nameSpace);
});

// GET /ibms/definitions/{name}
var ibmsDefinitionsGetByName = controller(function(req) {
var schemaUid = nameSpace + req.swagger.params.name.value;
var schema = schemaApiService.getSchema(schemaUid);
if (schema) {
return schema;
}
throw new Errors.NotFoundError(schemaUid + ' Not Found');
});

module.exports = {
ibmsGet: ibmsGet,
ibmsPut: ibmsPut,
ibmsGetById: ibmsGetById,
ibmsPatchById: ibmsPatchById,
ibmsDeleteById: ibmsDeleteById,
ibmsDefinitionsGetAll: ibmsDefinitionsGetAll,
ibmsDefinitionsGetByName: ibmsDefinitionsGetByName
};
Loading