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;
$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;
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) {
})
}
- 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 */
* 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;
- // });
}
});
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 {
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;
.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;
+}
--- /dev/null
+.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
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);
- }
+ //}
});
/**
<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> -->
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();
}
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();
+ }
+
}
});
-<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>
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;
* fills Endpoint object with data
* @param data
*/
+
function setData(data) {
this.data['context-type'] = data['context-type'];
this.data['context-id'] = data['context-id'];
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) {
});
}
- 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 () {
});
}
-
}
/**
this.setData = setData;
this.get = get;
this.getByEpg = getByEpg;
+ this.getByTenantId = getByTenantId;
this.clearData = clearData;
/* Implementation */
*/
function setData(data) {
var self = this;
- data.forEach(function (dataElement) {
+
+ data && data.forEach(function (dataElement) {
self.data.push(EndpointService.createObject(dataElement));
});
}
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() {
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,
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',
.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();
+ });
}
});
<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)">
-<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>
--- /dev/null
+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;
+});
/* @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];
}
};
+
+ function reloadTopology() {
+ $scope.fillTopologyData();
+ }
+
$scope.$watch('nxTopology', function() {
$rootScope.nxTopology = $scope.nxTopology;
});
-<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>
<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>