Merge "Fixed announcing of endpoint location by vpp-renderer"
authorKeith Burns <alagalah@gmail.com>
Tue, 21 Jun 2016 23:27:13 +0000 (23:27 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 21 Jun 2016 23:27:13 +0000 (23:27 +0000)
16 files changed:
groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.css
groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.css.orig [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/common/topology/next_topology.directive.js
groupbasedpolicy-ui/module/src/main/resources/gbp/common/views/index.tpl.html
groupbasedpolicy-ui/module/src/main/resources/gbp/endpoints/add-endpoint.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/endpoints/dialog-add-endpoint.tpl.html
groupbasedpolicy-ui/module/src/main/resources/gbp/endpoints/endpoint.service.js
groupbasedpolicy-ui/module/src/main/resources/gbp/endpoints/endpoints-list.service.js
groupbasedpolicy-ui/module/src/main/resources/gbp/endpoints/endpoints.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/endpoints/endpoints.tpl.html
groupbasedpolicy-ui/module/src/main/resources/gbp/endpoints/side_panel_endpoints_detail.tpl.html
groupbasedpolicy-ui/module/src/main/resources/gbp/forwarding/forwarding.service.js [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/resolved-policy/resolved-policy.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/resolved-policy/resolved-policy.tpl.html
groupbasedpolicy-ui/module/src/main/resources/gbp/resolved-policy/rule-sidepanel.tpl.html

index f1295b11cd5b69057be731abffd115690f2a45c1..fd8473e2d1225053dc404187233f0b8590e4afc7 100644 (file)
@@ -7,21 +7,25 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
 
     function RootGbpCtrl($state, $rootScope, $scope, $filter, RootGbpService, TenantListService, TenantService, EpgListService, ResolvedPolicyService, NextTopologyService, EndpointsListService) {
         /* properties */
-        $scope.stateUrl = null;
+        $scope.apiType = 'operational';
+        $scope.endpoints = EndpointsListService.createList();
+        $scope.policyDisabled = true;
+        $scope.rootTenant = null;
+        $scope.rootTenants = TenantListService.createList();
+        $scope.resolvedPolicy = {};
+        $scope.selectedNode = {};
+        $scope.sidePanelObject = {};
         $scope.sidePanelPage = false;
         $scope.sidePanelPageEndpoint = false;
-        $scope.sidePanelObject = {};
-        $scope.rootTenant = TenantService.createObject();
-        $scope.rootTenants = TenantListService.createList();
-        $scope.policyDisabled = true;
+        $scope.stateUrl = null;
+        $scope.topologyData = {nodes: [], links: []};
         $scope.viewPath = 'src/app/gbp/';
-        $scope.selectedNode = {};
-        $scope.apiType = 'operational';
-        $scope.parentTenant = 'tenant-red';
-        $scope.resolvedPolicy = {};
-        $scope.endpoints = EndpointsListService.createList();
+
+        var resolvedPolicies = ResolvedPolicyService.createObject();
+        resolvedPolicies.get(fillTopologyData);
 
         /* methods */
+        $scope.fillTopologyData = fillTopologyData;
         $scope.broadcastFromRoot = broadcastFromRoot;
         $scope.closeSidePanel = closeSidePanel;
         $scope.openSidePanel = openSidePanel;
@@ -40,145 +44,202 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
         $scope.fadeAll = fadeAll;
 
         RootGbpService.setMainClass();
-        console.log('RootGbpCtrl initialized');
-
         init();
 
-
-        $scope.topologyData = {
-            nodes: [],
-            links: [],
-        };
-
         /* implementations */
+
         /**
-         * Sets '$scope.sidePanelPage' to false. This variable is watched in index.tpl.html template
-         * and opens/closes side panel
+         *
+         * @param eventName
+         * @param val
          */
-        function init() {
-            $scope.rootTenants.clearData();
-            $scope.rootTenants.get('config');
-        }
-
         function broadcastFromRoot(eventName, val) {
             $scope.$broadcast(eventName, val);
         }
 
-        function setRootTenant() {
-            $scope.broadcastFromRoot('ROOT_TENANT_CHANGED');
-            enableButtons();
-        }
-
+        /**
+         *
+         */
         function closeSidePanel() {
             $scope.sidePanelPage = false;
             NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
         }
 
         /**
-         * fills $scope.stateUrl with loaded url
-         * It's called on $viewContentLoaded event
+         *
+         * @param arr
          */
-        function setStateUrl() {
-            $scope.stateUrl = $state.current.url;
+        function collapseAll(arr) {
+            arr.forEach(function(element) {
+                element.expanded = false;
+            });
         }
 
         /**
-         * Sets '$scope.sidePanelPage' to true. This variable is watched in index.tpl.html template
-         * and opens/closes side panel
+         *
+         * @param source
+         * @param target
+         * @param contract
+         * @param tenant
+         * @returns {{id: string, source: *, target: *, tenant: *}}
          */
-        function openSidePanel(page, object, cbk) {
-            if(object.constructor.name == 'Epg') {
-                $scope.endpoints.clearData();
-                $scope.endpoints.getByEpg(object.data.id);
-            }
-            var samePage = page === $scope.sidePanelPage;
+        function createLink( source, target, contract, tenant) {
+            return {
+                'id': generateLinkId(contract, source, target),
+                'source': source,
+                'target': target,
+                'tenant': tenant,
+            };
+        }
 
-            $scope.selectedNode = object;
+        /**
+         *
+         * @param nodeName
+         * @param tenantId
+         * @returns {{id: *, tenantId: *, node-id: *, label: *}}
+         */
+        function createNode(nodeName, tenantId) {
+            return {
+                'id': nodeName,
+                'tenantId' : tenantId,
+                'node-id': nodeName,
+                'label': nodeName,
+            };
+        }
 
-            $scope.sidePanelCbk = cbk;
-            $scope.sidePanelPage = page;
-            $scope.sidePanelObject = object;
+        /**
+         *
+         */
+        function deselectContract() {
+            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
+            $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
 
-            if ( samePage &&  $scope.sidePanelCbk) {
-                $scope.sidePanelCbk();
-            }
+            var obj = Object.keys($scope.resolvedPolicy).map(function(k) {
+                var obj = $scope.resolvedPolicy[k];
+                obj.linkId = k;
+
+                return obj;
+            });
+
+            $scope.sidePanelObject = obj;
+            $scope.selectedNode = null;
         }
 
+        /**
+         *
+         */
         function deselectEpg() {
             NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
             var elements;
 
             $scope.sidePanelPage = 'resolved-policy/epg-sidepanel';
             elements = EpgListService.createList();
-            elements.get($scope.apiType, $scope.parentTenant);
+            elements.get($scope.apiType, $scope.rootTenant);
             $scope.sidePanelObject = elements;
             $scope.selectedNode = null;
         }
 
-        function deselectContract() {
-            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
-            $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
-
-            var obj = Object.keys($scope.resolvedPolicy).map(function(k) {
-                var obj = $scope.resolvedPolicy[k];
-                obj.linkId = k;
+        /**
+         *
+         */
+        function enableButtons() {
+            $scope.policyDisabled = false;
+        }
 
-                return obj;
+        /**
+         *
+         * @param arr
+         */
+        function expandAll(arr) {
+            arr.forEach(function(element) {
+                element.expanded = true;
             });
+        }
 
-            $scope.sidePanelObject = obj;
-            $scope.selectedNode = null;
+        /**
+         *
+         */
+        function fadeAll() {
+            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
         }
 
-        function openSidePanelTpl(tpl) {
-            switch(tpl) {
-            case 'contract':
-                $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
-                break;
-            case 'subject':
-                $scope.sidePanelPage = 'resolved-policy/subject-sidepanel';
-                break;
-            case 'clause':
-                $scope.sidePanelPage = 'resolved-policy/clause-sidepanel';
-                break;
-            case 'rule':
-                $scope.sidePanelPage = 'resolved-policy/rule-sidepanel';
-                break;
+        /**
+         *
+         * @param data
+         */
+        function fillResolvedPolicy(data) {
+            if(data['policy-rule-group-with-endpoint-constraints']) {
+                processPolicyRuleGroupWithEpConstraints(
+                    data['policy-rule-group-with-endpoint-constraints'],
+                    data['provider-epg-id'],
+                    data['consumer-epg-id']);
             }
+
         }
 
-        function openSidePanelContract(idElement) {
-            var obj = $filter('filter')(Object.keys($scope.resolvedPolicy).map(function(k) {
-                var obj = $scope.resolvedPolicy[k];
-                obj.linkId = k;
+        /**
+         *
+         */
+        function fillTopologyData() {
+            var topoData = {nodes: [], links: [],},
+                filteredResolvedPolicies = $filter('filter')(resolvedPolicies.data, {'consumer-tenant-id': $scope.rootTenant, 'provider-tenant-id': $scope.rootTenant});
 
-                return obj;
-            }), {'contract-id': idElement});
 
-            $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
-            $scope.sidePanelObject = obj[0];
-            $scope.selectedNode = obj[0];
+            filteredResolvedPolicies && filteredResolvedPolicies.forEach(function(rp) {
+                if(rp['consumer-tenant-id'] === $scope.rootTenant) {
+                    topoData.nodes.push(createNode(rp['consumer-epg-id'], rp['consumer-tenant-id']));
+                }
+                topoData.nodes.push(createNode(rp['provider-epg-id'], rp['provider-tenant-id']));
 
-            NextTopologyService.highlightLink($rootScope.nxTopology, obj[0].linkId);
+                fillResolvedPolicy(rp);
+                topoData.links = getContracts(rp);
+            });
+
+            $scope.topologyData = topoData;
+            $scope.topologyLoaded = true;
         }
 
-        function openSidePanelChild(index, type) {
-            switch(type) {
-            case 'subject':
-                $scope.sidePanelPage = 'resolved-policy/subject-sidepanel';
-                $scope.subjectIndex = index;
-                break;
-            case 'clause':
-                $scope.sidePanelPage = 'resolved-policy/clause-sidepanel';
-                $scope.clauseIndex = index;
-                break;
-            case 'rule':
-                $scope.sidePanelPage = 'resolved-policy/rule-sidepanel';
-                $scope.ruleIndex = index;
-                break;
+        /**
+         *
+         * @param contractId
+         * @param providerEpgId
+         * @param consumerEpgId
+         * @returns {string}
+         */
+        function generateLinkId(contractId, providerEpgId, consumerEpgId) {
+            return contractId + '_' + providerEpgId + '_' + consumerEpgId;
+        }
+
+        /**
+         *
+         * @param data
+         * @returns {Array}
+         */
+        function getContracts(data) {
+            var retVal = [];
+
+            if( data['policy-rule-group-with-endpoint-constraints'] &&
+                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group']) {
+                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group'].forEach(function(prg) {
+                    retVal.push(
+                        createLink(
+                            data['provider-epg-id'],
+                            data['consumer-epg-id'],
+                            prg['contract-id'],
+                            prg['tenant-id']
+                        )
+                    )
+                });
             }
+
+            return retVal;
         }
 
+        /**
+         *
+         * @param obj
+         * @returns {*}
+         */
         function getObjectsCount(obj) {
             if(obj)
                 return Object.keys(obj).length;
@@ -186,61 +247,120 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
                 return 0;
         }
 
-        function enableButtons() {
-            $scope.policyDisabled = false;
+        /**
+         *
+         * @param node
+         */
+        function highlightNode(node) {
+            NextTopologyService.highlightNode($rootScope.nxTopology, node);
         }
 
-        function toggleExpanded(element) {
-            if(typeof element !== 'string') {
-                if(element.expanded)
-                    element.expanded = false;
-                else
-                    element.expanded = true;
-            }
+        /**
+         *
+         * @param link
+         */
+        function highlightLink(link) {
+            NextTopologyService.highlightLink($rootScope.nxTopology, link);
         }
 
-        function expandAll(arr) {
-            arr.forEach(function(element) {
-                element.expanded = true;
-            });
+        /**
+         *
+         */
+        function init() {
+            $scope.rootTenants.clearData();
+            $scope.rootTenants.get('config');
         }
 
-        function collapseAll(arr) {
-            arr.forEach(function(element) {
-                element.expanded = false;
-            });
-        }
+        /**
+         * Sets '$scope.sidePanelPage' to true. This variable is watched in index.tpl.html template
+         * and opens/closes side panel
+         */
+        function openSidePanel(page, object, cbk) {
+            if(object.constructor.name == 'Epg') {
+                $scope.endpoints.clearData();
+                $scope.endpoints.getByEpg(object.data.id);
+            }
+            var samePage = page === $scope.sidePanelPage;
 
-        var resolvedPolicies = ResolvedPolicyService.createObject();
-        resolvedPolicies.get(function () {
-            fillTopologyData();
-        });
+            $scope.selectedNode = object;
 
-        function fillTopologyData() {
-            var topoData = {nodes: [], links: [],};
+            $scope.sidePanelCbk = cbk;
+            $scope.sidePanelPage = page;
+            $scope.sidePanelObject = object;
 
-            resolvedPolicies.data.forEach(function(rp) {
-                topoData.nodes.push(createNode(rp['consumer-epg-id'], rp['consumer-tenant-id']));
-                topoData.nodes.push(createNode(rp['provider-epg-id'], rp['provider-tenant-id']));
+            if ( samePage &&  $scope.sidePanelCbk) {
+                $scope.sidePanelCbk();
+            }
+        }
 
-                fillResolvedPolicy(rp);
-                topoData.links = getContracts(rp);
-            });
+        /**
+         *
+         * @param idElement
+         */
+        function openSidePanelContract(idElement) {
+            var obj = $filter('filter')(Object.keys($scope.resolvedPolicy).map(function(k) {
+                var obj = $scope.resolvedPolicy[k];
+                obj.linkId = k;
 
-            $scope.topologyData = topoData;
-            $scope.topologyLoaded = true;
+                return obj;
+            }), {'contract-id': idElement});
+
+            $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
+            $scope.sidePanelObject = obj[0];
+            $scope.selectedNode = obj[0];
+
+            NextTopologyService.highlightLink($rootScope.nxTopology, obj[0].linkId);
         }
 
-        function fillResolvedPolicy(data) {
-            if(data['policy-rule-group-with-endpoint-constraints']) {
-                processPolicyRuleGroupWithEpConstraints(
-                    data['policy-rule-group-with-endpoint-constraints'],
-                    data['provider-epg-id'],
-                    data['consumer-epg-id']);
+        /**
+         * .
+         * @param index
+         * @param type
+         */
+        function openSidePanelChild(index, type) {
+            switch(type) {
+                case 'subject':
+                    $scope.sidePanelPage = 'resolved-policy/subject-sidepanel';
+                    $scope.subjectIndex = index;
+                    break;
+                case 'clause':
+                    $scope.sidePanelPage = 'resolved-policy/clause-sidepanel';
+                    $scope.clauseIndex = index;
+                    break;
+                case 'rule':
+                    $scope.sidePanelPage = 'resolved-policy/rule-sidepanel';
+                    $scope.ruleIndex = index;
+                    break;
             }
+        }
 
+        /**
+         *
+         * @param tpl
+         */
+        function openSidePanelTpl(tpl) {
+            switch(tpl) {
+                case 'contract':
+                    $scope.sidePanelPage = 'resolved-policy/contract-sidepanel';
+                    break;
+                case 'subject':
+                    $scope.sidePanelPage = 'resolved-policy/subject-sidepanel';
+                    break;
+                case 'clause':
+                    $scope.sidePanelPage = 'resolved-policy/clause-sidepanel';
+                    break;
+                case 'rule':
+                    $scope.sidePanelPage = 'resolved-policy/rule-sidepanel';
+                    break;
+            }
         }
 
+        /**
+         *
+         * @param data
+         * @param providerEpgId
+         * @param consumerEpgId
+         */
         function processPolicyRuleGroupWithEpConstraints(data, providerEpgId, consumerEpgId) {
             data.forEach(function(element) {
                 element['policy-rule-group'].forEach(function(el) {
@@ -262,58 +382,41 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
             })
         }
 
-        function generateLinkId(contractId, providerEpgId, consumerEpgId) {
-            return contractId + '_' + providerEpgId + '_' + consumerEpgId;
-        }
-
-        function createNode(nodeName, tenantId) {
-            return {
-                'id': nodeName,
-                'tenantId' : tenantId,
-                'node-id': nodeName,
-                'label': nodeName,
-            };
-        }
-
-        function createLink( source, target, contract, tenant) {
-            return {
-                'id': generateLinkId(contract, source, target),
-                'source': source,
-                'target': target,
-                'tenant': tenant,
-            };
-        }
-
-        function getContracts(data) {
-            var retVal = [];
+        /**
+         *
+         */
+        function setRootTenant() {
+            $scope.broadcastFromRoot('ROOT_TENANT_CHANGED');
 
-            if( data['policy-rule-group-with-endpoint-constraints'] &&
-                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group']) {
-                data['policy-rule-group-with-endpoint-constraints'][0]['policy-rule-group'].forEach(function(prg) {
-                        retVal.push(
-                            createLink(
-                                data['provider-epg-id'],
-                                data['consumer-epg-id'],
-                                prg['contract-id'],
-                                prg['tenant-id']
-                            )
-                        )
-                    });
+            if($scope.stateUrl.startsWith('/resolved-policy')) {
+                fillTopologyData();
             }
-
-            return retVal;
         }
 
-        function highlightNode(node) {
-            NextTopologyService.highlightNode($rootScope.nxTopology, node);
-        }
+        /**
+         * fills $scope.stateUrl with loaded url
+         * It's called on $viewContentLoaded event
+         */
+        function setStateUrl() {
+            $scope.stateUrl = $state.current.url;
+            closeSidePanel();
 
-        function highlightLink(link) {
-            NextTopologyService.highlightLink($rootScope.nxTopology, link);
+            if($scope.stateUrl.startsWith('/resolved-policy')) {
+                fillTopologyData();
+            }
         }
 
-        function fadeAll() {
-            NextTopologyService.fadeInAllLayers($rootScope.nxTopology);
+        /**
+         *
+         * @param element
+         */
+        function toggleExpanded(element) {
+            if(typeof element !== 'string') {
+                if(element.expanded)
+                    element.expanded = false;
+                else
+                    element.expanded = true;
+            }
         }
 
         /* event listeners */
@@ -321,9 +424,5 @@ define(['app/gbp/common/gbp.service', 'app/gbp/resolved-policy/resolved-policy.s
          * Event fired after content loaded, setStateUrl function is called to fill stateUrl method
          */
         $scope.$on('$viewContentLoaded', setStateUrl);
-
-        // $scope.$watch('nxTopology', function() {
-        //     $rootScope.nxTopology = $scope.nxTopology;
-        // });
     }
 });
index be7a35987fe4aebf4c744892740d2905fce53eb9..e7dbd567e465c275619a553858bafea0599d84dd 100644 (file)
@@ -101,12 +101,12 @@ md-dialog button span {
     color: #000;
 }
 
-md-sidenav span {
-    color: inherit !important;
+div.layout-padding h3 {
+    color: black;
 }
 
-span.md-subheader {
-    color: red;
+md-sidenav span {
+    color: inherit !important;
 }
 
 div.md-primary.md-subheader.ng-scope > div > span > span {
@@ -130,6 +130,34 @@ span.ng-binding.flex {
     color: rgba(0,0,0,0.87);
 }
 
+md-select:not([disabled]) .md-select-value .md-text {
+       color: black;
+}
+
+.md-input-has-value label {
+    color: rgba(0,0,0,0.54);
+}
+
+md-select-value span {
+       color: rgba(0,0,0,0.26);
+    font-weight: bold;
+    margin-bottom: 5px;
+    line-height: 1.428571429;
+}
+
+md-select-value span div {
+    font-weight: normal;
+}
+
+.md-chips {
+        padding: 0 0 0 0 !important;
+}
+
+md-dialog-content > div:first-child {
+    padding-top: 20px;
+    padding-bottom: 20px;
+}
+
 .gbpUiGlobalWrapper .md-locked-open {
     width: 500px;
     min-width: 500px;
@@ -177,4 +205,37 @@ span.ng-binding.flex {
 
 .status-circle.require-contract {
     color: orange;
-}
\ No newline at end of file
+}
+
+md-ink-bar {
+    background: red !important;
+}
+
+md-tab-item > span {
+    color: rgba(0,0,0,0.54);
+}
+
+md-tab-item.md-tab.ng-scope.ng-isolate-scope.md-ink-ripple.md-active > span {
+    color: rgb(16,108,200);
+}
+
+.layout-padding-lr15.ng-scope.layout-column > div {
+    padding-top: 15px;
+}
+
+div.md-primary.md-subheader > div > span > span {
+    color: rgb(33,150,243);
+}
+
+div.md-secondary.md-subheader.ng-scope > div > span > span {
+    color: rgb(33,150,243) !important;
+}
+
+li > md-autocomplete-parent-scope > span {
+    color: rgba(0,0,0,.54);
+}
+
+#tenantSelector div, #tenantSelector .md-select-placeholder span {
+    color: white;
+    font-weight: normal;
+}
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.css.orig b/groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.css.orig
new file mode 100644 (file)
index 0000000..af3d301
--- /dev/null
@@ -0,0 +1,226 @@
+.gbpUiGlobalWrapper {
+    background: #ffffff;
+    margin-bottom: 0!important;
+    min-height: 100%;
+    padding: 0px;
+}
+
+.gbpUiGlobalWrapper .main {
+    top: 0px;
+}
+
+.gbpUiWrapper {
+    background-color: #414042;
+}
+
+.gbpUiWrapper .pageContent {
+    margin: 0px;
+    padding: 0px;
+    width: 100%;
+    height: 100%;
+}
+
+.gbpUiWrapper .side-panel {
+    width: 400px;
+    color: #000 ! important;
+    border: 1px solid #000;
+}
+
+.gbpUiWrapper .h100 {
+    height: 100%;
+}
+
+.gbpUiWrapper.w100 {
+    width: 100%;
+}
+
+.gbpUiWrapper.flt-r {
+    float: right;
+}
+
+/* LAYOUT */
+.layout-padding-lr15 {
+    padding: 0 15px;
+}
+
+/* TABLES */
+.gbpUiWrapper .md-table span {
+    color: rgba(0,0,0,.87);
+}
+.gbpUiWrapper .md-table-pagination span {
+    color: rgba(0,0,0,.87);
+    font-weight: normal;
+}
+.gbpUiWrapper button.md-button.md-icon-button.w85 {
+    width: 85px;
+}
+
+/* BUTTONS */
+.gbpUiWrapper button.md-primary span {
+    color: rgb(33,150,243);
+}
+.gbpUiWrapper button .md-icon {
+    width: 30px;
+}
+
+/* DIALOG */
+.gbpDialogWrapper button.md-primary span {
+    color: rgba(0,0,0,0.87);
+}
+.gbpDialogWrapper button.md-primary[disabled] span {
+    color: rgba(0,0,0,0.26);
+}
+
+svg g.node text {
+    pointer-events: auto !important;
+}
+
+.expander md-content {
+    line-height: 15px;
+    width: 100%;
+}
+
+.expander .md-list-item-inner {
+    flex-flow: row wrap;
+}
+
+.expand-button {
+    min-width: 0px !important;
+    min-height: 0px !important;
+    margin-top: 0 !important;
+    margin-bottom: 0 !important;
+    line-height: normal !important;
+}
+
+#graph-container {
+    padding-left: 0;
+}
+
+/* $mdDialog.confirm */
+md-dialog button span {
+    color: #000;
+}
+
+md-sidenav span {
+    color: inherit !important;
+}
+
+div.md-primary.md-subheader.ng-scope > div > span > span {
+  color: rgb(33,150,243);
+}
+
+.md-subheader {
+    font-weight: bold !important;
+}
+
+md-sidenav > md-toolbar > div > h2 > span {
+    margin: 20px 0;
+    color: #666;
+}
+
+span.flex-35 > strong {
+    color: rgba(0,0,0,0.87);
+}
+
+span.ng-binding.flex {
+    color: rgba(0,0,0,0.87);
+}
+
+md-select:not([disabled]) .md-select-value .md-text {
+       color: black;
+}
+
+.md-input-has-value label {
+    color: rgba(0,0,0,0.54);
+}
+
+md-select-value span {
+       color: rgba(0,0,0,0.26);
+    font-weight: bold;
+    margin-bottom: 5px;
+    line-height: 1.428571429;
+}
+
+md-select-value span div {
+    font-weight: normal;
+}
+
+.md-chips {
+        padding: 0 0 0 0 !important;
+}
+
+md-dialog-content > div:first-child {
+    padding-top: 20px;
+    padding-bottom: 20px;
+}
+
+.gbpUiGlobalWrapper .md-locked-open {
+    width: 500px;
+    min-width: 500px;
+}
+
+.breadcrumbs {
+    display: inline-block;
+    font-size: 16px;
+    font-weight: 500;
+    line-height: 1em;
+    padding-left: 0;
+    margin: 10px 0;
+}
+
+.breadcrumbs .breadcrumb {
+    display: inline-block;
+    color: rgba(0,0,0,.54);
+    background-color: transparent;
+    padding: 0;
+    font-size: 13px;
+    margin-bottom: 0 !important;
+    vertical-align: middle;
+}
+
+.breadcrumbs .breadcrumb[role="button"] {
+    color: rgb(33, 150, 243);
+}
+
+<<<<<<< HEAD
+.layout-padding-r10 {
+    padding-right: 10px;
+}
+
+.layout-padding-b15 {
+    padding-bottom: 15px;
+}
+
+.order {
+    color: #000 !important;
+    margin: 0;
+}
+
+.status-circle.allow {
+    color: green;
+}
+
+.status-circle.require-contract {
+    color: orange;
+}
+=======
+md-ink-bar {
+    background: red !important;
+}
+
+md-tab-item > span {
+    color: rgba(0,0,0,0.54);
+}
+
+md-tab-item.md-tab.ng-scope.ng-isolate-scope.md-ink-ripple.md-active > span {
+    color: rgb(16,108,200);
+}
+
+.layout-padding-lr15.ng-scope.layout-column > div {
+    padding-top: 15px;
+}
+
+div.md-primary.md-subheader > div > span > span {
+    color: rgb(33,150,243);
+}
+>>>>>>> c391bea... Endpoints
index d758ebf19b7b1983eac48a5809249c24e7139c18..a3feac5f9d7647a4da20c8fa870ee6f4e4f494d3 100644 (file)
@@ -111,9 +111,9 @@ define(['next-ui'], function() {
                                scope.$watch('topologyData', function(){
                                        //console.log('scope.topologyData', scope.topologyData);
 
-                                       if( scope.topologyData.nodes.length ) { //&& initialized === false
+                                       //if( scope.topologyData.nodes.length ) { //&& initialized === false
                                                scope.init(scope.cbkFunctions.topologyGenerated);
-                                       }
+                                       //}
                                });
 
                                /**
index 5fe2381dc378d98167e48dd583dfad401e771271..487594b3584f6f6bc4c40d9332f28e8747fe6d0a 100644 (file)
                 <span flex></span>
                 <md-button ng-if="'main.gbp.index.resolvedPolicy' | isState" ng-click="deselectEpg()" ng-href="">Endpoint-groups</md-button>
                 <md-button ng-if="'main.gbp.index.resolvedPolicy' | isState" ng-click="deselectContract()" ng-href="">Contracts</md-button>
+                <md-input-container style="margin-right: 10px;">
+                    <md-select ng-model="rootTenant"
+                               placeholder="select tenant"
+                               md-on-close="setRootTenant();"
+                               id="tenantSelector">
+                        <md-option ng-repeat="tenant in rootTenants.data" ng-value="tenant.data.id">{{ tenant.data.id }}</md-option>
+                    </md-select>
+                </md-input-container>
             </div>
         </md-toolbar>
         <!-- <md-content md-scroll-y flex ui-view></md-content> -->
index 167c2ba56c4161c9edd14f0014587806465c302e..33262bfa3c5d57c59752f6331daa8f2e887a43a3 100644 (file)
@@ -1,24 +1,43 @@
 define([
     'app/gbp/endpoints/endpoint.service',
+    'app/gbp/forwarding/forwarding.service',
 ], function () {
     'use strict';
 
     angular.module('app.gbp').controller('AddEndpointController', AddEndpointController);
 
-    AddEndpointController.$inject = ['$mdDialog', '$scope', 'EndpointService', 'endpoint'];
+    AddEndpointController.$inject = ['$filter', '$mdDialog', '$scope', 'EndpointService', 'endpoint', 'ForwardingService', 'TenantService'];
     /* @ngInject */
-    function AddEndpointController($mdDialog, $scope, EndpointService, endpoint) {
+    function AddEndpointController($filter, $mdDialog, $scope, EndpointService, endpoint, ForwardingService, TenantService) {
         /* properties */
+
         $scope.endpoint = endpoint ? endpoint : EndpointService.createObject();
+        $scope.epgsChips = {
+            selectedItem: null,
+            searchText: null,
+        };
+        $scope.epgsListOfChoosenTenant = [];
+        $scope.forwarding = ForwardingService.createObject();
+        $scope.forwardingContexts = [];
+        $scope.forwardingNetworkDomainIds = [];
+        $scope.regexps = {
+            'ipv4cidr': '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))',
+            'ipv6cidr': 's*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))',
+            'mac-address': '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})',
+        };
+
+        $scope.regexps['ip-prefix'] = '(('+$scope.regexps.ipv4cidr + ')|(' + $scope.regexps.ipv6cidr + '))';
 
         /* methods */
         $scope.closeDialog = closeDialog;
         $scope.save = save;
-        $scope.checkEndpointGroup = checkEndpointGroup;
-        $scope.checkEndpointCondition = checkEndpointCondition;
+        $scope.filterContextIds = filterContextIds;
+        $scope.filterNetworkDomainIds = filterNetworkDomainIds;
+        $scope.searchEpgs = searchEpgs;
+        $scope.populateScopeAfterTenantSelected = populateScopeAfterTenantSelected;
 
-        console.log('$scope.rootTenants.data.Tenant', $scope.rootTenants.data.Tenant);
         /* Implementations */
+        $scope.forwarding.get(postForwardingGet);
 
         function closeDialog(){
             $mdDialog.cancel();
@@ -26,17 +45,62 @@ define([
         }
 
         function save() {
+            if ($scope.endpoint.data['network-containment'] && $scope.endpoint.data['network-containment']['network-domain-id']) {
+                $scope.endpoint.data['network-containment']['network-domain-type'] = 'l2-l3-forwarding:subnet';
+            }
+            else {
+                delete $scope.endpoint.data['network-containment'];
+            }
             $scope.endpoint.post(function () {
                 $scope.closeDialog();
             }, function () {
             } );
         }
 
-        function checkEndpointGroup(){
-            // $scope.bgpRouteForm.nextHopVal.invalidHops = $scope.bgpRoute.getInvalidHops();
+        function filterContextIds(contextType) {
+            $scope.forwardingContexts =  $filter('filter')($scope.forwarding.data['forwarding-context'], {'context-type': contextType});
+        }
+
+        function filterNetworkDomainIds(networkDomainType) {
+            $scope.forwardingNetworkDomainIds =  $filter('filter')($scope.forwarding.data['network-domain'], {'network-domain-type': networkDomainType});
+        }
+
+        function populateEpgsListOfChoosenTenant() {
+            $scope.rootTenants.data.some(function (tenant) {
+                if (tenant.data.id === $scope.endpoint.data.tenant) {
+                    $scope.epgsListOfChoosenTenant = tenant.data.policy['endpoint-group'].map(function (ele) { return ele.id; } );
+                }
+            });
+        }
+
+        function searchEpgs(query) {
+            var self = this,
+                results = query ? self.epgsListOfChoosenTenant.filter(createFilterFor(query) ) : self.epgsListOfChoosenTenant;
+            return results;
         }
 
-        function checkEndpointCondition(){
+        function createFilterFor(query) {
+            return function filterFn(epg) {
+                return (epg.indexOf(query) === 0);
+            };
         }
+
+        function postForwardingGet() {
+            var tenantForwarding = $filter('filter')($scope.forwarding.data, { 'tenant-id': $scope.endpoint.data.tenant });
+
+            if (tenantForwarding && tenantForwarding.length) {
+                $scope.forwarding.data = tenantForwarding[0];
+                $scope.filterNetworkDomainIds('l2-l3-forwarding:subnet');
+            }
+
+            if ($scope.endpoint && $scope.endpoint.data['context-type']) {
+                $scope.filterContextIds($scope.endpoint.data['context-type']);
+            }
+        }
+
+        function populateScopeAfterTenantSelected() {
+            populateEpgsListOfChoosenTenant();
+        }
+
     }
 });
index 5d9d6f058eda0d8acd53477ffc3527d76d970c07..84b167ec8ce54cfc1600a0920dbcfabb8b8282ac 100644 (file)
@@ -1,4 +1,4 @@
-<md-dialog ng-cloak class="gbpDialogWrapper" ng-cloak>
+<md-dialog ng-cloak class="gbpDialogWrapper">
     <form name="endpointForm">
         <md-toolbar>
             <div class="md-toolbar-tools">
                 <md-button ng-click="closeDialog()" class="md-button">Close dialog</md-button>
             </div>
         </md-toolbar>
-        <md-dialog-content style="width:800px;min-height:550px;">
-            <div layout="column" class="layout-padding-lr15">
-                <div layout="row">
-                    <md-input-container flex>
-                        <label>Tenant Id</label>
-                        <!-- <input name="tenant" ng-model="endpoint.data.tenant"> -->
-
-                        <md-select ng-model="endpoint.data.tenant">
-                            <md-option ng-repeat="tenant in rootTenants.data" value="tenant.data.id">{{ tenant.data.id }}</md-option>
-                        </md-select>
-
-
-                    </md-input-container>
-                    <md-input-container flex>
-                        <label>Context Type</label>
-                        <input name="context-type" ng-model="endpoint.data['context-type']" ng-required="true">
-                        <div ng-messages="endpointForm['context-type'].$error">
-                            <div ng-message="required">Required field</div>
+        <md-dialog-content style="width:800px;">
+            <md-tabs md-dynamic-height flex>
+                <md-tab label="Endpoint">
+                    <div layout="column" class="layout-padding-lr15">
+                        <div layout="row">
+                            <md-input-container flex >
+                                <label>Tenant Id</label>
+                                <md-select ng-model="endpoint.data.tenant" md-on-close="populateScopeAfterTenantSelected();" aria-label="Tenant select">
+                                    <md-option ng-repeat="tenant in rootTenants.data" ng-value="tenant.data.id">{{ tenant.data.id }}</md-option>
+                                </md-select>
+                            </md-input-container>
                         </div>
-                    </md-input-container>
-                    <md-input-container flex>
-                        <label>Context Id</label>
-                        <input name="context-id" ng-model="endpoint.data['context-id']" ng-required="true">
-                        <div ng-messages="endpointForm['context-id'].$error">
-                            <div ng-message="required">Required field.</div>
+                        <div layout="row">
+                            <md-input-container flex>
+                                <label>Context Type</label>
+                                <md-select name="contextTypeSelect" ng-model="endpoint.data['context-type']"
+                                           ng-change="filterContextIds(endpoint.data['context-type'])"
+                                           aria-label="Context type select">
+                                    <md-option ng-repeat="contextType in ['l2-l3-forwarding:l2-bridge-domain', 'l2-l3-forwarding:l2-flood-domain', 'l2-l3-forwarding:l3-context']"
+                                               ng-value="contextType"
+                                               ng-required="true">
+                                        {{ contextType }}
+                                    </md-option>
+                                </md-select>
+                            </md-input-container>
+                            <md-input-container flex ng-if="forwardingContexts.length">
+                                <label>Context Id</label>
+                                <md-select name="contextIdSelect" ng-model="endpoint.data['context-id']"
+                                           aria-label="Context Id select">
+                                    <md-option ng-repeat="contextId in forwardingContexts"
+                                               ng-value="contextId['context-id']"
+                                               ng-required="true">
+                                        {{ contextId['context-id'] }}
+                                    </md-option>
+                                </md-select>
+                            </md-input-container>
+                            <md-input-container flex ng-if="!forwardingContexts.length">
+                                <label>Context Id</label>
+                                <input ng-model="endpoint.data['context-id']" />
+                            </md-input-container>
                         </div>
-                    </md-input-container>
-                </div>
-                <div layout="row">
-                    <md-input-container flex>
-                        <label>Address Type</label>
-                        <input name="address-type" ng-model="endpoint.data['address-type']">
-                    </md-input-container>
-                    <md-input-container flex>
-                        <label>Address</label>
-                        <input name="address" ng-model="endpoint.data.address" ng-required="true">
-                        <div ng-messages="endpointForm.address.$error">
-                            <div ng-message="required">Required field</div>
+                        <div layout="row">
+                            <md-input-container flex>
+                                <label>Address Type</label>
+                                <md-select ng-model="endpoint.data['address-type']" aria-label="Address Type select">
+                                    <md-option ng-repeat="addressType in ['l2-l3-forwarding:mac-address-type', 'l2-l3-forwarding:ip-prefix-type']"
+                                               ng-value="addressType"
+                                               ng-required="true">
+                                        {{ addressType }}
+                                    </md-option>
+                                </md-select>
+                                <div ng-messages="endpointForm['address-type'].$error">
+                                    <div ng-message="required">Required field</div>
+                                </div>
+                            </md-input-container>
+                            <md-input-container flex>
+                                <label>Address</label>
+                                <input name="address" ng-model="endpoint.data.address" ng-required="true"
+                                       ng-pattern="(endpoint.data['address-type'] === 'l2-l3-forwarding:mac-address-type' ? regexps['mac-address'] : regexps['ip-prefix'])">
+                                <div ng-messages="endpointForm.address.$error" ng-show="endpointForm.address.$touched">
+                                    <div ng-message="required">Required field</div>
+                                    <div ng-message="pattern">Expected correct address type format</div>
+                               </div>
+                            </md-input-container>
                         </div>
-                    </md-input-container>
-                </div>
-                <div layout="row">
-                    <md-input-container flex>
-                        <label>Network Containment - Network Domain Type</label>
-                        <input name="network-domain-type" ng-model="endpoint.data['network-containment']['network-domain-type']">
-                    </md-input-container>
-                    <md-input-container flex>
-                        <label>Network Containment - Network Domain Id</label>
-                        <input name="network-domain-id" ng-model="endpoint.data['network-containment']['network-domain-id']">
-                    </md-input-container>
-                </div>
-                <div layout="row">
-                    <md-input-container flex>
-                        <label>Endpoint Group</label>
-                        <md-chips ng-model="endpoint.data['endpoint-group']"
-                                  placeholder="Add an item"
-                                  md-on-add="checkEndpointGroup()"
-                                  md-on-remove="checkEndpointGroup()">
-                        </md-chips>
-                    </md-input-container>
-                </div>
-        <div layout="row">
-            <md-input-container flex>
-                <label>Condition</label>
-                <md-chips ng-model="endpoint.data.condition"
-                          placeholder="Add an item"
-                          md-on-add="checkEndpointCondition()"
-                          md-on-remove="checkEndpointCondition()">
-                </md-chips>
-            </md-input-container>
-        </div>
-    </div>
-</md-dialog-content>
-<md-dialog-actions layout="row">
-    <span flex></span>
-    <md-button ng-click="closeDialog()" class="md-primary">
-        Close
-    </md-button>
-    <md-button ng-click="save()" style="margin-right:20px;" ng-disabled="endpointForm.$invalid" class="md-primary">
-        Save
-    </md-button>
-</md-dialog-actions>
-</form>
+                        <div layout="row">
+                            <md-input-container flex ng-if="forwardingNetworkDomainIds.length">
+                                <label>Network Containment - Network Domain Id</label>
+                                <md-select name="networkDomainIdSelect"
+                                           ng-model="endpoint.data['network-containment']['network-domain-id']"
+                                           aria-label="Network Domain Id select">
+                                    <md-option value="{{undefined}}"></md-option>
+                                    <md-option ng-repeat="NetworkDomainId in forwardingNetworkDomainIds"
+                                               ng-value="NetworkDomainId['network-domain-id']"
+                                               ng-required="true" >
+                                        {{ NetworkDomainId['network-domain-id'] }}
+                                    </md-option>
+                                </md-select>
+                                <div ng-messages="endpointForm.networkDomainIdSelect.$error">
+                                    <div ng-message="required">Required field.</div>
+                                </div>
+                            </md-input-container>
+                            <md-input-container flex ng-if="!forwardingNetworkDomainIds.length">
+                                <label>Network Containment - Network Domain Id</label>
+                                <input name="networkDomainIdInput" ng-model="endpoint.data['network-containment']['network-domain-id']"/>
+                                <div ng-messages="endpointForm.networkDomainIdInput.$error">
+                                    <div ng-message="required">Required field.</div>
+                                </div>
+                            </md-input-container>
+                        </div>
+                        <div layout="row">
+                            <md-input-container flex>
+                            <label>Endpoint Group</label>
+                                <md-chips
+                                               name="epgs"
+                                               ng-model="endpoint.data['endpoint-group']"
+                                    md-require-match = "true"
+                                               md-autocomplete-snap
+                                               flex>
+                                               <md-autocomplete
+                                                       md-selected-item="epgsChips.selectedItem"
+                                                       md-search-text="epgsChips.searchText"
+                                                       md-items="epg in searchEpgs(epgsChips.searchText)"
+                                                       md-item-text="epg"
+                                        placeholder="{{!endpoint.data.tenant ? 'Select Tenant first' : 'Add an item'}}"
+                                                       md-autocomplete-wrap-override
+                                                       md-input-name="epAutocomplete"
+                                                       flex
+                                        ng-disabled="!endpoint.data.tenant">
+                                                       <md-item-template>
+                                                               <span md-highlight-text="epgsChips.searchText">{{epg}}</span>
+                                                       </md-item-template>
+                                                       <md-not-found>
+                                                               No matches found.
+                                                       </md-not-found>
+                                               </md-autocomplete>
+                                               <md-chip-template>
+                                                       <span>{{$chip}}</span>
+                                               </md-chip-template>
+                                   </md-chips>
+                            </md-input-container>
+                        </div>
+                        <div layout="row">
+                            <md-input-container flex>
+                                <label>Condition</label>
+                                <md-chips ng-model="endpoint.data.condition"
+                                          placeholder="Add an item">
+                                </md-chips>
+                            </md-input-container>
+                        </div>
+                    </div>
+                </md-tab>
+                <md-tab label="Location">
+                    <div layout="column" class="layout-padding-lr15">
+                        <md-subheader class="md-primary">Absolute location</md-subheader>
+                        <div layout="row">
+                            <md-input-container flex>
+                                <label>Internal node</label>
+                                <input name="AbsoluteLocationInternalNode" ng-model="endpoint.data['absolute-location']['internal-node']">
+                            </md-input-container>
+                        </div>
+                        <div layout="row">
+                            <md-input-container flex>
+                                <label>Internal node connector</label>
+                                <input name="AbsoluteLocationInternalNodeConnector" ng-model="endpoint.data['absolute-location']['internal-node-connector']">
+                            </md-input-container>
+                        </div>
+                    </div>
+                </md-tab>
+            </md-tabs>
+        </md-dialog-content>
+        <md-dialog-actions layout="row">
+            <span flex></span>
+            <md-button ng-click="closeDialog()" class="md-primary">
+                Close
+            </md-button>
+            <md-button ng-click="save()" style="margin-right:20px;" ng-disabled="endpointForm.$invalid" class="md-primary">
+                Save
+            </md-button>
+        </md-dialog-actions>
+    </form>
 </md-dialog>
index 468d55294811fd786983044e069249fa4b3c06e8..fca475366c59a1621b46144b49b3925cc7a138a8 100644 (file)
@@ -18,10 +18,9 @@ define([], function () {
             this.data = {};
             this.data['endpoint-group'] = [];
             this.data.condition = [];
+
             /* methods */
             this.setData = setData;
-            this.get = get;
-            // this.put = put;
             this.post = post;
             this.deleteEndpoint = deleteEndpoint;
 
@@ -30,6 +29,7 @@ define([], function () {
              * fills Endpoint object with data
              * @param data
              */
+
             function setData(data) {
                 this.data['context-type'] = data['context-type'];
                 this.data['context-id'] = data['context-id'];
@@ -37,31 +37,19 @@ define([], function () {
                 this.data.address = data.address;
                 this.data['network-containment'] = data['network-containment'];
                 this.data.tenant = data.tenant;
-                this.data.timestamp = Date();
-                this.data['endpoint-group'] = data['endpoint-group'];
+                this.data['endpoint-group'] = data['endpoint-group'] ? data['endpoint-group'] : [];
+                this.data.condition = data.condition ? data.condition : [];
+                this.data.timestamp = data.timestamp ? data.timestamp : Date();
+                if (this.data['absolute-location']){
+                    this.data['absolute-location']['internal-node'] = data['absolute-location']['internal-node'];
+                    this.data['absolute-location']['internal-node-connector'] = data['absolute-location']['internal-node-connector'];
+                }
             }
             /**
              * gets one Endpoint object from Restconf
              * @param id
              * @returns {*}
              */
-            function get() {
-                var self = this;
-
-                var restObj = Restangular
-                    .one('restconf')
-                    .one('config')
-                    .one('policy:tenants')
-                    .one('tenant')
-                    .one(id)
-                    .one('policy')
-                    .one('Endpoint')
-                    .one(id);
-
-                return restObj.get().then(function (data) {
-                    self.setData(data.Endpoint[0]);
-                });
-            }
 
             function post(successCbk) {
 
@@ -81,26 +69,31 @@ define([], function () {
                 });
             }
 
-            function deleteEndpoint(id, successCallback) {
-                var self = this;
-
+            function deleteEndpoint(successCallback) {
+                var self = this,
+                    tmpEndpointObject = {
+                        'context-type': self.data['context-type'],
+                        'context-id': self.data['context-id'],
+                        'address': self.data.address,
+                        'address-type': self.data['address-type'],
+                    };
                 var restObj = Restangular
-                    .one('restconf')
-                    .one('config')
-                    .one('policy:tenants')
-                    .one('tenant')
-                    .one(id)
-                    .one('policy')
-                    .one('Endpoint')
-                    .one(self.data.id);
-
-                return restObj.remove().then(function (data) {
+                        .one('restconf')
+                        .one('operations')
+                        .one('base-endpoint:unregister-endpoint'),
+                    reqData = {
+                        'input': {
+                            'address-endpoint-unreg': [
+                                tmpEndpointObject,
+                            ],
+                        },
+                    };
+                return restObj.customPOST(reqData).then(function (data) {
                     successCallback(data);
                 }, function () {
 
                 });
             }
-
         }
 
         /**
index e678748b58530d5b2ec9864d8ee08039dfb23248..fc0bfac4988611bd0cb5109f5616ba12baf6892a 100644 (file)
@@ -17,6 +17,7 @@ define([], function () {
             this.setData = setData;
             this.get = get;
             this.getByEpg = getByEpg;
+            this.getByTenantId = getByTenantId;
             this.clearData = clearData;
 
             /* Implementation */
@@ -26,7 +27,8 @@ define([], function () {
              */
             function setData(data) {
                 var self = this;
-                data.forEach(function (dataElement) {
+
+                data && data.forEach(function (dataElement) {
                     self.data.push(EndpointService.createObject(dataElement));
                 });
             }
@@ -63,6 +65,18 @@ define([], function () {
                     self.setData(endpoints);
                 });
             }
+
+            function getByTenantId(rootTenant) {
+                var self = this;
+                var restObj = Restangular.one('restconf').one('operational').one('base-endpoint:endpoints');
+                return restObj.get().then(function (data) {
+                    var endpoints = $filter('filter')(data.endpoints['address-endpoints']['address-endpoint'].map(function(endpoint) {
+                        return endpoint;
+                    }), { 'tenant': rootTenant });
+                    self.setData(endpoints);
+                });
+            }
+
         }
 
         function createList() {
index a742ea08591b07efd0020de1143a4fe14151b7c1..20634ad2b2c003addb11a8ea6259fa9c331a9ac1 100644 (file)
@@ -9,10 +9,9 @@ define([
     EndpointsController.$inject = ['$scope', '$mdDialog', 'EndpointsListService', 'EndpointService'];
 
     function EndpointsController($scope, $mdDialog, EndpointsListService, EndpointService) {
+        /* properties */
         $scope.endpoints = EndpointsListService.createList();
-        $scope.openEndpointDialog = openEndpointDialog;
-        $scope.getEndpointsList = getEndpointsList;
-        $scope.deleteEndpointDialog = deleteEndpointDialog;
+        $scope.disableKeyFieldsEditing = false;
         $scope.endpointsTableQuery = {
             order: "data['context-id']",
             limit: 25,
@@ -20,15 +19,20 @@ define([
             options: [25, 50, 100],
             filter: '',
         };
+        /* methods */
+        $scope.openEndpointDialog = openEndpointDialog;
+        $scope.getEndpointsList = getEndpointsList;
+        $scope.deleteEndpointDialog = deleteEndpointDialog;
 
-        getEndpointsList();
+        $scope.getEndpointsList();
 
         function getEndpointsList() {
             $scope.endpoints.clearData();
-            $scope.endpoints.get();
+            $scope.rootTenant ? $scope.endpoints.getByTenantId($scope.rootTenant) : $scope.endpoints.get($scope.rootTenant);
         }
 
-        function openEndpointDialog(endpointData) {
+        function openEndpointDialog(operation, endpointData) {
+            $scope.disableKeyFieldsEditing = operation === 'edit';
             $mdDialog.show({
                 clickOutsideToClose: true,
                 controller: 'AddEndpointController',
@@ -50,14 +54,16 @@ define([
                 .cancel('Cancel');
 
             $mdDialog.show(confirm).then(function () {
-                contractData.deleteEndpoint($scope.rootTenant.data.id,
-                    function () {
-                        $scope.getEndpointsList();
-                    }
-                );
+                endpointData.deleteEndpoint(function () {
+                    $scope.getEndpointsList();
+                });
             }, function () {
 
             });
         }
+
+        $scope.$on('ROOT_TENANT_CHANGED', function () {
+            $scope.getEndpointsList();
+        });
     }
 });
index f3151c3aa8dc5e021078ecc4d0818f7d2e29d376..e3e6f78d55bff3063c2fc4e823c923a22a380d3e 100644 (file)
@@ -1,6 +1,6 @@
 <section flex layout="column">
     <div flex layout="row">
-        <md-button ng-click="openEndpointDialog()" class="md-primary">Add</md-button>
+        <md-button ng-click="openEndpointDialog('add', null)" class="md-primary">Add</md-button>
         <md-button ng-click="getEndpointsList()" class="md-primary">Reload</md-button>
     </div>
     <md-table-container ng-if="endpoints.data.length">
                 <td md-cell class="pointer" ng-click="openSidePanel('endpoints/side_panel_endpoints_detail', endpoint.data, null);">{{ endpoint.data['context-id'] }}</td>
                 <td md-cell class="pointer" ng-click="openSidePanel('endpoints/side_panel_endpoints_detail', endpoint.data, null);">{{ endpoint.data.address }}</td>
                 <td md-cell class="pointer" ng-click="openSidePanel('endpoints/side_panel_endpoints_detail', endpoint.data, null);">{{ endpoint.data.tenant }}</td>
-                <td md-cell ng-repeat="epg in endpoint.data['endpoint-group']">{{ epg }}
-                    <span ng-if="!$last">, </span>
+                <td md-cell>
+                    <span ng-repeat="epg in endpoint.data['endpoint-group']">{{epg}}<span ng-if="!$last">, </span>
+                    </span>
                 </td>
                 <td md-cell>
-                    <md-button class="md-icon-button" ng-click="openEndpointDialog(endpoint)">
+                    <md-button class="md-icon-button" ng-click="openEndpointDialog('edit', endpoint)">
                         <md-icon>edit</md-icon>
                     </md-button>
                     <md-button class="md-icon-button" ng-click="deleteEndpointDialog(endpoint)">
index 878227b0aee27004c9d3e121d2c19ef04c5c030e..c1876566cbe7a7cdb6736416a523208b24d959b2 100644 (file)
@@ -1,31 +1,49 @@
-<md-subheader class="md-primary">Endpoint properties</md-subheader>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Context type</strong></span><span flex>{{ sidePanelObject['context-type'] }}</span>
-</div>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Context Id</strong></span><span flex>{{ sidePanelObject['context-id'] }}</span>
-</div>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Address type</strong></span><span flex>{{ sidePanelObject['address-type'] }}</span>
-</div>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>address</strong></span><span flex>{{ sidePanelObject.address }}</span>
-</div>
-<md-divider></md-divider>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Network domain Id</strong></span><span flex>{{ sidePanelObject['network-containment']['network-domain-id'] }}</span>
-</div>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Network domain type</strong></span><span flex>{{ sidePanelObject['network-containment']['network-domain-type'] }}</span>
-</div>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Tenant</strong></span><span flex>{{ sidePanelObject.tenant }}</span>
-</div>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Timestamp</strong></span><span flex>{{ sidePanelObject.timestamp | date: 'short'}}</span>
-</div>
-<div layout="row" class="layout-padding-5-15">
-    <span flex="35"><strong>Endpoint group</strong></span><span ng-repeat="epg in sidePanelObject['endpoint-group']" flex>{{ epg }}
-        <span ng-if="!$last">, </span>
-    </span>
-</div>
+<md-content>
+    <md-subheader class="md-primary">Endpoint properties</md-subheader>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject.tenant.length">
+        <span flex="35"><strong>Tenant</strong></span><span flex>{{ sidePanelObject.tenant }}</span>
+    </div>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject['endpoint-group'].length">
+        <span flex="35"><strong>Endpoint group</strong></span><span ng-repeat="epg in sidePanelObject['endpoint-group']">{{epg}}<span ng-if="!$last">, </span>
+        </span>
+    </div>
+    <md-divider style="margin-bottom: 10px; margin-top: 10px;"></md-divider>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row">
+        <span flex="35"><strong>Context type</strong></span><span flex>{{ sidePanelObject['context-type'] }}</span>
+    </div>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row">
+        <span flex="35"><strong>Context Id</strong></span><span flex>{{ sidePanelObject['context-id'] }}</span>
+    </div>
+    <md-divider style="margin-bottom: 10px; margin-top: 10px;"></md-divider>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row">
+        <span flex="35"><strong>Address type</strong></span><span flex>{{ sidePanelObject['address-type'] }}</span>
+    </div>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row">
+        <span flex="35"><strong>Address</strong></span><span flex>{{ sidePanelObject.address }}</span>
+    </div>
+    <md-divider style="margin-bottom: 10px; margin-top: 10px;"></md-divider>
+    <md-subheader class="md-secondary" ng-if="sidePanelObject['network-containment']['network-domain-type'].length">Network domain</md-subheader>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject['network-containment']['network-domain-id'].length">
+        <span flex="35"><strong>Id</strong></span><span flex>{{ sidePanelObject['network-containment']['network-domain-id'] }}</span>
+    </div>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject['network-containment']['network-domain-type'].length">
+        <span flex="35"><strong>type</strong></span><span flex>{{ sidePanelObject['network-containment']['network-domain-type'] }}</span>
+    </div>
+    <md-subheader class="md-secondary"></md-subheader>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject.condition.length">
+        <span flex="35"><strong>Condition</strong></span><span ng-repeat="cndt in sidePanelObject.condition">{{cndt}}<span ng-if="!$last">, </span>
+        </span>
+    </div>
+    <section ng-if="sidePanelObject['absolute-location']['internal-node'].length || sidePanelObject['absolute-location']['internal-node-connector'].length">
+        <label class=".md-subhead">Absolute Location</label>
+        <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject['absolute-location']['internal-node']">
+            <span flex="35"><strong>Internal node</strong></span><span flex>{{ sidePanelObject['absolute-location']['internal-node'] }}</span>
+        </div>
+        <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject['absolute-location']['internal-node-connector']">
+            <span flex="35"><strong>Internal node connector</strong></span><span flex>{{ sidePanelObject['absolute-location']['internal-node-connector'] }}</span>
+        </div>
+    </section>
+    <div layout="row" class="layout-padding-lr15 .layout-padding-b15 layout-row" ng-if="sidePanelObject.timestamp">
+        <span flex="35"><strong>Timestamp</strong></span><span flex>{{ sidePanelObject.timestamp | date: 'short'}}</span>
+    </div>
+<md-content>
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/forwarding/forwarding.service.js b/groupbasedpolicy-ui/module/src/main/resources/gbp/forwarding/forwarding.service.js
new file mode 100644 (file)
index 0000000..1acb1f9
--- /dev/null
@@ -0,0 +1,65 @@
+define([], function () {
+    'use strict';
+
+    angular.module('app.gbp').service('ForwardingService', ForwardingService);
+
+    ForwardingService.$inject = ['Restangular'];
+
+    function ForwardingService(Restangular) {
+        /* methods */
+        this.createObject = createObject;
+
+        /**
+         * Endpoint constructor
+         * @constructor
+         */
+        function Forwarding() {
+            /* properties */
+            this.data = {};
+
+            /* methods */
+            this.setData = setData;
+            this.get = get;
+
+            /* Implementation */
+            /**
+             * fills Forwarding object with data
+             * @param data
+             */
+
+            function setData(data) {
+                this.data['forwarding-by-tenant'] = data['forwarding-by-tenant'];
+            }
+
+            function get(successCallback) {
+                var self = this;
+
+                var restObj = Restangular.one('restconf').one('config').one('forwarding:forwarding');
+
+                return restObj.get().then(function(data) {
+                    self.data = data['forwarding']['forwarding-by-tenant'];
+                    (successCallback || angular.noop)();
+                });
+            }
+        }
+
+
+
+        /**
+         * creates Endpoint object and fills it with data if available
+         * @param data
+         * @returns {Endpoint}
+         */
+        function createObject(data) {
+            var obj = new Forwarding();
+
+            if (data) {
+                obj.setData(data);
+            }
+
+            return obj;
+        }
+    }
+
+    return ForwardingService;
+});
index 4326625a9796f464d8de89fabdf708d274ca9659..32aaf877eed29e489f69ff2d43b0c279ee8d73ae 100644 (file)
@@ -7,25 +7,20 @@ define(['app/gbp/resolved-policy/resolved-policy.service'], function () {
 
     /* @ngInject */
     function ResolvedPolicyController($rootScope, $scope, ResolvedPolicyService, EpgService, EpgListService, ContractService, NextTopologyService) {
+        $scope.reloadTopology = reloadTopology;
+
         $scope.cbkFunctions = {
             clickNode: function(node){
                 var epg = EpgService.createObject();
+
                 epg.get(node['_data-id'], node['_model']['_data']['tenantId'], 'operational', function() {
                     $scope.openSidePanel('resolved-policy/epg-sidepanel', epg, null);
                 });
+
                 $scope.$apply();
                 $scope.parentTenant = node['_model']['_data']['tenantId'];
 
                 NextTopologyService.highlightNode($rootScope.nxTopology, node['_data-id']);
-                // //Example of highlighting
-                // NextTopologyService.highlightNode($scope.nxTopology, 1);
-                // NextTopologyService.highlightNode($scope.nxTopology, 1, true); //without links around
-                // NextTopologyService.highlightLink($scope.nxTopology, '1-7');
-                // NextTopologyService.highlightPath($scope.nxTopology, [array of links obj]);
-
-                // //Fade out or in whole topology
-                // NextTopologyService.fadeOutAllLayers();
-                // NextTopologyService.fadeInAllLayers();
             },
             clickLink: function(link){
                 var resolvedContract = $scope.resolvedPolicy[link['_model']['_data'].id];
@@ -39,6 +34,11 @@ define(['app/gbp/resolved-policy/resolved-policy.service'], function () {
             }
         };
 
+
+        function reloadTopology() {
+            $scope.fillTopologyData();
+        }
+
         $scope.$watch('nxTopology', function() {
             $rootScope.nxTopology = $scope.nxTopology;
         });
index 80850da0cb7818fb57d99cd8e23a2cdfef2e44dd..57ae5834f48239dd3ca3d882706a912ac36dde05 100644 (file)
@@ -1,5 +1,5 @@
-<div ng-controller="ResolvedPolicyController" id="topology-container">
-    <md-button md-no-ink class="md-primary reload-button" ng-click="reloadTopo()"><i class="material-icons">sync</i> Reload topology</md-button>
+<div id="topology-container">
+    <md-button md-no-ink class="md-primary reload-button" ng-click="reloadTopology()"><i class="material-icons">sync</i> Reload topology</md-button>
     <next-topology topology-data="topologyData" cbk-functions="cbkFunctions" dictionaries="nxDict" topo="nxTopology"
                topo-colors="nxTopoColors"></next-topology>
-</div>
\ No newline at end of file
+</div>
index 0abd8d9bb347c517816c4d4476316644000c8dff..d598867b051f90d2641a63491b2292d43354b79c 100644 (file)
@@ -22,7 +22,7 @@
                <div layout="row" class="layout-row">
                        <span>Actions ({{selectedNode.subjects[subjectIndex]['resolved-rule'][0][ruleIndex].action.length}})</span>
                        <span class="flex" flex></span>
-                       <md-button class="md-button md-primary md-button md-ink-ripple expand-button" type="button" ng-click="expandAll(selectedNode.subjects[subjectIndex]['resolved-rule'][0][ruleIndex].action)" aria-label="Expand all">            
+                       <md-button class="md-button md-primary md-button md-ink-ripple expand-button" type="button" ng-click="expandAll(selectedNode.subjects[subjectIndex]['resolved-rule'][0][ruleIndex].action)" aria-label="Expand all">
                    <i class="fa fa-expand ng-scope"></i>
                        <div class="md-ripple-container"></div>
                        <md-tooltip md-direction="bottom">
        </div>
        </md-subheader>
     <md-list class="expander">
-       <ng-repeat ng-repeat="action in selectedNode.subjects[subjectIndex]['resolved-rule'][0][ruleIndex].action">
-               <md-list-item ng-click="toggleExpanded(action)">
-                       <span class="layout-padding-r10">
-                           <h4 class="order">{{action.order}}</h4>
-                       </span>
-                       <span>{{action.name}}</span>
-                       <md-content ng-show="action.expanded" class="md-whiteframe-2dp ng-scope layout-margin">
-                               <div flex>
-                                       <div layout="row" class="layout-row">
-                                       <span flex="50" class="flex-50"><strong>Action definition ID</strong></span>
-                                               <span flex class="ng-binding flex">{{action['action-definition-id']}}</span>
-                                       </div>
-                                       <div layout="row" class="layout-row">
-                                       <span flex="50" class="flex-50"><strong>Name</strong></span>
-                                               <span flex class="ng-binding flex">{{action.name}}</span>
-                                       </div>
-                                       </div>
-                       </md-content>
-               </md-list-item>
-       </ng-repeat>
+               <md-list-item ng-click="toggleExpanded(action)" class="md-3-line" layout="row"
+                                         ng-repeat="action in selectedNode.subjects[subjectIndex]['resolved-rule'][0][ruleIndex].action">
+                       <div layout-padding flex="10">
+                               <h3>{{action.order}}</h3>
+                               <md-tooltip md-direction="right">
+                                       Order
+                               </md-tooltip>
+                       </div>
+                       <div class="md-list-item-text" flex>
+                               <h3>{{action.name}}</h3>
+                               <p>Action definition ID: {{action['action-definition-id']}} </p>
+                               <p>Name: {{action.name}} </p>
+                       </div>
+                       <div ng-if="action['action-definition-id'] === 'Action-Chain'" flex="10">
+                               <md-button class="md-icon-button" ng-click="openSfcDialog({{action.name}})">
+                                       <md-icon>visibility</md-icon>
+                               </md-button>
+                       </div>
+               </md-list-item>
     </md-list>
        <md-divider></md-divider>
        <md-subheader class="md-primary">
                </md-list-item>
        </ng-repeat>
     </md-list>
-</md-content>
\ No newline at end of file
+</md-content>