-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Cisco UCS Service Profile Discovery #420
Conversation
uppalk1
commented
Mar 7, 2017
ucsTool, | ||
rackmountData, | ||
rootData, | ||
serverData, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'serverData' is defined but never used.
graphId = uuid.v4(), | ||
ucsJob, | ||
ucsTool, | ||
rackmountData, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'rackmountData' is defined but never used.
throw error; | ||
}) | ||
.then(function(data){ | ||
return [data, waterline.obms.upsertByNode(data.id,obm)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
}) | ||
.then(function(data) { | ||
assert.object(data); | ||
return data['ServiceProfile']['members'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
['ServiceProfile'] is better written in dot notation.
['members'] is better written in dot notation.
Missing semicolon.
urlParse = require('url-parse'); | ||
|
||
module.exports = UcsServiceProfileDiscoveryJobFactory; | ||
di.annotate(UcsServiceProfileDiscoveryJobFactory, new di.Provide('Job.Ucs.Service.Profile.Discovery')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is too long.
|
||
return self.getRoot() | ||
.then(function(root) { | ||
return [ root, self.createServiceProfile(root) ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since root
is not used in following spread
, so it better to be removed from the array.
protocol: protocol, | ||
username: this.options.username, | ||
password: this.options.password, | ||
ucs: this.options.ucs, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please teach me what's the difference between the setting of ucs
and host
? Because I see you use the ucs
as the host in the query but rather than host
var host = this.settings.ucs;
var url= "/login?host=" + host+ "&user="+ username + "&password=" + password;
My understanding is:
host
is the ucs-service address, RackHD use the ucs-service to talk with UCS servers.ucs
is the target UCS server, the ucs-service proxies the request to UCS server.
Is correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper that is correct.
properties: { | ||
catalog: {} | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the schema for the new base task.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper can you point me to one that I could use as a reference ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty simple, just put a JSON schema in the property optionsSchema
, this is very alike with the JSON schema in swagger ui.
This is an example: https://github.com/RackHD/on-tasks/blob/master/lib/task-data/base-tasks/provide-catalog-data.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper We will revisit the schema soon for all ucs-service tasks. For now this may not be held as a gate for PR merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@uppalk1 : I am OK with your plan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper if ok with the plan, can you please help remove the -1 that currently blocks the PR from being merged?
return data['ServiceProfile']['members'] | ||
}) | ||
.map(function(members){ | ||
self.createNode(members, Constants.NodeTypes.Compute); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This promise has to be returned, otherwise this function will return earlier before all nodes are really created.
var node = { | ||
type: type, | ||
name: data.name, | ||
associatedServer: data.associatedServer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this property? I don't see it is defined in node model (https://github.com/RackHD/on-core/blob/master/lib/models/node.js). If it is not necessary, them remove it; if you think this is necessary, please explain the reason and then we can check whether it is suitable to create a new property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper I created a new relation called "associatedTo" instead of creating a new property
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good.
assert.string(data.name); | ||
assert.string(data.path); | ||
var id; | ||
id = [config.ucs, data.path]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the plural of id
or change to other better name.
Because when I see the code identifer: id
in line 174, I thought the identifer
need be array, but you wrongly gave it a single id. So I look back to check the node, and see the id
is really an array.
My point is choosing a good variable name and don't bring surprise to other people who read the code.
.then(function(curNode) { | ||
return waterline.nodes.updateOne( | ||
{ id: curNode.id }, | ||
node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In line 175, the relations is reset to be empty, since this line of code is to update the node document, so whether it is intentionally to reset the relations? And how the relations are built again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper Yes, the relation will be rebuilt with the discovery.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, thanks for explanation, could you please add some comment here
}); | ||
}; | ||
|
||
UcsServiceProfileDiscoveryJob.prototype.createNode = function(data, type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function name is not accurate, the code is to "update or create" node, not just "create" node.
@@ -0,0 +1,17 @@ | |||
// Copyright 2016, EMC, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect copyright date
injectableName: 'Task.Base.UCS.Service.Profile.Discovery', | ||
runJob: 'Job.Ucs.Service.Profile.Discovery', | ||
requiredOptions: [ | ||
'uri' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From your implementation, the username
, password
, ucs
are also required options.
assert.string(this.options.uri);
assert.string(this.options.username);
assert.string(this.options.password);
assert.string(this.options.ucs);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper this will be refactored as part of https://rackhd.atlassian.net/browse/RAC-4389
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sound good.
requiredProperties: { | ||
}, | ||
properties: { | ||
catalog: {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this property used for? I don't see any reason to define such property and I don't see any code is to create the catalog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper This is a place holder for follow on stories to create a catalog for UCS logical server (if we deem its necessary)
@@ -0,0 +1,17 @@ | |||
// Copyright 2016, EMC, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect copyright date
ucs: this.options.ucs, | ||
verifySSL: this.options.verifySSL || false | ||
}; | ||
this.ucs = new UcsTool(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.ucs
and this.settings.ucs
is a little confused here, please rename to another distinguish one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyscamper I don't understand your confusion. I'm creating an instance and assigning settings to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the same variable name ucs
, but when it is in this.settings
it means an IP address, however it is a UCS tool instance if it is in this
username:'user', | ||
password:'pass', | ||
ucs:"1.1.1.1" | ||
}, {}, graphId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is taskId
, not graphId
, though this doesn't break the unit-test, but don't bring confusion since unit-test is a kind of doc for the code.
ucs:"1.1.1.1" | ||
}, {}, graphId); | ||
|
||
sandbox.stub(ucsJob.ucs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct usage is sandbox.stub(ucsJob, 'ucs')
}); | ||
|
||
afterEach(function() { | ||
sandbox.restore(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All stubs are created once in before
, but all are restored after the first test case finishes. So when the 2nd test case begins to run, actually all stubs are not existing, so what's the purpose to create so many stubs in advance?
Meanwhile, I see a lot stubs are never been used, if so, just remove them.
return ucsJob.logIn() | ||
.then(function(data) { | ||
expect(data).to.deep.equal("cookie"); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, line 140-143 can be short for:
return ucsJob.logIn().to.become('cookie');
Your code is still OK, just for your awareness if you like it.
relations : [] | ||
}; | ||
// Update existing node or create a new one | ||
return waterline.nodes.needOne({identifiers:data.path}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am thinking of a corner case, since the identifiers is [config.ucs, data.path]
, here you only find node document by data.path
, but how about if the ucs server address is actually changed for the target node, then it means this node's obm service need be updated as well.
}); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the test coverage is good enough (this should be one of the reason why the coverage decrease a lot), I see a lot logic is actually not tested, for example:
(1) If ucs request error, then the job should fail.
(2) If input any invalid option, the job should fail.
(3) If ucs request returns multiple servers, then multiple nodes should be updated or created.
(4) The obm service should be created (or updated) when the node is created (or updated)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix my comment and improve the test coverage.
var obm = { | ||
config: { | ||
uri: "http://10.240.19.220:7080/sys", | ||
host: "10.240.19.220", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use a faked IP
} | ||
], | ||
"type": "compute" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
"associatedServer": "test", | ||
"name": "ls-test", | ||
"path": "org-root/ls-test" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
"associatedServer": "test", | ||
"name": "ls-test", | ||
"path": "org-root/ls-test" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
relationType: 'associatedTo', | ||
targets: [newNode.associatedServer] | ||
}]; | ||
return self.updateRelations(newNode.id, relations) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
}) | ||
.then(function(data) { | ||
assert.object(data); | ||
return data['ServiceProfile']['members']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
['ServiceProfile'] is better written in dot notation.
['members'] is better written in dot notation.
"associatedServer": "test", | ||
"name": "ls-test", | ||
"path": "org-root/ls-test" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
BUILD on-tasks #2136 : ABORTED
BUILD unit-tests #12504 Error Logs ▼Test Name: ucs-service-profile-discovery-spec.js task-data expected properties should have valid default option values Error Details: Task.Ucs.Service.Profile.Discovery: JSON schema validation failed - data.uri should be string Stack Trace: Error: Task.Ucs.Service.Profile.Discovery: JSON schema validation failed - data.uri should be string at TaskOptionValidator.JsonSchemaValidator.validatePatternsSkipped (node_modules/on-core/lib/common/json-schema-validator.js:95:23) at TaskOptionValidator.validateContextSkipped (lib/utils/task-option-validator.js:9:2054) at lib/task.js:9:29334 at arrayEach (node_modules/lodash/index.js:1289:13) at Function.<anonymous> (node_modules/lodash/index.js:3345:13) at Function.Task.validateOptions (lib/task.js:9:28969) at lib/task.js:9:20104 at tryCatcher (node_modules/on-core/node_modules/bluebird/js/main/util.js:26:23) at Promise._settlePromiseFromHandler (node_modules/on-core/node_modules/bluebird/js/main/promise.js:510:31) at Promise._settlePromiseAt (node_modules/on-core/node_modules/bluebird/js/main/promise.js:584:18) at Promise._settlePromises (node_modules/on-core/node_modules/bluebird/js/main/promise.js:700:14) at Async._drainQueue (node_modules/on-core/node_modules/bluebird/js/main/async.js:123:16) at Async._drainQueues (node_modules/on-core/node_modules/bluebird/js/main/async.js:133:10) at Immediate.Async.drainQueues [as _onImmediate] (node_modules/on-core/node_modules/bluebird/js/main/async.js:15:14) |
BUILD on-tasks #2137 : ABORTED
|
*Create base-task, task and job for a new workflow to discover UCS Service Profile Clean up ucs-service-profile-discovery test Address PR comments and improve unit test coverage Schema reference as a future enhancement
594ff87
to
6deddb8
Compare
"associatedServer": "test", | ||
"name": "ls-test", | ||
"path": "org-root/ls-test" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
BUILD on-tasks #2138 : ABORTED
|
It look like the coveralls decreased coverage is due to a change in the way node-coveralls calculates the coverage percentage. See nickmerwin/node-coveralls#158 The actual coverage as reported by istanbul has increased. from master: https://travis-ci.org/RackHD/on-tasks/jobs/206278092
from this PR: https://travis-ci.org/RackHD/on-tasks/jobs/209488312
|
test this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, 👍
verifySSL: this.options.verifySSL || false | ||
}; | ||
this.ucs = new UcsTool(); | ||
this.ucs.settings = this.settings; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's even more confusing between this.settings.ucs
and this.ucs.settings
ucsTool.clientRequest.onCall(1).resolves(rootData); | ||
return ucsJob._run() | ||
.then(function() { | ||
expect(waterline.nodes.updateOne).to.be.called.twice; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no called.twice
or called.once
, you should use calledTwice
and calledOnce
.
The twice
or once
actually has no assertion effect, actually you could append any arbitrary words after called
. For example:
expect(xxxx).to.be.called.notexisting
or expect(xxx).to.be.called.foobar
will always make the mocha happy. so the mocha success doesn't reflect such error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 after at least fix the called.once
and called.twice