$scope.OpenTenantPortal = function(tenant) {
$scope.currentTenent = tenant;
- window.location = "#cpeui/tenant/" + tenant.name;
+ window.location = "#cpeui/tenant/" + tenant.name +"/";
};
$scope.DeleteTenant = function(tenantID) {
}
$scope.tab = {
- tenantData : mainTabIndexs["tenants"],
+ tenantData : 1,
admin : 1
};
var selectedTab = mainTabIndexs[$state.params.tabName];
});
$stateProvider.state('main.cpeui.tenant', {
- url : '/tenant/:tenantid',
+ url : '/tenant/:tenantid/:tenantTabName',
access : access.public,
views : {
'cpeui' : {
<a ng-init="advancedCollapsed=true" ng-click="advancedCollapsed = !advancedCollapsed" class="btn btn-navbar btn-info">{{advancedCollapsed ? 'Show' : 'Hide'}} Advanced Options</a>
<div layout-gt-sm="row" ng-if-start="!advancedCollapsed">
<md-input-container class="md-block" flex-gt-sm>
- <md-switch name="is_preserve_vlan" ng-model="obj.is_preserve_vlan">{{obj.is_preserve_vlan ? "" : "Do Not"}} Preserve Vlan</md-switch>
+ <md-switch name="is_preserve_vlan" ng-model="obj.is_preserve_vlan">{{obj.is_preserve_vlan ? "" : "Do Not"}} Preserve VLAN</md-switch>
</md-input-container>
<md-input-container class="md-block" ng-if="obj.is_preserve_vlan" flex-gt-sm style="margin-bottom: 0px; margin-top: 36px;">
- <label>Preserved Vlan</label>
+ <label>Preserved VLAN</label>
<input required type="number" step="1" name="p_vlan" ng-model="obj.preserved_vlan">
<div ng-messages="projectForm.p_vlan.$error">
<div ng-message="required">Number is required!</div>
--- /dev/null
+<md-dialog class="cpe-dialog" aria-label="Create IP-UNI" ng-cloak>
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>Create IP-UNI (of UNI: {{params.uniid}})</h2>
+ <span flex></span>
+ <md-button class="md-icon-button" aria-label="Close dialog" ng-click="cancel()">
+ <i class="icon-remove-sign"></i>
+ </md-button>
+ </div>
+ </md-toolbar>
+ <form name="projectForm" novalidate>
+ <md-dialog-content>
+
+<div layout="column" ng-cloak>
+ <md-content layout-padding>
+ <md-input-container class="md-block">
+ <label>IP-UNI ID (Number)</label>
+ <input type="number" required name="ipuniid" ng-model="obj['ip-uni-id']" ng-init="obj['uni-id'] = params.uniid">
+ <div ng-messages="projectForm.ipuniid.$error">
+ <div ng-message="required">Number is required!</div>
+ </div>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <label>IP Address</label>
+ <input type="text" required name="ipaddress" ng-model="obj['ip-address']" ng-pattern="/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(?:[1-2]?[0-9]|3[0-2])\b/">
+ <div ng-messages="projectForm.ipaddress.$error">
+ <div ng-message="pattern">IP/Mask are required! (ex. 127.0.0.1/32)</div>
+ </div>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <label>Vlan</label>
+ <input type="number" ng-required="hasVlans" name="vlan" ng-model="obj.vlan">
+ <div ng-messages="projectForm.vlan.$error" ng-if="hasVlans">
+ <div ng-message="required">Vlan is required when there are other ip-unis with vlans</div>
+ </div>
+ </md-input-container>
+ </md-content>
+</div>
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="cancel()"> Cancel </md-button>
+ <md-button type="submit" ng-click="done(obj)"> Create </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
\ No newline at end of file
--- /dev/null
+<md-dialog class="cpe-dialog" aria-label="Add IP-UNI Subnet" ng-cloak>
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>Add IP-UNI Subnet</h2>
+ <span flex></span>
+ <md-button class="md-icon-button" aria-label="Close dialog" ng-click="cancel()">
+ <i class="icon-remove-sign"></i>
+ </md-button>
+ </div>
+ </md-toolbar>
+ <form name="projectForm" novalidate>
+ <md-dialog-content>
+
+<div layout="column" ng-cloak>
+ <md-content layout-padding>
+ <md-input-container class="md-block">
+ <label>Gateway</label>
+ <input type="text" required name="gateway" ng-model="obj.gateway" ng-pattern="/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/">
+ <div ng-messages="projectForm.gateway.$error">
+ <div ng-message="pattern">IP is required! (ex. 224.224.224.1)</div>
+ </div>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <label>Subnet</label>
+ <input type="text" required name="subnet" ng-model="obj.subnet" ng-pattern="/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(?:[1-2]?[0-9]|3[0-2])\b/">
+ <div ng-messages="projectForm.subnet.$error">
+ <div ng-message="pattern">IP/Mask is required! (ex. 127.0.0.1/32)</div>
+ </div>
+ </md-input-container>
+ </md-content>
+</div>
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="cancel()"> Cancel </md-button>
+ <span ng-hide="true" ng-init="obj.uniid = params.uniid"></span>
+ <span ng-hide="true" ng-init="obj.ipuniid = params.ipuniid"></span>
+ <md-button type="submit" ng-click="done(obj)"> Create </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
\ No newline at end of file
--- /dev/null
+<md-dialog class="cpe-dialog" aria-label="Create IPVC" ng-cloak>
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>Create IPVC</h2>
+ <span flex></span>
+ <md-button class="md-icon-button" aria-label="Close dialog" ng-click="cancel()">
+ <i class="icon-remove-sign"></i>
+ </md-button>
+ </div>
+ </md-toolbar>
+ <form name="projectForm" novalidate>
+ <md-dialog-content>
+
+<div layout="column" ng-cloak>
+ <md-content layout-padding>
+ <md-input-container class="md-block">
+ <label>IPVC ID (Number)</label>
+ <input type="number" required name="ipvcid" ng-model="obj.id">
+ <div ng-messages="projectForm.ipvcid.$error">
+ <div ng-message="required">Number is required!</div>
+ </div>
+ </md-input-container>
+ <!--
+ <a ng-init="advancedCollapsed=true" ng-click="advancedCollapsed = !advancedCollapsed" class="btn btn-navbar btn-info">{{advancedCollapsed ? 'Show' : 'Hide'}} Advanced Options</a>
+ <div layout-gt-sm="row" ng-if-start="!advancedCollapsed">
+ <md-input-container class="md-block" flex-gt-sm>
+ <md-switch name="is_preserve_vlan" ng-model="obj.is_preserve_vlan">{{obj.is_preserve_vlan ? "" : "Do Not"}} Preserve VLAN</md-switch>
+ </md-input-container>
+ <md-input-container class="md-block" ng-if="obj.is_preserve_vlan" flex-gt-sm style="margin-bottom: 0px; margin-top: 36px;">
+ <label>Preserved VLAN</label>
+ <input required type="number" step="1" name="p_vlan" ng-model="obj.preserved_vlan">
+ <div ng-messages="projectForm.p_vlan.$error">
+ <div ng-message="required">Number is required!</div>
+ </div>
+ </md-input-container>
+ </div>
+ <md-input-container class="md-block" ng-init="obj.mtu_size = 1522">
+ <label>IPVC MTU size</label>
+ <input type="number" step="1" name="mtu" min="1522" max="16384" ng-model="obj.mtu_size">
+ <div ng-messages="projectForm.mtu.$error">
+ <div ng-message="min">Number must be in range [1522..16384]</div>
+ </div>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <label>Unicast Service Frame Delivery</label>
+ <md-select ng-model="obj.unicast" name="unicast">
+ <md-option value="{{ undefined }}"></md-option>
+ <md-option value="discard">Discard</md-option>
+ <md-option value="unconditional">Unconditional</md-option>
+ <md-option value="conditional">Conditional</md-option>
+ </md-select>
+ </md-input-container>
+ <md-input-container class="md-block" ng-if-end>
+ <label>Multicast Service Frame Delivery</label>
+ <md-select ng-model="obj.multicast" name="multicast">
+ <md-option value="{{ undefined }}"></md-option>
+ <md-option value="discard">Discard</md-option>
+ <md-option value="unconditional">Unconditional</md-option>
+ <md-option value="conditional">Conditional</md-option>
+ </md-select>
+ </md-input-container>
+ -->
+
+ </md-content>
+</div>
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="cancel()"> Cancel </md-button>
+ <md-button type="submit" ng-click="done(obj)"> Create </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
\ No newline at end of file
<md-dialog class="cpe-dialog" aria-label="Update vlans" ng-cloak>
<md-toolbar>
<div class="md-toolbar-tools">
- <h2>Vlans</h2>
+ <h2>VLANs</h2>
<span flex></span>
<md-button class="md-icon-button" aria-label="Close dialog"
ng-click="cancel()"> <i class="icon-remove-sign"></i> </md-button>
<md-dialog class="cpe-dialog" aria-label="Update UNI" ng-cloak>
<md-toolbar>
<div class="md-toolbar-tools">
- <h2>Update {{ params.evc['svc-id'] }} Uni</h2>
+ <h2>Update {{ params.svc['svc-id'] }} Uni</h2>
<span flex></span>
<md-button class="md-icon-button" aria-label="Close dialog" ng-click="cancel()">
<i class="icon-remove-sign"></i>
<md-input-container class="md-block">
<label>Uni</label>
<md-select ng-model="obj.uni_id" name="uniid">
- <md-option ng-repeat="uni in params.unis.filterByField('device',obj.device_id) | filter: filterUsedUnis(params.evc) " value="{{ uni['uni-id'] }}" default>{{ uni.prettyID }}</md-option>
+ <md-option ng-repeat="uni in params.unis.filterByField('device',obj.device_id) | filter: filterUsedUnis(params.svc) " value="{{ uni['uni-id'] }}" default>{{ uni.prettyID }}</md-option>
</md-select>
</md-input-container>
- <md-input-container class="md-block" ng-if="params.evc.evc['evc-type'] == 'rooted-multipoint'">
+ <md-input-container class="md-block" ng-if="params.svc.evc['evc-type'] == 'rooted-multipoint'">
<label>Role</label>
<md-select ng-model="obj.role" name="role">
<md-option value="root" default>Root</md-option>
</md-select>
</md-input-container>
<input type="hidden" name="vlans" ng-model="obj.vlans">
- <div ng-if="params.evc.evc['preserve-ce-vlan-id']">
- Preserved Vlan: {{params.evc.evc['preserved-vlan']}}
- <i ng-init="obj.vlans = [params.evc.evc['preserved-vlan']]"></i>
+ <div ng-if="params.svc.evc['preserve-ce-vlan-id']">
+ Preserved VLAN: {{params.svc.evc['preserved-vlan']}}
+ <i ng-init="obj.vlans = [params.svc.evc['preserved-vlan']]"></i>
</div>
- <md-input-container class="md-block" ng-if="!params.evc.evc['preserve-ce-vlan-id']">
- <h4 style="color:black;">VLans</h4>
+ <md-input-container class="md-block" ng-if="!params.svc.evc['preserve-ce-vlan-id']">
+ <h4 style="color:black;">VLANs</h4>
<table ng-init="obj.vlans = []" class="inner-table table table-striped">
<thead>
</thead>
<md-button ng-click="cancel()">
Cancel
</md-button>
- <md-button type="submit" ng-click="obj.svc_id = params.evc['svc-id'];obj.evc_unis = params.evc_unis; done(obj)">
+ <md-button type="submit" ng-click="obj.svc_id = params.svc['svc-id'];obj.evc_unis = params.svc_unis; done(obj)">
link
</md-button>
</md-dialog-actions>
--- /dev/null
+<md-dialog class="cpe-dialog" aria-label="Update UNI" ng-cloak>
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>Update {{ params.svc['svc-id'] }} Uni</h2>
+ <span flex></span>
+ <md-button class="md-icon-button" aria-label="Close dialog" ng-click="cancel()">
+ <i class="icon-remove-sign"></i>
+ </md-button>
+ </div>
+ </md-toolbar>
+ <form name="projectForm" novalidate>
+ <md-dialog-content>
+
+<div ng-controller="AppCtrl" layout="column" ng-cloak ng-init="obj.role = 'root'">
+ <md-content layout-padding>
+ <md-input-container class="md-block">
+ <label>Device</label>
+ <md-select ng-model="obj.device_id" name="device">
+ <md-option ng-repeat="ce in params.ces" ng-value="ce['dev-id']">{{ ce.displayName }}</md-option>
+ </md-select>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <label>Uni</label>
+ <md-select ng-model="obj.uni" name="uniid" ng-disabled="!obj.device_id">
+ <md-option ng-repeat="uni in params.unis.filterByField('device',obj.device_id)" ng-value="uni" >{{ uni.prettyID }}</md-option>
+ </md-select>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <label>IP Uni</label>
+ <md-select ng-model="obj.ip_uni" name="ip_uni" ng-disabled="!obj.uni">
+ <md-option ng-repeat="ipuni in obj.uni['ip-unis']['ip-uni'] " value="{{ ipuni['ip-uni-id'] }}" >{{ ipuni['ip-uni-id'] }} : {{ipuni['ip-address']}}{{ipuni.vlan ? (' (vlan: ' + ipuni.vlan+')') : ''}}</md-option>
+ </md-select>
+ </md-input-container>
+ </md-content>
+</div>
+
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="cancel()">
+ Cancel
+ </md-button>
+ <md-button type="submit" ng-click="obj.svc_id = params.svc['svc-id'];obj.evc_unis = params.svc_unis; done(obj)">
+ link
+ </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
\ No newline at end of file
$mdDialog.show(confirm).then(callback_ok, callback_cancel);
};
+ svc.alert = function(title, content, callback_ok) {
+ var alert = $mdDialog.alert().title(title).textContent(content).ok(
+ 'Ok');
+ $mdDialog.show(alert).then(callback_ok);
+ };
+
return svc;
});
}
});
};
-
+
svc.addCeName = function(ce, new_name, callback) {
$http({
method:'POST',
if (callback != undefined) {
callback();
}
- }, function errorCallback(response) {
+ }, function errorCallback(response) {
console.log(response);
$http({
method:'GET',
- url:"/restconf/config/mef-topology:mef-topology/devices/device/" + ce['dev-id']
+ url:"/restconf/config/mef-topology:mef-topology/devices/device/" + ce['dev-id']
}).then(function successCallback(response) {
ce["device-name"] = response.data["device"][0]["device-name"];
});
unis = response.data["unis"]["uni"];
if (unis != undefined){
for (i=0; i < unis.length; i++) {
- if ((unis[i]["physical-layers"] != undefined) && (unis[i].device = unis[i]["physical-layers"].links != undefined)){
+ if ((unis[i]["physical-layers"] != undefined) && (unis[i]["physical-layers"].links != undefined)){
unis[i].device = unis[i]["physical-layers"].links.link[0].device;
}
}
});
};
- // EVCs
+ // IPVCs
+ svc.addIpvc = function(ipvc, tenant, callback) {
+// var uni_json = getJsonUnis(evc.unis);
+// preserved-vlan
+ var data = {
+ "mef-service" : {
+ "svc-id" : ipvc.id,
+ "svc-type" : 'eplan',
+ "tenant-id" : tenant,
+ "ipvc" : {
+ "ipvc-id" : ipvc.id,
+ "ipvc-type" : 'multipoint',
+// "unis" : {
+// "uni" : uni_json
+// },
+ }
+ }
+ };
+ $http({
+ method:'POST',
+ url:"/restconf/config/mef-services:mef-services/",
+ data:data
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+ svc.addIpUni = function(uniid, ipuni_id, ip_address, vlan, subnets, callback) {
+ var data = {"ip-uni":{
+ "ip-uni-id": ipuni_id,
+ "ip-address": ip_address,
+ "subnets":{
+ "subnet":subnets
+ }
+ }};
+ if (vlan){
+ data["ip-uni"].vlan = vlan;
+ }
+ $http({
+ method:'POST',
+ url:"/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/",
+ data:data
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+ svc.addIpUniSubnet = function(uniid, ipuniid, subnet, gateway,
+ callback) {
+ var data = {
+ "subnet":
+ {
+ "subnet": subnet,
+ "gateway": gateway
+ }
+
+ };
+ $http(
+ {
+ method : 'POST',
+ url : "/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/ip-uni/"+ipuniid+"/subnets/",
+ data : data
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+ svc.deleteIpUniSubnet = function(uniid, ipuni_id, subnet, callback) {
+
+ $http({
+ method:'DELETE',
+ url:"/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/ip-uni/"+ipuni_id+"/subnets/subnet/"+subnet.replace("/","%2F")+"/"
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+ svc.deleteIpUni = function(uniid, ipuni_id, callback) {
+
+ $http({
+ method:'DELETE',
+ url:"/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/ip-uni/"+ipuni_id+"/"
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+ svc.getIpUniSubnets = function(uniid, ipuni_id, callback) {
+ $http({
+ method:'GET',
+ url:"/restconf/config/mef-interfaces:mef-interfaces/unis/uni/"+uniid+"/ip-unis/ip-uni/"+ipuni_id+"/subnets"
+ }).then(function successCallback(response) {
+ subnets = response.data["subnets"]["subnet"];
+ if (callback != undefined) {
+ callback(subnets);
+ }
+ });
+ };
- function getJsonUnis(unis) {
+
+ // EVCs
+ function getJsonUnis(unis) {
var uni_json = [];
if (unis == undefined) {
unis = [];
unis.forEach(function(i){uni_json.push({"uni-id":i});});
return uni_json;
}
-
svc.addEvc = function(evc, evc_type, tenant, callback) {
var uni_json = getJsonUnis(evc.unis);
// preserved-vlan
},
"admin-state-enabled" : true
}
- }
+ }
};
if (evc.is_preserve_vlan) {
data["mef-service"]["evc"]["preserved-vlan"] = evc.preserved_vlan;
}
});
};
-
svc.getServices = function(tenantid, callback) {
var evcs;
$http({
url:"/restconf/config/mef-services:mef-services/"
}).then(function successCallback(response) {
evcs = response.data["mef-services"]["mef-service"]; // TODO try to filter on server side
-
if (evcs != undefined) {
evcs = evcs.filter(function(evc){return evc["tenant-id"] == tenantid;});
for (i=0; i < evcs.length; i++) {
}, function errorCallback(response) {
console.log(response);
});
-
return evcs;
};
- svc.getAllServices = function(callback) {
+ svc.getAllServices = function(callback) {
$http({
method:'GET',
url:"/restconf/config/mef-services:mef-services/"
- }).then(function successCallback(response) {
+ }).then(function successCallback(response) {
if (callback != undefined) {
callback(response.data["mef-services"]["mef-service"]);
}
console.log(response);
});
};
-
+
svc.addTenantToService = function(svcId, tenantName, callbackSuccess, callbackFailure){
$http({
method:'POST',
});
};
+ svc.addIpvcUni = function(svcid, uni_id, ipuni_id, callback) {
+ var data = {"uni":{
+ "uni-id":uni_id,
+ "ip-uni-id":ipuni_id
+ }
+ };
+ $http({
+ method:'PUT',
+ url:"/restconf/config/mef-services:mef-services/mef-service/" + svcid + "/ipvc/unis/uni/"+uni_id,
+ data: data
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ }, function failureCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+ svc.deleteIpvcUni = function(svcid, uni_id, callback) {
+ $http({
+ method:'DELETE',
+ url:"/restconf/config/mef-services:mef-services/mef-service/" + svcid + "/ipvc/unis/uni/" + uni_id + "/"
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+
+
svc.addEvcUni = function(svcid, uni_id, role, vlans, callback) {
var data = {"uni":{
"uni-id":uni_id,
svc.getNetworkNames = function(callback){
$http({
method:'GET',
- url:"/restconf/config/neutron:neutron/networks/"
+ url:"/restconf/config/neutron:neutron/networks/"
}).then(function successCallback(response) {
- if (callback != undefined) {
+ if (callback != undefined) {
callback(response.data.networks.network);
}
});
};
-
+
return svc;
});
.inner-table {
border: 1px solid;
+ margin-top: 0;
+ margin-bottom: 0;
}
.clickable {
cursor: pointer;
cpeui.register.controller('OpenTenantCtrl', function($scope, CpeuiSvc, CpeuiDialogs, $stateParams) {
$scope.curTenant = $stateParams.tenantid;
-
$scope.unisTables = {};
$scope.unis = [];
$scope.ces = [];
$scope.cesDisplayNames = {};
$scope.unisMap = {};
$scope.networkNames = {};
+ $scope.expandFlags = {
+ ipuni:{},
+ tuni:{}
+ };
+ var tabIndexs = {
+ "L2" : 1,
+ "L3" : 2,
+ "unis" : 3,
+ }
+ if (tabIndexs[$stateParams.tenantTabName]) {
+ $scope.tab.tenantData = tabIndexs[$stateParams.tenantTabName];
+ }
function init(){
$scope.updateUnis(function(unis){
CpeuiSvc.getCes(function(ces) {
$scope.ces = ces.filter(function(item) {
-
- var filteredUnis = unis.filterByField('device', item["dev-id"]);
+
+ var filteredUnis = unis.filterByField('device', item["dev-id"]);
filteredUnis = filteredUnis.filterByField('prettyID', 'br-int', true);
filteredUnis = filteredUnis.filter(function(i){return !(i.prettyID && i.prettyID.startsWith('tun'));});
$scope.updateEvcView();
});
});
-
- CpeuiSvc.getNetworkNames(function(networks){
+
+ CpeuiSvc.getNetworkNames(function(networks){
networks.forEach(function(net){
$scope.networkNames[net.uuid] = net.name;
});
$scope.updateEvcView = function() {
CpeuiSvc.getServices($scope.curTenant, function(services) {
-
+
$scope.evcs = services.filter(function(svc){ return svc.evc != undefined;});
$scope.ipvcs = services.filter(function(svc){ return svc.ipvc != undefined;});
-
$scope.updateUnis();
-
+ console.log($scope.ipvcs);
$scope.ipvcs.forEach(function(e){
- e.isTree = (e.ipvc['ipvc-type'] == 'rooted-multipoint');
+ if (e.ipvc.unis != undefined && e.ipvc.unis.uni != undefined){
+ e.ipvc.unis.uni.forEach(function(u){
+ u.device = u['uni-id'].split(":")[u['uni-id'].split(":").length-2];
+ u.prettyID = u['uni-id'].split(":")[u['uni-id'].split(":").length-1];
+ });
+ }
});
-
$scope.evcs.forEach(function(e){
e.isTree = (e.evc['evc-type'] == 'rooted-multipoint');
e.device2unis = {};
- if (e.evc.unis.uni != undefined){
+ if (e.evc.unis != undefined && e.evc.unis.uni != undefined){
e.evc.unis.uni.forEach(function(u){
if (e.device2unis[$scope.unisMap[u['uni-id']].device] == undefined){
e.device2unis[$scope.unisMap[u['uni-id']].device] = [];
}
- u.prettyID = u['uni-id'].split(":")[u['uni-id'].split(":").length - 1];
+ u.prettyID = u['uni-id'].split(":")[u['uni-id'].split(":").length - 1];
e.device2unis[$scope.unisMap[u['uni-id']].device].push(u);
});
}
});
}, addEvcController);
+ $scope.ipvcDialog = new CpeuiDialogs.Dialog('AddIpvc', {}, function(obj) {
+ CpeuiSvc.addIpvc(obj, $scope.curTenant, function() {
+ $scope.updateEvcView();
+ });
+ });
+
+ $scope.linkIpvcUniDialog = new CpeuiDialogs.Dialog('LinkIpvcUni', {},
+ function(obj) {
+ CpeuiSvc.addIpvcUni(obj.svc_id, obj.uni['uni-id'], obj.ip_uni,
+ function() {
+ $scope.updateEvcView();
+ });
+ });
+
+ var ipUniDialogController = function($scope, $mdDialog) {
+ $scope.hasVlans = false;
+ if ($scope.params.uni['ip-unis'] && $scope.params.uni['ip-unis']['ip-uni']) {
+ var ipunis = $scope.params.uni['ip-unis']['ip-uni'];
+ for (i = 0; i < ipunis.length; i++) {
+ if (ipunis[i].vlan){
+ $scope.hasVlans = true;
+ }
+ }
+ }
+ };
+
+ $scope.ipUniDialog = new CpeuiDialogs.Dialog('AddIpUni', {}, function(obj) {
+ CpeuiSvc.addIpUni(obj['uni-id'], obj['ip-uni-id'], obj['ip-address'], obj.vlan, obj.subnets, function() {
+ $scope.unis.filterByField('uni-id',obj['uni-id'])[0]['ip-unis']['ip-uni'].push(obj);
+ });
+ }, ipUniDialogController);
+
+ $scope.openIpUniDialog = function(event,uni){
+ if (uni['ip-unis'] && (uni['ip-unis']['ip-uni'] != undefined)){
+ var ipunis = uni['ip-unis']['ip-uni'];
+ for (i = 0; i < ipunis.length; i++) {
+ if (!ipunis[i].vlan){
+ CpeuiDialogs.alert("Error","You Can't have more then one ip-uni with no vlan. please remove the non-vlan ip-uni before adding new.")
+ return;
+ }
+ }
+ }
+ $scope.ipUniDialog.show(event,{'uniid':uni['uni-id'], uni:uni})
+ }
+
+ $scope.ipUniSubnetDialog = new CpeuiDialogs.Dialog('AddIpUniSubnet', {}, function(obj) {
+ CpeuiSvc.addIpUniSubnet(obj.uniid, obj.ipuniid, obj.subnet, obj.gateway, function() {
+ CpeuiSvc.getIpUniSubnets(obj.uniid, obj.ipuniid, function(subnets) {
+ $scope.unis.filterByField('uni-id',obj.uniid)[0]['ip-unis']['ip-uni'].filterByField('ip-uni-id',obj.ipuniid)[0].subnets = {subnet:subnets};
+ });
+ });
+ });
+
+ $scope.deleteIpUni = function(uniid, ipuni_id) {
+ CpeuiDialogs.confirm(function() {
+ CpeuiSvc.deleteIpUni(uniid, ipuni_id, function() {
+ $scope.updateEvcView(); // TODO update unis only
+ });
+ });
+ };
+ $scope.deleteIpvcUni = function(svc_id, uni_id) {
+ CpeuiDialogs.confirm(function() {
+ CpeuiSvc.deleteIpvcUni(svc_id, uni_id, function() {
+ $scope.updateEvcView();
+ });
+ });
+ };
+ $scope.getMefInterfaceIpvc = function(uni_id,ipuni_id){
+ var uni = $scope.unis.filterByField('uni-id',uni_id)[0];
+ if ((uni == undefined) || (uni['ip-unis'] == undefined) || (uni['ip-unis']['ip-uni'] == undefined)) {
+ return undefined;
+ }
+ return uni['ip-unis']['ip-uni'].filterByField('ip-uni-id',ipuni_id)[0];
+ }
+
+ $scope.deleteIpUniSubnet = function(uniid, ipuni_id, subnet) {
+ CpeuiDialogs.confirm(function() {
+ CpeuiSvc.deleteIpUniSubnet(uniid, ipuni_id, subnet, function() {
+ $scope.updateEvcView(); // TODO update unis only
+ });
+ });
+ };
+
$scope.deleteEvc = function(svcid) {
CpeuiDialogs.confirm(function() {
CpeuiSvc.removeEvc(svcid, function() {
}
$('#vlan_input').val(undefined);
};
-
+
$scope.filterUsedUnis = function(evc){
- return function(u) {
+ return function(u) {
if (u.prettyID == 'br-int') {
return false;
}
if (u.prettyID && u.prettyID.startsWith('tun')) {
return false;
}
- if (evc.evc.unis.uni == undefined){
- evc.evc.unis.uni = [];
+ if (evc.evc == undefined || evc.evc.unis.uni == undefined){
+ return true;
}
return evc.evc.unis.uni.filterByField('uni-id',u['uni-id']).length == 0;
};
};
$scope.sortIpvc = function(ipvc) {
return ipvc['ipvc-id'];
- };
+ };
init();
});
<div class="menu">
<ul id="EVCs-tab" class="nav nav-pills" role="tablist">
<li ng-class="{ active: isTabSet('tenantData',1)}" ng-click="setTab('tenantData',1)" >
- <a id="evcs-configure-tab" > <i class="icon-tasks"></i> L2 Services</a>
- </li>
- <!-- UnComment to add L3 Services
+ <a id="evcs-configure-tab" href="#/cpeui/tenant/{{curTenant}}/L2"> <i class="icon-tasks"></i> L2 Services</a>
+ </li>
<li ng-class="{ active: isTabSet('tenantData',2)}" ng-click="setTab('tenantData',2)" >
- <a id="evcs-configure-tab" > <i class="icon-tasks"></i> L3 Services</a>
- </li>
- END of UnComment to add L3 Services-->
+ <a id="evcs-configure-tab" href="#/cpeui/tenant/{{curTenant}}/L3" > <i class="icon-tasks"></i> L3 Services</a>
+ </li>
+ <li ng-class="{ active: isTabSet('tenantData',3)}" ng-click="setTab('tenantData',3)" >
+ <a id="evcs-configure-tab" href="#/cpeui/tenant/{{curTenant}}/unis"> <i class="icon-tasks"></i> UNIs</a>
+ </li>
<li id="refresh_btn" class="active refresh-btn" ng-click="updateEvcView()">
<button class="btn add-row"> <i class="icon-refresh"></i> Refresh</button>
</li>
</ul>
</div>
- <div id="EVCsContent" class="tab-content">
+ <div id="EVCsContent" class="tab-content">
<div ng-show="isTabSet('tenantData',1)">
<div class="table-header">EVCs Table</div>
<table class="footable table table-striped">
<thead>
<tr>
- <th>EVC ID</th>
+ <th class="minimal-width">EVC ID</th>
<th>UNIs</th>
<th>Network Name</th>
<th>SVC Type</th>
</thead>
<tbody id="l2_table">
<tr ng-repeat-start="item in evcs | orderBy : sortEvc">
- <td rowspan="{{ 1 + unisTables[item['svc-id']] }}">{{ item.evc['evc-id'] }}</td>
+ <td rowspan="{{ 1 + unisTables[item['svc-id']] }}" class="minimal-width">{{ item.evc['evc-id'] }}</td>
<td >
<button ng-show="!unisTables[item['svc-id']]" class="btn add-row btn-block" ng-click="unisTables[item['svc-id']] = true;">Show Unis</button>
<button ng-show="unisTables[item['svc-id']]" class="btn add-row btn-block" ng-click="unisTables[item['svc-id']] = false;">Hide Unis</button>
<th>Device</th>
<th>UNI</th>
<th ng-if="item.isTree" >Role</th>
- <th>Vlans <span style="font-size:small;color:inherit;"> (click to edit)</span></th>
- <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="linkEvcUniDialog.show($event, {'evc':item,'unis':unis,'ces':ces})"> <i class="icon-plus"></i> </button></th>
+ <th>VLANs <span style="font-size:small;color:inherit;"> (click to edit)</span></th>
+ <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="linkEvcUniDialog.show($event, {'svc':item,'unis':unis,'ces':ces})"> <i class="icon-plus"></i> </button></th>
</tr>
</thead>
<tbody id="l2_table">
</table>
<div><a class="btn btn-info add-row" ng-click="evcDialog.show($event,{'svcTypes':svcTypes})" >Create EVC</a></div>
</div>
- <!-- UnComment to add L3 Services
<div ng-show="isTabSet('tenantData',2)">
<div class="table-header">IPVCs Table</div>
<table class="footable table table-striped">
<thead>
<tr>
- <th>IPVC ID</th>
+ <th class="minimal-width">IPVC ID</th>
<th>UNIs</th>
<th>IPVC Type</th>
<th colspan="2" >Tenant</th>
</thead>
<tbody id="l2_table">
<tr ng-repeat-start="ipvc in ipvcs | orderBy : sortIpvc">
- <td rowspan="{{ 1 + unisTables[ipvc.ipvc['ipvc-id']] }}">{{ ipvc.ipvc['ipvc-id'] }}</td>
+ <td rowspan="{{ 1 + unisTables[ipvc.ipvc['ipvc-id']] }}" class="minimal-width">{{ ipvc.ipvc['ipvc-id'] }}</td>
<td >
<button ng-show="!unisTables[ipvc.ipvc['ipvc-id']]" class="btn add-row btn-block" ng-click="unisTables[ipvc.ipvc['ipvc-id']] = true;">Show Unis</button>
<button ng-show="unisTables[ipvc.ipvc['ipvc-id']]" class="btn add-row btn-block" ng-click="unisTables[ipvc.ipvc['ipvc-id']] = false;">Hide Unis</button>
<tr>
<th>Device</th>
<th>UNI</th>
- <th ng-if="ipvc.isTree" >Role</th>
- <th>Vlans <span style="font-size:small;color:inherit;"> (click to edit)</span></th>
- <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="linkEvcUniDialog.show($event, {'ipvc':ipvc,'unis':unis,'ces':ces})"> <i class="icon-plus"></i> </button></th>
+ <th>IP Address</th>
+ <th>vlan</th>
+ <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="linkIpvcUniDialog.show($event, {'svc':ipvc,'unis':unis,'ces':ces})"> <i class="icon-plus"></i> </button></th>
</tr>
</thead>
<tbody id="l2_table">
- <tr ng-repeat-start="(ce, unis) in ipvc.device2unis | orderBy : ce ">
- <td rowspan="{{unis.length}}">{{ cesDisplayNames[ce] }}</td>
- <td ng-repeat-start="uni in unis | orderBy: sortUni | limitTo :1">{{ uni['uni-id'] }}</td>
- <td ng-if="ipvc.isTree">{{ uni['role'] }}</td>
- <td class="clickable" ng-click="!ipvc.evc['preserve-ce-vlan-id'] ? editVlanDialog.show($event, {svcid:ipvc['svc-id'], uniid:uni['uni-id'], vlans:uni.vlans}) : 0">
- {{ uni.vlans.join(', ') }} {{ipvc.evc['preserve-ce-vlan-id'] ? '(Preserved)' : ''}}
- </td>
- <td ng-repeat-end class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteEvcUni(ipvc['svc-id'], uni['uni-id'])"> <i class="icon-trash"></i> </button></td>
+ <tr ng-repeat="ipuni in ipvc.ipvc.unis.uni">
+ <td ng-init="serviceIpuni = getMefInterfaceIpvc(ipuni['uni-id'],ipuni['ip-uni-id'])">{{ ipuni.device }}</td>
+ <td>{{ ipuni.prettyID }}</td>
+ <td>{{serviceIpuni['ip-address']}}</td>
+ <td>{{serviceIpuni.vlan}}</td>
+ <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpvcUni(ipvc['svc-id'], ipuni['uni-id'])"> <i class="icon-trash"></i> </button></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div><a class="btn btn-info add-row" ng-click="ipvcDialog.show($event,{'svcTypes':svcTypes})" >Create IPVC</a></div>
+ </div>
+ <div ng-show="isTabSet('tenantData',3)">
+ <div class="table-header">Tenant UNIs</div>
+ <table class="footable table table-striped">
+ <thead>
+ <tr>
+ <th class="minimal-width">Device</th>
+ <th class="minimal-width">UNI</th>
+ <th>Ports</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="uni in unis | orderBy: '[\'uni-id\']'">
+ <td class="minimal-width">{{ uni.device }}</td>
+ <td class="minimal-width">{{ uni.prettyID }}</td>
+ <td>
+ <button class="btn btn-info add-row" ng-click="expandFlags.tuni[uni['uni-id']] = false" ng-if="expandFlags.tuni[uni['uni-id']]">
+ <i class="icon-plus"></i> Show Ports
+ </button>
+ <table class="footable table table-striped inner-table" ng-if="!expandFlags.tuni[uni['uni-id']]">
+ <thead>
+ <tr>
+ <th class="minimal-width">
+ <button class="btn btn-info add-row" ng-click="expandFlags.tuni[uni['uni-id']] = true">
+ <i class="icon-minus"></i>
+ </button>
+ </th>
+ <th class="minimal-width">IP UNI ID</th>
+ <th class="minimal-width">VLAN</th>
+ <th class="minimal-width">Address</th>
+ <th>Remote Subnets</th>
+ <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="openIpUniDialog($event,uni)"> <i class="icon-plus"></i> </button></th>
</tr>
- <tr ng-repeat-end ng-repeat="uni in unis | orderBy: sortUni | limitTo :(unis.length-1) :1">
- <td>{{ uni['uni-id'] }}</td>
- <td ng-if="item.isTree">{{ uni['role'] }}</td>
- <td class="clickable" ng-click="!item.evc['preserve-ce-vlan-id'] ? editVlanDialog.show($event, {svcid:ipvc['svc-id'], uniid:uni['uni-id'], vlans:uni.vlans}) : 0">
- {{ uni.vlans.join(', ') }} {{ipvc.evc['preserve-ce-vlan-id'] ? '(Preserved)' : ''}}
+ </thead>
+ <tbody>
+ <tr ng-repeat="ipuni in uni['ip-unis']['ip-uni'] | orderBy: '[\'ip-uni-id\']'">
+ <td colspan="2" class="minimal-width">{{ ipuni['ip-uni-id'] }}</td>
+ <td class="minimal-width">{{ ipuni.vlan }}</td>
+ <td class="minimal-width">{{ ipuni['ip-address'] }}</td>
+ <td>
+ <button class="btn btn-info add-row" ng-click="expandFlags.ipuni[ipuni['ip-uni-id']] = true" ng-if="!expandFlags.ipuni[ipuni['ip-uni-id']]">
+ <i class="icon-plus"></i> Show Subnets
+ </button>
+ <table class="footable table table-striped inner-table" ng-if="expandFlags.ipuni[ipuni['ip-uni-id']]">
+ <thead>
+ <tr>
+ <th class="minimal-width">
+ <button class="btn btn-info add-row" ng-click="expandFlags.ipuni[ipuni['ip-uni-id']] = false">
+ <i class="icon-minus"></i>
+ </button>
+ </th>
+ <th>Subnet</th>
+ <th>Gateway</th>
+ <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="ipUniSubnetDialog.show($event,{uniid:uni['uni-id'],ipuniid:ipuni['ip-uni-id']})"> <i class="icon-plus"></i> </button></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="subnet in ipuni['subnets']['subnet'] | orderBy: subnet">
+ <td colspan="2">{{ subnet.subnet }}</td>
+ <td>{{ subnet.gateway }}</td>
+ <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpUniSubnet(uni['uni-id'],ipuni['ip-uni-id'],subnet.subnet)"> <i class="icon-trash"></i> </button></td>
+ </tr>
+ </tbody>
+ </table>
</td>
- <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteEvcUni(ipvc['svc-id'], uni['uni-id'])"> <i class="icon-trash"></i> </button></td>
- </tr>
+ <td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpUni(uni['uni-id'],ipuni['ip-uni-id'])"> <i class="icon-trash"></i> </button></td>
+ </tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
- <div><a class="btn btn-info add-row" ng-click="evcDialog.show($event,{'svcTypes':svcTypes})" >Create IPVC</a></div>
</div>
- END OF UnComment to add L3 Services -->
</div>
<div class="clear">
<button class="btn btn-default pull-right" onclick="window.location='#/cpeui/admin/tenants'" > Back </button>
$scope.OpenTenantPortal = function(tenant) {
$scope.currentTenent = tenant;
- window.location = "#cpeui/tenant/" + tenant.name;
+ window.location = "#cpeui/tenant/" + tenant.name + "/";
};
$scope.DeleteTenant = function(tenantID) {
container ipvc {\r
container unis {\r
list uni {\r
+ key "uni-id";\r
leaf uni-id {\r
type leafref {\r
path "/mef-interfaces:mef-interfaces/" +\r