The current yang model for ACLs is ietf-access-control-list(2016-02-18).
sfc-ui, is constructing ACL requests as per
ietf-acces-control-list(2015-03-17)causing breakage.
The acl key has changed from "acl-name" to "acl-type acl-name",
in Rev 2016-02-18.
Fix done in sfc-ui module for acl key change as well as schema change
for all ietf-access-list config requests.
Input box added to "Create Access List" screen for configuring ACL Type.
Fix added for service-classifier requests to adhere to yang model Rev
service-function-classifier(2014-07-01)
Change-Id: I7947047d1cf08fbb8104f040de04d786e9faefa1
Signed-off-by: swatideshpande <swati.deshpande@serro.com>
<div class="col-lg-6">
<select class="form-control input-sm" id="access-list" name="access-list"
ui-select2="{allowClear: true}"
- ng-model="data['access-list']"
+ ng-model="data['acl']['name']"
ng-required="false"
+ ng-change="setAclType(data['acl']['name'])"
data-placeholder="{{'SFC_CLASSIFIER_CREATE_ACCESS_LIST' | translate}}">
<option value=""></option>
if (!_.isEmpty(acl['access-list-entries']['ace'])) {
_.each(acl['access-list-entries']['ace'], function (entry) {
entry['acl-name'] = acl['acl-name'];
+ entry['acl-type'] = acl['acl-type'];
$scope.acls.push(entry);
thisCtrl.stringifyComposedProperties(entry);
});
ModalDeleteSvc.open(ace['acl-name'], function (result) {
if (result == 'delete') {
//delete the row
- SfcAclSvc.deleteItemByKey(ace['acl-name'], function () {
+ SfcAclSvc.deleteItemByKey(ace['acl-type'], ace['acl-name'], function () {
thisCtrl.fetchData();
});
}
};
$scope.editItem = function editItem(ace) {
- $state.transitionTo('main.sfc.acl-edit', {itemKey: ace['acl-name']}, { location: true, inherit: true, relative: $state.$current, notify: true });
+ $state.transitionTo('main.sfc.acl-edit',{itemKeyType: ace['acl-type'], itemKey: ace['acl-name']},
+ { location: true, inherit: true, relative: $state.$current, notify: true });
};
});
$scope.appid = data.sort(function(a, b) { return a['selector-id'] - b['selector-id']; }); // sort by id
});
- if ($stateParams.itemKey) {
- SfcAclSvc.getItem($stateParams.itemKey, function (item) {
+ if ($stateParams.itemKey && $stateParams.itemKeyType) {
+ SfcAclSvc.getItem($stateParams.itemKeyType + '/' + $stateParams.itemKey, function (item) {
$scope.data = item;
});
} else {
sfc.register.controller('sfcClassifierCreateCtrl', function ($scope, $rootScope, $state, $stateParams, SfcClassifierSvc, SfcClassifierHelper, SfcAclSvc, ServicePathSvc, ServiceForwarderSvc){
- $scope.data = {'scl-service-function-forwarder': []};
+ $scope.data = {'scl-service-function-forwarder': [],'acl':{}};
+
+ $scope.setAclType = function(aclName){
+ var arr = $scope.acls.filter(function(acl) {
+ return acl['acl-name'] === aclName;
+ });
+ if(arr.length > 0) {
+ $scope.data['acl']['type'] = arr[0]['acl-type'];
+ }
+ }
if ($stateParams.itemKey) {
SfcClassifierSvc.getItem($stateParams.itemKey, function (item) {
$modalInstance.dismiss('ok');
};
});
-});
\ No newline at end of file
+});
</div>
</div>
</div>
+ <div class="formElement">
+ <div class="form-group" show-validation-error>
+ <label for="acl-type" class="col-lg-6 control-label small-label">{{'SFC_ACL_TYPE' | translate}}
+ </label>
+ <div class="col-lg-6">
+ <select class="form-control input-sm" id="acl-type" ui-select2="{allowClear: true}"
+ ng-model="data['acl-type']" ng-required="true" data-placeholder="{{'SFC_ACL_CREATE_ACE_TYPE' | translate}}"
+ ng-change="$broadcast('acl_type_change', data['acl-type'])">
+ <option value=""></option>
+ <option ng-repeat="t in aclConstants['acl-type']" value="{{t}}">{{t}}</option>
+ </select>
+ </div>
+ </div>
+ </div>
</div>
<div class="col-md-6"></div>
<div class="col-md-12"
sfc-watch-for-reinit="ace"
- ng-init="ace['matches']= (ace['matches'] || {}); ace['matches']['absolute-time']= (ace['matches']['absolute-time'] || {});
+ ng-init="ace['matches']= (ace['matches'] || {});
ace['actions']= (ace['actions'] || {}); ace_type = valueOfAceType(ace['matches']); ">
<div style="text-align: right; margin-bottom: 10px">
<span class="spanTip">{{ 'SFC_ACL_ACE_REMOVE' | translate }}</span>
</div>
</div>
- <div class="form-group" show-validation-error>
+ <!--<div class="form-group" show-validation-error>
<label for="metadata-absolute-start_{{$index}}" class="col-lg-6 control-label small-label">{{'SFC_ACL_METADATA_ABSOLUTE_START'
| translate}}</label>
placeholder="{{'SFC_ACL_CREATE_METADATA_ABSOLUTE_START' | translate}}"
date-and-time>
</div>
- </div>
+ </div> -->
- <div class="form-group" show-validation-error>
+ <!-- <div class="form-group" show-validation-error>
<label for="metadata-absolute-end_{{$index}}" class="col-lg-6 control-label small-label">{{'SFC_ACL_METADATA_ABSOLUTE_END'
| translate}}</label>
placeholder="{{'SFC_ACL_CREATE_METADATA_ABSOLUTE_END' | translate}}"
date-and-time>
</div>
- </div>
+ </div> -->
- <div class="form-group">
+ <!-- <div class="form-group">
<label class="col-lg-6 control-label small-label"
ui-select2-label="metadata-absolute-active_{{$index}}">
{{'SFC_ACL_METADATA_ABSOLUTE_ACTIVE' | translate}}
<option value="false">{{'SFC_FALSE' | translate}}</option>
</select>
</div>
- </div>
+ </div> -->
</div>
ng-model="ace_type" ng-required="false"
data-placeholder="{{'SFC_ACL_CREATE_ACE_TYPE' | translate}}"
ng-change="$broadcast('ace_type_change', ace_type)">
-
<option value=""></option>
<option ng-repeat="t in aclConstants['ace-type']" value="{{t}}">{{t}}</option>
</select>
<button-cancel type="button" state="main.sfc.acl"></button-cancel>
<span class="error clearfix">{{ error }}</span>
</div>
-</form>
\ No newline at end of file
+</form>
delete $scope['matches']['source-port-range'];
delete $scope['matches']['destination-ipv4-network'];
delete $scope['matches']['source-ipv4-network'];
+ delete $scope['matches']['protocol'];
$scope.$broadcast('ace_ip_change', null);
}
});
if (arg != $scope.notResetCondition) {
delete $scope['matches']['destination-ipv4-network'];
delete $scope['matches']['source-ipv4-network'];
+ delete $scope['matches']['protocol'];
}
});
}
delete $scope['matches']['destination-ipv6-network'];
delete $scope['matches']['source-ipv6-network'];
delete $scope['matches']['flow-label'];
+ delete $scope['matches']['protocol'];
}
});
}
};
});
-});
\ No newline at end of file
+});
</label>
<div class="col-lg-6">
- <input type="text" class="form-control input-sm" ng-model="matches['source-ipv6-address']"
+ <input type="text" class="form-control input-sm" ng-model="matches['source-ipv6-network']"
id="acl_source_ipv6_add{{idSuffix}}" name="source-ipv6-address"
placeholder="{{'SFC_ACL_CREATE_SOURCE_IPV6_ADDRESS' | translate}}"
- ip-address="{version:6, prefix:false}">
+ ip-address="{version:6, prefix:true}">
</div>
</div>
</label>
<div class="col-lg-6">
- <input type="text" class="form-control input-sm" ng-model="matches['destination-ipv6-address']"
+ <input type="text" class="form-control input-sm" ng-model="matches['destination-ipv6-network']"
id="acl_dest_ipv6_add{{idSuffix}}" name="destination-ipv6-address"
placeholder="{{'SFC_ACL_CREATE_DESTINATION_IPV6_ADDRESS' | translate}}"
ip-address="{version:6, prefix:true}">
number-range="{from:0, to:1048575}">
</div>
</div>
-</div>
\ No newline at end of file
+</div>
"SFC_ACL_ACE_ADD": "Add Access List entry",\r
"SFC_ACL_ACE_REMOVE": "Remove this Access List entry",\r
"SFC_ACL_NAME": "Access List name",\r
+ "SFC_ACL_TYPE": "Access List type",\r
"SFC_ACL_CREATE_NAME": "Type in a name",\r
"SFC_ACL_ACE": "Access List entries",\r
"SFC_ACL_RULE_NAME": "Entry name",\r
"SFC_ACL_DSCP": "Differentiated Services Code-Point (DSCP)",\r
"SFC_ACL_CREATE_DSCP": "Number in range 0-63",\r
"SFC_ACL_IP_PROTOCOL": "IP protocol number",\r
- "SFC_ACL_CREATE_IP_PROTOCOL": "Number in range 0-255 (TCP=7, UDP=17)",\r
+ "SFC_ACL_CREATE_IP_PROTOCOL": "Number in range 0-255 (TCP=6, UDP=17)",\r
"SFC_ACL_ACE_IP_VERSION": "IP version",\r
"SFC_ACL_CREATE_ACE_IP_VERSION": "Select a version",\r
"SFC_ACL_DESTINATION_IPV4_ADDRESS": "Destination IPv4 address/network",\r
"SFC_ACL_CREATE_SOURCE_IPV4_ADDRESS": "Example: 10.0.0.1/8",\r
"SFC_ACL_DESTINATION_IPV6_ADDRESS": "Destination IPv6 address/network",\r
"SFC_ACL_CREATE_DESTINATION_IPV6_ADDRESS": "Example: 2001:0db8::1428:57ab/64",\r
- "SFC_ACL_SOURCE_IPV6_ADDRESS": "Source IPv6 address",\r
- "SFC_ACL_CREATE_SOURCE_IPV6_ADDRESS": "Example: 2001:0db8::1428:57ab",\r
+ "SFC_ACL_SOURCE_IPV6_ADDRESS": "Source IPv6 address/network",\r
+ "SFC_ACL_CREATE_SOURCE_IPV6_ADDRESS": "Example: 2001:0db8::1428:57ab/64",\r
"SFC_ACL_FLOW_LABEL": "IPv6 Flow label",\r
"SFC_ACL_CREATE_FLOW_LABEL": "Number in range 0-1048575",\r
"SFC_ACL_DESTINATION_MAC_ADDRESS": "Destination MAC address",\r
$rootScope.aclConstants =
{
"ace-type": ["ip", "eth", "ipfix"],
- "ace-ip": ["IPv4", "IPv6"]
+ "ace-ip": ["IPv4", "IPv6"],
+ "acl-type": ["IPv4", "IPv6", "eth"]
};
$rootScope.classifierConstants =
{
"rule-name": "ACE1",
"matches": {
- "absolute-time": {
- "active": true
- },
- "protocol": 7,
"source-ipv4-network": "11.11.11.0/24",
"destination-ipv4-network": "22.22.22.0/24"
}
}
};
});
-});
\ No newline at end of file
+});
});\r
\r
$stateProvider.state('main.sfc.acl-edit', {\r
- url: '/acl-edit-:itemKey',\r
+ url: '/acl-edit-:itemKeyType-:itemKey',\r
access: access.public,\r
views: {\r
'sfc': {\r
this['subListName'] = "access-list-entry";
this['subListKeyName'] = "rule-name";
}
+ //utility function
+ function getAclType(aclTypeKey) {
+ var acltype;
+
+ /* This function returns the aclType as per
+ * ietf-access-control-list(2016-02-18) yang model
+ * If the aclTypeKye is set by user input on create form,
+ * it would have value IPv4/Ipv6/eth.
+ * If its fetched from controller, it would have value,
+ * "ietf-access-control-list:xxx"
+ */
+ switch (aclTypeKey) {
+ case "IPv4":
+ acltype = "ietf-access-control-list:ipv4-acl";
+ break;
+ case "IPv6":
+ acltype = "ietf-access-control-list:ipv6-acl";
+ break;
+ case "eth":
+ acltype = "ietf-access-control-list:eth-acl";
+ break;
+ case "ietf-access-control-list:ipv4-acl":
+ acltype = aclTypeKey;
+ break;
+ case "ietf-access-control-list:ipv6-acl":
+ acltype = aclTypeKey;
+ break;
+ case "ietf-access-control-list:eth-acl":
+ acltype = aclTypeKey;
+ break;
+ default:
+ acltype = "unknown";
+ break;
+ }
+ return acltype;
+ }
SfcAclSvc.prototype = new SfcRestBaseSvc(modelUrl, containerName, listName);
return aclArray;
};
+ //@override
+ SfcAclSvc.prototype.getItem = function (key, callback) {
+ var instance = this; // save 'this' to closure
+ var keycomp = key.split('/');
+ key = getAclType(keycomp[0]) + '/' + keycomp[1];
+
+ this.getOne(key).then(function (result) {
+ var stripped = instance.stripNamespacePrefixes(result[instance.listName]);
+ callback(stripped[0]); // return only nested object
+ }, /* on error*/ function (response) {
+
+ if (response.status = "404") {
+ console.log("No data, returning empty item");
+ } else {
+ console.error("Error with status code ", response.status);
+ }
+
+ callback({}); // return empty item
+ });
+ };
+
+ //@override
+ SfcAclSvc.prototype.getOne = function (key) {
+ var keycomp = key.split('/');
+ return this.baseRest().customGET(this.modelUrl + ":" + this.containerName + '/' + this.listName + '/' +
+ encodeURIComponent(keycomp[0]) + '/' + encodeURIComponent(keycomp[1]));
+ };
+ // @override
+ SfcAclSvc.prototype.put = function (elem, key) {
+ var elemcopy = {};
+ var keycomp = key.split('/');
+ angular.copy(elem, elemcopy);
+ elemcopy[this.listName]['acl-type'] = keycomp[0];
+ return this.baseRest().customPUT(elemcopy, this.modelUrl + ':' + this.containerName + '/' + this.listName + '/' +
+ encodeURIComponent(keycomp[0]) + '/' + encodeURIComponent(keycomp[1]));
+ };
// @override
SfcAclSvc.prototype.getListKeyFromItem = function (itemData) {
- return itemData['acl-name'];
+ var acltype = getAclType(itemData['acl-type']);
+ return acltype + '/' + itemData['acl-name'];
};
- SfcAclSvc.prototype.deleteItemByKey = function (itemKey, callback) {
+ SfcAclSvc.prototype.deleteItemByKey = function (itemKeyType, itemKey, callback) {
var item = {};
item['acl-name'] = itemKey;
+ item['acl-type'] = itemKeyType;
this.deleteItem(item, callback);
};
+ //@override
+ SfcAclSvc.prototype._delete = function (key) {
+ var keycomp = key.split('/');
+ return this.baseRest().customDELETE(this.modelUrl + ':' + this.containerName + '/' + this.listName + '/' +
+ encodeURIComponent(keycomp[0]) + '/' + encodeURIComponent(keycomp[1]));
+ };
// sub item functions