diff options
Diffstat (limited to 'onap-client')
8 files changed, 328 insertions, 118 deletions
diff --git a/onap-client/onap_client/etc/payloads/add_vsp_contributer.jinja b/onap-client/onap_client/etc/payloads/add_vsp_contributer.jinja index ac75634..2ab8f3b 100644 --- a/onap-client/onap_client/etc/payloads/add_vsp_contributer.jinja +++ b/onap-client/onap_client/etc/payloads/add_vsp_contributer.jinja @@ -1 +1,5 @@ -{"removedUsersIds":[],"addedUsersIds":["{{user_id}}"]}
\ No newline at end of file +{% if user_id is string %} +{"removedUsersIds":[],"addedUsersIds":["{{user_id}}"]} +{% else %} +{"removedUsersIds":[],"addedUsersIds": {{user_id|tojson}} } +{% endif %} diff --git a/onap-client/onap_client/etc/payloads/catalog_vnf_input_single.jinja b/onap-client/onap_client/etc/payloads/catalog_vnf_input_single.jinja new file mode 100644 index 0000000..e883489 --- /dev/null +++ b/onap-client/onap_client/etc/payloads/catalog_vnf_input_single.jinja @@ -0,0 +1,22 @@ +{ +"defaultValue": "{{input_default_value}}", +"description": null, +"name": "{{input_name}}", +"parentUniqueId": "{{input_parent_unique_id}}", +"password": false, +"required": false, +"schema": { + "property": {} +}, +"type": "string", +"uniqueId": "{{input_unique_id}}", +"value": null, +"definition": false, +"getInputValues": null, +"instanceUniqueId": null, +"propertyId": null, +"properties": null, +"inputs": null, +"ownerId": "{{input_owner_id}}", +"inputPath": null +} diff --git a/onap-client/onap_client/etc/payloads/catalog_vnf_policy_property_single.jinja b/onap-client/onap_client/etc/payloads/catalog_vnf_policy_property_single.jinja new file mode 100644 index 0000000..5d54c9a --- /dev/null +++ b/onap-client/onap_client/etc/payloads/catalog_vnf_policy_property_single.jinja @@ -0,0 +1,22 @@ +{ +"defaultValue": null, +"description": "{{description}}", +"name": "{{property_name}}", +"parentUniqueId": null, +"password": false, +"required": true, +"schema": { + "property": {} +}, +"schemaType": null, +"type": "{{property_type}}", +"uniqueId": "{{unique_id}}", +"value": "{{property_default_value}}", +"definition": true, +"getInputValues": null, +"parentPropertyType": null, +"subPropertyInputPath": null, +"getPolicyValues": null, +"inputPath": null, +"ownerId": null +} diff --git a/onap-client/onap_client/etc/payloads/catalog_vnf_property_single.jinja b/onap-client/onap_client/etc/payloads/catalog_vnf_property_single.jinja new file mode 100644 index 0000000..bcdfb86 --- /dev/null +++ b/onap-client/onap_client/etc/payloads/catalog_vnf_property_single.jinja @@ -0,0 +1,18 @@ +{ +"constraints": [], +"name": "{{property_name}}", +"parentUniqueId": "{{parent_unique_id}}", +"password": false, +"required": false, +"schema": {"property": {}}, +{% if schema_type != "" %} +"schemaType": "{{schema_type}}", +{% endif %} +"type": "{{property_type}}", +"uniqueId": "{{unique_id}}", +"value": "{{property_default_value}}", +"definition": false, +"toscaPresentation": { + "ownerId": "{{owner_id}}" +} +} diff --git a/onap-client/onap_client/lib.py b/onap-client/onap_client/lib.py index 02641ce..32f5ef5 100644 --- a/onap-client/onap_client/lib.py +++ b/onap-client/onap_client/lib.py @@ -52,15 +52,19 @@ def make_request(catalog_item, attempts, verify_request, **kwargs): :return: ResponseHandler object with response data from request """ - request_input = validate_request(catalog_item, kwargs) - - catalog_request = APICatalogRequestObject(catalog_item, **request_input,) + catalog_request = get_request_object(catalog_item, **kwargs) request_handler = RequestHandler(catalog_request) return request_handler.make_request(attempts, verify_request) +def get_request_object(catalog_item, **kwargs): + request_input = validate_request(catalog_item, kwargs) + + return APICatalogRequestObject(catalog_item, **request_input) + + def validate_request(catalog_item, kwargs): request_input = {} diff --git a/onap-client/onap_client/sdc/catalog/vnf_catalog.py b/onap-client/onap_client/sdc/catalog/vnf_catalog.py index 8d0ad32..a5ae09b 100644 --- a/onap-client/onap_client/sdc/catalog/vnf_catalog.py +++ b/onap-client/onap_client/sdc/catalog/vnf_catalog.py @@ -104,7 +104,7 @@ class VNFCatalog(SDCClient): endpoint=self.config.sdc.SDC_BE_ENDPOINT, service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, ), - "payload": "{}/catalog_vnf_input.jinja".format(self.config.payload_directory), + "payload": "{}/catalog_vnf_input_single.jinja".format(self.config.payload_directory), "payload-parameters": [ "input_default_value", "input_name", @@ -122,6 +122,28 @@ class VNFCatalog(SDCClient): }, "auth": self.auth, }, + "ADD_CATALOG_RESOURCE_INPUT_MULTI": { + "verb": "POST", + "description": "Adds an input value for a VNF", + "uri": partial( + "{endpoint}{service_path}/{catalog_resource_id}/update/inputs".format, + endpoint=self.config.sdc.SDC_BE_ENDPOINT, + service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, + ), + "payload": "{}/generic_payload.jinja".format(self.config.payload_directory), + "payload-parameters": [ + "payload_data", + ], + "uri-parameters": ["catalog_resource_id"], + "success_code": 200, + "headers": { + "Accept": "application/json", + "Content-Type": "application/json", + "USER_ID": self.sdc_designer_user_id, + "X-FromAppId": self.config.application_id, + }, + "auth": self.auth, + }, "UPDATE_CATALOG_RESOURCE": { "verb": "PUT", "description": "Creates a new version of a VF resource", @@ -168,7 +190,7 @@ class VNFCatalog(SDCClient): endpoint=self.config.sdc.SDC_BE_ENDPOINT, service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, ), - "payload": "{}/catalog_vnf_property.jinja".format(self.config.payload_directory), + "payload": "{}/catalog_vnf_property_single.jinja".format(self.config.payload_directory), "payload-parameters": [ "unique_id", "parent_unique_id", @@ -188,6 +210,26 @@ class VNFCatalog(SDCClient): }, "auth": self.auth, }, + "ADD_CATALOG_RESOURCE_PROPERTY_MULTI": { + "verb": "POST", + "description": "Adds an property value for a VNF", + "uri": partial( + "{endpoint}{service_path}/{catalog_resource_id}/resourceInstance/{catalog_resource_instance_id}/inputs".format, + endpoint=self.config.sdc.SDC_BE_ENDPOINT, + service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, + ), + "payload": "{}/generic_payload.jinja".format(self.config.payload_directory), + "payload-parameters": ["payload_data"], + "uri-parameters": ["catalog_resource_id", "catalog_resource_instance_id"], + "success_code": 200, + "headers": { + "Accept": "application/json", + "Content-Type": "application/json", + "USER_ID": self.sdc_designer_user_id, + "X-FromAppId": self.config.application_id, + }, + "auth": self.auth, + }, "ADD_CATALOG_RESOURCE_PROPERTY_NON_VF": { "verb": "POST", "description": "Adds an property value for a VNF", @@ -196,7 +238,7 @@ class VNFCatalog(SDCClient): endpoint=self.config.sdc.SDC_BE_ENDPOINT, service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, ), - "payload": "{}/catalog_vnf_property.jinja".format(self.config.payload_directory), + "payload": "{}/catalog_vnf_property_single.jinja".format(self.config.payload_directory), "payload-parameters": [ "unique_id", "parent_unique_id", @@ -216,6 +258,28 @@ class VNFCatalog(SDCClient): }, "auth": self.auth, }, + "ADD_CATALOG_RESOURCE_PROPERTY_NON_VF_MULTI": { + "verb": "POST", + "description": "Adds an property value for a VNF", + "uri": partial( + "{endpoint}{service_path}/{catalog_resource_id}/resourceInstance/{catalog_resource_instance_id}/properties".format, + endpoint=self.config.sdc.SDC_BE_ENDPOINT, + service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, + ), + "payload": "{}/generic_payload.jinja".format(self.config.payload_directory), + "payload-parameters": [ + "payload_data", + ], + "uri-parameters": ["catalog_resource_id", "catalog_resource_instance_id"], + "success_code": 200, + "headers": { + "Accept": "application/json", + "Content-Type": "application/json", + "USER_ID": self.sdc_designer_user_id, + "X-FromAppId": self.config.application_id, + }, + "auth": self.auth, + }, "ADD_CATALOG_RESOURCE_POLICY": { "verb": "POST", "description": "Adds an policy resource to a VNF", @@ -262,7 +326,7 @@ class VNFCatalog(SDCClient): service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, ), "uri-parameters": ["catalog_resource_id", "catalog_policy_id"], - "payload": "{}/catalog_vnf_policy_property.jinja".format(self.config.payload_directory), + "payload": "{}/catalog_vnf_policy_property_single.jinja".format(self.config.payload_directory), "payload-parameters": [ "unique_id", "property_name", @@ -279,6 +343,28 @@ class VNFCatalog(SDCClient): }, "auth": self.auth, }, + "ADD_CATALOG_POLICY_PROPERTY_MULTI": { + "verb": "PUT", + "description": "Adds a property to a policy for a VNF", + "uri": partial( + "{endpoint}{service_path}/{catalog_resource_id}/policies/{catalog_policy_id}/properties".format, + endpoint=self.config.sdc.SDC_BE_ENDPOINT, + service_path=self.config.sdc.SDC_CATALOG_RESOURCES_PATH, + ), + "uri-parameters": ["catalog_resource_id", "catalog_policy_id"], + "payload": "{}/generic_payload.jinja".format(self.config.payload_directory), + "payload-parameters": [ + "payload_data", + ], + "success_code": 200, + "headers": { + "Accept": "application/json", + "Content-Type": "application/json", + "USER_ID": self.sdc_designer_user_id, + "X-FromAppId": self.config.application_id, + }, + "auth": self.auth, + }, "ADD_CATALOG_RESOURCE_GROUP": { "verb": "POST", "description": "Adds an group resource to a VNF", diff --git a/onap-client/onap_client/sdc/vnf.py b/onap-client/onap_client/sdc/vnf.py index 4f7e4d7..83df9f6 100644 --- a/onap-client/onap_client/sdc/vnf.py +++ b/onap-client/onap_client/sdc/vnf.py @@ -34,7 +34,7 @@ # limitations under the License. # # ============LICENSE_END============================================ -from onap_client.lib import generate_dummy_string +from onap_client.lib import generate_dummy_string, get_request_object from onap_client.resource import Resource from onap_client import exceptions from onap_client.client.clients import get_client as Client @@ -44,6 +44,7 @@ from onap_client.util import utility import time import random import json +import copy class VNF(Resource): @@ -152,13 +153,20 @@ class VNF(Resource): instance_ids = instance_ids_for_property(model, "vm_type_tag", vm_type_tag) x = 0 for instance_id in instance_ids: + payloads = [] name_index = "" if x > 0: name_index = x vm_type_instances.append(instance_id) - self._add_instance_properties(instance_id, properties) + payloads.extend(self._get_instance_properties_payloads(instance_id, properties)) + payloads.extend(self._get_vm_type_network_role_payloads(instance_id, network_roles)) + if payloads: + self.oc.sdc.vnf.add_catalog_resource_property_multi( + **self.attributes, + catalog_resource_instance_id=instance_id, + payload_data=json.dumps(payloads) + ) self._add_resources(instance_id, resources, resource_name_index=name_index) - self._add_vm_type_network_role(instance_id, network_roles) x += 1 for policy in policies: @@ -172,11 +180,27 @@ class VNF(Resource): policy_id = self.add_policy_resource(policy_name) self.associate_policy(policy_id, vm_type_instances) + policy_payloads = [] + for k, v in policy.get("properties", {}).items(): - self.add_policy_property(policy_id, k, v) + policy_payloads.append(self.get_policy_property_payloads(policy_id, k, v)) + if len(policy_payloads): + self.oc.sdc.vnf.add_catalog_policy_property_multi( + **self.attributes, + catalog_policy_id=policy_id, + payload_data=json.dumps(policy_payloads) + ) + + input_payloads = [] for k, v in inputs.items(): - self.add_input_value(k, v) + input_payloads.append(self.get_input_payload(k, v)) + + if len(input_payloads): + self.oc.sdc.vnf.add_catalog_resource_input_multi( + **self.attributes, + payload_data=json.dumps(input_payloads) + ) def _submit(self): """Submits the vnf in SDC""" @@ -192,10 +216,11 @@ class VNF(Resource): self.oc.cache("vnf", self.vnf_name, "tosca", self.tosca) - def _add_instance_properties(self, instance_id, properties_dict): + def _get_instance_properties_payloads(self, instance_id, properties_dict): + payloads = [] for k, v in properties_dict.items(): - # updating vm_type properties - self.add_instance_property(instance_id, k, v) + payloads.append(self.get_instance_property_payload(instance_id, k, v)) + return payloads def _add_resources(self, instance_id, resources_dict, resource_name_index=""): for resource in resources_dict: @@ -227,8 +252,17 @@ class VNF(Resource): relationship_requirement = resource_relationship.get("requirement") relationship_requirement_id = resource_relationship.get("requirement_id") self.add_resource_relationship(new_resource_id, instance_id, relationship_type, relationship_requirement, relationship_requirement_id) + + resource_payloads = [] for k, v in resource_relationship.get("properties", {}).items(): - self.add_instance_property_non_vf(new_resource_id, k, v, origin_section="componentInstancesProperties") + resource_payloads.append(self.get_instance_property_non_vf_payload(new_resource_id, k, v, origin_section="componentInstancesProperties")) + + if len(resource_payloads): + self.oc.sdc.vnf.add_catalog_resource_property_non_vf_multi( + **self.attributes, + catalog_resource_instance_id=new_resource_id, + payload_data=json.dumps(resource_payloads) + ) def add_resource_relationship(self, from_node, to_node, relationship_type, relationship_requirement, relationship_requirement_id): components = self.tosca.get("componentInstances", []) @@ -252,8 +286,9 @@ class VNF(Resource): requirement_id=relationship_requirement_id, ) - def _add_vm_type_network_role(self, instance_id, network_roles_dict): + def _get_vm_type_network_role_payloads(self, instance_id, network_roles_dict): model = self.tosca + payloads = [] for network_role in network_roles_dict: # checking if abstract node has matching network role, # and updating if found @@ -264,7 +299,7 @@ class VNF(Resource): nrt, model, instance_id ) for instance_property in instance_properties: - self.add_instance_property(instance_id, instance_property, nr) + payloads.append(self.get_instance_property_payload(instance_id, instance_property, nr)) if related_networks: property_val = [ {"related_network_role": related_network_role} @@ -273,12 +308,16 @@ class VNF(Resource): rnr_instance_property = instance_property.replace( "_network_role", "_related_networks" ) - self.add_instance_property( - instance_id, - rnr_instance_property, - str(property_val).replace("'", '\\"'), + payloads.append( + self.get_instance_property_payload( + instance_id, + rnr_instance_property, + str(property_val).replace("'", '\\"'), + ) ) + return payloads + def resource_exists(self, resource_name): """Checking the tosca model for a VF to see if a resource has already been added""" @@ -320,7 +359,7 @@ class VNF(Resource): return None - def add_input_value(self, input_name, input_default_value): + def get_input_payload(self, input_name, input_default_value): """Updates an input value on a VNF :input_name: input name to update @@ -333,18 +372,19 @@ class VNF(Resource): unique_id = item["uniqueId"] parent_unique_id = item["parentUniqueId"] owner_id = item["ownerId"] - default_value = item.get("defaultValue", "") - if default_value != input_default_value: - return self.oc.sdc.vnf.add_catalog_resource_input( - **self.attributes, - input_default_value=input_default_value, - input_name=input_name, - input_parent_unique_id=parent_unique_id, - input_unique_id=unique_id, - input_owner_id=owner_id, - ) - else: - return None + payload_string = get_request_object( + self.oc.sdc.vnf.catalog_items["ADD_CATALOG_RESOURCE_INPUT"], + **self.attributes, + input_default_value=input_default_value, + input_name=input_name, + input_parent_unique_id=parent_unique_id, + input_unique_id=unique_id, + input_owner_id=owner_id, + ).payload + try: + return json.loads(payload_string) + except Exception: + return payload_string raise exceptions.InputNotFoundException( "Input {} was not found in VF".format(input_name) @@ -354,14 +394,7 @@ class VNF(Resource): # instance, policy, and group properties can probably be merged # rn there is a lot of dup - def add_instance_property(self, instance_id, property_name, property_value, origin_section="componentInstancesInputs"): - """Updates an instance property on a abstract instance attached to a VNF - - :instance_id: ID of a instance attached to a VNF - :property_name: property name to update - :property_value: value to update property with - - """ + def get_instance_property_payload(self, instance_id, property_name, property_value, origin_section="componentInstancesInputs"): instance_inputs = self.tosca.get(origin_section, {}).get( instance_id, {} ) @@ -373,21 +406,22 @@ class VNF(Resource): owner_id = prop.get("ownerId") schemaType = prop.get("schemaType", "") property_type = prop.get("type") - value = prop.get("value", "") - if value != property_value: - return self.oc.sdc.vnf.add_catalog_resource_property( - **self.attributes, - unique_id=unique_id, - parent_unique_id=parent_unique_id, - owner_id=owner_id, - catalog_resource_instance_id=instance_id, - property_name=property_name, - property_default_value=property_value, - schema_type=schemaType, - property_type=property_type, - ) - else: - return None + payload_string = get_request_object( + self.oc.sdc.vnf.catalog_items["ADD_CATALOG_RESOURCE_PROPERTY"], + **self.attributes, + unique_id=unique_id, + parent_unique_id=parent_unique_id, + owner_id=owner_id, + catalog_resource_instance_id=instance_id, + property_name=property_name, + property_default_value=property_value, + schema_type=schemaType, + property_type=property_type, + ).payload + try: + return json.loads(payload_string) + except Exception: + return payload_string raise exceptions.PropertyNotFoundException( "Property {} was not found in Instance {}".format( @@ -395,7 +429,7 @@ class VNF(Resource): ) ) - def add_instance_property_non_vf(self, instance_id, property_name, property_value, origin_section="componentInstancesProperties"): + def get_instance_property_non_vf_payload(self, instance_id, property_name, property_value, origin_section="componentInstancesProperties"): """Updates an instance property on a abstract instance attached to a VNF :instance_id: ID of a instance attached to a VNF @@ -414,21 +448,22 @@ class VNF(Resource): owner_id = prop.get("ownerId") schemaType = prop.get("schemaType", "") property_type = prop.get("type") - value = prop.get("value", "") - if value != property_value: - return self.oc.sdc.vnf.add_catalog_resource_property_non_vf( - **self.attributes, - unique_id=unique_id, - parent_unique_id=parent_unique_id, - owner_id=owner_id, - catalog_resource_instance_id=instance_id, - property_name=property_name, - property_default_value=property_value, - schema_type=schemaType, - property_type=property_type, - ) - else: - return None + payload_string = get_request_object( + self.oc.sdc.vnf.catalog_items["ADD_CATALOG_RESOURCE_PROPERTY_NON_VF"], + **self.attributes, + unique_id=unique_id, + parent_unique_id=parent_unique_id, + owner_id=owner_id, + catalog_resource_instance_id=instance_id, + property_name=property_name, + property_default_value=property_value, + schema_type=schemaType, + property_type=property_type, + ).payload + try: + return json.loads(payload_string) + except Exception: + return payload_string raise exceptions.PropertyNotFoundException( "Property {} was not found in Instance {}".format( @@ -436,7 +471,7 @@ class VNF(Resource): ) ) - def add_policy_property(self, policy_id, property_name, property_value): + def get_policy_property_payloads(self, policy_id, property_name, property_value): """Updates a policy property on a polic attached to a VNF :policy_id: ID of a policy attached to a VNF @@ -453,19 +488,20 @@ class VNF(Resource): unique_id = prop.get("uniqueId") property_type = prop.get("type") description = prop.get("description") - value = prop.get("value", "") - if value != property_value: - return self.oc.sdc.vnf.add_catalog_policy_property( - catalog_resource_id=self.catalog_resource_id, - unique_id=unique_id, - catalog_policy_id=policy_id, - property_name=property_name, - property_default_value=property_value, - description=description, - property_type=property_type, - ) - else: - return None + payload_string = get_request_object( + self.oc.sdc.vnf.catalog_items["ADD_CATALOG_POLICY_PROPERTY"], + catalog_resource_id=self.catalog_resource_id, + unique_id=unique_id, + catalog_policy_id=policy_id, + property_name=property_name, + property_default_value=property_value, + description=description, + property_type=property_type, + ).payload + try: + return json.loads(payload_string) + except Exception: + return payload_string raise exceptions.PropertyNotFoundException( "Property {} was not found in policy {}".format(property_name, policy_id) @@ -522,10 +558,10 @@ def update_vnf(catalog_resource_id, vnf_input, oc=None): if existing_vnf.get("lifecycleState") != "NOT_CERTIFIED_CHECKOUT": vnf = oc.sdc.vnf.checkout_catalog_resource(catalog_resource_id=catalog_resource_id).response_data + new_vnf_metadata = oc.sdc.vnf.get_catalog_resource_metadata(catalog_resource_id=vnf.get("uniqueId")).response_data.get("metadata", {}) else: - vnf = existing_vnf - - new_vnf_metadata = oc.sdc.vnf.get_catalog_resource_metadata(catalog_resource_id=vnf.get("uniqueId")).response_data.get("metadata", {}) + vnf = oc.sdc.vnf.get_catalog_resource_metadata(catalog_resource_id=catalog_resource_id).response_data.get("metadata", {}) + new_vnf_metadata = copy.deepcopy(vnf) csar_version = oc.get_cached("vsp", vnf_input.get("software_product_name"), "csar_version") if not csar_version: @@ -586,7 +622,14 @@ def create_vnf(vnf_input, oc=None): vnf_input["contact_id"] = owner - vnf = oc.sdc.vnf.add_catalog_resource(**vnf_input, categories=[category]) + try: + vnf = oc.sdc.vnf.add_catalog_resource(**vnf_input, categories=[category]) + except Exception as e: + if str(e).lower().find("was already imported for vf") != -1: + catalog_resource_id, __ = get_vnf_id(vnf_input.get("vnf_name"), oc=oc, no_certified=True) + if catalog_resource_id: + return update_vnf(catalog_resource_id, vnf_input, oc=oc) + raise vnf_input["catalog_resource_id"] = vnf.catalog_resource_id vnf_input["tosca"] = vnf.response_data @@ -697,30 +740,37 @@ def get_resource_category(category_name, oc=None): return None -def get_vnf_id(vnf_name, oc=None): +def get_vnf_id(vnf_name, oc=None, no_certified=False): """Returns the latest VNF id for a VNF Model. If there is only one version of a VNF model, that will also be returned""" if not oc: oc = Client() - response = oc.sdc.vnf.get_resource_by_name_version( - catalog_resource_name=vnf_name, - catalog_resource_version="1.0", - raise_on_error=False, - attempts=1, - ) - if not response.success: - return None, None - - versions = response.response_data.get("allVersions") - catalog_resource_id = "" - catalog_resource = None - highest_version = 0 - for version, vnf_id in versions.items(): - if float(version) > highest_version: - highest_version = float(version) - catalog_resource_id = vnf_id - - if highest_version == 1.0: - catalog_resource = response.response_data - return catalog_resource_id, catalog_resource + if no_certified: + resources = oc.sdc.vnf.get_resources().response_data.get("resources", []) + for resource in resources: + if resource.get("name") == vnf_name: + return resource.get("uniqueId"), resource + return "", None + else: + response = oc.sdc.vnf.get_resource_by_name_version( + catalog_resource_name=vnf_name, + catalog_resource_version="1.0", + raise_on_error=False, + attempts=1, + ) + if not response.success: + return None, None + + versions = response.response_data.get("allVersions") + catalog_resource_id = "" + catalog_resource = None + highest_version = 0 + for version, vnf_id in versions.items(): + if float(version) > highest_version: + highest_version = float(version) + catalog_resource_id = vnf_id + + if highest_version == 1.0: + catalog_resource = response.response_data + return catalog_resource_id, catalog_resource diff --git a/onap-client/onap_client/sdc/vsp.py b/onap-client/onap_client/sdc/vsp.py index 100fca0..fca674b 100644 --- a/onap-client/onap_client/sdc/vsp.py +++ b/onap-client/onap_client/sdc/vsp.py @@ -102,14 +102,18 @@ class VSP(Resource): requestor_id = self.oc.sdc.vsp.catalog_resources["MODIFY_VSP_OWNER"].get("headers").get("USER_ID") if user_exists(requestor_id, vsp_permissions, permission="Owner"): + tmp_list = [] for contributer in self.contributers: if ( not user_exists(contributer, vsp_permissions, permission="Contributor") and contributer != requestor_id ): - self.oc.sdc.vsp.add_vsp_contributer( - user_id=contributer, software_product_id=self.software_product_id - ) + tmp_list.append(contributer) + + if len(tmp_list): + self.oc.sdc.vsp.add_vsp_contributer( + user_id=tmp_list, software_product_id=self.software_product_id + ) if self.owner and self.owner != requestor_id: self.oc.sdc.vsp.modify_vsp_owner( |