diff options
12 files changed, 424 insertions, 832 deletions
diff --git a/vbd/gui/bundle/pom.xml b/vbd/gui/bundle/pom.xml index a8e4ba602..ff2b787b5 100644 --- a/vbd/gui/bundle/pom.xml +++ b/vbd/gui/bundle/pom.xml @@ -33,6 +33,11 @@ <artifactId>loader</artifactId> <version>0.3.0-SNAPSHOT</version> </dependency> + <dependency> + <groupId>io.fd.honeycomb.vbd</groupId> + <artifactId>vbd-ui-module</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> </dependencies> <build> diff --git a/vbd/gui/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/vbd/gui/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml index 265cd7538..5812bcf70 100644 --- a/vbd/gui/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/vbd/gui/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -13,6 +13,7 @@ <list> <value>src/app/vpp/assets/css/next.css</value> <value>src/app/vpp/bower_components/angular-material/angular-material.min.css</value> + <value>src/app/vpp/bower_components/angular-ui-grid/ui-grid.css</value> <value>src/app/vpp/assets/css/vpp.css</value> </list> </property> 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 45eb9f1d1..b196bcd70 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 @@ -8,7 +8,6 @@ html,body { width: 100%; - overflow: hidden; background-color: #414040; } @@ -31,8 +30,8 @@ md-sidenav.md-locked-open { width: 35px; } -.white { - color: white; +.ui-grid-header-cell-label { + color: black !important; } span.center { @@ -45,6 +44,10 @@ span.center { background-color: white; } +.n-topology-nav { + display: none; +} + .node-label { fill: #414040 !important; } @@ -84,10 +87,6 @@ span.center { z-index: 10000000; } -text.node-label { - font-size: 16px !important; -} - .n-topology.n-topology-blue .n-topology-nav-mode-selected:hover { background: #414040 !important; } @@ -108,7 +107,3 @@ a.md-button.md-warn[disabled], .md-button.md-default-theme[disabled], .md-button .md-button.md-accent[disabled], .md-button.md-default-theme.md-warn[disabled], .md-button.md-warn[disabled] { color: #FFA500 !important; } - -/*md-select.md-default-theme, md-select .md-select-value.md-select-placeholder {*/ - -/*}*/
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/bower.json b/vbd/gui/module/src/main/resources/vpp/bower.json index a6edf5837..441b933b6 100644 --- a/vbd/gui/module/src/main/resources/vpp/bower.json +++ b/vbd/gui/module/src/main/resources/vpp/bower.json @@ -1,7 +1,7 @@ { - "name": "open-vpp", - "description": "open-vpp", - "main": "app.js", + "name": "odl-vpp-ui", + "description": "Opendaylight VPP UI", + "main": "main.js", "authors": [ "Varun Seereeram", "Chris Metz", @@ -28,10 +28,10 @@ "angular-animate": "^1.3.0 || >1.4.0-beta.0", "angular-aria": "^1.3.15 || >1.4.0-beta.0", "angular-material": "~0.11.4", - "angular-smart-table": "~2.1.6", - "angular-route": "~1.4.7" + "angular-smart-table": "~2.1.7", + "angular-ui-grid": "~3.1.0" }, "resolutions": { - "angular": "1.4.8" + "angular": "1.4.9" } } diff --git a/vbd/gui/module/src/main/resources/vpp/main.js b/vbd/gui/module/src/main/resources/vpp/main.js index 6fdc5c209..a39513bdd 100644 --- a/vbd/gui/module/src/main/resources/vpp/main.js +++ b/vbd/gui/module/src/main/resources/vpp/main.js @@ -13,6 +13,7 @@ require.config({ 'angular-smart-table' : 'app/vpp/bower_components/angular-smart-table/dist/smart-table', 'lodash' : 'app/vpp/assets/js/lodash.min', 'next': 'app/vpp/assets/js/next', + 'angular-ui-grid': 'app/vpp/bower_components/angular-ui-grid/ui-grid.min', }, shim : { @@ -20,6 +21,7 @@ require.config({ 'angular-animate' : ['angular'], 'angular-aria' : ['angular'], 'angular-smart-table' : ['angular'], + 'angular-ui-grid' : ['angular'] }, }); diff --git a/vbd/gui/module/src/main/resources/vpp/views/inventory-table-interfaces-subgrid.tpl.html b/vbd/gui/module/src/main/resources/vpp/views/inventory-table-interfaces-subgrid.tpl.html new file mode 100644 index 000000000..c47617cb1 --- /dev/null +++ b/vbd/gui/module/src/main/resources/vpp/views/inventory-table-interfaces-subgrid.tpl.html @@ -0,0 +1 @@ +<div ui-grid="row.entity.subGridOptions" style="height:150px;"></div>
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html b/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html index ad24bce14..4f15332de 100644 --- a/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html +++ b/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html @@ -1,7 +1,8 @@ <div ng-controller="InventoryTableController"> <md-button ng-click="addVppShowForm()">Mount VPP</md-button> <md-button ng-click="getVppList()">Reload VPPs</md-button> - <table class="footable"> + <!--FIXME: decide which element to use, if static, or ui-grid--> + <!--<table class="footable"> <thead> <tr> <th>VPP Name</th> @@ -24,5 +25,8 @@ </td> </tr> </tbody> - </table> + </table>--> + <div ng-controller="InventoryTableDefinitonController" class="black"> + <div ui-grid="gridOptions" ui-grid-expandable class="grid"></div> + </div> </div>
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html b/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html index d0ce47604..39178716d 100644 --- a/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html +++ b/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html @@ -59,7 +59,7 @@ <md-dialog-actions layout="row"> <span flex></span> <md-button ng-click="NewVppDialogCtrl.updateConfig();" style="margin-right:20px;" class="md-accent"> - Mount + <span style="color: black">Mount</span> </md-button> </md-dialog-actions> </form> diff --git a/vbd/gui/module/src/main/resources/vpp/vpp.controller.js b/vbd/gui/module/src/main/resources/vpp/vpp.controller.js index ebfd49ae8..acb7d0a5c 100644 --- a/vbd/gui/module/src/main/resources/vpp/vpp.controller.js +++ b/vbd/gui/module/src/main/resources/vpp/vpp.controller.js @@ -13,8 +13,8 @@ var modules = ['app/vpp/vpp.module', define(modules, function(vpp) { - vpp.register.controller('vppCtrl', ['$scope', '$rootScope', '$timeout', 'httpService' ,'dataService', 'toastService', '$mdSidenav', '$mdDialog', - function ($scope, $rootScope, $timeout, httpService ,dataService, toastService, $mdSidenav, $mdDialog) { + vpp.register.controller('vppCtrl', ['$scope', '$rootScope', '$timeout' ,'dataService', 'toastService', '$mdSidenav', '$mdDialog', + function ($scope, $rootScope, $timeout ,dataService, toastService, $mdSidenav, $mdDialog) { $rootScope['section_logo'] = 'src/app/vpp/assets/images/vpp.gif'; $scope.view_path = 'src/app/vpp/views/'; @@ -27,259 +27,312 @@ define(modules, function(vpp) { vpp.register.controller('InventoryTableController', ['$scope', '$rootScope','$filter', 'toastService', 'VppService', '$mdDialog', 'dataService', 'VppInterfaceService', function($scope, $rootScope, filter, toastService, VppService, $mdDialog, dataService, VppInterfaceService) { - - $scope.getInterfaces = function(index) { - VppInterfaceService.getInterfaceList( - $scope.vppList[index].name, - //success callback - function(data) { - var interfaces = data['interfaces-state'].interface; - var vpp = $scope.vppList[index]; - vpp.interfaces = []; - - interfaces.forEach(function(i){ - if (i.name != 'local0') { - vpp.interfaces.push(i); - } - }); - console.log($scope.vppList); - }, - //error callback - function(res) { - console.error(res); - } - ) - }; + $scope.initTable = - $scope.getVppList = function() { - $scope.initVppList(); - - VppService.getVppList( - // success callback - function(data) { - if(data.topology.length || data.topology[0].node.length) { - data.topology[0].node.forEach(function(n) { - if(n['node-id'] !== 'controller-config') { - var vppObj = VppService.createObj(n['node-id'], n['netconf-node-topology:host'], n['netconf-node-topology:port'], null, null, n['netconf-node-topology:connection-status']); - $scope.vppList.push(vppObj); - $scope.getInterfaces($scope.vppList.length - 1); //pass index. + $scope.getInterfaces = function(index) { + VppInterfaceService.getInterfaceList( + $scope.vppList[index].name, + //success callback + function(data) { + var interfaces = data['interfaces-state'].interface; + var vpp = $scope.vppList[index]; + vpp.interfaces = []; + interfaces.forEach(function(i){ + if (i.name != 'local0') { + vpp.interfaces.push(i); } }); + console.log($scope.vppList); + angular.copy($scope.vppList, dataService.vpps); + }, + //error callback + function(res) { + console.error(res); } - }, - // error callback - function(res) { - console.error(res); - } - ); - }; - - $scope.initVppList = function() { - $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'; + $scope.getVppList = function() { + $scope.initVppList(); + + VppService.getVppList( + // success callback + function(data) { + if(data.topology.length || data.topology[0].node.length) { + data.topology[0].node.forEach(function(n) { + if(n['node-id'] !== 'controller-config') { + var vppObj = VppService.createObj(n['node-id'], n['netconf-node-topology:host'], n['netconf-node-topology:port'], null, null, n['netconf-node-topology:connection-status']); + $scope.vppList.push(vppObj); + $scope.getInterfaces($scope.vppList.length - 1); //pass index. } - } - }, - linkConfig: { - label: 'model.label', - linkType: 'parallel', - color: function(link) { - if (link.getData().type === 'tunnel') { - return '#00FF00'; - } else { - return '#414040'; + }); + } + + $scope.$broadcast('RELOAD_VPP_TABLE'); + }, + // error callback + function(res) { + console.error(res); + } + ); + }; + + $scope.initVppList = function() { + $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'; + } } }, - width: function(link) { - if (link.getData().type === 'tunnel') { - return 5; + 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' } - }, - 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(); - }; + }); + $scope.app = new nx.ui.Application; - }, - 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 - }) - }; + vm.vpp = vpp; + vm.vpp.type = 'vpp'; + vm.vpp.label = vm.vpp.name; - $scope.addVppShowForm = function() { - $mdDialog.show({ - controller: function() { - var vm = this; - vm.vpp = {}; - //function called when the cancel button ( 'x' in the top right) is clicked - vm.close = function() { - $mdDialog.cancel(); - }; + var nodes = [].concat(vm.vpp); + var links = []; - vm.finished = function(successful) { - if (successful) { - vm.close(); - vm.waiting = false; - toastService.showToast('New VPP added!'); - $scope.getVppList(); - } else { - vm.waiting = false; - toastService.showToast('Error adding new VPP'); - } - }; + _.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}); + }); - //function called when the update button is clicked - vm.updateConfig = function() { - vm.waiting = true; - VppService.mountVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finished); - }; - }, - controllerAs: 'NewVppDialogCtrl', - templateUrl: $scope.view_path + 'new-vpp-dialog.html', - parent: angular.element(document.body), - clickOutsideToClose:true - }) - }; + console.log(vpp); + console.log(nodes); + console.log(links); + + $scope.topo.data({ + nodes: nodes, + links: links + }); - $scope.editVppShowForm = function(vppObject) { + 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 + }) + }; - $mdDialog.show({ - controller: function() { - var vm = this; + $scope.addVppShowForm = function() { + $mdDialog.show({ + controller: function() { + var vm = this; + vm.vpp = {}; + //function called when the cancel button ( 'x' in the top right) is clicked + vm.close = function() { + $mdDialog.cancel(); + }; + + vm.finished = function(successful) { + if (successful) { + vm.close(); + vm.waiting = false; + toastService.showToast('New VPP added!'); + $scope.getVppList(); + } else { + vm.waiting = false; + toastService.showToast('Error adding new VPP'); + } + }; + + //function called when the update button is clicked + vm.updateConfig = function() { + vm.waiting = true; + VppService.mountVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finished); + }; + }, + controllerAs: 'NewVppDialogCtrl', + templateUrl: $scope.view_path + 'new-vpp-dialog.html', + parent: angular.element(document.body), + clickOutsideToClose:true + }) + }; - vm.vpp = { - name: vppObject.name, - status: vppObject.status, - ip: vppObject.ipAddress, - port: vppObject.port - }; + $scope.editVppShowForm = function(vppObject) { + + $mdDialog.show({ + controller: function() { + var vm = this; + + vm.vpp = { + name: vppObject.name, + status: vppObject.status, + ip: vppObject.ipAddress, + port: vppObject.port + }; + + //function called when the cancel button ( 'x' in the top right) is clicked + vm.close = function() { + $mdDialog.cancel(); + }; + + vm.finishedUpdating = function(successful) { + if (successful) { + vm.close(); + vm.waiting = false; + toastService.showToast('VPP configuration updated!'); + $scope.getVppList(); + } else { + vm.waiting = false; + toastService.showToast('Error configuring VPP'); + } + }; + + vm.finishedDeleting = function(successful) { + if (successful) { + VppService.mountVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finishedUpdating); + $scope.getVppList(); + } else { + vm.waiting = false; + toastService.showToast('Error configuring VPP'); + } + }; + + //function called when the update button is clicked + vm.updateConfig = function() { + //VppService.editVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finishedUpdating); + VppService.deleteVpp(vm.vpp, vm.finishedDeleting); + }; + }, + controllerAs: 'ConfigVppDialogCtrl', + templateUrl: $scope.view_path + 'config-vpp-dialog.html', + parent: angular.element(document.body), + clickOutsideToClose:true + }); + }; - //function called when the cancel button ( 'x' in the top right) is clicked - vm.close = function() { - $mdDialog.cancel(); - }; + $scope.deleteVpp = function(vppObject) { - vm.finishedUpdating = function(successful) { - if (successful) { - vm.close(); - vm.waiting = false; - toastService.showToast('VPP configuration updated!'); - $scope.getVppList(); - } else { - vm.waiting = false; - toastService.showToast('Error configuring VPP'); - } - }; + var finished = function(successful) { + if (successful) { + toastService.showToast('Removed VPP!'); + $scope.getVppList(); + } else { + toastService.showToast('Error removing VPP'); + } + }; - vm.finishedDeleting = function(successful) { - if (successful) { - VppService.mountVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finishedUpdating); - $scope.getVppList(); - } else { - vm.waiting = false; - toastService.showToast('Error configuring VPP'); - } - }; + VppService.deleteVpp(vppObject, finished); + }; - //function called when the update button is clicked - vm.updateConfig = function() { - //VppService.editVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finishedUpdating); - VppService.deleteVpp(vm.vpp, vm.finishedDeleting); - }; - }, - controllerAs: 'ConfigVppDialogCtrl', - templateUrl: $scope.view_path + 'config-vpp-dialog.html', - parent: angular.element(document.body), - clickOutsideToClose:true - }); - }; + $scope.getVppList(); + }]); - $scope.deleteVpp = function(vppObject) { + vpp.register.controller('InventoryTableDefinitonController', ['$scope', function($scope) { - var finished = function(successful) { - if (successful) { - toastService.showToast('Removed VPP!'); - $scope.getVppList(); - } else { - toastService.showToast('Error removing VPP'); - } - }; + var actionCellTemplate = + '<md-button ng-click="grid.appScope.viewTopology(row.entity)"><span style="color:black !important;">View Topology</span></md-button>' + + '<md-button ng-click="grid.appScope.editVppShowForm(row.entity)" ng-hide="row.entity.status === \'connected\'"><span style="color:black !important;">Edit</span></md-button>' + + '<md-button ng-click="grid.appScope.deleteVpp(row.entity)"><span style="color:black !important;">Delete</span></md-button>'; + + $scope.gridOptions = { + + expandableRowTemplate: $scope.view_path + 'inventory-table-interfaces-subgrid.tpl.html', + expandableRowHeight: 150, + //subGridVariable will be available in subGrid scope + expandableRowScope: { + subGridVariable: 'subGridScopeVariable' + } + + } + + $scope.gridOptions.columnDefs = [ + { name: 'name' }, + { name: 'ipAddress'}, + { name: 'port'}, + { name: 'status'}, + { name:' ',cellTemplate: actionCellTemplate} + ]; + + + //$scope.gridOptions.data = $scope.vppList; - VppService.deleteVpp(vppObject, finished); + $scope.gridOptions.onRegisterApi = function(gridApi){ + $scope.gridApi = gridApi; }; - $scope.getVppList(); + $scope.$on('RELOAD_VPP_TABLE', function(event) { + $scope.gridOptions.data = $scope.vppList.map(function(item) { + item.subGridOptions = { + columnDefs: [ + { name:"Name", field:"name" }, + {name:"Mac Address", field: "phys-address"}, + {name:"Oper. Status", fiels: "oper-status"} + ], + data: item.interfaces + }; + + return item; + }); + }); + }]); - vpp.register.controller('TableController', ['$scope', '$rootScope','$filter', 'dataService', 'httpService', 'toastService', function ($scope, $rootScope, filter, dataService, httpService, toastService) { + 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); @@ -301,279 +354,95 @@ define(modules, function(vpp) { }; }]); - vpp.register.controller('InventoryController', function(dataService, $mdDialog, httpService, $location, toastService, $window) { + vpp.register.controller('BridgeDomainsController', function(dataService, $location, $mdDialog, toastService) { var vm = this; vm.dataService = dataService; - var nextApp = new nx.ui.Application; - - nextApp.container(document.getElementById('inventory-next-app')); - dataService.vppTopo.attach(nextApp); - dataService.vppTopo.tooltipManager().nodeTooltip().close(); - dataService.bridgeDomainsTopo.tooltipManager().nodeTooltip().close(); - - window.addEventListener('resize', function() { - if ($location.path() === '/inventory') { - dataService.vppTopo.adaptToContainer(); - } - }); + dataService.nextApp.container(document.getElementById('bridge-domains-next-app')); + dataService.bridgeDomainsTopo.attach(dataService.nextApp); - dataService.vppTopo.on("topologyGenerated", function() { //on topology generated... - dataService.vppTopo.stage().on('dblclick', function(sender, event) { - var target = event.target; - var nodesLayerDom = dataService.vppTopo.getLayer('nodes').dom().$dom; - var id; - - //db click node - if (nodesLayerDom.contains(target)) { - while (!target.classList.contains('node')) { - target = target.parentElement; - } - id = target.getAttribute('data-id'); - dataService.vppTopo.tooltipManager().nodeTooltip().close(); - - if(dataService.vppTopo.getNode(id).model().get().type ==='iana-if-type:ethernetCsmacd') { - vm.configInterface(dataService.vppTopo.getData().nodes[id]); - } else { - vm.configVpp(dataService.vppTopo.getNode(id)); - } - } - }); //Double click handler - - dataService.vppTopo.on('clickNode',function(topo, node){ - if(node.model().get().type!='iana-if-type:ethernetCsmacd') { - dataService.vppTopo.tooltipManager().nodeTooltip().close(); + window.addEventListener('resize', function () { + if ($location.path() === '/bridgedomains') { + dataService.topo.adaptToContainer(); } - console.log(node.model().get()); - }); }); - vm.configVpp = function(node) { - console.log(node.model().get()); - $mdDialog.show({ - controller: function() { - var vm = this; - var nodeModel = node.model().get(); - vm.vpp = { - name: nodeModel['node-id'], - status: nodeModel['netconf-node-topology:connection-status'], - ip: nodeModel['netconf-node-topology:host'], - port: nodeModel['netconf-node-topology:port'] - }; - - //function called when the cancel button ( 'x' in the top right) is clicked - vm.close = function() { - $mdDialog.cancel(); - }; - - vm.finishedUpdating = function(successful) { - if (successful) { - vm.close(); - vm.waiting = false; - toastService.showToast('VPP configuration updated!'); - $window.location.reload(true); - } else { - vm.waiting = false; - toastService.showToast('Error configuring VPP'); - } - }; - - vm.finishedDeleting = function(successful) { - if (successful) { - vm.close(); - vm.waiting = false; - toastService.showToast('VPP deleted!'); - $window.location.reload(true); - } else { - vm.waiting = false; - toastService.showToast('Error deleting VPP'); - } - }; + vm.bridgedomains = dataService.bridgedomains; + vm.selectedBd = dataService.selectedBd; - vm.deleteVpp = function() { - vm.waiting = true; - httpService.deleteVpp(vm.vpp.name, vm.finishedDeleting); - }; + dataService.bridgeDomainsTopo.on('clickNode',function(topo,node) { + console.log(node); + }); - //function called when the update button is clicked - vm.updateConfig = function() { - //TODO: Function to send a POST with the entered content in the form field - httpService.configVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finishedUpdating); - }; - }, - controllerAs: 'ConfigVppDialogCtrl', - templateUrl: 'templates/config-vpp-dialog.html', - parent: angular.element(document.body), - clickOutsideToClose:false - }) + vm.bdChanged = function() { + dataService.injectBridgeDomainsTopoElements(); + dataService.buildTableContent(); }; - vm.addVpp = function() { - //show dialog - $mdDialog.show({ - controller: function() { - var vm = this; - vm.vpp = {}; - //function called when the cancel button ( 'x' in the top right) is clicked - vm.close = function() { - $mdDialog.cancel(); - }; + vm.addBd = function() { + //show dialog + $mdDialog.show({ + controller: function() { + var vm = this; + vm.bd = {}; + vm.waiting = false; - vm.finished = function(successful) { - if (successful) { - vm.close(); - vm.waiting = false; - toastService.showToast('New VPP added!'); - $window.location.reload(true); - } else { - vm.waiting = false; - toastService.showToast('Error adding new VPP'); - } - }; + //function called when the cancel button ( 'x' in the top right) is clicked + vm.close = function() { + $mdDialog.cancel(); + }; - //function called when the update button is clicked - vm.updateConfig = function() { - vm.waiting = true; - //TODO: Function to send a POST with the entered content in the form field - httpService.mountVpp(vm.vpp.name, vm.vpp.ip, vm.vpp.port, vm.vpp.un, vm.vpp.pw, vm.finished); - }; - }, - controllerAs: 'NewVppDialogCtrl', - templateUrl: 'templates/new-vpp-dialog.html', - parent: angular.element(document.body), - clickOutsideToClose:false - }) + 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.configInterface = function(interf) { - //show dialog - $mdDialog.show({ - controller: function() { - var vm = this; - var oldDescription = interf.description; - var oldAdminStatus = interf['admin-status']; - vm.interf = interf; - //function called when the cancel button ( 'x' in the top right) is clicked - vm.cancel = function() { - $mdDialog.cancel(); - vm.revert(); - }; - vm.revert = function() { - interf['admin-status'] = oldAdminStatus; - interf.description = oldDescription - }; - vm.success = function() { - $mdDialog.cancel(); - }; - //function called when the update button is clicked - vm.updateConfig = function() { - vm.waiting = true; + vm.deploy = function() { - //send a POST with the entered content in the form field - httpService.updateInterface(vm.interf,vm.waiting,vm.cancel, vm.success); - }; - }, - controllerAs: 'ConfigInterfaceDialogCtrl', - templateUrl: 'templates/config-interface-dialog.html', - parent: angular.element(document.body), - clickOutsideToClose:false - }) }; - dataService.vppTopo.adaptToContainer(); - }); - vpp.register.controller('BridgeDomainsController', function(dataService, $location, $mdDialog, httpService, toastService) { - var vm = this; - vm.dataService = dataService; - var nextApp = new nx.ui.Application; - nextApp.container(document.getElementById('bridge-domains-next-app')); - dataService.bridgeDomainsTopo.attach(nextApp); + 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!'); - window.addEventListener('resize', function () { - if ($location.path() === '/bridgedomains') { - dataService.bridgeDomainsTopo.adaptToContainer(); } - }); - - dataService.vppTopo.tooltipManager().nodeTooltip().close(); - dataService.bridgeDomainsTopo.tooltipManager().nodeTooltip().close(); - - 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(httpService) { - 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 - httpService.addBdToODL(vm.bd.name, vm.isDone); - }; - }, - controllerAs: 'NewBdDialogCtrl', - templateUrl: 'templates/new-bd-dialog.html', - parent: angular.element(document.body), - clickOutsideToClose:false - }) - }; - - vm.deploy = function() { - httpService.deploy(); - }; - - 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!'); - - } - }; + }; - httpService.removeBdFromOdl(vm.selectedBd.name, successCallback); - } - }; + //... removeBdFromOdl(vm.selectedBd.name, successCallback); + } + }; }); }); diff --git a/vbd/gui/module/src/main/resources/vpp/vpp.css b/vbd/gui/module/src/main/resources/vpp/vpp.css deleted file mode 100644 index 32ed57831..000000000 --- a/vbd/gui/module/src/main/resources/vpp/vpp.css +++ /dev/null @@ -1,3 +0,0 @@ -.n-topology-nav { - display: none; -}
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/vpp.module.js b/vbd/gui/module/src/main/resources/vpp/vpp.module.js index 04367de45..7d6ed8568 100644 --- a/vbd/gui/module/src/main/resources/vpp/vpp.module.js +++ b/vbd/gui/module/src/main/resources/vpp/vpp.module.js @@ -5,9 +5,12 @@ * 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(['angularAMD', 'app/routingConfig', 'ui-bootstrap', 'Restangular', 'angular-animate', 'angular-aria', 'angular-material', 'angular-smart-table', 'angular-translate', 'angular-translate-loader-partial'], function() { +define(['angularAMD', 'app/routingConfig', 'ui-bootstrap', 'Restangular', 'angular-animate', 'angular-aria', + 'angular-material', 'angular-smart-table', 'angular-ui-grid', 'angular-translate', + 'angular-translate-loader-partial'], function() { - var vpp = angular.module('app.vpp', ['ui.router.state','app.core', 'ui.bootstrap', 'restangular', 'ngAnimate', 'ngAria', 'ngMaterial', 'smart-table', 'pascalprecht.translate']); + var vpp = angular.module('app.vpp', ['ui.router.state','app.core', 'ui.bootstrap', 'restangular', 'ngAnimate', + 'ngAria', 'ngMaterial', 'smart-table', 'ui.grid', 'ui.grid.expandable', 'pascalprecht.translate']); vpp.register = vpp; diff --git a/vbd/gui/module/src/main/resources/vpp/vpp.services.js b/vbd/gui/module/src/main/resources/vpp/vpp.services.js index 7f082ae1e..49337b109 100644 --- a/vbd/gui/module/src/main/resources/vpp/vpp.services.js +++ b/vbd/gui/module/src/main/resources/vpp/vpp.services.js @@ -30,344 +30,59 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { } }); - vpp.register.service('httpService', function($http, dataService, $log, toastService, $q) { - /* - this.requestVpps = function() { - $http.get(vppsUrl, { - headers: { - 'Content-Type': 'application/json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(response) { - dataService.vpps = processVpps(response.data); - var counter = 0; - angular.forEach(dataService.vpps, function(vpp) { - counter++; - var isFinalInterfaceRequest = counter === dataService.vpps.length; - requestInterfaces(vpp, isFinalInterfaceRequest); - }); - }, function errorCallback(response) { - toastService.showToast('Error retrieving VPPs'); - $log.error(response); - }); - }; - - var requestInterfaces = function(vpp, isFinalInterfaceRequest) { - $http.get(interfacesUrl+vpp['node-id']+interfacesUri, { - headers: { - 'Content-Type': 'application/json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(response) { - vpp.interfaces = response.data.interfaces.interface; - //------ - $http.get(operationalUrl+vpp['node-id']+operationalUri, { - headers: { - 'Content-Type': 'application/json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(response) { - vpp.operational = response.data; - var interfaceStates = vpp.operational['ietf-interfaces:interfaces-state'].interface; - _.forEach(interfaceStates, function(interf) { - var matchedInterface = _.find(vpp.interfaces,{name: interf.name}); - if (matchedInterface) { - matchedInterface['oper-status'] = interf['oper-status']; - matchedInterface['admin-status'] = interf['admin-status']; - } - }); - if (isFinalInterfaceRequest) { - dataService.updateInventoryTopology(); - } - }, function errorCallback() { - $log.error('Error receiving interface states for '+vpp['node-id']); - }); - //------- - }, function errorCallback() { - $log.error('Error receiving interfaces for '+vpp['node-id']); - }); - }; - - var requestBridgeDomains = function() { - $http.get(bridgedomainsUrl, { - headers: { - 'Content-Type': 'application/json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(response) { - dataService.setBridgeDomains(response.data["v3po:vpp-state"]); - // done loading... - dataService.requestsFinished(); - }, function errorCallback(response) { - toastService.showToast('Error retrieving Bridge Domains'); - $log.error(response); - }); - }; - - this.deploy = function() { - var errorOccurred = false; - - var success = function(succeeded, lastAssignment) { - if (!errorOccurred && !succeeded) { - toastService.showToast('Error deploying configuration!'); - errorOccurred = true; - } else if (!errorOccurred && succeeded && lastAssignment){ - toastService.showToast('Deployed! Bridge Domain Validated'); - } - }; - for (var x = 0; x < dataService.changedInterfaces.length; x++) { - this.updateAssignmentInODL(dataService.changedInterfaces[x], success, x === dataService.changedInterfaces.length - 1); - } - dataService.changedInterfaces.length = 0; - }; - - this.updateAssignmentInODL = function(interf, success, lastAssignment) { - var postData = { - "interface": [ - { - "name": interf.name, - "link-up-down-trap-enable": "disabled", - "v3po:ethernet": { - "mtu": interf['v3po:ethernet']['mtu'] - }, - "v3po:l2": { - "bridge-domain": interf['v3po:l2']['bridge-domain'], - "split-horizon-group": 0, - "bridged-virtual-interface": false - }, - "type": interf.type, - "description": "", - "enabled": true - } - ] - }; - $http.put(interfacesConfigUrl + encodeURIComponent(interf.name), postData, { - headers: { - 'Content-Type': 'application/yang.data+json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(response) { - //... - success(true, lastAssignment); - }, function errorCallback(response) { - success(false, lastAssignment); - $log.error(response); - }); - }; - - - this.addBdToODL = function(bdName, isDone) { - var putData = { - "bridge-domain": [ - { - "name": bdName, - "flood": "true", - "forward": "true", - "learn": "true", - "unknown-unicast-flood": "true", - "arp-termination": "false" - } - ] - }; - $http.put(newBridgeDomainUrl+bdName, putData, - { - headers: { - 'Content-Type': 'application/yang.data+json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback() { - toastService.showToast('Bridge Domain Added!'); - isDone('success'); - }, function errorCallback(response) { - $log.error(response); - toastService.showToast('Error adding Bridge Domain.'); - isDone('failure'); - }); - }; - - this.updateInterface = function(interf, isWaiting, cancel, success) { - $http.get(interfacesOperUrl + encodeURIComponent(interf.name), { - headers: { - 'Content-Type': 'application/json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(r) { - var receivedData = r.data.interface[0]; - var postData = { - "interface": [ - { - "name": receivedData.name, - "link-up-down-trap-enable": "disabled", - "v3po:ethernet": { - "mtu": receivedData['v3po:ethernet']['mtu'] - }, - "v3po:l2": { - "bridge-domain": receivedData['v3po:l2']['bridge-domain'], - "split-horizon-group": 0, - "bridged-virtual-interface": false - }, - "type": receivedData.type, - "description": interf.description, - "enabled": interf['admin-status'] === 'up' ? true : false - } - ] - }; - $http.put(interfacesConfigUrl + encodeURIComponent(interf.name), postData, - { - headers: { - 'Content-Type': 'application/yang.data+json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback() { - toastService.showToast('Updated!'); - isWaiting = false; - success(); - }, function errorCallback(response) { - $log.error(response); - toastService.showToast('Error updating'); - isWaiting = false; - cancel(); - }); - }, function errorCallback(response) { - $log.error(response); - toastService.showToast('Error updating'); - isWaiting = false; - cancel(); - }); - }; - - this.removeBdFromOdl = function(name,success) { - $http.delete(newBridgeDomainUrl+name, { - headers: { - 'Content-Type': 'application/json', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }) - .then(function successCallback() { - success(true); - }, function errorCallback() { - success(false); - }); - }; - - this.configVpp = function(name,ip,port,un,pw,finishedSuccessfullyCallback) { - - var putData = '\ - <module xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">\ - <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>\ - <name>'+name+'</name>\ - <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">'+ip+'</address>\ - <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">'+port+'</port>\ - <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">'+un+'</username>\ - <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">'+pw+'</password>\ - <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>\ - <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">\ - <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>\ - <name>global-event-executor</name>\ - </event-executor>\ - <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">\ - <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>\ - <name>binding-osgi-broker</name>\ - </binding-registry>\ - <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">\ - <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>\ - <name>dom-broker</name>\ - </dom-registry>\ - <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">\ - <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>\ - <name>global-netconf-dispatcher</name>\ - </client-dispatcher>\ - <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">\ - <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>\ - <name>global-netconf-processing-executor</name>\ - </processing-executor>\ - </module>'; - - $http.put(configVpp+name, putData, { - headers: { - "Accept": 'application/xml', - "Content-Type": 'application/xml', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(response) { - //... - finishedSuccessfullyCallback(true); - }, function errorCallback(response) { - finishedSuccessfullyCallback(false); - $log.error(response); - }); - }; - - this.deleteVpp = function(name, finishedSuccessfullyCallback) { - $http.delete(configVpp+name, { - headers: { - "Accept": 'application/xml', - "Content-Type": 'application/xml', - "Authorization": "Basic " + btoa(username + ":" + password) - } - }).then(function successCallback(response) { - //... - finishedSuccessfullyCallback(true); - }, function errorCallback(response) { - finishedSuccessfullyCallback(false); - $log.error(response); - }); */ - }); - vpp.register.service('dataService', function() { 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); -/* - var Topo = function() { - return new nx.graphic.Topology({ - adaptive:true, - 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'; - } + + this.bridgeDomainsTopo = 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; - } + } + }, + linkConfig: { + label: 'model.label', + linkType: 'parallel', + color: function(link) { + if (link.getData().type === 'tunnel') { + return '#00FF00'; + } else { + return '#414040'; } }, - showIcon: true, - dataProcessor: 'force', - autoLayout: true, - enableSmartNode: false, - tooltipManagerConfig: { - nodeTooltipContentClass: 'TooltipNode', - linkTooltipContentClass: 'TooltipLink' + width: function(link) { + if (link.getData().type === 'tunnel') { + return 5; + } } - }); - }; + }, + showIcon: true, + dataProcessor: 'force', + autoLayout: true, + enableSmartNode: false, + tooltipManagerConfig: { + nodeTooltipContentClass: 'TooltipNode', + linkTooltipContentClass: 'TooltipLink' + } + }); + this.nextApp = new nx.ui.Application; - this.bridgeDomainsTopo = Topo(); this.vpps = []; this.tableContent = []; @@ -440,7 +155,7 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { this.interfaces[x].assigned = true; } } - }; */ + }; }); |