Initial commit of vBd Manager functions. 41/241/7
authorDaniel Malachovsky <daniel.malachovsky@pantheon.sk>
Mon, 8 Feb 2016 18:05:54 +0000 (19:05 +0100)
committerGerrit Code Review <gerrit@fd.io>
Mon, 8 Feb 2016 21:55:02 +0000 (21:55 +0000)
- 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>
vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css
vbd/gui/module/src/main/resources/vpp/controllers/bdm.controller.js
vbd/gui/module/src/main/resources/vpp/controllers/bdm.vpp.controller.js
vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js
vbd/gui/module/src/main/resources/vpp/services/bdm.bridgedomain.service.js
vbd/gui/module/src/main/resources/vpp/services/bdm.interface.service.js
vbd/gui/module/src/main/resources/vpp/services/bdm.vpp.service.js
vbd/gui/module/src/main/resources/vpp/services/vpp.services.js
vbd/gui/module/src/main/resources/vpp/views/bridge-domains.tpl.html
vbd/gui/module/src/main/resources/vpp/views/new-bd-dialog.html

index cd5b73d..2566d90 100644 (file)
@@ -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
index d8fe8ea..e5ad012 100644 (file)
@@ -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
index 69dfd2f..44a4b0c 100644 (file)
@@ -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
index c8ca1e5..7f2a4ec 100644 (file)
@@ -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
index 5d3b696..1438208 100644 (file)
@@ -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;
     });
index 341fb5d..d2abc77 100644 (file)
@@ -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
index b817a75..0a24c23 100644 (file)
@@ -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
index 70b1631..4c20f84 100644 (file)
@@ -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();
+        };
+    }]);
 
 
 
index 263fc09..8060973 100644 (file)
@@ -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>
index fd04f8e..41e6ad8 100644 (file)
@@ -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>