Add passthrough attributes 21/100621/3
authorvrvarma <vv8305@att.com>
Wed, 22 Jan 2020 19:05:33 +0000 (14:05 -0500)
committerLukasz Rajewski <lukasz.rajewski@orange.com>
Fri, 24 Jan 2020 14:20:40 +0000 (14:20 +0000)
Added passthrough attributes in placement request.
Current attributes HAS request section changed to
filtering_attributes and new passthrough attributes
added in HAS request - this one is read from vnf policy
passthroughAttributes section.

Change-Id: Ic1e9dcafb0aa0ce5c1b4ddcf35d034d457ac7d48
Signed-off-by: vrvarma <vv8305@att.com>
Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com>
Issue-ID: OPTFRA-611

apps/placement/optimizers/conductor/translation.py
config/has_config.yaml
osdf/models/policy/placement/tosca/vnfPolicy-v20181031.yml
osdf/models/policy/placement/tosca_upload/onap.policies.optimization.VnfPolicy.yaml
test/functest/simulators/build_sim_image.sh
test/placement-tests/request_placement_vfmod.json
test/policy-local-files/vnfPolicy_vFW_TD.json
test/policy-local-files/vnfPolicy_vPGN_TD.json
test/test-requirements.txt
test/test_ConductorApiBuilder.py

index d361755..46bee1d 100644 (file)
 #
 import copy
 import json
 #
 import copy
 import json
-import yaml
 import re
 
 import re
 
-from osdf.utils.data_conversion import text_to_symbol
+import yaml
+
 from osdf.utils.programming_utils import dot_notation
 
 policy_config_mapping = yaml.safe_load(open('config/has_config.yaml')).get('policy_config_mapping')
 from osdf.utils.programming_utils import dot_notation
 
 policy_config_mapping = yaml.safe_load(open('config/has_config.yaml')).get('policy_config_mapping')
@@ -157,7 +157,7 @@ def gen_attribute_policy(vnf_list, attribute_policy):
     cur_policies, related_policies = gen_policy_instance(vnf_list, attribute_policy, rtype=None)
     for p_new, p_main in zip(cur_policies, related_policies):  # add additional fields to each policy
         properties = p_main['content']['cloudAttributeProperty']
     cur_policies, related_policies = gen_policy_instance(vnf_list, attribute_policy, rtype=None)
     for p_new, p_main in zip(cur_policies, related_policies):  # add additional fields to each policy
         properties = p_main['content']['cloudAttributeProperty']
-        attribute_mapping = policy_config_mapping['attributes']  # wanted attributes and mapping
+        attribute_mapping = policy_config_mapping['filtering_attributes']  # wanted attributes and mapping
         p_new[p_main['content']['identity']]['properties'] = {
             'evaluate': dict((k, properties.get(attribute_mapping.get(k))) for k in attribute_mapping.keys())
         }
         p_new[p_main['content']['identity']]['properties'] = {
             'evaluate': dict((k, properties.get(attribute_mapping.get(k))) for k in attribute_mapping.keys())
         }
@@ -231,42 +231,47 @@ def get_demand_properties(demand, policies):
 
         prop.update({'unique': policy_property['unique']} if 'unique' in policy_property and
                                                              policy_property['unique'] else {})
 
         prop.update({'unique': policy_property['unique']} if 'unique' in policy_property and
                                                              policy_property['unique'] else {})
-        prop['attributes'] = dict()
-        prop['attributes'].update({'global-customer-id': policy_property['customerId']}
+        prop['filtering_attributes'] = dict()
+        prop['filtering_attributes'].update({'global-customer-id': policy_property['customerId']}
                                   if policy_property['customerId'] else {})
                                   if policy_property['customerId'] else {})
-        prop['attributes'].update({'model-invariant-id': demand['resourceModelInfo']['modelInvariantId']}
+        prop['filtering_attributes'].update({'model-invariant-id': demand['resourceModelInfo']['modelInvariantId']}
                                   if demand['resourceModelInfo']['modelInvariantId'] else {})
                                   if demand['resourceModelInfo']['modelInvariantId'] else {})
-        prop['attributes'].update({'model-version-id': demand['resourceModelInfo']['modelVersionId']}
+        prop['filtering_attributes'].update({'model-version-id': demand['resourceModelInfo']['modelVersionId']}
                                   if demand['resourceModelInfo']['modelVersionId'] else {})
                                   if demand['resourceModelInfo']['modelVersionId'] else {})
