BUG 7171: ACL configuration via GUI Broken 81/48681/3
authorswatideshpande <swati.deshpande@serro.com>
Thu, 24 Nov 2016 18:57:39 +0000 (10:57 -0800)
committerBrady Johnson <brady.allen.johnson@ericsson.com>
Fri, 25 Nov 2016 09:04:09 +0000 (09:04 +0000)
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>
sfc-ui/module/src/main/resources/sfc/acl/acl.classifier.create.tpl.html
sfc-ui/module/src/main/resources/sfc/acl/acl.controller.js
sfc-ui/module/src/main/resources/sfc/acl/acl.create.tpl.html
sfc-ui/module/src/main/resources/sfc/acl/acl.directives.js
sfc-ui/module/src/main/resources/sfc/acl/acl.ip.v6.tpl.html
sfc-ui/module/src/main/resources/sfc/assets/data/locale-en_US.json
sfc-ui/module/src/main/resources/sfc/sfc.controller.js
sfc-ui/module/src/main/resources/sfc/sfc.module.js
sfc-ui/module/src/main/resources/sfc/sfc.services.js

index 9e80a15c84e96a2314ce581438d79dde49dd39a4..264172c623ea75c849ed07b8daebc87612186631 100644 (file)
@@ -28,8 +28,9 @@
                     <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>
index 45fd7f560e3870f6fc9740509767027e9d2db3aa..a8260e6c15c1641387091ddd3d688b937e5e52ee 100644 (file)
@@ -44,6 +44,7 @@ define(['app/sfc/sfc.module'], function (sfc) {
           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);
             });
@@ -84,7 +85,7 @@ define(['app/sfc/sfc.module'], function (sfc) {
       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();
           });
         }
@@ -102,7 +103,8 @@ define(['app/sfc/sfc.module'], function (sfc) {
     };
 
     $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 });
     };
   });
 
@@ -126,8 +128,8 @@ define(['app/sfc/sfc.module'], function (sfc) {
       $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 {
@@ -256,7 +258,16 @@ define(['app/sfc/sfc.module'], function (sfc) {
 
   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) {
@@ -302,4 +313,4 @@ define(['app/sfc/sfc.module'], function (sfc) {
       $modalInstance.dismiss('ok');
     };
   });
-});
\ No newline at end of file
+});
index c487996c5ea8c238b814a074ee3ab4c61e6d051f..f28af9f17d3eb1da4702eda7f8367b0373f9c962 100644 (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>
@@ -34,7 +48,7 @@
 
             <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>
index 4f77d4e1457db52babb8cac6c9e7c5a25ada51ab..a482012bdc3a84c8a3dc66147c8c09a3dbb6f4e0 100644 (file)
@@ -69,6 +69,7 @@ define(['app/sfc/sfc.module'], function (sfc) {
             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);
           }
         });
@@ -93,6 +94,7 @@ define(['app/sfc/sfc.module'], function (sfc) {
           if (arg != $scope.notResetCondition) {
             delete $scope['matches']['destination-ipv4-network'];
             delete $scope['matches']['source-ipv4-network'];
+            delete $scope['matches']['protocol'];
           }
         });
       }
@@ -117,6 +119,7 @@ define(['app/sfc/sfc.module'], function (sfc) {
             delete $scope['matches']['destination-ipv6-network'];
             delete $scope['matches']['source-ipv6-network'];
             delete $scope['matches']['flow-label'];
+            delete $scope['matches']['protocol'];
           }
         });
       }
@@ -237,4 +240,4 @@ define(['app/sfc/sfc.module'], function (sfc) {
     };
   });
 
-});
\ No newline at end of file
+});
index 6f0e9946cd8a6c6266c685472675a2c30110e25f..4947c7f3b633c071bf19ca0eeed8f8c9ac38f386 100644 (file)
@@ -5,10 +5,10 @@
         </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>
 
@@ -18,7 +18,7 @@
         </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}">
@@ -37,4 +37,4 @@
                    number-range="{from:0, to:1048575}">
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
index 2c884824e812a308fef9ba2c1ac15e8c439a6e54..04514b28adc72742e5bfdd3fd20ba78808bcac86 100644 (file)
     "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
index 836bac36cfa34d156476098e0ac877a8449fb1ab..753ed73aaba9d73b377f5db15ed90d13988be375 100644 (file)
@@ -100,7 +100,8 @@ define([].concat(modules).concat(services).concat(directives).concat(controllers
     $rootScope.aclConstants =
     {
       "ace-type": ["ip", "eth", "ipfix"],
-      "ace-ip": ["IPv4", "IPv6"]
+      "ace-ip": ["IPv4", "IPv6"],
+      "acl-type": ["IPv4", "IPv6", "eth"]  
     };
 
     $rootScope.classifierConstants =
@@ -149,10 +150,6 @@ define([].concat(modules).concat(services).concat(directives).concat(controllers
             {
               "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"
               }
@@ -279,4 +276,4 @@ define([].concat(modules).concat(services).concat(directives).concat(controllers
       }
     };
   });
-});
\ No newline at end of file
+});
index 061b8771da2c1b801568e25b628265c636256cb2..c50891567e06b93c0dfe3f95db73bf5ef8b2f383 100644 (file)
@@ -454,7 +454,7 @@ define([
     });\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
index 0960684fa39aa5b611942c95fb4422c2717cdb48..80039d3030fdcb26f1aadf0980516fb1f7696999 100644 (file)
@@ -1070,6 +1070,42 @@ define(['app/sfc/sfc.module'], function (sfc) {
       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);
 
@@ -1094,18 +1130,62 @@ define(['app/sfc/sfc.module'], function (sfc) {
       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