- Change the icon for ones more appropriate.
- Attempt to solve the invisible vxlan when using
a "triange" vxlan topology.
- Change the logical dialog to be "half-static".
The position will be set one time and will keep the
last given instead of trying to appear near the related node.
Change-Id: I1bdd92a5b97c9f8638c5415391c02f3deb6d168a
Signed-off-by: Maxime Millette-Coulombe <mmcoulombe@inocybe.com>
-define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function(d3, OvsCore, _) {
+define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'underscore'], function (d3, OvsCore, _) {
'use strict';
var root = null,
canvasWidth = -1,
canvasHeight = -1,
- bbox = { x:0, y:15, width: 0, height: 0},
+ bbox = {
+ x: 0,
+ y: 15,
+ width: 0,
+ height: 0
+ },
// config
nodeWidth = 15,
nodeHeight = -1,
- defaultRouterWidth = 66,
- defaultRouterHeight = 66,
- networkMargin = { width: 120, height: 15},
- routerMargin = { width: 120, height: 40},
- vmMargin = { width: 90, height: 30},
+ defaultRouterWidth = 52,
+ defaultRouterHeight = 52,
+ networkMargin = {
+ width: 120,
+ height: 15
+ },
+ routerMargin = {
+ width: 120,
+ height: 40
+ },
+ vmMargin = {
+ width: 90,
+ height: 30
+ },
defaultVmsWidth = 48,
defaultVmsHeight = 48,
ipNetworkTextMaxLength = 60,
d3Router = null,
randomize = OvsCore.Util.Math.Random(42);
- function LogicalGraph(id, width , height) {
+ function LogicalGraph(id, width, height) {
canvasWidth = width;
canvasHeight = height;
nodeHeight = height - 15;
var tmp = d3.select(id).append("svg")
- .attr('width', width)
- .attr('height', height)
- .append("svg:g")
- .attr('class', 'layer_0');
+ .attr('width', width)
+ .attr('height', height)
+ .append("svg:g")
+ .attr('class', 'layer_0');
tmp.append('svg:rect')
- .attr('width', width)
- .attr('height', height)
- .attr('fill', 'white');
+ .attr('width', width)
+ .attr('height', height)
+ .attr('fill', 'white');
root = tmp.call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
- .append("g");
+ .append("g");
tmp.on("dblclick.zoom", null);
addDefs();
}
var defs = d3.select('svg').insert('svg:defs', ':first-child');
var filter = defs.append('svg:filter').attr('id', 'boxShadow').attr('x', '0').attr('y', '0').attr('width', '200%').attr('height', '200%');
filter.append('feOffset').attr('in', 'SourceAlpha').attr('result', 'offOut').attr('dx', 0).attr('dy', 0);
- filter.append('feGaussianBlur').attr('stdDeviation', '5').attr('in','offOut').attr('result', 'blurOut');
+ filter.append('feGaussianBlur').attr('stdDeviation', '5').attr('in', 'offOut').attr('result', 'blurOut');
filter.append('feOffset').attr('in', 'SourceGraphic').attr('in2', 'blurOut').attr('mode', 'normal');
}
Object.defineProperties(LogicalGraph.prototype, {
networks: {
- set: function(value) {
+ set: function (value) {
networkData = value;
- value.forEach(function(net) {
+ value.forEach(function (net) {
routerData = routerData.concat(net.routers);
});
- value.forEach(function(net) {
+ value.forEach(function (net) {
vmData = vmData.concat(net.instances);
});
}
}
});
- LogicalGraph.prototype.start = function() {
+ LogicalGraph.prototype.start = function () {
setTopologyPosition.call(this, networkData);
addLinksToDom.call(this, linkData);
addNetWorkRouterVmsToDom.call(this, networkData, routerData, vmData);
update.call(this);
};
- LogicalGraph.prototype.freeDOM = function() {
+ LogicalGraph.prototype.freeDOM = function () {
d3Node.remove();
d3Link.remove();
d3Vm.remove();
routerData = [];
vmData = [];
linkData = [];
- bbox = { x:0, y:15, width: 0, height: 0};
+ bbox = {
+ x: 0,
+ y: 15,
+ width: 0,
+ height: 0
+ };
};
function addLinksToDom(linksData) {
- d3Link = root.selectAll('.llink')
+ d3Link = root.selectAll('.llink')
.data(linksData).enter().append('svg:g');
- d3Link.append('rect')
- .attr('width', function(d) {
+ d3Link.append('rect')
+ .attr('width', function (d) {
return d.target.x - d.source.x;
})
.attr('height', linkHeight)
- .style('fill', function(d) {
+ .style('fill', function (d) {
return d.color;
});
- d3Link.append('text')
+ d3Link.append('text')
.attr('x', 40)
.attr('y', -3)
- .text(function(d) {return d.text;});
+ .text(function (d) {
+ return d.text;
+ });
}
function addNetWorkRouterVmsToDom(networks, routers, vms) {
var ctx = this,
timer = null;
- function getAbsPos() {
- var elem = d3.select(this)[0][0],
- elemAbsBBox = elem.getBoundingClientRect(),
- parentAbsBox = d3.select('#l_graph').node().getBoundingClientRect(),
- left = elemAbsBBox.left - parentAbsBox.left + (elemAbsBBox.right - elemAbsBBox.left),
- top = elemAbsBBox.top - parentAbsBox.top;
-
- if (top < 0 ) {
- top = 10;
- }
- var event = {
- left : left,
- top : top
- };
- return event;
- }
d3Node = root.selectAll('.network')
.data(networks).enter()
.append('svg:g');
.attr('height', nodeHeight)
.attr('rx', 10)
.attr('ry', 10)
- .style('fill', function(d) {
+ .style('fill', function (d) {
return d.color;
- }).on('click', function(d) {
+ }).on('click', function (d) {
if (d3.event.defaultPrevented) return;
- timer = setTimeout(function() {
- var e = getAbsPos.call(this);
- ctx.onClick(e, d);
+ timer = setTimeout(function () {
+ ctx.onClick(d);
}.bind(this), 150);
- }).on('dblclick', function(d) {
+ }).on('dblclick', function (d) {
clearTimeout(timer);
ctx.dblClick(d);
});
// append the network name text
d3Node.append('text')
- .attr('x', nodeWidth / 2 )
- .attr('y', nodeHeight /2 )
+ .attr('x', nodeWidth / 2)
+ .attr('y', nodeHeight / 2)
.style('text-anchor', 'middle')
.style('writing-mode', 'tb')
.style('font-size', '12px')
.style('glyph-orientation-vertical', '0')
- .text(function(d) { return d.name; });
+ .text(function (d) {
+ return d.name;
+ });
// text info for the network ip
d3Node.append('text')
.attr('transform',
OvsCore.Util.String.Format('translate({0} {1}) rotate(-90) translate(-{0} -{1})', nodeWidth + 10, nodeHeight - 15))
.attr('class', 'linfolabel')
- .text(function(d) {return d.ip;});
+ .text(function (d) {
+ return d.ip;
+ });
// vm
d3Vm.append('svg:image')
.attr('width', defaultVmsWidth)
.attr('height', defaultVmsHeight)
.attr('filter', 'url(#boxShadow)')
- .attr('xlink:href', function(d) {
+ .attr('xlink:href', function (d) {
return d.type === 'network:dhcp' ?
'src/app/ovsdb/assets/dhcp.png' : 'src/app/ovsdb/assets/vm.png';
})
- .on('click', function(d) {
+ .on('click', function (d) {
if (d3.event.defaultPrevented) return;
- timer = setTimeout(function() {
- var e = getAbsPos.call(this);
- ctx.onClick(e, d);
+ timer = setTimeout(function () {
+ ctx.onClick(d);
}.bind(this), 150);
- }).on('dblclick', function(d) {
+ }).on('dblclick', function (d) {
clearTimeout(timer);
ctx.dblClick(d);
});
.attr('width', defaultRouterWidth)
.attr('height', defaultRouterHeight)
.attr('xlink:href', 'src/app/ovsdb/assets/router.png')
- .on('click', function(d) {
+ .on('click', function (d) {
if (d3.event.defaultPrevented) return;
- timer = setTimeout(function() {
- var e = getAbsPos.call(this);
- ctx.onClick(e, d);
+ timer = setTimeout(function () {
+ ctx.onClick(d);
}.bind(this), 150);
- }).on('dblclick', function(d) {
+ }).on('dblclick', function (d) {
clearTimeout(timer);
ctx.dblClick(d);
});
.attr('y', defaultRouterHeight + 15)
.attr('text-anchor', 'middle')
.attr('class', 'linfolabel')
- .text(function(d) { return d.name; });
+ .text(function (d) {
+ return d.name;
+ });
// vm name label
d3Vm.append('text')
.attr('y', defaultVmsHeight + 15)
.attr('text-anchor', 'middle')
.attr('class', 'linfolabel')
- .text(function(d) { return d.name; });
+ .text(function (d) {
+ return d.name;
+ });
// vm floating ip label
d3Vm.append('text')
.attr('x', -35)
.attr('y', 40)
.attr('text-anchor', 'middle')
- .text(function(d) {
+ .text(function (d) {
return (d.floatingIp) ? d.floatingIp.ip : '';
});
function findNetworkWithRouter(router) {
var result = [];
- _.each(router.interfaces, function(inter) {
+ _.each(router.interfaces, function (inter) {
if (inter.type === 'router_interface') {
- var net = tmpNetHolder[inter.networkId] || null;
+ var net = tmpNetHolder[inter.networkId] || null;
if (net) {
- result.push({network: net, interface: inter});
+ result.push({
+ network: net,
+ interface: inter
+ });
}
}
});
network.color = d3.hsl(randomize.next() * 360, 1, 0.6).toString();
// look is the network is the highest
- bbox.height = network.y > bbox.height ? network.y : bbox.height ;
+ bbox.height = network.y > bbox.height ? network.y : bbox.height;
bbox.width = network.x > bbox.width ? network.x : bbox.width;
// get the number of "childs" (router, vm)
var nbVm = network.instances.length;
if (!network.external) {
- _.each(network.subnets, function(subnet, i) {
+ _.each(network.subnets, function (subnet, i) {
network.ip += subnet.cidr;
- if (i < network.subnets.length -1) {
- network.ip += ', ';
+ if (i < network.subnets.length - 1) {
+ network.ip += ', ';
}
});
}
function positionateRouter(network, x, y) {
var px = x,
- py = y ;
+ py = y;
// loop over all routers
- _.each(network.routers, function(router, i) {
- router.x = getRouterCentroid(x, py).x ;
+ _.each(network.routers, function (router, i) {
+ router.x = getRouterCentroid(x, py).x;
router.y = py;
py += getRouterMarginHeight();
}
// look is the router is the highest
- bbox.height = router.y > bbox.height ? router.y : bbox.height ;
+ bbox.height = router.y > bbox.height ? router.y : bbox.height;
bbox.width = router.x > bbox.width ? router.x : bbox.width;
linkData.push({
- source: {x: network.x + (nodeWidth * 0.5), y: router.y + (defaultRouterHeight * 0.5)},
- target: {x: router.x + (defaultRouterWidth * 0.5), y: router.y + (nodeWidth * 0.5)},
- color: network.color,
+ source: {
+ x: network.x + (nodeWidth * 0.5),
+ y: router.y + (defaultRouterHeight * 0.5)
+ },
+ target: {
+ x: router.x + (defaultRouterWidth * 0.5),
+ y: router.y + (nodeWidth * 0.5)
+ },
+ color: network.color,
text: router.externalGateway.external_fixed_ips[0].ip_address
});
var nets = findNetworkWithRouter(router),
step = defaultRouterHeight / (nets.length + 1);
- _.forEach(nets, function(net, i) {
+ _.forEach(nets, function (net, i) {
var netPos = getNetworkLayerPosition(bbox.width + defaultRouterWidth);
positionateNetwork(net.network, netPos.x, netPos.y);
linkData.push({
- source: {x: router.x + (2 * nodeWidth), y: router.y + step * (i + 1) },
- target: {x: net.network.x + (nodeWidth * 0.5), y: router.y + (nodeWidth * 0.5 )},
+ source: {
+ x: router.x + (2 * nodeWidth),
+ y: router.y + step * (i + 1)
+ },
+ target: {
+ x: net.network.x + (nodeWidth * 0.5),
+ y: router.y + (nodeWidth * 0.5)
+ },
color: net.network.color,
text: net.interface.ip.ip_address
});
// I do vm before router because router
// will step to another BUS
- _.each(network.instances, function(vm) {
+ _.each(network.instances, function (vm) {
vm.x = x;
vm.y = y;
// look is the network is the highest
- bbox.height = vm.y > bbox.height ? vm.y : bbox.height ;
+ bbox.height = vm.y > bbox.height ? vm.y : bbox.height;
bbox.width = vm.x > bbox.width ? vm.x : bbox.width;
y += getVmMarginHeight();
linkData.push({
- source: {x: network.x + (nodeWidth * 0.5), y: vm.y + (defaultVmsHeight * 0.5 )},
- target: {x: vm.x + (defaultVmsWidth * 0.5), y: vm.y + (nodeWidth * 0.5)},
- color: network.color,
+ source: {
+ x: network.x + (nodeWidth * 0.5),
+ y: vm.y + (defaultVmsHeight * 0.5)
+ },
+ target: {
+ x: vm.x + (defaultVmsWidth * 0.5),
+ y: vm.y + (nodeWidth * 0.5)
+ },
+ color: network.color,
text: vm.ip
});
});
}
/*
- * Scan the whole "BUS" to display it properly
- * ------------------------------------------------
- * I build it in a virtual space, if it need to be
- * resize it at the end when the overal bounding
- * box is known
- */
+ * Scan the whole "BUS" to display it properly
+ * ------------------------------------------------
+ * I build it in a virtual space, if it need to be
+ * resize it at the end when the overal bounding
+ * box is known
+ */
function setTopologyPosition(networks) {
- _.each(networks, function(net) {
+ _.each(networks, function (net) {
tmpNetHolder[net.id] = net;
});
var i = 0;
- for(var key in tmpNetHolder) {
- var margin = (i === 0) ? 5 : networkMargin.width,
- net = tmpNetHolder[key];
- if (net.routers.length > 0) {
- positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
- ++i;
- }
+ for (var key in tmpNetHolder) {
+ var margin = (i === 0) ? 5 : networkMargin.width,
+ net = tmpNetHolder[key];
+ if (net.routers.length > 0) {
+ positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
+ ++i;
+ }
}
- for(var key in tmpNetHolder) {
- var margin = networkMargin.width,
- net = tmpNetHolder[key];
- positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
+ for (var key in tmpNetHolder) {
+ var margin = networkMargin.width,
+ net = tmpNetHolder[key];
+ positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
}
}
/*
- * Check and ajust the height for a network.
- */
+ * Check and ajust the height for a network.
+ */
function ajustHeighBaseOnChilds(nbRouter, nbVm) {
// calculate the height for the number of childs
var childHeight = nbRouter * (getRouterMarginHeight()) +
}
/*
- * Set the view to the modal position
- */
+ * Set the view to the modal position
+ */
function update() {
- d3Node.attr('transform', function(d) {
+ d3Node.attr('transform', function (d) {
return OvsCore.Util.String.Format("translate({0}, {1})",
d.x, d.y
);
});
- d3Router.attr('transform', function(d, i) {
+ d3Router.attr('transform', function (d, i) {
return OvsCore.Util.String.Format("translate({0}, {1})",
d.x, d.y
);
});
- d3Vm.attr('transform', function(d) {
+ d3Vm.attr('transform', function (d) {
return OvsCore.Util.String.Format("translate({0}, {1})",
d.x, d.y
);
});
- d3Link.attr('transform', function(d) {
+ d3Link.attr('transform', function (d) {
return OvsCore.Util.String.Format("translate({0}, {1})",
d.source.x, d.source.y
);
function getRouterCentroid(x, y) {
return {
- x : x + defaultRouterWidth * 0.5,
- y : y + defaultRouterHeight * 0.5
+ x: x + defaultRouterWidth * 0.5,
+ y: y + defaultRouterHeight * 0.5
};
}
function getNetworkLayerPosition(x) {
return {
- x : x + networkMargin.width,
- y : networkMargin.height
+ x: x + networkMargin.width,
+ y: networkMargin.height
};
}
function getVmLayerPosition(nbRouter, x) {
- var t = {
- x : x + vmMargin.width * 2,
- y : getRoutersDim(nbRouter).height + getVmMarginHeight()
+ var t = {
+ x: x + vmMargin.width * 2,
+ y: getRoutersDim(nbRouter).height + getVmMarginHeight()
};
return t;
}
}
},
nodes: {
- get: function() {
+ get: function () {
return _.extend({}, this._bridgeNodes, this._ovsdbNodes);
}
},
Topology.prototype.updateLink = function () {
_.each(this._links, (function (link, key) {
if (link instanceof Link) {
- srcNode = _.filter(this._bridgeNodes, function(node) {
+ srcNode = _.filter(this._bridgeNodes, function (node) {
return node.getFLowName() === link.srcNodeId;
});
- destNode = _.filter(this._bridgeNodes, function(node) {
+ destNode = _.filter(this._bridgeNodes, function (node) {
return node.getFLowName() === link.destNodeId;
});
link.srcNodeId = srcNode[0].nodeId;
this.ovsVersion = ovsVersion;
}
- OvsNode.prototype.showIpAdress = function() {
+ OvsNode.prototype.showIpAdress = function () {
return this.otherLocalIp;
};
- OvsNode.prototype.pretty = function() {
+ OvsNode.prototype.pretty = function () {
return {
- 'tabs' : ['Info'],
- 'containts' : [ {
- 'hasHeader' : false,
- 'headers' : [],
- 'datas' : [
- { key: 'ID', value: this.nodeId},
- { key: 'InetMgr', value: this.inetMgr},
- { key: 'InetNode', value: this.inetNode},
- { key: 'Local IP', value: this.otherLocalIp},
- { key: 'OVS Version', value: this.ovsVersion}
+ 'tabs': ['Info'],
+ 'containts': [{
+ 'hasHeader': false,
+ 'headers': [],
+ 'datas': [
+ {
+ key: 'ID',
+ value: this.nodeId
+ },
+ {
+ key: 'InetMgr',
+ value: this.inetMgr
+ },
+ {
+ key: 'InetNode',
+ value: this.inetNode
+ },
+ {
+ key: 'Local IP',
+ value: this.otherLocalIp
+ },
+ {
+ key: 'OVS Version',
+ value: this.ovsVersion
+ }
]
}]
};
BridgeNode.prototype.addTerminationPoint = function (tp) {
this._tpList.push(tp);
- this._tpList.sort(function(tp1, tp2) {
+ this._tpList.sort(function (tp1, tp2) {
return tp1.ofPort - tp2.ofPort;
});
};
- BridgeNode.prototype.addFlowTableInfo = function(flowTable) {
+ BridgeNode.prototype.addFlowTableInfo = function (flowTable) {
this.flowTable.push(flowTable);
- this.flowTable.sort(function(ft1, ft2) {
+ this.flowTable.sort(function (ft1, ft2) {
return ft1.key - ft2.key;
});
};
- BridgeNode.prototype.pretty = function() {
+ BridgeNode.prototype.pretty = function () {
return {
- 'tabs' : [
+ 'tabs': [
'Basic Info',
'Ports',
'Flow Info',
'Flow Tables'
],
- 'containts' : [
+ 'containts': [
{
- 'hasHeader' : false,
- 'headers' : [],
- 'datas' : [
- { key: 'ID', value: this.nodeId},
- { key: 'Name', value: this.name},
- { key: 'OpenFlow Name', value: this.getFLowName()},
- { key: 'Controller Target', value: this.controllerTarget},
- { key: 'Controller Connected', value: this.controllerConnected}
+ 'hasHeader': false,
+ 'headers': [],
+ 'datas': [
+ {
+ key: 'ID',
+ value: this.nodeId
+ },
+ {
+ key: 'Name',
+ value: this.name
+ },
+ {
+ key: 'OpenFlow Name',
+ value: this.getFLowName()
+ },
+ {
+ key: 'Controller Target',
+ value: this.controllerTarget
+ },
+ {
+ key: 'Controller Connected',
+ value: this.controllerConnected
+ }
]
},
{
- 'hasHeader' : true,
- 'header' : ['Of Port', 'Name', 'Mac', 'IFace Id',],
- 'datas' : this._tpList.map(function(s) {
+ 'hasHeader': true,
+ 'header': ['Of Port', 'Name', 'Mac', 'IFace Id', ],
+ 'datas': this._tpList.map(function (s) {
return [s.ofPort, s.name, s.mac, s.ifaceId];
})
},
{
- 'hasHeader' : false,
- 'headers' : [],
- 'datas': [
- {key : 'Manufacturer', value: this.flowInfo.manufacturer},
- {key : 'Hardware', value: this.flowInfo.hardware},
- {key : 'Software', value: this.flowInfo.software},
- {key : 'Feature', value: this.flowInfo.features},
- {key : 'Ip', value: this.flowInfo.ip}
+ 'hasHeader': false,
+ 'headers': [],
+ 'datas': [
+ {
+ key: 'Manufacturer',
+ value: this.flowInfo.manufacturer
+ },
+ {
+ key: 'Hardware',
+ value: this.flowInfo.hardware
+ },
+ {
+ key: 'Software',
+ value: this.flowInfo.software
+ },
+ {
+ key: 'Feature',
+ value: this.flowInfo.features
+ },
+ {
+ key: 'Ip',
+ value: this.flowInfo.ip
+ }
]
},
{
- 'hasHeader' : true,
- 'headers' : ['Table Id', 'Value'],
- 'datas' :this.flowTable.map(function(t) {
+ 'hasHeader': true,
+ 'headers': ['Table Id', 'Value'],
+ 'datas': this.flowTable.map(function (t) {
return [t.key, t.value];
})
}
return TerminationPoint;
})();
- var BaseLink = (function() {
+ var Tunnel = (function () {
+ function Tunnel(name, ofPort, tpType, mac, ifaceId, localIp, remoteIp) {
+ TerminationPoint.call(this, name, ofPort, tpType, mac, ifaceId);
+ this.localIp = localIp;
+ this.remoteIp = remoteIp;
+ }
+ Tunnel.prototype = Object.create(TerminationPoint.prototype);
+ Tunnel.prototype.constructor = Tunnel;
+
+ return Tunnel;
+ })();
+
+ var BaseLink = (function () {
function BaseLink(linkId, srcNodeId, destNodeId, linkType, styles) {
this.linkId = linkId;
this.srcNodeId = srcNodeId;
this.destNodeId = destNodeId;
- this.linkType = linkType;
+ this.linkType = linkType;
// styling
styles = _.extend({}, styles);
return Link;
})();
- var TunnelLink = (function() {
+ var TunnelLink = (function () {
function TunnelLink(linkId, srcNodeId, destNodeId, linkType, color) {
var opt = {
color: 'green',
return TunnelLink;
})();
- var BridgeOvsLink = (function() {
+ var BridgeOvsLink = (function () {
function BridgeOvsLink(linkId, srcNodeId, destNodeId, linkType, color) {
var opt = {
color: 'gray',
return BridgeOvsLink;
})();
- var Util = (function() {
- var Maths = (function() {
+ var Util = (function () {
+ var Maths = (function () {
function Maths() {
}
// random function in javascript use timespan only
- Maths.Random = function(nseed) {
- var constant = Math.pow(2, 13)+1,
+ Maths.Random = function (nseed) {
+ var constant = Math.pow(2, 13) + 1,
prime = 1987,
maximum = 1000;
- if (nseed) {
- seed = nseed;
- }
+ if (nseed) {
+ seed = nseed;
+ }
- return {
- next : function(min, max) {
- seed *= constant;
- seed += prime;
+ return {
+ next: function (min, max) {
+ seed *= constant;
+ seed += prime;
- return min && max ? min+seed%maximum/maximum*(max-min) : seed%maximum/maximum;
- }
- };
+ return min && max ? min + seed % maximum / maximum * (max - min) : seed % maximum / maximum;
+ }
+ };
};
return Maths;
})();
- var String = (function() {
+ var String = (function () {
function String() {
}
- String.Format = function() {
+ String.Format = function () {
var s = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) {
- var reg = new RegExp("\\{" + i + "\\}", "gm");
- s = s.replace(reg, arguments[i + 1]);
+ var reg = new RegExp("\\{" + i + "\\}", "gm");
+ s = s.replace(reg, arguments[i + 1]);
}
return s;
};
};
})();
- var Neutron = (function() {
+ var Neutron = (function () {
- var SubNet = (function() {
+ var SubNet = (function () {
function SubNet(id, networkId, name, ipVersion, cidr, gatewayIp, tenantId) {
this.id = id;
this.networkId = networkId;
return SubNet;
})();
- var Network = (function() {
+ var Network = (function () {
function Network(id, name, shared, status, external, tenantId) {
this.id = id;
this.ip = '';
this.routers = [];
}
- Network.prototype.addSubNets = function(subnets) {
- if(subnets) {
+ Network.prototype.addSubNets = function (subnets) {
+ if (subnets) {
if (_.isArray(subnets)) {
var i = 0;
for (; i < subnets.length; ++i) {
this.subnets.push(subnets[i]);
}
- }
- else {
+ } else {
this.subnets.push(subnet);
}
}
};
- Network.prototype.asSubnet = function(subnet) {
- return _.every(subnet, function(sub) {
- return _.some(this.subnets, function(s) {
+ Network.prototype.asSubnet = function (subnet) {
+ return _.every(subnet, function (sub) {
+ return _.some(this.subnets, function (s) {
return s.id === sub;
});
}.bind(this));
};
- Network.prototype.pretty = function() {
+ Network.prototype.pretty = function () {
return {
- 'tabs' : [
+ 'tabs': [
'Info',
'Subnets'
],
- 'containts' : [
+ 'containts': [
{
- 'hasHeader' : false,
+ 'hasHeader': false,
'headers': [],
- 'datas' : [
- {key : 'ID', value: this.id},
- {key : 'Ip', value: this.ip},
- {key : 'Name', value: this.name},
- {key : 'Shared', value: this.shared},
- {key : 'Status', value: this.status},
- {key : 'External', value: this.external},
- {key : 'Tenant Id', value: this.tenantId}
+ 'datas': [
+ {
+ key: 'ID',
+ value: this.id
+ },
+ {
+ key: 'Ip',
+ value: this.ip
+ },
+ {
+ key: 'Name',
+ value: this.name
+ },
+ {
+ key: 'Shared',
+ value: this.shared
+ },
+ {
+ key: 'Status',
+ value: this.status
+ },
+ {
+ key: 'External',
+ value: this.external
+ },
+ {
+ key: 'Tenant Id',
+ value: this.tenantId
+ }
]
},
{
- 'hasHeader' : true,
- 'header' : ['ID', 'Name', 'Ip Version', 'Ip', 'Gateway Ip'],
- 'datas' : this.subnets.map(function(s) {
+ 'hasHeader': true,
+ 'header': ['ID', 'Name', 'Ip Version', 'Ip', 'Gateway Ip'],
+ 'datas': this.subnets.map(function (s) {
return [s.id, s.name, s.ipVersion, s.cidr, s.gatewayIp];
})
}
return Network;
})();
- var Port = (function() {
+ var Port = (function () {
function Port(id, networkId, name, tenantId, deviceId, deviceOwner, fixed_ips, mac) {
this.id = id;
this.networkId = networkId;
this.mac = mac;
}
- Port.prototype.pretty = function() {
+ Port.prototype.pretty = function () {
return [
- { key: 'ID', value : this.id },
- { key: 'Name', value: name },
- { key: 'Tenant Id', value : this.tenantId },
- { key: 'Device Id', value : this.deviceId },
- { key: 'Device Owner', value : this.deviceOwner },
- { key: 'MAC', value : this.mac }
+ {
+ key: 'ID',
+ value: this.id
+ },
+ {
+ key: 'Name',
+ value: name
+ },
+ {
+ key: 'Tenant Id',
+ value: this.tenantId
+ },
+ {
+ key: 'Device Id',
+ value: this.deviceId
+ },
+ {
+ key: 'Device Owner',
+ value: this.deviceOwner
+ },
+ {
+ key: 'MAC',
+ value: this.mac
+ }
];
};
return Port;
})();
- var Router = (function() {
+ var Router = (function () {
function Router(id, name, status, tenantId, externalGateway) {
this.id = id;
this.name = name;
this.externalGateway = externalGateway;
}
- Router.prototype.pretty = function() {
+ Router.prototype.pretty = function () {
return {
- 'tabs' : [
+ 'tabs': [
'Info',
'Interfaces'
],
- 'containts' : [
+ 'containts': [
{
- 'hasHeader' : false,
+ 'hasHeader': false,
'headers': [],
- 'datas' : [
- { key: 'ID', value: this.id},
- { key: 'Name', value: this.name},
- { key: 'status', value: this.status},
- { key: 'Tenant ID', value: this.tenantId}
+ 'datas': [
+ {
+ key: 'ID',
+ value: this.id
+ },
+ {
+ key: 'Name',
+ value: this.name
+ },
+ {
+ key: 'status',
+ value: this.status
+ },
+ {
+ key: 'Tenant ID',
+ value: this.tenantId
+ }
]
},
{
- 'hasHeader' : true,
- 'header' : ['ID', 'Type', 'Mac Address', 'Ip', 'Tenant Id'],
- 'datas' : this.interfaces.map(function(s) {
+ 'hasHeader': true,
+ 'header': ['ID', 'Type', 'Mac Address', 'Ip', 'Tenant Id'],
+ 'datas': this.interfaces.map(function (s) {
return [s.id, s.type, s.mac, s.ip.ip_address, s.tenantId];
})
}
return Router;
})();
- var Instance = (function() {
+ var Instance = (function () {
function Instance(id, networkId, name, ip, mac, deviceOwner, tenantId, topoInfo) {
this.id = id;
this.networkId = networkId;
this.floatingIp = {};
}
- Instance.prototype.extractFloatingIps = function(floatingIps) {
+ Instance.prototype.extractFloatingIps = function (floatingIps) {
var ctx = this;
- this.floatingIp = _.find(floatingIps, function(fIp) {
+ this.floatingIp = _.find(floatingIps, function (fIp) {
return fIp.tenantId === ctx.tenantId &&
fIp.fixedIp === ctx.ip;
});
};
- Instance.prototype.pretty = function() {
+ Instance.prototype.pretty = function () {
return {
- 'tabs' : [
+ 'tabs': [
'Info',
'Ports'
],
- 'containts' : [
+ 'containts': [
{
- 'hasHeader' : false,
+ 'hasHeader': false,
'headers': [],
- 'datas' : [
- { key: 'ID', value: this.id},
- { key: "Network Id", value : this.networkId},
- { key: 'Name', value: this.name},
- { key: 'Ip', value: this.ip},
- { key: 'Floating Ip', value: (this.floatingIp) ? this.floatingIp.ip : 'Not found' },
- { key: 'MAC', value: this.mac},
- { key: 'Type', value: this.type},
- { key: 'Tenant ID', value: this.tenantId}
+ 'datas': [
+ {
+ key: 'ID',
+ value: this.id
+ },
+ {
+ key: "Network Id",
+ value: this.networkId
+ },
+ {
+ key: 'Name',
+ value: this.name
+ },
+ {
+ key: 'Ip',
+ value: this.ip
+ },
+ {
+ key: 'Floating Ip',
+ value: (this.floatingIp) ? this.floatingIp.ip : 'Not found'
+ },
+ {
+ key: 'MAC',
+ value: this.mac
+ },
+ {
+ key: 'Type',
+ value: this.type
+ },
+ {
+ key: 'Tenant ID',
+ value: this.tenantId
+ }
]
},
{
- 'hasHeader' : true,
- 'header' : ['Name', 'Of Port', 'Mac', 'Flow', 'Ovsdb Node', 'Ovsdb Node IP'],
- 'datas' : this.topoInfo.map(function(s) {
+ 'hasHeader': true,
+ 'header': ['Name', 'Of Port', 'Mac', 'Flow', 'Ovsdb Node', 'Ovsdb Node IP'],
+ 'datas': this.topoInfo.map(function (s) {
return [s.name, s.ofPort, s.mac, s.bridge.getFLowName(), s.ovsNode.nodeId, s.ovsNode.showIpAdress()];
})
}
return Instance;
})();
- var FloatingIp =(function() {
+ var FloatingIp = (function () {
function FloatingIp(id, networkId, portId, fixedIp, floatingIp, tentantId, status) {
this.id = id;
this.networkId = networkId;
BridgeNode: BridgeNode,
TerminationPoint: TerminationPoint,
Topology: Topology,
+ Tunnel: Tunnel,
BaseLink: BaseLink,
Link: Link,
TunnelLink: TunnelLink,
- BridgeOvsLink:BridgeOvsLink,
- Util:Util,
+ BridgeOvsLink: BridgeOvsLink,
+ Util: Util,
Neutron: Neutron
};
});
-define(['app/ovsdb/ovsdb.module'], function(ovsdb) {
+define(['app/ovsdb/ovsdb.module'], function (ovsdb) {
ovsdb.register.constant('nodeIdentifier', {
IP: 'ip',
ID: 'link-id',
DEST: 'destination'
});
+
+ ovsdb.register.constant('OVSConstant', {
+ TP_TYPE: {
+ INTERNAL: 'ovsdb:interface-type-internal',
+ VXLAN: 'ovsdb:interface-type-vxlan'
+ }
+ })
+
});
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'app/ovsdb/LogicalGraph','app/ovsdb/OvsCore', 'underscore', 'jquery', 'jquery-ui'], function (ovsdb, d3, Graph, LogicalGraph, OvsCore, _, $) {
+define(['app/ovsdb/ovsdb.module', 'app/ovsdb/lib/d3.min', 'app/ovsdb/Graph', 'app/ovsdb/LogicalGraph', 'app/ovsdb/OvsCore', 'underscore', 'jquery', 'jquery-ui'], function (ovsdb, d3, Graph, LogicalGraph, OvsCore, _, $) {
'use strict';
- ovsdb.register.directive('logicalGraph', function() {
+ ovsdb.register.directive('logicalGraph', function () {
return {
restrict: 'EA',
scope: false,
- link : function (scope, elem, attr) {
+ link: function (scope, elem, attr) {
var lgraph = null,
- tabCreated = false,
- width = scope.canvasWidth, //ele[0].clientWidth,
- height = scope.canvasHeight;
+ tabCreated = false,
+ width = scope.canvasWidth, //ele[0].clientWidth,
+ height = scope.canvasHeight;
scope.lDialogData = {};
- scope.lgraphIsReadyPromise.then(function(ltopo) {
+ scope.lgraphIsReadyPromise.then(function (ltopo) {
if (!lgraph) {
lgraph = new LogicalGraph(elem[0], width, height);
}
lgraph.start();
- lgraph.onClick = function(e, d) {
+ lgraph.onClick = function (d) {
var dialogId = '#lDialog';
scope.lDialogData = d.pretty();
scope.$apply();
$(dialogId).tabs();
$(dialogId).draggable({
containment: 'parent',
- cancel:'.window_content'
+ cancel: '.window_content'
});
tabCreated = true;
} else {
$(dialogId).tabs('refresh');
}
- var $dia = $(dialogId);
- $dia.css('left', e.left + 30);
- $dia.css('top', e.top + 35);
+ var $dia = $(dialogId),
+ left = $dia.css('left'),
+ top = $dia.css('top') || e.top + 35;
+ $dia.css('left', left !== 'auto' ? left : 10);
+ $dia.css('top', top !== 'auto' ? top : 10);
$dia.show();
};
- lgraph.dblClick = function(d) {
+ lgraph.dblClick = function (d) {
scope.goToPhysicalView(d);
};
});
- scope.hideLogicalDialog = function() {
- $('#lDialog').tabs("option", "active", 0)
+ scope.hideLogicalDialog = function () {
+ $('#lDialog').tabs("option", "active", 0)
.hide();
};
elem.on('$destroy', function () {
});
links.style("stroke", function (o) {
- return ((o.source.index == d.index || o.target.index == d.index) && o.linkType != 'tunnel') ? "blue" : o.color;
+ return ((o.source.index == d.index || o.target.index == d.index) && o.linkType != 'tunnel') ? "blue" : o.color;
});
};
graph.onNodeOut = function (d, nodes, links) {
nodes.selectAll('.switch > rect').style("stroke", "black");
- links.style("stroke", function(o) { return o.color; });
+ links.style("stroke", function (o) {
+ return o.color;
+ });
};
graph.onNodeClick = function (d, nodes, links, ctx) {
$(dialogId).tabs();
$(dialogId).draggable({
containment: 'parent',
- cancel:'.window_content'
+ cancel: '.window_content'
});
tabCreated = true;
} else {
$(dialogId).tabs('refresh');
}
- $dia.css('left', /*e.left + */30);
- $dia.css('top', /*e.top + */35);
+ $dia.css('left', /*e.left + */ 30);
+ $dia.css('top', /*e.top + */ 35);
$dia.show();
};
});
- ele.on('$destroy', function() {
+ ele.on('$destroy', function () {
graph.freeDOM();
});
- scope.hidePhysicalDialog = function() {
+ scope.hidePhysicalDialog = function () {
$('#pDialog').tabs("option", "active", 0)
- .hide();
+ .hide();
};
scope.rotateGraph = function (value) {
$('path.tunnel').toggle();
};
- scope.filterNode = function(nodeIds, tags, exclude) {
+ scope.filterNode = function (nodeIds, tags, exclude) {
exclude = (exclude === null) ? true : exclude;
var nodes = d3.selectAll(tags);
- nodes.each(function(d) {
- if (nodeIds.indexOf(d.node.nodeId) < 0) {
- d.hidden = exclude;
- } else {
- d.hidden = !exclude;
- }
- });
- nodes.transition().duration(200).style('opacity', function(d) {
- return d.hidden ? '0.3' : '1';
+ nodes.each(function (d) {
+ if (nodeIds.indexOf(d.node.nodeId) < 0) {
+ d.hidden = exclude;
+ } else {
+ d.hidden = !exclude;
+ }
+ });
+ nodes.transition().duration(200).style('opacity', function (d) {
+ return d.hidden ? '0.3' : '1';
});
};
- scope.filterLink = function() {
+ scope.filterLink = function () {
var links = d3.selectAll(".tunnel, .link, .bridgeOvsLink");
- links.each(function(d, i) {
+ links.each(function (d, i) {
d.hidden = d.source.hidden || d.target.hidden;
});
- links.transition().duration(200).style('opacity', function(d) {
- return d.hidden ? '0.3' : '1';
+ links.transition().duration(200).style('opacity', function (d) {
+ return d.hidden ? '0.3' : '1';
});
};
}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/ovsdb.constant'], function(ovsdb, OvsCore, _) {
+define(['app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'underscore', 'app/ovsdb/ovsdb.constant'], function (ovsdb, OvsCore, _) {
'use strict';
- ovsdb.register.factory('OvsdbRestangular', ['Restangular', 'ENV', function(Restangular, ENV) {
- return Restangular.withConfig(function(RestangularConfig) {
+ ovsdb.register.factory('OvsdbRestangular', ['Restangular', 'ENV', function (Restangular, ENV) {
+ return Restangular.withConfig(function (RestangularConfig) {
RestangularConfig.setBaseUrl(ENV.getBaseURL("MD_SAL"));
});
}]);
// nbv2 support depricated in dlux
- ovsdb.register.factory('NeutronRestangular', ['Restangular', function(Restangular) {
- return Restangular.withConfig(function(RestangularConfig) {
+ ovsdb.register.factory('NeutronRestangular', ['Restangular', function (Restangular) {
+ return Restangular.withConfig(function (RestangularConfig) {
RestangularConfig.setBaseUrl('http://localhost:8080/controller/nb/v2/neutron');
});
}]);
- ovsdb.register.factory('CacheFactory', function($q) {
+ ovsdb.register.factory('CacheFactory', function ($q) {
var svc = {},
ovsCache = {};
/*BUG : Using the persistant cache make the physical
* algorithm. The current behavior is to use the cache
* only the pile up the datas.
*/
- svc.obtainDataFromCache = function(key, fn, ctx) {
+ svc.obtainDataFromCache = function (key, fn, ctx) {
var cacheDefer = $q.defer();
if (angular.isUndefined(ovsCache[key])) {
- fn.call(ctx, function(data) {
- ovsCache[key] = {
- obj : data,
- timestamp : Date.now() + 2000//300000 // 5 mintues
- };
- cacheDefer.resolve(data);
+ fn.call(ctx, function (data) {
+ ovsCache[key] = {
+ obj: data,
+ timestamp: Date.now() + 2000 //300000 // 5 mintues
+ };
+ cacheDefer.resolve(data);
});
} else {
var cacheObj = ovsCache[key];
- if (cacheObj.timestamp < Date.now() || _.isEmpty(cacheObj.obj)) {
- fn.call(ctx, function(data) {
- ovsCache[key] = {
- obj : data,
- timestamp : Date.now() + 2000//300000 // 5 mintues
- };
- cacheDefer.resolve(data);
+ if (cacheObj.timestamp < Date.now() || _.isEmpty(cacheObj.obj)) {
+ fn.call(ctx, function (data) {
+ ovsCache[key] = {
+ obj: data,
+ timestamp: Date.now() + 2000 //300000 // 5 mintues
+ };
+ cacheDefer.resolve(data);
});
} else {
cacheDefer.resolve(cacheObj.obj);
return cacheDefer.promise;
};
- svc.getCacheObj = function(key) {
+ svc.getCacheObj = function (key) {
if (angular.isUndefined(ovsCache[key])) {
ovsCache[key] = {};
}
return svc;
});
- var TopologySvc = function(OvsdbRestangular, nodeIdentifier, ovsNodeKeys, bridgeNodeKeys, tpKeys, flowInfoKeys, linkIdentifier, $q, $http, CacheFactory) {
+ var TopologySvc = function (OvsdbRestangular, nodeIdentifier, ovsNodeKeys, bridgeNodeKeys, tpKeys, flowInfoKeys, linkIdentifier, OVSConstant, $q, $http, CacheFactory) {
var svc = {
- base: function(type) {
+ base: function (type) {
return OvsdbRestangular.one('restconf').one(type);
}
};
}
if (_.isArray(otherInfo)) {
- _.each(otherInfo, function(value) {
+ _.each(otherInfo, function (value) {
if (value[ovsNodeKeys.OTHER_CONFIG_KEY] === 'local_ip') {
otherLocalIp = value[ovsNodeKeys.OTHER_CONFIG_VALUE];
}
tp = node[bridgeNodeKeys.TP],
controllerEntries = node[bridgeNodeKeys.CONTROLLER_ENTRY];
- _.each(controllerEntries, function(value) {
+ _.each(controllerEntries, function (value) {
controllerTarget = value[bridgeNodeKeys.TARGET];
controllerEntries = value[bridgeNodeKeys.IS_CONNECTED];
return false; // break the anonymus function
bridgeNode = new OvsCore.BridgeNode(node[bridgeNodeKeys.NODE_ID], node[bridgeNodeKeys.DATA_PATH], node[bridgeNodeKeys.BRIDGE_NAME], controllerTarget, controllerConnected);
- _.each(tp, function(value) {
+ _.each(tp, function (value) {
var tp = parseBridgeTP(value);
if (tp.ofPort == '65534' && (tp.name === 'br-ex' || tp.name === 'br-int')) {
function parseBridgeTP(tp) {
var mac = '',
ifaceId = '',
- extInfo = tp['ovsdb:port-external-ids'] || tp['ovsdb:interface-external-ids'];
+ extInfo = tp['ovsdb:port-external-ids'] || tp['ovsdb:interface-external-ids'],
+ type = tp[tpKeys.INTERFACE_TYPE];
- _.each(extInfo, function(ext) {
+ _.each(extInfo, function (ext) {
if (ext[tpKeys.EXTERNAL_KEY_ID] === tpKeys.ATTACHED_MAC) {
mac = ext[tpKeys.EXTERNAL_KEY_VALUE];
}
ifaceId = ext[tpKeys.EXTERNAL_KEY_VALUE] || '';
}
});
+ if (type === OVSConstant.TP_TYPE.VXLAN) {
+ var localIp = null,
+ remoteIp = null;
+ _.each(tp['ovsdb:options'], function (option) {
+ switch (option.option) {
+ case 'local_ip':
+ localIp = option.value;
+ break;
+ case 'remote_ip':
+ remoteIp = option.value;
+ break;
+ }
+ });
+ return new OvsCore.Tunnel(tp[tpKeys.NAME], tp[tpKeys.OF_PORT], type, mac, ifaceId, localIp, remoteIp);
+ }
+ return new OvsCore.TerminationPoint(tp[tpKeys.NAME], tp[tpKeys.OF_PORT], type, mac, ifaceId);
- return new OvsCore.TerminationPoint(tp[tpKeys.NAME], tp[tpKeys.OF_PORT], tp[tpKeys.INTERFACE_TYPE], mac, ifaceId);
}
function fetchTopology(cb) {
var netTopoDefer = this.base('operational').one('network-topology:network-topology').getList();
// be sure all data are loaded
- $q.all([invNodeDefer, netTopoDefer]).then(function(values) {
+ $q.all([invNodeDefer, netTopoDefer]).then(function (values) {
var invNode = values[0],
netTopo = values[1],
index_hash = [],
nodes = invNode.nodes.node,
topo = new OvsCore.Topology();
- _.each(topologies, function(topology, topo_index) {
+ _.each(topologies, function (topology, topo_index) {
if (!topology.hasOwnProperty('topology-id')) {
throw new Error('Invalide JSON format, no topology-id for the topology [' + topo_index + ']');
}
// if there no node it will be an empty array so noop
- (topology.node || []).forEach(function(node) {
+ (topology.node || []).forEach(function (node) {
if (!node[nodeIdentifier.ID]) {
throw new Error('Unexpected node : undefined ' + nodeIdentifier.ID + ' key');
}
});
// if there no link it will be an empty array so noop
- (topology.link || []).forEach(function(link) {
+ (topology.link || []).forEach(function (link) {
var source = link[linkIdentifier.SRC]['source-node'],
dest = link[linkIdentifier.DEST]['dest-node'];
});
- _.each(nodes, function(node, index) {
+ _.each(nodes, function (node, index) {
if (!node.id) {
return;
}
var bridgeId = node.id;
- var bridgeNode = _.filter(topo.bridgeNodes, function(bridgeNode) {
+ var bridgeNode = _.filter(topo.bridgeNodes, function (bridgeNode) {
return bridgeNode.getFLowName() === bridgeId;
})[0];
bridgeNode.flowInfo.manufacturer = node[flowInfoKeys.MANUFACTURER];
bridgeNode.flowInfo.ip = node[flowInfoKeys.IP];
- _.each(node[flowInfoKeys.TABLE], function(entry) {
+ _.each(node[flowInfoKeys.TABLE], function (entry) {
if (!_.isUndefined(entry.id)) {
- _.each(entry.flow, function(flow) {
- bridgeNode.addFlowTableInfo({ key: flow.table_id, value: flow.id});
+ _.each(entry.flow, function (flow) {
+ bridgeNode.addFlowTableInfo({
+ key: flow.table_id,
+ value: flow.id
+ });
});
}
});
});
// show relation between ovsNode and switch with a link
- _.each(topo.ovsdbNodes, function(node, index) {
- var bridges = _.filter(topo.bridgeNodes, function(bnode) {
+ _.each(topo.ovsdbNodes, function (node, index) {
+ var bridges = _.filter(topo.bridgeNodes, function (bnode) {
return bnode.nodeId.indexOf(node.nodeId) > -1;
});
- _.each(bridges, function(bridge) {
+ _.each(bridges, function (bridge) {
var size = _.size(topo.links),
link = new OvsCore.BridgeOvsLink(++size, node.nodeId, bridge.nodeId);
topo.registerLink(link);
function findVxlan(bridgeNode) {
var tunnels = [];
- _.each(bridgeNode, function(node) {
- var ovsdbNode = _.find(topo.ovsdbNodes, function(oNode) {
+ _.each(bridgeNode, function (node) {
+ var ovsdbNode = _.find(topo.ovsdbNodes, function (oNode) {
return node.nodeId.indexOf(oNode.nodeId) > -1;
});
if (!ovsdbNode) {
return false;
}
- _.each(node.tPs, function(tp, index) {
- if (tp.name.indexOf('vxlan-') > -1) {
+ _.each(node.tPs, function (tp, index) {
+ if (tp instanceof OvsCore.Tunnel) {
tunnels.push({
- port : tp,
- bridge : node,
- ovsIp : ovsdbNode.otherLocalIp || ovsdbNode.inetMgr
+ port: tp,
+ bridge: node
});
}
});
// extract all tunnel paired with their bridge
var tunnels = findVxlan(topo.bridgeNodes);
// loop over all pairs
- _.each(tunnels, function(tunnel, index) {
- var currIp = tunnel.ovsIp,
- destIp = tunnel.port.name.replace('vxlan-', ''),
- linkedBridge = _.find(tunnels.slice(index), function(t) {
- var vxlanIp = t.port.name.replace('vxlan-', '');
- return vxlanIp === currIp;
+ for (var index = 0; index < tunnels.length; ++index) {
+ var tunnel = tunnels[index],
+ currIp = tunnel.port.localIp,
+ destIp = tunnel.port.remoteIp,
+ pairIndex = 0,
+ linkedBridge = _.find(tunnels, function (t, i) {
+ pairIndex = i;
+ return t.port.remoteIp === currIp && t.port.localIp == destIp;
});
- if (linkedBridge) {
- topo.registerLink(new OvsCore.TunnelLink(tunnel.port.name + linkedBridge.port.name, tunnel.bridge.nodeId, linkedBridge.bridge.nodeId));
- }
- });
+ if (linkedBridge) {
+ tunnels.splice(pairIndex, 1);
+ topo.registerLink(new OvsCore.TunnelLink(tunnel.port.name + linkedBridge.port.name, tunnel.bridge.nodeId, linkedBridge.bridge.nodeId));
+ }
+ }
topo.updateLink();
cb(topo);
},
- function(err) {
+ function (err) {
throw err;
}
);
}
- svc.getTopologies = function() {
+ svc.getTopologies = function () {
return CacheFactory.obtainDataFromCache('topologies', fetchTopology, this);
};
return svc;
};
- TopologySvc.$inject = ['OvsdbRestangular', 'nodeIdentifier', 'ovsNodeKeys', 'bridgeNodeKeys', 'tpKeys', 'flowInfoKeys', 'linkIdentifier', '$q', '$http', 'CacheFactory'];
+ TopologySvc.$inject = ['OvsdbRestangular', 'nodeIdentifier', 'ovsNodeKeys', 'bridgeNodeKeys', 'tpKeys', 'flowInfoKeys', 'linkIdentifier', 'OVSConstant', '$q', '$http', 'CacheFactory'];
- var NeutronSvc = function(NeutronRestangular, CacheFactory, $q, $http) {
+ var NeutronSvc = function (NeutronRestangular, CacheFactory, $q, $http) {
var svc = {
- base: function(type) {
- return NeutronRestangular.one(type);
- }
- },
- tenant_hash = {};
+ base: function (type) {
+ return NeutronRestangular.one(type);
+ }
+ },
+ tenant_hash = {};
function fetchSubNetworks(cb) {
var subnetskDefer = svc.base('subnets').getList();
- subnetskDefer.then(function(data) {
+ subnetskDefer.then(function (data) {
var subnets = data,
subnetHash = {};
throw new Error('Invalid format from neutron subnets');
}
- _.each(subnets.subnets, function(subnet) {
- if (!subnetHash[subnet.network_id]) {
- subnetHash[subnet.network_id] = [];
- }
- tenant_hash[subnet.tenant_id] = {};
- subnetHash[subnet.network_id].push(new OvsCore.Neutron.SubNet(
- subnet.id,
- subnet.network_id,
- subnet.name,
- subnet.ip_version,
- subnet.cidr,
- subnet.gateway_ip,
- subnet.tenant_id
- ));
+ _.each(subnets.subnets, function (subnet) {
+ if (!subnetHash[subnet.network_id]) {
+ subnetHash[subnet.network_id] = [];
+ }
+ tenant_hash[subnet.tenant_id] = {};
+ subnetHash[subnet.network_id].push(new OvsCore.Neutron.SubNet(
+ subnet.id,
+ subnet.network_id,
+ subnet.name,
+ subnet.ip_version,
+ subnet.cidr,
+ subnet.gateway_ip,
+ subnet.tenant_id
+ ));
});
cb(subnetHash);
});
var networkDefer = svc.base('networks').getList();
var subnetskDefer = svc.getSubNets();
- $q.all([subnetskDefer, networkDefer]).then(function(datas) {
+ $q.all([subnetskDefer, networkDefer]).then(function (datas) {
var subnetsHash = datas[0],
networks = datas[1],
networkArray = [];
throw new Error('Invalid format from neutron networks');
}
- _.each(networks.networks, function(network) {
+ _.each(networks.networks, function (network) {
var net = new OvsCore.Neutron.Network(
network.id,
network.name,
net.addSubNets(subnetsHash[net.id]);
networkArray.push(net);
});
- cb(networkArray);
+ cb(networkArray);
});
}
function fetchRouters(cb) {
var routerDefer = svc.base('routers').getList();
- routerDefer.then(function(data) {
+ routerDefer.then(function (data) {
var routers = data.routers,
routerArray = [];
if (!routers) {
throw new Error('Invalid format from neutron routers');
}
- _.each(routers, function(router) {
- var id = router.id,
+ _.each(routers, function (router) {
+ var id = router.id,
name = router.name,
status = router.status,
tenantId = router.tenant_id,
extGateWayInfo = router.external_gateway_info;
- tenant_hash[tenantId] = {};
- routerArray.push(new OvsCore.Neutron.Router(
- id, name, status, tenantId, extGateWayInfo
- ));
+ tenant_hash[tenantId] = {};
+ routerArray.push(new OvsCore.Neutron.Router(
+ id, name, status, tenantId, extGateWayInfo
+ ));
});
cb(routerArray);
});
function fetchPorts(cb) {
var portDefer = svc.base('ports').getList();
- portDefer.then(function(data){
+ portDefer.then(function (data) {
var ports = data.ports,
portArray = [];
if (!ports) {
throw new Error('Invalid format from neutron ports');
}
- _.each(ports, function(port) {
+ _.each(ports, function (port) {
tenant_hash[port.tenant_id] = {};
portArray.push(new OvsCore.Neutron.Port(
port.id,
function fetchFloatingIps(cb) {
var floatingIpDefer = svc.base('floatingips').getList();
- floatingIpDefer.then(function(data) {
+ floatingIpDefer.then(function (data) {
var floatingIps = data.floatingips,
floatingIpArray = [];
throw new Error('Invalid format from neutron floatingIps');
}
- _.each(floatingIps, function(fIp) {
+ _.each(floatingIps, function (fIp) {
tenant_hash[fIp.tenant_id] = {};
floatingIpArray.push(new OvsCore.Neutron.FloatingIp(
fIp.id,
});
}
- svc.getNetworks = function() {
- return CacheFactory.obtainDataFromCache('networks', fetchNetworks, this);
+ svc.getNetworks = function () {
+ return CacheFactory.obtainDataFromCache('networks', fetchNetworks, this);
};
- svc.getSubNets = function() {
+ svc.getSubNets = function () {
return CacheFactory.obtainDataFromCache('subnet', fetchSubNetworks, this);
};
- svc.getPorts = function() {
+ svc.getPorts = function () {
return CacheFactory.obtainDataFromCache('ports', fetchPorts, this);
};
- svc.getRouters = function() {
+ svc.getRouters = function () {
return CacheFactory.obtainDataFromCache('routers', fetchRouters, this);
};
- svc.getFloatingIps = function() {
+ svc.getFloatingIps = function () {
return CacheFactory.obtainDataFromCache('floatingips', fetchFloatingIps, this);
};
- svc.getAllTenants = function() {
+ svc.getAllTenants = function () {
return Object.keys(tenant_hash);
};
};
NeutronSvc.$inject = ['NeutronRestangular', 'CacheFactory', '$q', '$http'];
- var OvsUtil = function(NeutronSvc, TopologySvc, CacheFactory, $q) {
+ var OvsUtil = function (NeutronSvc, TopologySvc, CacheFactory, $q) {
var svc = {};
function findOvsdbNodeForBridge(ovsdbNodes, bridge) {
- return _.find(ovsdbNodes, function(node) {
+ return _.find(ovsdbNodes, function (node) {
return bridge.nodeId.indexOf(node.nodeId) > -1;
});
}
$q.all([networksDefer, routersDefer, portsDefer, floatingDefer, netTopoDefer]).then(function (datas) {
var networks = datas[0],
- routers = datas[1],
- ports = datas[2],
- floatingIps = datas[3],
- topo = datas[4];
+ routers = datas[1],
+ ports = datas[2],
+ floatingIps = datas[3],
+ topo = datas[4];
// match ports with elements
- _.each(ports, function(port) {
- port.topoInfo = [];
- // corelate port.topoInfo data with network topology termination point
- _.each(topo.bridgeNodes, function(bridge) {
- _.each(bridge.tPs, function(tp) {
- if (tp.ifaceId === port.id) {
- port.topoInfo.push({
- name : tp.name,
- ofPort : tp.ofPort,
- mac : bridge.dpIp,
- bridge : bridge,
- ovsNode : findOvsdbNodeForBridge(topo.ovsdbNodes, bridge)
- });
- }
- });
- });
-
- switch(port.deviceOwner) {
- case 'network:router_gateway':
- case 'network:router_interface':
- var router = _.find(routers, function(r) { return r.id === port.deviceId; });
+ _.each(ports, function (port) {
+ port.topoInfo = [];
+ // corelate port.topoInfo data with network topology termination point
+ _.each(topo.bridgeNodes, function (bridge) {
+ _.each(bridge.tPs, function (tp) {
+ if (tp.ifaceId === port.id) {
+ port.topoInfo.push({
+ name: tp.name,
+ ofPort: tp.ofPort,
+ mac: bridge.dpIp,
+ bridge: bridge,
+ ovsNode: findOvsdbNodeForBridge(topo.ovsdbNodes, bridge)
+ });
+ }
+ });
+ });
+
+ switch (port.deviceOwner) {
+ case 'network:router_gateway':
+ case 'network:router_interface':
+ var router = _.find(routers, function (r) {
+ return r.id === port.deviceId;
+ });
if (router) {
router.interfaces.push({
id: port.id,
- networkId : port.networkId,
- ip : port.fixed_ips[0],
- mac : port.mac,
+ networkId: port.networkId,
+ ip: port.fixed_ips[0],
+ mac: port.mac,
type: port.deviceOwner.replace('network:', ''),
- tenantId : port.tenantId,
+ tenantId: port.tenantId,
topoInfo: port.topoInfo
});
}
case 'compute:None':
case 'compute:nova':
case 'network:dhcp':
- var network = _.find(networks, function(n) { return n.id === port.networkId;}),
+ var network = _.find(networks, function (n) {
+ return n.id === port.networkId;
+ }),
inst = null;
if (network) {
- inst = new OvsCore.Neutron.Instance(port.id, port.networkId,
+ inst = new OvsCore.Neutron.Instance(port.id, port.networkId,
port.name, port.fixed_ips[0].ip_address, port.mac,
- port.deviceOwner, port.tenantId, port.topoInfo );
+ port.deviceOwner, port.tenantId, port.topoInfo);
inst.extractFloatingIps(floatingIps);
network.instances.push(inst);
}
break;
- }
+ }
- });
+ });
- // find all routers for a specific network
- _.each(networks, function(network) {
- network.routers = _.filter(routers, function(router) {
- return network.id === router.externalGateway.network_id;
- });
+ // find all routers for a specific network
+ _.each(networks, function (network) {
+ network.routers = _.filter(routers, function (router) {
+ return network.id === router.externalGateway.network_id;
+ });
- // order instance by ip
- network.instances.sort(function(a, b) {
- var ipA = a.ip.slice(a.ip.lastIndexOf('.') + 1),
- ipB = b.ip.slice(b.ip.lastIndexOf('.') + 1);
- return ipA - ipB;
- });
- });
+ // order instance by ip
+ network.instances.sort(function (a, b) {
+ var ipA = a.ip.slice(a.ip.lastIndexOf('.') + 1),
+ ipB = b.ip.slice(b.ip.lastIndexOf('.') + 1);
+ return ipA - ipB;
+ });
+ });
- cb(networks);
+ cb(networks);
});
}
- svc.getLogicalTopology = function() {
+ svc.getLogicalTopology = function () {
return CacheFactory.obtainDataFromCache('logicalTopology', pileUpTopologyData, this);
};
- svc.extractLogicalByTenant = function(tenantId, subSet) {
+ svc.extractLogicalByTenant = function (tenantId, subSet) {
var lTopoDefer = svc.getLogicalTopology(),
resultDefer = $q.defer();
- lTopoDefer.then(function() {
+ lTopoDefer.then(function () {
var ports = CacheFactory.getCacheObj('ports').obj,
- filteredPorts = _.filter(ports, function(p) {
+ filteredPorts = _.filter(ports, function (p) {
return p.tenantId === tenantId;
});
if (!_.isEmpty(filteredPorts)) {
var bridgeHash = {};
- _.each(filteredPorts, function(p) {
+ _.each(filteredPorts, function (p) {
if (!_.isEmpty(p.topoInfo) && !bridgeHash[p.topoInfo[0].bridge.nodeId]) {
bridgeHash[p.topoInfo[0].bridge.nodeId] = {};
}
});
var ovsdbHash = {};
- _.each(filteredPorts, function(p) {
+ _.each(filteredPorts, function (p) {
if (!_.isEmpty(p.topoInfo) && !ovsdbHash[p.topoInfo[0].ovsNode.nodeId]) {
ovsdbHash[p.topoInfo[0].ovsNode.nodeId] = {};
}
return resultDefer.promise;
};
- svc.extractLogicalBySubnet = function(subnets, subSet) {
+ svc.extractLogicalBySubnet = function (subnets, subSet) {
var lTopoDefer = svc.getLogicalTopology(),
resultDefer = $q.defer();
- lTopoDefer.then(function() {
+ lTopoDefer.then(function () {
var ports = CacheFactory.getCacheObj('ports').obj,
networks = CacheFactory.getCacheObj('networks').obj;
- var filteredPorts = _.filter(ports, function(p) {
- var net = _.find(networks, function(d) {
+ var filteredPorts = _.filter(ports, function (p) {
+ var net = _.find(networks, function (d) {
return d.id === p.networkId;
});
});
if (!_.isEmpty(filteredPorts)) {
var bridgeHash = {};
- _.each(filteredPorts, function(p) {
+ _.each(filteredPorts, function (p) {
if (!_.isEmpty(p.topoInfo) && !bridgeHash[p.topoInfo[0].bridge.nodeId]) {
bridgeHash[p.topoInfo[0].bridge.nodeId] = {};
}
});
var ovsdbHash = {};
- _.each(filteredPorts, function(p) {
+ _.each(filteredPorts, function (p) {
if (!_.isEmpty(p.topoInfo) && !ovsdbHash[p.topoInfo[0].ovsNode.nodeId]) {
ovsdbHash[p.topoInfo[0].ovsNode.nodeId] = {};
}
* and is available at http://www.eclipse.org/legal/epl-v10.html\r
-->\r
<div id="ovsdb_contain">\r
-<!--\r
+ <!--\r
<div class="row">\r
<div class="col-md-2 form-inline">\r
<label class="switch-light well">\r
</div>\r
</div>\r
-->\r
-<div class="row">\r
- <div class="col-md-12">\r
- <div id="tabs" >\r
- <ul class="nav nav-tabs tabsHeader" style="margin-bottom:15px;">\r
- <li><a href="#logical_view">Logical View</a></li>\r
- <li><a href="#2d_view">2D View</a></li>\r
- <li><a href="#3d_view">3D View</a></li>\r
- </ul>\r
- <div id="logical_view" style="background-color:white; position:relative;">\r
- <div id="l_graph" style="position:relative; height:580px;" logical-graph ></div>\r
+ <div class="row">\r
+ <div class="col-md-12">\r
+ <div id="tabs">\r
+ <ul class="nav nav-tabs tabsHeader" style="margin-bottom:15px;">\r
+ <li><a href="#logical_view">Logical View</a></li>\r
+ <li><a href="#2d_view">2D View</a></li>\r
+ </ul>\r
+ <div id="logical_view" style="background-color:white; position:relative;">\r
+ <div id="l_graph" style="position:relative; height:580px;" logical-graph></div>\r
\r
- <div id="lDialog" class="ovsDialog arrow-left">\r
- <div style="height:10px;">\r
- <i data-ng-click="hideLogicalDialog()" class="window-icon icon-remove"></i>\r
- </div>\r
- <div class="window_content">\r
- <ul class="nav nav-tabs tabsHeader">\r
- <li ng-repeat="tab in lDialogData.tabs track by $index" >\r
- <a href="#lDialogTab_{{$index}}" class="active">{{tab}}</a>\r
- </li>\r
- </ul>\r
- <div ng-repeat="tabContaint in lDialogData.containts track by $index" id="lDialogTab_{{$index}}">\r
- <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
- <tr ng-repeat="info in tabContaint.datas track by $index">\r
- <td > {{info.key}} </td> <td> {{ info.value }} </td>\r
- </tr>\r
- </table>\r
- <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
- <tr>\r
- <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
- </tr>\r
- <tr ng-repeat="item in tabContaint.datas track by $index">\r
- <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
- </tr>\r
- </table>\r
+ <div id="lDialog" class="ovsDialog arrow-left">\r
+ <div style="height:10px;">\r
+ <i data-ng-click="hideLogicalDialog()" class="window-icon icon-remove"></i>\r
+ </div>\r
+ <div class="window_content">\r
+ <ul class="nav nav-tabs tabsHeader">\r
+ <li ng-repeat="tab in lDialogData.tabs track by $index">\r
+ <a href="#lDialogTab_{{$index}}" class="active">{{tab}}</a>\r
+ </li>\r
+ </ul>\r
+ <div ng-repeat="tabContaint in lDialogData.containts track by $index" id="lDialogTab_{{$index}}">\r
+ <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+ <tr ng-repeat="info in tabContaint.datas track by $index">\r
+ <td> {{info.key}} </td>\r
+ <td> {{ info.value }} </td>\r
+ </tr>\r
+ </table>\r
+ <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+ <tr>\r
+ <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
+ </tr>\r
+ <tr ng-repeat="item in tabContaint.datas track by $index">\r
+ <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
+ </tr>\r
+ </table>\r
+ </div>\r
</div>\r
</div>\r
- </div>\r
\r
- </div>\r
- <div id="2d_view">\r
- <div class="row">\r
- <div class="col-md-4 col-md-offset-1 form-inline">\r
- <span>Tenant</span>\r
- <select id="tenantSelect" ng-model="selectedTenant" ng-change="fiterByTenant()" ng-options="tenant.name for tenant in tenants track by tenant.id">\r
- <option value="">---All---</option>\r
- </select>\r
- </div>\r
- <div class="col-md-4 form-inline">\r
- <span>Subnet</span>\r
- <select id="tagPicker" multiple="multiple" ng-model="selectedSubnet" ng-change="filterBySubnet()" ng-options="subnet.name for subnet in subnets track by subnet.id">\r
- </select>\r
- </div>\r
</div>\r
- <div id="nv_graph" style="position:relative; height:580px;" physical-graph></div>\r
- <div id="pDialog" class="ovsDialog arrow-left">\r
+ <div id="2d_view">\r
+ <div class="row">\r
+ <div class="col-md-4 col-md-offset-1 form-inline">\r
+ <span>Tenant</span>\r
+ <select id="tenantSelect" ng-model="selectedTenant" ng-change="fiterByTenant()" ng-options="tenant.name for tenant in tenants track by tenant.id">\r
+ <option value="">---All---</option>\r
+ </select>\r
+ </div>\r
+ <div class="col-md-4 form-inline">\r
+ <span>Subnet</span>\r
+ <select id="tagPicker" multiple="multiple" ng-model="selectedSubnet" ng-change="filterBySubnet()" ng-options="subnet.name for subnet in subnets track by subnet.id">\r
+ </select>\r
+ </div>\r
+ </div>\r
+ <div id="nv_graph" style="position:relative; height:580px;" physical-graph></div>\r
+ <div id="pDialog" class="ovsDialog arrow-left">\r
<div style="height:10px">\r
<i data-ng-click="hidePhysicalDialog()" class="window-icon icon-remove"></i>\r
</div>\r
- <div class="window_content">\r
- <ul class="nav nav-tabs tabsHeader">\r
- <li ng-repeat="tab in pDialogData.tabs track by $index" >\r
- <a href="#pDialogTab_{{$index}}" class="active">{{tab}}</a>\r
- </li>\r
- </ul>\r
- <div ng-repeat="tabContaint in pDialogData.containts track by $index" id="pDialogTab_{{$index}}">\r
- <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
- <tr ng-repeat="info in tabContaint.datas track by $index">\r
- <td > {{info.key}} </td> <td> {{ info.value }} </td>\r
- </tr>\r
- </table>\r
- <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
- <tr>\r
- <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
- </tr>\r
- <tr ng-repeat="item in tabContaint.datas track by $index">\r
- <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
- </tr>\r
- </table>\r
+ <div class="window_content">\r
+ <ul class="nav nav-tabs tabsHeader">\r
+ <li ng-repeat="tab in pDialogData.tabs track by $index">\r
+ <a href="#pDialogTab_{{$index}}" class="active">{{tab}}</a>\r
+ </li>\r
+ </ul>\r
+ <div ng-repeat="tabContaint in pDialogData.containts track by $index" id="pDialogTab_{{$index}}">\r
+ <table ng-if="!tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+ <tr ng-repeat="info in tabContaint.datas track by $index">\r
+ <td> {{info.key}} </td>\r
+ <td> {{ info.value }} </td>\r
+ </tr>\r
+ </table>\r
+ <table ng-if="tabContaint.hasHeader" class="table table-bordered" style="margin-bottom:0;">\r
+ <tr>\r
+ <th ng-repeat=" h in tabContaint.header track by $index">{{h}}</th>\r
+ </tr>\r
+ <tr ng-repeat="item in tabContaint.datas track by $index">\r
+ <td ng-repeat="value in item track by $index"> {{ value }} </td>\r
+ </tr>\r
+ </table>\r
+ </div>\r
</div>\r
</div>\r
</div>\r
-\r
</div>\r
- <!-- <div id="3d_view">\r
- </div> -->\r
- </div><!-- tab -->\r
-</div>\r
+ <!-- tab -->\r
+ </div>\r