-        prop['attributes'].update({'equipment-role': policy_property['equipmentRole']}
+        prop['filtering_attributes'].update({'equipment-role': policy_property['equipmentRole']}
                                   if policy_property['equipmentRole'] else {})
 
         if policy_property.get('attributes'):
             for attr_key, attr_val in policy_property['attributes'].items():
                                   if policy_property['equipmentRole'] else {})
 
         if policy_property.get('attributes'):
             for attr_key, attr_val in policy_property['attributes'].items():
-                update_converted_attribute(attr_key, attr_val, prop)
+                update_converted_attribute(attr_key, attr_val, prop, 'filtering_attributes')
+        if policy_property.get('passthroughAttributes'):
+            prop['passthrough_attributes'] = dict()
+            for attr_key, attr_val in policy_property['passthroughAttributes'].items():
+                update_converted_attribute(attr_key, attr_val, prop, 'passthrough_attributes')
 
         prop.update(get_candidates_demands(demand))
         demand_properties.append(prop)
     return demand_properties
 
 
 
         prop.update(get_candidates_demands(demand))
         demand_properties.append(prop)
     return demand_properties
 
 
-def update_converted_attribute(attr_key, attr_val, properties):
+def update_converted_attribute(attr_key, attr_val, properties, attribute_type):
     """
     Updates dictonary of attributes with one specified in the arguments.
     Automatically translates key namr from camelCase to hyphens
     """
     Updates dictonary of attributes with one specified in the arguments.
     Automatically translates key namr from camelCase to hyphens
+    :param attribute_type: attribute section name
     :param attr_key: key of the attribute
     :param attr_val: value of the attribute
     :param properties: dictionary with attributes to update
     :return:
     """
     if attr_val:
     :param attr_key: key of the attribute
     :param attr_val: value of the attribute
     :param properties: dictionary with attributes to update
     :return:
     """
     if attr_val:
-        remapping = policy_config_mapping['attributes']
+        remapping = policy_config_mapping[attribute_type]
         if remapping.get(attr_key):
             key_value = remapping.get(attr_key)
         else:
             key_value = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', attr_key)
             key_value = re.sub('([a-z0-9])([A-Z])', r'\1-\2', key_value).lower()
         if remapping.get(attr_key):
             key_value = remapping.get(attr_key)
         else:
             key_value = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', attr_key)
             key_value = re.sub('([a-z0-9])([A-Z])', r'\1-\2', key_value).lower()
-        properties['attributes'].update({key_value: attr_val})
+        properties[attribute_type].update({key_value: attr_val})
 
 
 def gen_demands(req_json, vnf_policies):
 
 
 def gen_demands(req_json, vnf_policies):
index 38a4781..2371508 100644 (file)
@@ -1,5 +1,5 @@
 policy_config_mapping:
 policy_config_mapping:
-    attributes:
+    filtering_attributes:
         hypervisor: hypervisor
         cloudVersion: cloud_version
         cloudType: cloud_type
         hypervisor: hypervisor
         cloudVersion: cloud_version
         cloudType: cloud_type
@@ -19,6 +19,7 @@ policy_config_mapping:
         cloudRegionId: cloud-region-id
         orchestrationStatus: orchestration-status
         provStatus: prov-status
         cloudRegionId: cloud-region-id
         orchestrationStatus: orchestration-status
         provStatus: prov-status
+    passthrough_attributes: {}
     candidates:
         # for (k1, v1), if k1 is in demand, set prop[k2] = _get_candidates(demand[k1])
         excludedCandidates: excluded_candidates
     candidates:
         # for (k1, v1), if k1 is in demand, set prop[k2] = _get_candidates(demand[k1])
         excludedCandidates: excluded_candidates
index 46d8c32..8eaf178 100644 (file)
@@ -69,3 +69,17 @@ data_types:
             unique:
                 type: string
                 required: false
             unique:
                 type: string
                 required: false
+            attributes:
+                type: list
+                required: false
+                entry_schema:
+                    type:policy.data.vnfProperties_filteringAttributes
+            passthroughAttributes:
+                type: list
+                required: false
+                entry_schema:
+                    type:policy.data.vnfProperties_passthroughAttributes
+    policy.data.vnfProperties_filteringAttributes:
+        derived_from: tosca.nodes.Root
+    policy.data.vnfProperties_passthroughAttributes:
+        derived_from: tosca.nodes.Root
index e1ec36d..e242a92 100644 (file)
@@ -73,4 +73,18 @@ data_types:
             unique:
                 type: string
                 required: false
             unique:
                 type: string
                 required: false
