diff options
author | Daniel Malachovsky <daniel.malachovsky@pantheon.sk> | 2016-02-08 19:05:54 +0100 |
---|---|---|
committer | Gerrit Code Review <gerrit@fd.io> | 2016-02-08 21:55:02 +0000 |
commit | 37c09259c1958fe5ed7c28bc24f593577070bbcb (patch) | |
tree | 19789c34c78a241a94fc55246a0fd412ed5f307d /vbd/gui/module/src/main/resources | |
parent | 1fe1660a989f6018115331e6a6c4b096ef088c82 (diff) |
Initial commit of vBd Manager functions.
- Bug Fixes for graphical manipulation. Fix req'd for unassigning pre-assigned.
- Fixed Graphical issues, interface, vpp and vBD manipulation
- Added REST functionality, GUI enhancements and squashed a few bugs.
- reworked assigning and unassigning IF to vBD
Change-Id: Ice13835699455439f6ab49a18facb49f7a16b7ef
Signed-off-by: Varun Seereeram <vseereer@cisco.com>
Signed-off-by: Daniel Malachovsky <daniel.malachovsky@pantheon.sk>
Diffstat (limited to 'vbd/gui/module/src/main/resources')
10 files changed, 464 insertions, 356 deletions
diff --git a/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css b/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css index cd5b73d48..2566d90cb 100644 --- a/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css +++ b/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css @@ -186,7 +186,9 @@ md-input-container .md-placeholder { } md-input-container.md-default-theme:not(.md-input-invalid).md-input-focused, -md-input-container:not(.md-input-invalid).md-input-focused label, +md-input-container:not(.md-input-invalid).md-input-focused label { + color: orange; +} md-input-container.md-default-theme:not(.md-input-invalid).md-input-has-value, md-input-container:not(.md-input-invalid).md-input-has-value label { color: white; @@ -218,4 +220,15 @@ md-select-menu md-option[selected] { /*tab overrides*/ md-tab.md-active { color: orange; + +md-input-container label { + color: white !important; +} + +md-input-container.md-input-focused label { + color: orange !important; +} + +md-option div.md-text { + color: orange !important; }
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/controllers/bdm.controller.js b/vbd/gui/module/src/main/resources/vpp/controllers/bdm.controller.js index d8fe8ea0f..e5ad012fa 100644 --- a/vbd/gui/module/src/main/resources/vpp/controllers/bdm.controller.js +++ b/vbd/gui/module/src/main/resources/vpp/controllers/bdm.controller.js @@ -11,62 +11,125 @@ define(['app/vpp/vpp.module'], function(vpp) { }]); - vpp.register.controller('TableController', ['$scope', '$rootScope','$filter', 'dataService', 'toastService', function ($scope, $rootScope, filter, dataService, toastService) { - var vm = this; - vm.rowCollection = dataService.tableContent; - vm.displayedCollection = [].concat(vm.rowCollection); - vm.updateAssignment = function(receivedInterface) { - var interf = _.find(dataService.interfaces, {name: receivedInterface.name, 'phys-address': receivedInterface['phys-address']}); - angular.copy(receivedInterface, interf); - if (interf.assigned){ - interf['v3po:l2']['bridge-domain'] = dataService.selectedBd.name; - } else { - interf['v3po:l2']['bridge-domain'] = ''; - } - dataService.injectBridgeDomainsTopoElements(); - dataService.buildTableContent(); - var previouslyChangedInterface = _.find(dataService.changedInterfaces, {name: interf.name, 'phys-address': interf['phys-address']}); - if (!previouslyChangedInterface) { - dataService.changedInterfaces.push(interf); - } - console.log(dataService.changedInterfaces); - }; - }]); + vpp.register.controller('TableController', ['$scope', '$rootScope','$filter', 'dataService', 'toastService', 'bdmInterfaceService', + function ($scope, $rootScope, filter, dataService, toastService, bdmInterfaceService) { + var vm = this; + vm.rowCollection = dataService.tableContent; + vm.displayedCollection = [].concat(vm.rowCollection); - vpp.register.controller('BridgeDomainsController', ['$scope', '$rootScope','$filter', 'dataService', 'bdmBridgeDomainService', 'toastService', - function($scope, $rootScope, $filter, dataService, bdmBridgeDomainService, toastService) { - $scope.addBd = function() { - var obj = bdmBridgeDomainService.createObj('vBD' + ((Math.random() * 100) + 1) ); + vm.updateAssignment = function(receivedInterface) { + console.log(receivedInterface); + var interf = _.find(dataService.interfaces, {name: receivedInterface.name, 'vppName': receivedInterface.vppName}); + if (receivedInterface.assigned){ + interf.assigned = true; + interf.vbd = dataService.selectedBd.name; + receivedInterface.vbd = dataService.selectedBd.name; + + vm.assignInterface(interf); + } else { + var vbdName = receivedInterface.vbd, + vppName = receivedInterface.vppName; + + interf.assigned = false; + interf.vbd = ''; + receivedInterface.vbd = ''; + + vm.unassignInterface(interf, vbdName, vppName); + } + //dataService.buildTableContent(); + var previouslyChangedInterface = _.find(dataService.changedInterfaces, {name: interf.name, 'vppName': interf.vppName}); + if (!previouslyChangedInterface) { + dataService.changedInterfaces.push(interf); + } + console.log(dataService.changedInterfaces); + dataService.injectBridgeDomainsTopoElements(); - bdmBridgeDomainService.add(obj, - function(data) { - console.log('successadding vbd'); - }, - function() { - console.warn('add bd failed'); - }); }; - $scope.dataService = dataService; + vm.assignInterface = function(interface) { + var interfaceObject = bdmInterfaceService.createObj(interface.name, interface.name); - dataService.nextApp.container(document.getElementById('bridge-domains-next-app')); - dataService.bridgeDomainsTopo.attach(dataService.nextApp); + var successCallback = function() { + toastService.showToast('Interface assigned'); + }; - window.addEventListener('resize', function () { - if ($location.path() === '/bridgedomains') { - dataService.topo.adaptToContainer(); - } - }); + var errorCallback = function() { + toastService.showToast('Unable to assign interface'); + }; + + bdmInterfaceService.add(interfaceObject, interface.vbd, interface.vppName, successCallback, errorCallback); + }; + + vm.unassignInterface = function(interface, vbdname, vppName) { + var interfaceObject = bdmInterfaceService.createObj(interface.name, interface.name); + + var successCallback = function() { + toastService.showToast('Interface unassigned'); + }; + + var errorCallback = function() { + toastService.showToast('Unable to unassign interface'); + }; + + bdmInterfaceService.delete(interfaceObject, vbdname, vppName, successCallback, errorCallback); + + }; + }]); + + vpp.register.controller('BridgeDomainsController', ['$scope', '$rootScope','$filter', 'dataService', 'bdmBridgeDomainService', 'toastService', '$mdDialog','bdmInterfaceService', + function($scope, $rootScope, $filter, dataService, bdmBridgeDomainService, toastService, $mdDialog,bdmInterfaceService) { + console.log('Bridge Domains Controller executed.'); + + $scope.dataService = dataService; $scope.bridgedomains = dataService.bridgedomains; $scope.selectedBd = dataService.selectedBd; + dataService.nextApp.container(document.getElementById('bridge-domains-next-app')); + dataService.bridgeDomainsTopo.attach(dataService.nextApp); + + if (!dataService.bridgedomainsLoaded) { + dataService.generateInterfaces(); + bdmBridgeDomainService.get(function(data) { + //success callback + angular.copy(data['network-topology'].topology, dataService.bridgedomains); + dataService.bridgedomainsLoaded = true; + console.log('Loaded BridgeDomains:'); + console.log(dataService.bridgedomains); + dataService.buildAssignedInterfaces(); + }, function(data,status) { + //error callback + console.log(status); + }); + } + dataService.bridgeDomainsTopo.on('clickNode',function(topo,node) { console.log(node); }); + $scope.reload = function() { + dataService.selectedBd.name = ''; + dataService.changedInterfaces.length = 0; + dataService.originalAssignments.length = 0; + dataService.interfaces.length = 0; + dataService.tableContent.length = 0; + dataService.bridgeDomainsTopo.clear(); + dataService.injectedInterfaces.length = 0; + dataService.generateInterfaces(); + bdmBridgeDomainService.get(function(data) { + //success callback + angular.copy(data['network-topology'].topology, dataService.bridgedomains); + dataService.bridgedomainsLoaded = true; + console.log('Loaded BridgeDomains:'); + console.log(dataService.bridgedomains); + dataService.buildAssignedInterfaces(); + }, function(data,status) { + //error callback + console.log(status); + }); + }; + $scope.bdChanged = function() { - dataService.injectBridgeDomainsTopoElements(); dataService.buildTableContent(); }; @@ -88,8 +151,7 @@ define(['app/vpp/vpp.module'], function(vpp) { if (status === 'success') { dataService.bridgedomains.push(vm.bd); dataService.selectedBd.name = vm.bd.name; - dataService.injectBridgeDomainsTopoElements(); - dataService.buildTableContent(); + $scope.reload(); vm.close(); } }; @@ -99,23 +161,102 @@ define(['app/vpp/vpp.module'], function(vpp) { vm.waiting = true; //send a POST with the entered content in the form field + var obj = bdmBridgeDomainService.createObj(vm.bd.name); + + bdmBridgeDomainService.add(obj, + function(data) { + vm.isDone('success'); + }, + function() { + vm.isDone('failed'); + }); + }; }, controllerAs: 'NewBdDialogCtrl', - templateUrl: 'templates/new-bd-dialog.html', + templateUrl: $scope.view_path + 'new-bd-dialog.html', parent: angular.element(document.body), clickOutsideToClose:false }) }; + /* FIXME: remove after testing */ + /*$scope.deploy = function() { + var successfulRequestsRequired = dataService.changedInterfaces.length; + var successfulRequests = 0; - $scope.deploy = function() { + console.log('Removing previous assignments...'); + _.forEach(dataService.changedInterfaces, function(interf) { - }; + //Check if previously assigned.. then DELETE + //.... + var previousAssignment = _.find(dataService.originalAssignments, { + 'vbridge-topology:user-interface': interf.name, + vppName: interf.vppName + }); + + if (previousAssignment) { + successfulRequestsRequired++; + bdmInterfaceService.delete( + { + "tp-id":previousAssignment['tp-id'], + "vbridge-topology:user-interface": previousAssignment['vbridge-topology:user-interface'] + }, + previousAssignment.vbd, + previousAssignment.vppName, + function() { + //success callback + console.log('Removed previous assignment:',previousAssignment); + successfulRequests++; + + if (successfulRequests >= successfulRequestsRequired) { + toastService.showToast('Deployed! Bridge Domain Validated.'); + dataService.changedInterfaces.length = 0; + console.log('Changed interfaces tracker has been reset.'); + $scope.reload(); + } + }, + function() { + //error callback + console.error('ERROR removing assignment:',previousAssignment); + } + ) + } + if (interf.assigned) { + //Send PUT to correct vBD + bdmInterfaceService.add( + { + "tp-id":interf.vppName+'-'+interf.name, + "vbridge-topology:user-interface": interf.name + }, + interf.vbd, + interf.vppName, + function() { + //success callback + console.log('Added assignment:',interf); + successfulRequests++; + + if (successfulRequests >= successfulRequestsRequired) { + toastService.showToast('Deployed! Bridge Domain Validated.'); + dataService.changedInterfaces.length = 0; + console.log('Changed interfaces tracker has been reset.') + $scope.reload(); + } + }, + function() { + //error callback + console.error('ERROR adding assignment:',interf); + } + ) + } else { + successfulRequests++; + } + }); + };*/ $scope.removeBd = function() { - if($scope.selectedBd.name) { + if(dataService.selectedBd.name) { var successCallback = function(success) { if (success) { console.log($scope.bridgedomains); @@ -124,18 +265,20 @@ define(['app/vpp/vpp.module'], function(vpp) { }); toastService.showToast('Bridge Domain Removed!'); $scope.selectedBd.name = ''; - dataService.clearInjectedInterfacesInBridgeDomainTopo(); - dataService.injectBdIntoBridgeDomainsTopo(); + dataService.clearTopology(); dataService.tableContent.length = 0; + $scope.reload(); } else { toastService.showToast('Error removing Bridge Domain!'); - } }; - - //... removeBdFromOdl(vm.selectedBd.name, successCallback); + bdmBridgeDomainService.remove(dataService.selectedBd.name, function(){successCallback(true)}, function(){successCallback(false)}); } }; + window.addEventListener('resize', function () { + dataService.bridgeDomainsTopo.adaptToContainer(); + }); + }]); });
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/controllers/bdm.vpp.controller.js b/vbd/gui/module/src/main/resources/vpp/controllers/bdm.vpp.controller.js index 69dfd2fcb..44a4b0cf2 100644 --- a/vbd/gui/module/src/main/resources/vpp/controllers/bdm.vpp.controller.js +++ b/vbd/gui/module/src/main/resources/vpp/controllers/bdm.vpp.controller.js @@ -11,132 +11,4 @@ define(['app/vpp/vpp.module'], function(vpp) { }]); - vpp.register.controller('TableController', ['$scope', '$rootScope','$filter', 'dataService', 'toastService', function ($scope, $rootScope, filter, dataService, toastService) { - var vm = this; - vm.rowCollection = dataService.tableContent; - vm.displayedCollection = [].concat(vm.rowCollection); - vm.updateAssignment = function(receivedInterface) { - var interf = _.find(dataService.interfaces, {name: receivedInterface.name, 'phys-address': receivedInterface['phys-address']}); - angular.copy(receivedInterface, interf); - if (interf.assigned){ - interf['v3po:l2']['bridge-domain'] = dataService.selectedBd.name; - } else { - interf['v3po:l2']['bridge-domain'] = ''; - } - dataService.injectBridgeDomainsTopoElements(); - dataService.buildTableContent(); - var previouslyChangedInterface = _.find(dataService.changedInterfaces, {name: interf.name, 'phys-address': interf['phys-address']}); - if (!previouslyChangedInterface) { - dataService.changedInterfaces.push(interf); - } - console.log(dataService.changedInterfaces); - }; - }]); - - vpp.register.controller('BridgeDomainsController', ['$scope', '$rootScope','$filter', 'dataService', 'bdmBridgeDomainService', 'toastService', - function($scope, $rootScope, $filter, dataService, bdmBridgeDomainService, toastService) { - $scope.addBd = function() { - var obj = bdmBridgeDomainService.createObj('vBD' + ((Math.random() * 100) + 1) ); - - bdmBridgeDomainService.add(obj, - function(data) { - console.log('successadding vbd'); - }, - function() { - console.warn('add bd failed'); - }); - }; - - /*var vm = this; - vm.dataService = dataService; - - dataService.nextApp.container(document.getElementById('bridge-domains-next-app')); - dataService.bridgeDomainsTopo.attach(dataService.nextApp); - - window.addEventListener('resize', function () { - if ($location.path() === '/bridgedomains') { - dataService.topo.adaptToContainer(); - } - }); - - vm.bridgedomains = dataService.bridgedomains; - vm.selectedBd = dataService.selectedBd; - - dataService.bridgeDomainsTopo.on('clickNode',function(topo,node) { - console.log(node); - }); - - vm.bdChanged = function() { - dataService.injectBridgeDomainsTopoElements(); - dataService.buildTableContent(); - }; - - vm.addBd = function() { - //show dialog - $mdDialog.show({ - controller: function() { - var vm = this; - vm.bd = {}; - vm.waiting = false; - - //function called when the cancel button ( 'x' in the top right) is clicked - vm.close = function() { - $mdDialog.cancel(); - }; - - vm.isDone = function(status) { - vm.waiting = false; - if (status === 'success') { - dataService.bridgedomains.push(vm.bd); - dataService.selectedBd.name = vm.bd.name; - dataService.injectBridgeDomainsTopoElements(); - dataService.buildTableContent(); - vm.close(); - } - }; - - //function called when the update button is clicked - vm.updateConfig = function() { - vm.waiting = true; - //send a POST with the entered content in the form field - - }; - }, - controllerAs: 'NewBdDialogCtrl', - templateUrl: 'templates/new-bd-dialog.html', - parent: angular.element(document.body), - clickOutsideToClose:false - }) - }; - - - - vm.deploy = function() { - - }; - - vm.removeBd = function() { - if(vm.selectedBd.name) { - var successCallback = function(success) { - if (success) { - console.log(vm.bridgedomains); - _.remove(vm.bridgedomains, { - name: vm.selectedBd.name - }); - toastService.showToast('Bridge Domain Removed!'); - vm.selectedBd.name = ''; - dataService.clearInjectedInterfacesInBridgeDomainTopo(); - dataService.injectBdIntoBridgeDomainsTopo(); - dataService.tableContent.length = 0; - } else { - toastService.showToast('Error removing Bridge Domain!'); - - } - }; - - //... removeBdFromOdl(vm.selectedBd.name, successCallback); - } - }; - */ - }]); });
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js b/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js index c8ca1e575..7f2a4ec0c 100644 --- a/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js +++ b/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js @@ -22,6 +22,9 @@ define(['app/vpp/vpp.module'], function(vpp) { dataService.vpps = $scope.vppList; $scope.$broadcast('RELOAD_VPP_TABLE'); + + //for vppList access in BDM + dataService.vpps = $scope.vppList; }, // error callback function(res) { @@ -33,105 +36,8 @@ define(['app/vpp/vpp.module'], function(vpp) { $scope.initVppList = function() { $scope.vppList = []; $scope.displayVppList = []; - - //setting reference for vpp access in BDM - //dataService.vpps = $scope.vppList; }; - /*$scope.viewTopology = function(vpp) { - $mdDialog.show({ - controller: function() { - var vm = this; - - $scope.topo = new nx.graphic.Topology({ - height: 350, - width: 500, - scalable: true, - theme:'blue', - enableGradualScaling:true, - nodeConfig: { - color: '#414040', - label: 'model.label', - scale: 'model.scale', - iconType: function(vertex) { - var type = vertex.get().type; - if (type === 'bd') { - return 'bd' - } else if (type === 'vpp') { - return 'switch' - } else { - return 'interf'; - } - } - }, - linkConfig: { - label: 'model.label', - linkType: 'parallel', - color: function(link) { - if (link.getData().type === 'tunnel') { - return '#00FF00'; - } else { - return '#414040'; - } - }, - width: function(link) { - if (link.getData().type === 'tunnel') { - return 5; - } - } - }, - showIcon: true, - dataProcessor: 'force', - autoLayout: true, - enableSmartNode: false, - tooltipManagerConfig: { - nodeTooltipContentClass: 'TooltipNode', - linkTooltipContentClass: 'TooltipLink' - } - }); - $scope.app = new nx.ui.Application; - - vm.vpp = vpp; - vm.vpp.type = 'vpp'; - vm.vpp.label = vm.vpp.name; - - var nodes = [].concat(vm.vpp); - var links = []; - - _.forEach(vm.vpp.interfaces, function(interf, index){ - interf.label = interf.name; - interf.scale = 0.5; - nodes.push(interf); - links.push({source: 0, target: index + 1}); - }); - - console.log(vpp); - console.log(nodes); - console.log(links); - - $scope.topo.data({ - nodes: nodes, - links: links - }); - - this.close = function() { - $mdDialog.cancel(); - }; - - }, - onComplete: function() { - console.log(document.getElementById('next-vpp-topo')); - $scope.app.container(document.getElementById('next-vpp-topo')); - $scope.topo.attach($scope.app); - - }, - templateUrl: $scope.view_path + 'vpp-topo.html', - controllerAs: 'VppTopoCtrl', - parent: angular.element(document.body), - clickOutsideToClose:true - }) - };*/ - $scope.addVppShowForm = function() { $mdDialog.show({ controller: function() { @@ -340,9 +246,5 @@ define(['app/vpp/vpp.module'], function(vpp) { $scope.viewTopology($scope.selectedVpp); - /*$scope.$on('RELOAD_SELECTED_VPP', function(event) { - $scope.viewTopology($scope.selectedVpp); - });*/ - }]); });
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/services/bdm.bridgedomain.service.js b/vbd/gui/module/src/main/resources/vpp/services/bdm.bridgedomain.service.js index 5d3b69632..1438208d2 100644 --- a/vbd/gui/module/src/main/resources/vpp/services/bdm.bridgedomain.service.js +++ b/vbd/gui/module/src/main/resources/vpp/services/bdm.bridgedomain.service.js @@ -55,6 +55,16 @@ define(['app/vpp/vpp.module'], function(vpp) { }); }; + s.remove = function(bdName,successCallback,errorCallback) { + //http://localhost:8181/restconf/config/network-topology:network-topology/topology/testBD + var restObj = VPPRestangular.one('restconf').one('config').one('network-topology:network-topology').one('topology').one(bdName); + + restObj.remove().then(function(data) { + successCallback(data); + }, function(res) { + errorCallback(res.data, res.status); + }); + }; return s; }); diff --git a/vbd/gui/module/src/main/resources/vpp/services/bdm.interface.service.js b/vbd/gui/module/src/main/resources/vpp/services/bdm.interface.service.js index 341fb5d48..d2abc77b1 100644 --- a/vbd/gui/module/src/main/resources/vpp/services/bdm.interface.service.js +++ b/vbd/gui/module/src/main/resources/vpp/services/bdm.interface.service.js @@ -6,7 +6,7 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ define(['app/vpp/vpp.module'], function(vpp) { - vpp.register.factory('bdmInterfaceService', function(VPPRestangular) { + vpp.register.factory('bdmInterfaceService', function(VPPRestangular, bdmVppService) { var s = {}; var Interface = function(tpId, interfaceName) { @@ -18,12 +18,32 @@ define(['app/vpp/vpp.module'], function(vpp) { return new Interface(tpId, interfaceName); }; - s.add = function(interface, bridgeDomainId, vppId, successCallback, errorCallback) { + s.add = function(interf, bridgeDomainId, vppId, successCallback, errorCallback) { var restObj = VPPRestangular.one('restconf').one('config').one('network-topology:network-topology') - .one('topology').one(bridgeDomainId).one('node').one(vppId).one('termination-point').one(interface['tp-id']); - var dataObj = {'termination-point': [interface]}; + .one('topology').one(bridgeDomainId).one('node').one(vppId).one('termination-point').one(encodeURIComponent(interf['tp-id'])); - restObj.customPUT(dataObj).then(function(data) { + var dataObj = {'termination-point': [interf]}; + + var write = function() { + restObj.customPUT(dataObj).then(function(data) { + successCallback(data); + }, function(res) { + errorCallback(res.data, res.status); + }); + }; + + var errorCallback = function() {}; + + bdmVppService.checkAndWriteVpp(bridgeDomainId, vppId, write, errorCallback); + + + }; + + s.delete = function(interf, bridgeDomainId, vppId, successCallback, errorCallback) { + var restObj = VPPRestangular.one('restconf').one('config').one('network-topology:network-topology') + .one('topology').one(bridgeDomainId).one('node').one(vppId).one('termination-point').one(encodeURIComponent(interf['tp-id'])); + + restObj.remove().then(function(data) { successCallback(data); }, function(res) { errorCallback(res.data, res.status); @@ -41,7 +61,6 @@ define(['app/vpp/vpp.module'], function(vpp) { }); }; - return s; }); });
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/services/bdm.vpp.service.js b/vbd/gui/module/src/main/resources/vpp/services/bdm.vpp.service.js index b817a75a3..0a24c2329 100644 --- a/vbd/gui/module/src/main/resources/vpp/services/bdm.vpp.service.js +++ b/vbd/gui/module/src/main/resources/vpp/services/bdm.vpp.service.js @@ -38,14 +38,40 @@ define(['app/vpp/vpp.module'], function(vpp) { s.get = function(bridgeDomainId, successCallback, errorCallback) { var restObj = VPPRestangular.one('restconf').one('config').one('network-topology:network-topology').one('topology').one(bridgeDomainId); - restObj.get().then(function(data) { + return restObj.get().then(function(data) { successCallback(data); }, function(res) { errorCallback(res.data, res.status); }); }; + s.getOne = function(bridgeDomainId, vppId, successCallback, errorCallback) { + var restObj = VPPRestangular.one('restconf').one('config').one('network-topology:network-topology').one('topology').one(bridgeDomainId).one('node').one(vppId); + return restObj.get().then(function(data) { + successCallback(data); + }, function(res) { + errorCallback(res.data, res.status); + }); + }; + + s.checkAndWriteVpp = function(bridgeDomainId, vppId, successCallback, errorCallback) { + s.getOne(bridgeDomainId, vppId, + function() { + successCallback(); + }, function() { + var vppObject = s.createObj(vppId, vppId); + + s.add(vppObject, bridgeDomainId, function() { + successCallback(); + }, function() { + errorCallback(); + }); + } + ); + + //getPromise.then + }; return s; }); });
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/services/vpp.services.js b/vbd/gui/module/src/main/resources/vpp/services/vpp.services.js index 70b1631f7..4c20f844e 100644 --- a/vbd/gui/module/src/main/resources/vpp/services/vpp.services.js +++ b/vbd/gui/module/src/main/resources/vpp/services/vpp.services.js @@ -30,14 +30,15 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { } }); - vpp.register.service('dataService', function() { + vpp.register.service('dataService', ['$timeout', function($timeout) { + + var self = this; nx.graphic.Icons.registerIcon("bd", "src/app/vpp/assets/images/bd1.svg", 45, 45); nx.graphic.Icons.registerIcon("interf", "src/app/vpp/assets/images/interf.svg", 45, 45); this.bridgeDomainsTopo = new nx.graphic.Topology({ - height: 350, - width: 500, + adaptive: true, scalable: true, theme:'blue', enableGradualScaling:true, @@ -49,8 +50,6 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { var type = vertex.get().type; if (type === 'bd') { return 'bd' - } else if (type === 'vpp') { - return 'switch' } else { return 'interf'; } @@ -82,11 +81,11 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { } }); this.nextApp = new nx.ui.Application; + this.bridgedomainsLoaded = false; this.vpps = []; - this.tableContent = []; - this.unassignedInterfaces = []; + this.originalAssignments = []; this.interfaces = []; this.injectedInterfaces = []; this.bridgedomains = []; @@ -95,69 +94,188 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { name: '' }; - this.setBridgeDomains = function(data) { - angular.copy(data['bridge-domains']['bridge-domain'], this.bridgedomains); + this.generateInterfaces = function() { + self.interfaces.length = 0; + _.forEach(this.vpps, function(vpp) { + _.forEach(vpp.interfaces, function(interf) { + interf.vppName = vpp.name; + interf.label = vpp.name+'/'+interf.name; + interf.scale = 0.5; + self.interfaces.push(interf); + }); + }); + console.log(this.interfaces); }; - this.clearInjectedInterfacesInBridgeDomainTopo = function() { - this.bridgeDomainsTopo.clear(); - this.injectedInterfaces.length = 0; + this.buildAssignedInterfaces = function() { + this.originalAssignments.length = 0; + _.forEach(this.bridgedomains, function(bd){ + var bdName = bd['topology-id']; + var nodes = bd.node; + if (nodes) { + _.forEach(nodes, function(vpp) { + var vppName = vpp['node-id']; + var tps = vpp['termination-point']; + if (tps) { + _.forEach(tps, function(tp) { + tp.vppName = vppName; + tp.vbd = bdName; + self.originalAssignments.push(tp); + }) + } + }) + } + }); + console.log('Assigned Interfaces: '); + console.log(this.originalAssignments); }; - this.generateUnassignedInterfaces = function() { - this.unassignedInterfaces.length = 0; - for (var x=0; x<this.interfaces.length; x++) { - if (!this.interfaces[x]['v3po:l2']['bridge-domain']) { - this.unassignedInterfaces.push(this.interfaces[x]); + this.buildTableContent = function() { + this.tableContent.length = 0; + angular.copy(this.interfaces,this.tableContent); + + + //Makes assignements based on previously changed interfaces, or assignments retrieved from ODL + _.forEach(this.tableContent, function(interf) { + var matchedChangedInterface = _.find(self.changedInterfaces, { + name: interf.name, + vppName: interf.vppName + }); + + var matchedOriginalAssignment = _.find(self.originalAssignments, { + 'vbridge-topology:user-interface': interf.name, + vppName: interf.vppName + }); + + if (matchedChangedInterface) { + interf.assigned = matchedChangedInterface.assigned; + interf.vbd = matchedChangedInterface.vbd; + } else if (matchedOriginalAssignment) { + interf.assigned = true; + interf.vbd = matchedOriginalAssignment.vbd; + } else { + interf.assigned = false; + interf.vbd = ''; } - } - }; + }); + + _.remove(self.tableContent, function(interf){ + var isAssigned = interf.assigned === true; + var isNotCorrectBd = !(interf.vbd === self.selectedBd.name); + return(isAssigned && isNotCorrectBd); + }); + + //_.forEach(this.originalAssignments, function(origAssignment) { + // if (origAssignment.vbd === self.selectedBd.name) { + // var matchedInterface = _.find(self.tableContent, { + // name: origAssignment['vbridge-topology:user-interface'], + // vppName: origAssignment.vppName + // }); + // if (matchedInterface) { + // matchedInterface.assigned = true; + // matchedInterface.vbd = origAssignment.vbd; + // } else { + // console.error('Interface "'+origAssignment['vbridge-topology:user-interface']+'" on VPP "'+origAssignment.vppName+'" in vBD "'+origAssignment.vbd+'" was not found at mount point!'); + // } + // } else { + // _.remove(self.tableContent, { + // name: origAssignment['vbridge-topology:user-interface'], + // vppName: origAssignment.vppName + // }); + // } + //}); + // + //_.forEach(this.changedInterfaces, function(changedInterface) { + // + // var matchedInterface = _.find(self.tableContent, { + // name: changedInterface.name, + // vppName: changedInterface.vppName + // }); + // + // if (matchedInterface) { + // if (changedInterface.assigned) { + // if (changedInterface.vbd === self.selectedBd.name) { + // matchedInterface.assigned = true; + // matchedInterface.vbd = changedInterface.vbd; + // } + // else { + // _.remove(self.tableContent, { + // name: changedInterface.name, + // vppName: changedInterface.vppName + // }); + // } + // } else { + // matchedInterface.assigned = false; + // matchedInterface.vbd = ''; + // } + // } + //}); + + //.. + + //_.remove(self.tableContent, { + // name: origAssignment['vbridge-topology:user-interface'], + // vppName: origAssignment.vppName + //}); + + this.injectBridgeDomainsTopoElements(); - this.injectBridgeDomainsTopoElements = function() { - this.clearInjectedInterfacesInBridgeDomainTopo(); - this.injectBdIntoBridgeDomainsTopo(); - this.injectInterfacesIntoBridgeDomainsTopo(); - this.injectInterfacesLinksIntoBridgeDomainsTopo(); - this.bridgeDomainsTopo.adaptToContainer(); }; - this.buildTableContent = function() { - this.tableContent.length = 0; - this.generateUnassignedInterfaces(); - angular.copy(this.unassignedInterfaces.concat(this.injectedInterfaces),this.tableContent); + + this.clearTopology = function() { + this.bridgeDomainsTopo.clear(); + this.injectedInterfaces.length = 0; + }; - this.injectBdIntoBridgeDomainsTopo = function() { - this.bridgeDomainsTopo.addNode({ + //this.generateUnassignedInterfaces = function() { + // this.unassignedInterfaces.length = 0; + // for (var x=0; x<this.interfaces.length; x++) { + // if (!this.interfaces[x]['v3po:l2']['bridge-domain']) { + // this.unassignedInterfaces.push(this.interfaces[x]); + // } + // } + //}; + + this.setData = function() { + + for (var x=0; x<this.tableContent.length; x++) { + if (this.tableContent[x].assigned) { + this.bridgeDomainsTopo.addNode(this.tableContent[x]); + this.injectedInterfaces.push(this.tableContent[x]); + } + } + + var nodes = [{ name : this.selectedBd.name, label: this.selectedBd.name, - x: 60, - y: -50, - scale: 5 - }); - }; + type:'bd', + x: 0, + y: 0, + scale: 1 + }].concat(this.injectedInterfaces); - this.injectInterfacesLinksIntoBridgeDomainsTopo = function() { - var nodes = this.bridgeDomainsTopo.getNodes(); + var links = []; for (var x=1; x<nodes.length; x++){ - var target = nodes[x].get('data-id'); - this.bridgeDomainsTopo.addLink({'source':0, 'target': target}); + links.push({'source':0, 'target': x}); } - }; - this.injectInterfacesIntoBridgeDomainsTopo = function() { - for (var x=0; x<this.interfaces.length; x++) { - if ((this.interfaces[x]['v3po:l2']['bridge-domain'] === this.selectedBd.name) && (this.interfaces[x].type==='iana-if-type:ethernetCsmacd')) { - this.interfaces[x].label = 'vpp1/'+this.interfaces[x].name; - this.bridgeDomainsTopo.addNode(this.interfaces[x]); - this.injectedInterfaces.push(this.interfaces[x]); - this.interfaces[x].assigned = true; - } - } + var topoData = { + nodes: nodes, + links: links + }; + + this.bridgeDomainsTopo.data(topoData); }; - }); + this.injectBridgeDomainsTopoElements = function() { + this.clearTopology(); + this.setData(); + self.bridgeDomainsTopo.adaptToContainer(); + }; + }]); diff --git a/vbd/gui/module/src/main/resources/vpp/views/bridge-domains.tpl.html b/vbd/gui/module/src/main/resources/vpp/views/bridge-domains.tpl.html index 263fc0949..806097346 100644 --- a/vbd/gui/module/src/main/resources/vpp/views/bridge-domains.tpl.html +++ b/vbd/gui/module/src/main/resources/vpp/views/bridge-domains.tpl.html @@ -1,39 +1,44 @@ <div ng-controller="BridgeDomainsController"> - <div layout="row" layout-xs="column" style="height:100%"> - <div id="bridge-domains-next-app" style="height: 550px; width: 50%" flex></div> - <div class="md-sidenav-left md-whiteframe-z2" style="height: 550px" flex> + <div layout="row" layout-xs="column" style="height: 550px; width: 100%"> + <div id="bridge-domains-next-app" style="height: 550px; width: 60%"></div> + <div class="md-sidenav-left md-whiteframe-z2" style="height: 550px; background-color: #414042; overflow: scroll" flex> <md-content layout-padding ng-controller="TableController as TableCtrl"> <md-input-container style="margin-right: 5px;" layout="row"> <md-select ng-model='selectedBd.name' placeholder="Select BD" ng-change="bdChanged()" style="width: 100%;"> - <md-option ng-repeat="bd in bridgedomains" value="{{bd.name}}">{{bd.name}}</md-option> + <md-option ng-repeat="bd in bridgedomains" value="{{bd['topology-id']}}">{{bd['topology-id']}}</md-option> </md-select> <md-button class="md-raised" md-no-ink ng-click="addBd()" style="width: 25%;">Add BD</md-button> - <md-button class="md-raised" md-no-ink ng-click="removeBd()" style="width: 35%;" ng-if="dataService.injectedInterfaces.length===0 && dataService.selectedBd.name">Remove BD</md-button> + <md-button class="md-raised" md-no-ink ng-click="removeBd()" style="width: 35%;" ng-if="dataService.injectedInterfaces.length===0 && dataService.selectedBd.name && dataService.changedInterfaces.length===0">Remove BD</md-button> + <md-button class="md-raised" md-no-ink ng-click="reload()" style="width: 25%;">Reload</md-button> </md-input-container> - <table st-table="TableCtrl.displayedCollection" class="table table-striped" st-safe-src="TableCtrl.rowCollection"> + <table st-table="TableCtrl.displayedCollection" class="table" st-safe-src="TableCtrl.rowCollection"> <thead> <tr> <th>Assigned</th> + <th st-sort="vppName" st-sort-default="true">Vpp</th> <th st-sort="name" st-sort-default="true">Interface Name</th> - <th st-sort="description">Description</th> + <!--<th st-sort="description">Description</th>--> <th st-sort="bridge-domain">Bridge Domain</th> </tr> </thead> <tbody> <tr ng-repeat="row in TableCtrl.displayedCollection"> - <td> - <md-switch ng-model="row.assigned" aria-label="Assign Switch" ng-change="TableCtrl.updateAssignment(row);"> - </md-switch> - </td> - <td>{{row.label}}</td> - <td>{{row.description}}</td> - <td>{{row['v3po:l2']['bridge-domain']}}</td> + <div ng-hide="row.hidden"> + <td> + <md-switch ng-model="row.assigned" aria-label="Assign Switch" ng-change="TableCtrl.updateAssignment(row);"> + </md-switch> + </td> + <td>{{row.vppName}}</td> + <td>{{row.name}}</td> + <!--<td>{{row.description}}</td>--> + <td>{{row.vbd}}</td> + </div> </tr> </tbody> </table> <!--<md-input-container style="bottom: 10px">--> - <md-button class="md-raised" md-no-ink ng-click="deploy()" style="width: 94%;position: fixed;" ng-if="dataService.changedInterfaces.length">Deploy</md-button> + <md-button class="md-raised" md-no-ink ng-click="deploy()" style="width: 94%;" ng-if="dataService.changedInterfaces.length">Deploy</md-button> <!--</md-input-container>--> </md-content> </div> diff --git a/vbd/gui/module/src/main/resources/vpp/views/new-bd-dialog.html b/vbd/gui/module/src/main/resources/vpp/views/new-bd-dialog.html index fd04f8e84..41e6ad8a4 100644 --- a/vbd/gui/module/src/main/resources/vpp/views/new-bd-dialog.html +++ b/vbd/gui/module/src/main/resources/vpp/views/new-bd-dialog.html @@ -7,7 +7,7 @@ </h2> <span flex></span> <md-button class="md-icon-button" ng-click="NewBdDialogCtrl.close()" aria-label="close button"> - <div class="glyphicon glyphicon-remove"></div> + <div>X</div> </md-button> </div> </md-toolbar> |