Drawing a rack with 2 Compute Nodes
diff --git a/views/ngXosViews/diagnostic/env/default.js b/views/ngXosViews/diagnostic/env/default.js
index f139cf2..11ee777 100644
--- a/views/ngXosViews/diagnostic/env/default.js
+++ b/views/ngXosViews/diagnostic/env/default.js
@@ -8,6 +8,6 @@
module.exports = {
host: 'http://clnode078.clemson.cloudlab.us:9999/',
- xoscsrftoken: '3l5fr6tkXW0dxJ2OqqD0ftEzzD9URc4C',
- xossessionid: 'tagguvgkn2vpif4eml6ynvdw9vlx6os9'
+ xoscsrftoken: 'nGSrDjG6Ryqho9Kl6eSXAcyPg2YudUZQ',
+ xossessionid: '2x7omv64a2mpb1f62vhcy40kq32swv75'
};
diff --git a/views/ngXosViews/diagnostic/env/local.js b/views/ngXosViews/diagnostic/env/local.js
index d3076b7..c65eb2f 100644
--- a/views/ngXosViews/diagnostic/env/local.js
+++ b/views/ngXosViews/diagnostic/env/local.js
@@ -7,7 +7,7 @@
// (works only for local environment as both application are served on the same domain)
module.exports = {
- host: 'http://xos.local:9999/',
+ host: 'http://localhost:4000/',
xoscsrftoken: 'IGSrPSAOmBorK8uxbbscQbn3ODPb9dDW',
xossessionid: 'i8hltbdt3po3uxkbvfmzy15o98p9s157'
};
diff --git a/views/ngXosViews/diagnostic/src/css/serviceTopology.css b/views/ngXosViews/diagnostic/src/css/serviceTopology.css
index 525ca41..19a24a0 100644
--- a/views/ngXosViews/diagnostic/src/css/serviceTopology.css
+++ b/views/ngXosViews/diagnostic/src/css/serviceTopology.css
@@ -4,6 +4,16 @@
height: 50%;
}
+diagnostic .onethird-height {
+ position: relative;
+ height: 33%;
+}
+
+diagnostic .twothird-height {
+ position: relative;
+ height: 67%;
+}
+
diagnostic .subscriber-select{
max-width: 200px;
position: absolute;
diff --git a/views/ngXosViews/diagnostic/src/js/diagnostic.js b/views/ngXosViews/diagnostic/src/js/diagnostic.js
index f499d4e..2b31f31 100644
--- a/views/ngXosViews/diagnostic/src/js/diagnostic.js
+++ b/views/ngXosViews/diagnostic/src/js/diagnostic.js
@@ -8,7 +8,7 @@
templateUrl: 'templates/diagnostic.tpl.html',
controllerAs: 'vm',
controller: function(Subscribers, ServiceRelation){
- Subscribers.queryWithDevices().$promise
+ Subscribers.query().$promise
.then((subscribers) => {
this.subscribers = subscribers;
return ServiceRelation.get();
diff --git a/views/ngXosViews/diagnostic/src/js/logicTopology.js b/views/ngXosViews/diagnostic/src/js/logicTopology.js
index c126053..9181e56 100644
--- a/views/ngXosViews/diagnostic/src/js/logicTopology.js
+++ b/views/ngXosViews/diagnostic/src/js/logicTopology.js
@@ -11,7 +11,7 @@
bindToController: true,
controllerAs: 'vm',
template: '',
- controller: function($element, $log, $scope, $rootScope, d3, LogicTopologyHelper, Node){
+ controller: function($element, $log, $scope, $rootScope, d3, LogicTopologyHelper, Node, Tenant, Ceilometer){
$log.info('Logic Plane');
var svg;
@@ -45,16 +45,35 @@
}
});
- $rootScope.$on('instance.detail', (evt, instance) => {
+ $rootScope.$on('instance.detail', (evt, service) => {
- $log.info(`Highlight instance; ${instance.id}`)
+ $log.info(`Highlight instance`, service)
- LogicTopologyHelper.getInstanceStatus(instance.id);
- LogicTopologyHelper.updateTree(svg);
+ let param = {
+ 'service_vsg': {kind: 'vCPE'},
+ 'service_vbng': {kind: 'vBNG'},
+ 'service_volt': {kind: 'vOLT'}
+ };
+
+ Tenant.queryVsgInstances(param[service.name]).$promise
+ .then((instances) => {
+ console.log(instances);
+ LogicTopologyHelper.getInstanceStatus(instances);
+ LogicTopologyHelper.updateTree(svg);
+
+ return Ceilometer.getInstancesStats(instances);
+ })
+ .then((stats) => {
+ console.log('stats', stats);
+ })
+ .catch((e) => {
+ throw new Error(e);
+ });
})
handleSvg($element[0]);
LogicTopologyHelper.setupTree(svg);
+
}
};
});
diff --git a/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js b/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
index 8703344..f9c0850 100644
--- a/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
+++ b/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
@@ -211,7 +211,7 @@
baseData.children[0].children[0].computeNodes = computeNodes;
};
- this.getInstanceStatus = (instanceId) => {
+ this.getInstanceStatus = (instances) => {
const computeNodes = baseData.children[0].children[0].computeNodes;
@@ -223,19 +223,16 @@
});
});
- let targetInstance = computeNodes.reduce((selected, node) => {
- let found = lodash.find(node.instances, {id: instanceId});
-
- if(found){
- return found;
- }
- }, null);
-
- // object are passed by reference,
- // updating this update the instance in the tree
- if(targetInstance){
- targetInstance.selected = true;
- }
+ lodash.forEach(instances, (id) => {
+ computeNodes.map((node) => {
+ node.instances.map((instance) => {
+ if(instance.id === id){
+ instance.selected = true;
+ }
+ return instance;
+ });
+ });
+ });
}
});
diff --git a/views/ngXosViews/diagnostic/src/js/nodeDrawer.js b/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
index 2548812..128848d 100644
--- a/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
+++ b/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
@@ -10,6 +10,9 @@
angular.module('xos.serviceTopology')
.service('NodeDrawer', function(d3, serviceTopologyConfig, RackHelper){
+
+ var _this = this;
+
this.addNetworks = (nodes) => {
nodes.append('path')
.attr({
@@ -131,9 +134,10 @@
// if there are Compute Nodes
if(nodeContainer.length > 0){
- angular.forEach(nodeContainer.data(), (computeNode) => {
- this.drawInstances(nodeContainer, computeNode.instances);
- });
+ // draw instances for each compute node
+ nodeContainer.each(function(a){
+ _this.drawInstances(d3.select(this), a.instances);
+ })
}
};
@@ -150,7 +154,7 @@
};
this.drawInstances = (container, instances) => {
-
+
let {width, height} = container.node().getBoundingClientRect();
let elements = container.selectAll('.instances')
@@ -166,7 +170,7 @@
.transition()
.duration(serviceTopologyConfig.duration)
.attr({
- transform: d => `translate(${RackHelper.getInstancePosition(d.d3Id.replace('instance-', '') - 1)})`
+ transform: (d, i) => `translate(${RackHelper.getInstancePosition(i)})`
});
instanceContainer.append('rect')
diff --git a/views/ngXosViews/diagnostic/src/js/rest_services.js b/views/ngXosViews/diagnostic/src/js/rest_services.js
index 6e3771a..733a690 100644
--- a/views/ngXosViews/diagnostic/src/js/rest_services.js
+++ b/views/ngXosViews/diagnostic/src/js/rest_services.js
@@ -6,13 +6,91 @@
return $resource('/xos/services/:id', {id: '@id'});
})
.service('Tenant', function($resource){
- return $resource('/xos/tenants');
+ return $resource('/xos/tenants', {id: '@id'}, {
+ queryVsgInstances: {
+ method: 'GET',
+ isArray: true,
+ interceptor: {
+ response: (res) => {
+
+ // NOTE
+ // Note that VCPETenant is now VSGTenant.
+
+ let instances = [];
+
+ angular.forEach(res.data, (tenant) => {
+ let info = JSON.parse(tenant.service_specific_attribute);
+ if(info && info.instance_id){
+ instances.push(info.instance_id);
+ }
+ });
+
+ return instances;
+ }
+ }
+ }
+ });
+ })
+ .service('Ceilometer', function($http, $q, Instances) {
+
+ /**
+ * Get stats for a single instance
+ */
+ this.getInstanceStats = (instanceUuid) => {
+ let deferred = $q.defer();
+
+ $http.get('/xoslib/meterstatistics', {resource: instanceUuid})
+ .then((res) => {
+ deferred.resolve(res.data);
+ })
+ .catch((e) => {
+ deferred.reject(e);
+ })
+
+ return deferred.promise;
+ };
+
+ /**
+ * Collect stats for an array of instances
+ */
+ this.getInstancesStats = (instances) => {
+ let deferred = $q.defer();
+ let instancePromises = [];
+ let instanceList = [];
+
+ // retrieve instance details
+ instances.forEach((instanceId) => {
+ instancePromises.push(Instances.get({id: instanceId}).$promise);
+ });
+
+ // get all instance data
+ $q.all(instancePromises)
+ .then((_instanceList) => {
+ instanceList = _instanceList;
+ let promises = [];
+ // foreach instance query stats
+ instanceList.forEach((instance) => {
+ promises.push(this.getInstanceStats(instance.instance_uuid));
+ });
+ return $q.all(promises);
+ })
+ .then(stats => {
+ // augment instance with stats information
+ instanceList.map((instance, i) => {
+ instance.stats = stats[i];
+ });
+ deferred.resolve(instanceList);
+ })
+ .catch(deferred.reject);
+
+ return deferred.promise;
+ };
})
.service('Slice', function($resource){
return $resource('/xos/slices', {id: '@id'});
})
.service('Instances', function($resource){
- return $resource('/xos/instances', {id: '@id'}, {});
+ return $resource('/xos/instances/:id', {id: '@id'});
})
.service('Node', function($resource, $q, Instances){
return $resource('/xos/nodes', {id: '@id'}, {
@@ -237,8 +315,6 @@
parent: null,
children: [buildChild(services, tenants, baseService)]
};
-
- console.log(baseData);
return baseData;
};
diff --git a/views/ngXosViews/diagnostic/src/js/serviceTopology.js b/views/ngXosViews/diagnostic/src/js/serviceTopology.js
index 0587cb0..b358abf 100644
--- a/views/ngXosViews/diagnostic/src/js/serviceTopology.js
+++ b/views/ngXosViews/diagnostic/src/js/serviceTopology.js
@@ -57,6 +57,10 @@
this.selectedSlice = slice;
this.instances = instances;
})
+ .catch(e => {
+ this.errors = e;
+ throw new Error(e);
+ })
};
$scope.$watch(() => this.serviceChain, (chain) => {
diff --git a/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js b/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js
index 05ddba7..2b92ba5 100644
--- a/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js
+++ b/views/ngXosViews/diagnostic/src/js/serviceTopologyHelper.js
@@ -120,7 +120,6 @@
var nodeEnter = node.enter().append('g')
.attr({
class: d => {
- console.log(d);
return `node ${d.type}`
},
transform: `translate(${source.y0}, ${source.x0})`
@@ -220,14 +219,7 @@
const serviceClick = function(d) {
- $log.info('TODO emit an event to highlight VMs', d);
-
- // TODO how I get the instance id???
- $rootScope.$emit('instance.detail', {id: d.service.service_specific_attribute.instance_id || null});
-
- if(!d.service){
- return;
- }
+ $rootScope.$emit('instance.detail', {name: d.humanReadableName});
// unselect all
_svg.selectAll('circle')
diff --git a/views/ngXosViews/diagnostic/src/templates/diagnostic.tpl.html b/views/ngXosViews/diagnostic/src/templates/diagnostic.tpl.html
index b2375c7..ff88b49 100644
--- a/views/ngXosViews/diagnostic/src/templates/diagnostic.tpl.html
+++ b/views/ngXosViews/diagnostic/src/templates/diagnostic.tpl.html
@@ -1,8 +1,8 @@
<div class="container-fluid">
- <div class="half-height">
+ <div class="onethird-height">
<service-topology service-chain="vm.serviceChain"></service-topology>
</div>
- <div class="half-height">
+ <div class="twothird-height">
<!-- <div class="panel panel-primary subscriber-select">
<div class="panel-heading">Select a subscriber:</div>
<div class="panel-body">