+            attributes:
+                type: list
+                required: false
+                entry_schema:
+                    type:policy.data.vnfProperties_filteringAttributes
+            passthroughAttributes:
+                type: list
+                required: false
+                entry_schema:
+                    type:policy.data.vnfProperties_passthroughAttributes
+    policy.data.vnfProperties_filteringAttributes:
+        derived_from: tosca.nodes.Root
+    policy.data.vnfProperties_passthroughAttributes:
+        derived_from: tosca.nodes.Root
 
 
index 8efb273..6d6cb13 100755 (executable)
@@ -32,6 +32,7 @@ cp $SIMULATORS_DIR/Dockerfile $DOCKER_DIR/.
 cp -r $OSDF_DIR/osdf $DOCKER_DIR/sim
 mkdir -p $DOCKER_DIR/sim/config/
 cp $SIMULATORS_DIR/simulated-config/*.yaml $DOCKER_DIR/sim/config/
 cp -r $OSDF_DIR/osdf $DOCKER_DIR/sim
 mkdir -p $DOCKER_DIR/sim/config/
 cp $SIMULATORS_DIR/simulated-config/*.yaml $DOCKER_DIR/sim/config/
+cp $SIMULATORS_DIR/simulated-config/*.yml $DOCKER_DIR/sim/config/
 cp $SIMULATORS_DIR/simulated-config/*.config $DOCKER_DIR/sim/config/
 cp -r $SIMULATORS_DIR/configdb $DOCKER_DIR/sim
 cp -r $SIMULATORS_DIR/has-api $DOCKER_DIR/sim
 cp $SIMULATORS_DIR/simulated-config/*.config $DOCKER_DIR/sim/config/
 cp -r $SIMULATORS_DIR/configdb $DOCKER_DIR/sim
 cp -r $SIMULATORS_DIR/has-api $DOCKER_DIR/sim
index e9f1966..4b2b852 100644 (file)
 {
 {
-    "name": "de4f04e3-0a65-470b-9d07-8ea6c2fb3e10",
-    "template": {
-        "constraints": {
-            "affinity_vFW_TD": {
-                "demands": ["vFW-SINK", "vPGN"],
-                "properties": {
-                    "category": "region",
-                    "qualifier": "same"
-                },
-                "type": "zone"
-            }
-        },
-        "parameters": {
-            "service_name": "vFW_TD",
-            "chosen_region": "RegionOne",
-            "service_id": "3e8d118c-10ca-4b4b-b3db-089b5e9e6a1c",
-            "customer_long": 2.2,
-            "REQUIRED_MEM": "",
-            "customer_lat": 1.1,
-            "REQUIRED_DISK": ""
+  "name": "de4f04e3-0a65-470b-9d07-8ea6c2fb3e10",
+  "files": {},
+  "timeout": 1200,
+  "num_solution": "100",
+  "template": {
+    "homing_template_version": "2017-10-10",
+    "parameters": {
+      "REQUIRED_MEM": "",
+      "REQUIRED_DISK": "",
+      "customer_lat": 1.1,
+      "customer_long": 2.2,
+      "service_name": "vFW_TD",
+      "service_id": "3e8d118c-10ca-4b4b-b3db-089b5e9e6a1c",
+      "chosen_region": "RegionOne"
+    },
+    "locations": {
+      "customer_loc": {
+        "latitude": {
+          "get_param": "customer_lat"
         },
         },
-        "locations": {
-            "customer_loc": {
-                "longitude": {
-                    "get_param": "customer_long"
-                },
-                "latitude": {
-                    "get_param": "customer_lat"
-                }
+        "longitude": {
+          "get_param": "customer_long"
+        }
+      }
+    },
+    "demands": {
+      "vFW-SINK": [
+        {
+          "inventory_provider": "aai",
+          "inventory_type": "vfmodule",
+          "service_type": "vFW-SINK-XX",
+          "service_resource_id": "vFW-SINK-XX",
+          "filtering_attributes": {
+            "global-customer-id": {
+              "get_param": "chosen_customer_id"
+            },
+            "model-invariant-id": "e7227847-dea6-4374-abca-4561b070fe7d",
+            "model-version-id": "763731df-84fd-494b-b824-01fc59a5ff2d",
+            "orchestration-status": [
+              "active"
+            ],
+            "prov-status": "ACTIVE",
+            "cloud-region-id": {
+              "get_param": "chosen_region"
+            },
+            "service_instance_id": {
+              "get_param": "service_id"
             }
             }
-        },
-        "demands": {
-            "vFW-SINK": [{
-                "attributes": {
-                    "global-customer-id": {
-                        "get_param": "chosen_customer_id"
-                    },
-                    "cloud-region-id": {
-                        "get_param": "chosen_region"
-                    },
-                    "model-version-id": "763731df-84fd-494b-b824-01fc59a5ff2d",
-                    "orchestration-status": ["active"],
-                    "model-invariant-id": "e7227847-dea6-4374-abca-4561b070fe7d",
-                    "service_instance_id": {
-                        "get_param": "service_id"
-                    },
-                    "prov-status": "ACTIVE"
-                },
-                "inventory_provider": "aai",
-                "service_resource_id": "vFW-SINK-XX",
-                "inventory_type": "vfmodule",
-                "service_type": "vFW-SINK-XX",
-                "excluded_candidates": [{
-                    "inventory_type": "vfmodule",
-                    "candidate_id": ["e765d576-8755-4145-8536-0bb6d9b1dc9a"]
-                }]
-            }],
-            "vPGN": [{
-                "attributes": {
-                    "global-customer-id": {
-                        "get_param": "chosen_customer_id"
-                    },
-                    "cloud-region-id": {
-                        "get_param": "chosen_region"
-                    },
-                    "model-version-id": "e02a7e5c-9d27-4360-ab7c-73bb83b07e3b",
-                    "orchestration-status": ["active"],
-                    "model-invariant-id": "762472ef-5284-4daa-ab32-3e7bee2ec355",
-                    "service_instance_id": {
-                        "get_param": "service_id"
-                    },
-                    "prov-status": "ACTIVE"
-                },
-                "inventory_provider": "aai",
-                "service_resource_id": "vPGN-XX",
-                "unique": "False",
-                "inventory_type": "vfmodule",
-                "service_type": "vPGN-XX"
-            }]
-        },
-        "optimization": {
-            "minimize": {
-                "sum": []
+          },
+          "passthrough_attributes": {
+            "td-role": "destination"
+          },
+          "excluded_candidates": [
+            {
+              "inventory_type": "vfmodule",
+              "candidate_id": [
+                "e765d576-8755-4145-8536-0bb6d9b1dc9a"
+              ]
             }
             }
-        },
-        "homing_template_version": "2017-10-10"
+          ]
+        }
+      ],
+      "vPGN": [
+        {
+          "inventory_provider": "aai",
+          "inventory_type": "vfmodule",
+          "service_type": "vPGN-XX",
+          "service_resource_id": "vPGN-XX",
+          "unique": "False",
+          "filtering_attributes": {
+            "global-customer-id": {
+              "get_param": "chosen_customer_id"
+            },
+            "model-invariant-id": "762472ef-5284-4daa-ab32-3e7bee2ec355",
+            "model-version-id": "e02a7e5c-9d27-4360-ab7c-73bb83b07e3b",
+            "orchestration-status": [
+              "active"
+            ],
+            "prov-status": "ACTIVE",
+            "cloud-region-id": {
+              "get_param": "chosen_region"
+            },
+            "service_instance_id": {
+              "get_param": "service_id"
+            }
+          },
+          "passthrough_attributes": {
+            "td-role": "anchor"
+          }
+        }
+      ]
+    },
+    "constraints": {
+      "affinity_vFW_TD": {
+        "type": "zone",
+        "demands": [
+          "vFW-SINK",
+          "vPGN"
+        ],
+        "properties": {
+          "category": "region",
+          "qualifier": "same"
+        }
+      }
     },
     },
-    "num_solution": "100",
-    "files": {},
-    "timeout": 1200
-}
+    "optimization": {
+      "minimize": {
+        "sum": []
+      }
+    }
+  }
+}
\ No newline at end of file
index 9a9cbe0..a471a77 100644 (file)
                 "service_instance_id": {
                     "get_param": "service_id"
                 }
                 "service_instance_id": {
                     "get_param": "service_id"
                 }
+            },
+            "passthroughAttributes": {
+                "td-role": "destination"
             }
         }]
     }
             }
         }]
     }
-}
\ No newline at end of file
+}
index 3724f8a..2e79f2f 100644 (file)
@@ -1,42 +1,51 @@
 {
 {
-    "service": "vnfPolicy",
-    "policyName": "OSDF_DUBLIN.vnfPolicy_vPGN_TD",
-    "description": "vnfPolicy",
-    "templateVersion": "OpenSource.version.1",
-    "version": "oofDublin",
-    "priority": "6",
-    "riskType": "test",
-    "riskLevel": "3",
-    "guard": "False",
-    "content": {
-        "identity": "vnf_vPGN_TD",
-        "policyScope": [
-            "td",
-            "us",
-            "vPGN"
-        ],
-        "policyType": "vnfPolicy",
-        "resources": ["vPGN"],
-        "applicableResources": "any",
-        "vnfProperties": [{
-            "inventoryProvider": "aai",
-            "serviceType": "",
-            "inventoryType": "vfmodule",
-            "customerId": {
-                "get_param": "chosen_customer_id"
-            },
-            "equipmentRole": "",
-            "unique": "False",
-            "attributes": {
-                "orchestrationStatus": ["active"],
-                "provStatus": "ACTIVE",
-                "cloudRegionId": {
-                    "get_param": "chosen_region"
-                },
-                "service_instance_id": {
-                    "get_param": "service_id"
-                }
-            }
-        }]
-    }
+  "service": "vnfPolicy",
+  "policyName": "OSDF_DUBLIN.vnfPolicy_vPGN_TD",
+  "description": "vnfPolicy",
+  "templateVersion": "OpenSource.version.1",
+  "version": "oofDublin",
+  "priority": "6",
+  "riskType": "test",
+  "riskLevel": "3",
+  "guard": "False",
+  "content": {
+    "identity": "vnf_vPGN_TD",
+    "policyScope": [
+      "td",
+      "us",
+      "vPGN"
+    ],
+    "policyType": "vnfPolicy",
+    "resources": [
+      "vPGN"
+    ],
+    "applicableResources": "any",
+    "vnfProperties": [
+      {
+        "inventoryProvider": "aai",
+        "serviceType": "",
+        "inventoryType": "vfmodule",
+        "customerId": {
+          "get_param": "chosen_customer_id"
+        },
+        "equipmentRole": "",
+        "unique": "False",
+        "attributes": {
+          "orchestrationStatus": [
+            "active"
+          ],
+          "provStatus": "ACTIVE",
+          "cloudRegionId": {
+            "get_param": "chosen_region"
+          },
+          "service_instance_id": {
+            "get_param": "service_id"
+          }
+        },
+        "passthroughAttributes": {
+          "td-role": "anchor"
+        }
+      }
+    ]
+  }
 }
\ No newline at end of file
 }
\ No newline at end of file
index 043d87a..c8d5613 100644 (file)
@@ -3,3 +3,4 @@ moto
 pytest
 pytest-tap
 requests-mock
 pytest
 pytest-tap
 requests-mock
+pylint
index e69e954..07cb3bb 100644 (file)
@@ -47,7 +47,7 @@ class TestConductorApiBuilder(unittest.TestCase):
         main_dir = self.main_dir
         request_json = self.request_json
         policies = self.policies
         main_dir = self.main_dir
         request_json = self.request_json
         policies = self.policies
-        local_config = yaml.load(open(self.local_config_file))
+        local_config = yaml.safe_load(open(self.local_config_file))
         templ_string = conductor_api_builder(request_json, policies, local_config, self.conductor_api_template)
         templ_json = json.loads(templ_string)
         self.assertEqual(templ_json["name"], "yyy-yyy-yyyy")
         templ_string = conductor_api_builder(request_json, policies, local_config, self.conductor_api_template)
         templ_json = json.loads(templ_string)
         self.assertEqual(templ_json["name"], "yyy-yyy-yyyy")
@@ -55,7 +55,7 @@ class TestConductorApiBuilder(unittest.TestCase):
     def test_conductor_api_call_builder_vfmod(self):
         request_json = self.request_vfmod_json
         policies = self.policies
     def test_conductor_api_call_builder_vfmod(self):
         request_json = self.request_vfmod_json
         policies = self.policies
-        local_config = yaml.load(open(self.local_config_file))
+        local_config = yaml.safe_load(open(self.local_config_file))
         templ_string = conductor_api_builder(request_json, policies, local_config, self.conductor_api_template)
         templ_json = json.loads(templ_string)
         self.assertEqual(templ_json, self.request_placement_vfmod_json)
         templ_string = conductor_api_builder(request_json, policies, local_config, self.conductor_api_template)
         templ_json = json.loads(templ_string)
         self.assertEqual(templ_json, self.request_placement_vfmod_json)