From 01f00de4f76c2241872fd5d631a20b1f2f1bdc9e Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 15 Sep 2020 17:50:01 +0200 Subject: [PATCH 01/60] Add SapData to rano Instantiate operation body. --- openapi/MSO-LO-swagger-resolved.yaml | 50 +++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index c381cbc..d990e2c 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1034,7 +1034,7 @@ paths: description: Instantiate NS request body required: false schema: - $ref: '#/definitions/NfvoNsInstantiateRequest' + $ref: '#/definitions/RanoNsInstantiateRequest' responses: "202": description: | @@ -1624,6 +1624,54 @@ definitions: properties: additionalParamsForNs: $ref: '#/definitions/NfvoNsInstantiateRequest_additionalParamsForNs' + RanoNsInstantiateRequest: + type: object + properties: + SapData: + required: + - sapdId + - radioSliceProfile + properties: + sapdId: + type: string + description: Reference to the SAPD for this SAP. + example: sap_ext_mobile + sapName: + type: string + description: Human readable name for the SAP. + example: External Mobile Sap + description: + type: string + description: Human readable description for the SAP. + example: Sap description + radioSliceProfile: + type: object + description: Radio Slice Profile parameters + required: + - sST + - coverageArea + properties: + sST: + type: string + description: One of eMBB, URLLC and mMTC + example: eMBB + coverageArea: + type: string + example: ITALY.TIM_LAB + latency: + type: integer + description: Desired latency in milliseconds + example: 10 + uLThptPerSlice: + type: integer + example: 50 + description: Up-Link throughput per slice in Mbps + dLThptPerSlice: + type: integer + example: 50 + description: Down-Link throughput per slice in Mbps + additionalParamsForNs: + type: object NfvoNsInstancesScaleRequest: type: object properties: From 857b3e4717087b62978587e763930d68cb12fb3d Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 15 Oct 2020 17:14:37 +0200 Subject: [PATCH 02/60] Add radioAccessTechnology and site to SapData. --- openapi/MSO-LO-swagger-resolved.yaml | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index 2698549..9481600 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1634,15 +1634,15 @@ definitions: properties: sapdId: type: string - description: Reference to the SAPD for this SAP. + description: ID reference to the SAPD for this SAP example: sap_ext_mobile sapName: type: string - description: Human readable name for the SAP. + description: Human readable name for the SAP example: External Mobile Sap description: type: string - description: Human readable description for the SAP. + description: Human readable description for the SAP example: Sap description radioSliceProfile: type: object @@ -1651,25 +1651,35 @@ definitions: - sST - coverageArea properties: - sST: + site: type: string - description: One of eMBB, URLLC and mMTC - example: eMBB + description: The target site + enum: [ ITALY_TURIN, SPAIN_5TONIC, FRANCE_PARIS, FRANCE_NICE, FRANCE_RENNES, GREECE_ATHENS ] coverageArea: type: string + description: The radio coverage area example: ITALY.TIM_LAB + # TODO define enum + radioAccessTechnology: + type: string + description: The radio access technology + enum: [ 4G, 5GNSA , 5GSA , NB-IoT , LTE-M ] + sST: + type: string + description: The Slice/Service Type + enum: [ eMBB, URLLC and mMTC ] latency: type: integer - description: Desired latency in milliseconds + description: Desired latency in milliseconds (only for URLLC) example: 10 uLThptPerSlice: type: integer + description: Up-Link throughput per slice in Mbps (only for eMBB) example: 50 - description: Up-Link throughput per slice in Mbps dLThptPerSlice: type: integer + description: Down-Link throughput per slice in Mbps (only for eMBB) example: 50 - description: Down-Link throughput per slice in Mbps additionalParamsForNs: type: object NfvoNsInstancesScaleRequest: From 4176d82b980e7bd95bb690c0d973af24f7727b24 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 15 Oct 2020 17:20:28 +0200 Subject: [PATCH 03/60] Make SapData an array. --- openapi/MSO-LO-swagger-resolved.yaml | 107 ++++++++++++++------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index 9481600..bb1dd2d 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1628,58 +1628,61 @@ definitions: type: object properties: SapData: - required: - - sapdId - - radioSliceProfile - properties: - sapdId: - type: string - description: ID reference to the SAPD for this SAP - example: sap_ext_mobile - sapName: - type: string - description: Human readable name for the SAP - example: External Mobile Sap - description: - type: string - description: Human readable description for the SAP - example: Sap description - radioSliceProfile: - type: object - description: Radio Slice Profile parameters - required: - - sST - - coverageArea - properties: - site: - type: string - description: The target site - enum: [ ITALY_TURIN, SPAIN_5TONIC, FRANCE_PARIS, FRANCE_NICE, FRANCE_RENNES, GREECE_ATHENS ] - coverageArea: - type: string - description: The radio coverage area - example: ITALY.TIM_LAB - # TODO define enum - radioAccessTechnology: - type: string - description: The radio access technology - enum: [ 4G, 5GNSA , 5GSA , NB-IoT , LTE-M ] - sST: - type: string - description: The Slice/Service Type - enum: [ eMBB, URLLC and mMTC ] - latency: - type: integer - description: Desired latency in milliseconds (only for URLLC) - example: 10 - uLThptPerSlice: - type: integer - description: Up-Link throughput per slice in Mbps (only for eMBB) - example: 50 - dLThptPerSlice: - type: integer - description: Down-Link throughput per slice in Mbps (only for eMBB) - example: 50 + type: array + items: + type: object + required: + - sapdId + - radioSliceProfile + properties: + sapdId: + type: string + description: ID reference to the SAPD for this SAP + example: sap_ext_mobile + sapName: + type: string + description: Human readable name for the SAP + example: External Mobile Sap + description: + type: string + description: Human readable description for the SAP + example: Sap description + radioSliceProfile: + type: object + description: Radio Slice Profile parameters + required: + - sST + - coverageArea + properties: + site: + type: string + description: The target site + enum: [ ITALY_TURIN, SPAIN_5TONIC, FRANCE_PARIS, FRANCE_NICE, FRANCE_RENNES, GREECE_ATHENS ] + coverageArea: + type: string + description: The radio coverage area + example: ITALY.TIM_LAB + # TODO define enum + radioAccessTechnology: + type: string + description: The radio access technology + enum: [ 4G, 5GNSA , 5GSA , NB-IoT , LTE-M ] + sST: + type: string + description: The Slice/Service Type + enum: [ eMBB, URLLC and mMTC ] + latency: + type: integer + description: Desired latency in milliseconds (only for URLLC) + example: 10 + uLThptPerSlice: + type: integer + description: Up-Link throughput per slice in Mbps (only for eMBB) + example: 50 + dLThptPerSlice: + type: integer + description: Down-Link throughput per slice in Mbps (only for eMBB) + example: 50 additionalParamsForNs: type: object NfvoNsInstancesScaleRequest: From 5b985bcce547fdbf070a2821bfb0f739ca1eb521 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 15 Oct 2020 17:27:57 +0200 Subject: [PATCH 04/60] Make 'site' a required field. --- openapi/MSO-LO-swagger-resolved.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index bb1dd2d..3ff62da 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1651,8 +1651,9 @@ definitions: type: object description: Radio Slice Profile parameters required: - - sST + - site - coverageArea + - sST properties: site: type: string From 66a0640970e1c473b9134c9639e6ffa9737a4d7d Mon Sep 17 00:00:00 2001 From: Aitor Zabala Date: Thu, 22 Oct 2020 09:44:15 +0200 Subject: [PATCH 05/60] adapt to 5gr-so deployment --- adaptation_layer/seed/nfvo_credentials_mock.json | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adaptation_layer/seed/nfvo_credentials_mock.json b/adaptation_layer/seed/nfvo_credentials_mock.json index 75a9acb..d30a2b1 100644 --- a/adaptation_layer/seed/nfvo_credentials_mock.json +++ b/adaptation_layer/seed/nfvo_credentials_mock.json @@ -21,7 +21,7 @@ "nfvo_id": 3 }, { - "host": "localhost", + "host": "10.0.200.212", "user": "admin", "password": "admin", "project": "admin", diff --git a/docker-compose.yml b/docker-compose.yml index a443eab..d22b8d1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.7' x-environment: &environment - IWFREPO: 'true' + IWFREPO: 'false' IWFREPO_HTTPS: 'false' IWFREPO_HOST: '192.168.18.14' IWFREPO_PORT: '8087' From 3bdabff01c30109d421d19e9c6dab9ce81845d86 Mon Sep 17 00:00:00 2001 From: Aitor Zabala Date: Mon, 26 Oct 2020 11:01:05 +0100 Subject: [PATCH 06/60] Added UserAccessInfo to the data model and fixed some minor issues during 5gr-so integration. Minor issues - 5gr-so does not support the get_ns just after the ns_create. The get_ns has been removed from the create_ns, and a simple NSInstance is sent as a response. --- adaptation_layer/driver/fivegr_so.py | 39 +++++++++++++----- .../seed/nfvo_credentials_mock.json | 2 +- adaptation_layer/tests/fivegr_so-openapi.yaml | 40 +++++++++++-------- docker-compose.dev.yml | 2 +- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/adaptation_layer/driver/fivegr_so.py b/adaptation_layer/driver/fivegr_so.py index 5a1a7de..b1d7dad 100644 --- a/adaptation_layer/driver/fivegr_so.py +++ b/adaptation_layer/driver/fivegr_so.py @@ -47,7 +47,7 @@ def __init__(self, nfvo_cred): self._port = nfvo_cred["port"] if "port" in nfvo_cred else 8080 self._headers = {"Content-Type": "application/json", "Accept": "application/json"} - + print("[DEBUG] _host:{} _port:{}".format(self._host, self._port)) if TESTING is False: self._base_path = 'http://{0}:{1}/5gt/so/v1'.format(self._host, self._port) else: @@ -163,9 +163,11 @@ def create_ns(self, args: Dict = None) -> Tuple[Body, Headers]: nsIdRaw, resp_headers = self._exec_post( _url, json=args['payload'], headers=self._headers) nsId = nsIdRaw['nsId'] - nsInstance, resp_headers = self.get_ns(nsId) - nsInstance["nsInstanceName"] = args['payload']['nsName'] - nsInstance["nsInstanceDescription"] = args['payload']['nsDescription'] + print("[DEBUG] nsId:" + nsId) + # nsInstance, resp_headers = self.get_ns(nsId) # FIXME get_ns without instantiation does not work in 5gr-so + sol005NsInstance = SOL005NSInstance(id=nsId, nsInstanceName=args['payload']['nsName'], nsInstanceDescription=args['payload']['nsDescription'], nsState="NOT_INSTANTIATED") + + nsInstance = to_dict(sol005NsInstance) except ResourceNotFound: nsd_Id = args['payload']['nsdId'] raise NsdNotFound(nsd_id=nsd_Id) @@ -177,11 +179,13 @@ def get_ns(self, nsId: str, args: Dict = None) -> Tuple[Body, Headers]: _url = self._build_url_query(_url, args) try: nsInfoDict, resp_headers = self._exec_get(_url, headers=self._headers) - status = nsInfoDict.pop('status', None) - nsInfoDict['nsState'] = status + print(json.dumps(nsInfoDict, indent=2, sort_keys=True)) + nsInfoDict = nsInfoDict["queryNsResult"][0] + # status = nsInfoDict.pop('status', None) + # nsInfoDict['nsState'] = status nsInfo = IFA013NsInfo(**nsInfoDict) nsInstance = ifa013nsinfo_to_sol005nsinstance(nsInfo) - nsInstance.id = nsId # NSInfo does not contain the id of the NS instance + # nsInstance.id = nsId # NSInfo does not contain the id of the NS instance except ResourceNotFound: raise NsNotFound(ns_id=nsId) headers = {} @@ -194,11 +198,11 @@ def instantiate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: _url = '{0}/ns/{1}/instantiate'.format(self._base_path, nsId) _url = self._build_url_query(_url, args) if 'payload' not in args: - raise BadRequest(ns_id=nsId) + raise BadRequest(description="Payload not found for id: {}".format(nsId)) sol005InstantiateNsRequest = SOL005InstantiateNsRequest(**args['payload']) ifa013InstantiateNsRequest = sol005InstantiateNsRequest_to_ifa013InstantiateNsRequest(sol005InstantiateNsRequest) ifa013InstantiateNsRequestDict = to_dict(ifa013InstantiateNsRequest) - # print(json.dumps(ifa013InstantiateNsRequestDict, indent=4, sort_keys=True)) + print(json.dumps(ifa013InstantiateNsRequestDict, indent=2, sort_keys=True)) try: operationIdRaw, resp_headers = self._exec_put( _url, headers=self._headers, json=ifa013InstantiateNsRequestDict) @@ -227,6 +231,7 @@ def scale_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: sol005ScaleNsRequest = SOL005ScaleNsRequest(**args['payload']) ifa013ScaleNsRequest = sol005ScaleNsRequest_to_ifa013ScaleNsRequest(nsId, sol005ScaleNsRequest) ifa013ScaleNsRequestDict = to_dict(ifa013ScaleNsRequest) + print(json.dumps(ifa013ScaleNsRequestDict, indent=2, sort_keys=True)) try: operationIdRaw, resp_headers = self._exec_put( _url, json=ifa013ScaleNsRequestDict, headers=self._headers) @@ -337,13 +342,22 @@ def __init__(self, nsVirtualLinkDescId="", resourceHandle=None, linkPort=None): [self.linkPort.append(IFA013NsLinkPort(**element)) for element in linkPort or []] +class UserAccessInfo: + def __init__(self, address="", sapdId="", vnfdId=""): + self.address: str = address + self.sapdId: str = sapdId + self.vnfdId: str = vnfdId + + class IFA013SapInfo: - def __init__(self, sapInstanceId="", sapdId="", sapName="", description="", address=""): + def __init__(self, sapInstanceId="", sapdId="", sapName="", description="", address="", userAccessInfo=None): self.sapInstanceId: str = sapInstanceId self.sapdId: str = sapdId self.sapName: str = sapName self.description: str = description self.address: str = address + self.userAccessInfo: List[UserAccessInfo] = [] + [self.userAccessInfo.append(UserAccessInfo(**element)) for element in userAccessInfo or []] class IFA013Nfp: @@ -728,13 +742,15 @@ def __init__(self, layerProtocol="IP_OVER_ETHERNET", ipOverEthernet=None): class SOL005SapInfo: - def __init__(self, id="", sapdId="", sapName="", description="", sapProtocolInfo=None): + def __init__(self, id="", sapdId="", sapName="", description="", sapProtocolInfo=None, userAccessInfo=None): self.id: str = id self.sapdId: str = sapdId self.sapName: str = sapName self.description: str = description self.sapProtocolInfo: List[SOL005CpProtocolInfo] = [] [self.sapProtocolInfo.append(element) for element in sapProtocolInfo or []] + self.userAccessInfo: List[UserAccessInfo] = [] + [self.userAccessInfo.append(element) for element in userAccessInfo or []] class SOL005NsScaleInfo: @@ -1254,6 +1270,7 @@ def ifa013SapInfo_to_sol005Sapinfo(ifaSapInfoArray: List[IFA013SapInfo]) -> List else: # Mac address sol005cpProtocolInfo.ipOverEthernet.macAddress = ifaSapInfo.address sol005SapInfo.sapProtocolInfo.append(sol005cpProtocolInfo) + sol005SapInfo.userAccessInfo = ifaSapInfo.userAccessInfo sol005SapInfoArray.append(sol005SapInfo) return sol005SapInfoArray diff --git a/adaptation_layer/seed/nfvo_credentials_mock.json b/adaptation_layer/seed/nfvo_credentials_mock.json index d30a2b1..75a9acb 100644 --- a/adaptation_layer/seed/nfvo_credentials_mock.json +++ b/adaptation_layer/seed/nfvo_credentials_mock.json @@ -21,7 +21,7 @@ "nfvo_id": 3 }, { - "host": "10.0.200.212", + "host": "localhost", "user": "admin", "password": "admin", "project": "admin", diff --git a/adaptation_layer/tests/fivegr_so-openapi.yaml b/adaptation_layer/tests/fivegr_so-openapi.yaml index 0fb1db4..c4e0e33 100644 --- a/adaptation_layer/tests/fivegr_so-openapi.yaml +++ b/adaptation_layer/tests/fivegr_so-openapi.yaml @@ -60,7 +60,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/NsInfo" + $ref: "#/components/schemas/QueryNsResult" "404": description: Not Found content: @@ -567,26 +567,25 @@ components: nsdId: nsdId nsName: nsName nsDescription: nsDescription - NsInfo: + QueryNsResult: type: object properties: - status: - type: string - sapInfo: + queryNsResult: type: array items: - $ref: "#/components/schemas/SapInfo" + $ref: "#/components/schemas/NsInfo" example: - status: NOT_INSTANTIATED - sapInfo: - - sapInstanceId: sapInstanceId - sapName: sapName - description: description - address: 10.10.10.10 - - sapInstanceId: sapInstanceId2 - sapName: sapName2 - description: description2 - address: 10.10.10.11 + queryNsResult: + - nsState: NOT_INSTANTIATED + sapInfo: + - sapInstanceId: sapInstanceId + sapName: sapName + description: description + address: 10.10.10.10 + - sapInstanceId: sapInstanceId2 + sapName: sapName2 + description: description2 + address: 10.10.10.11 NsInstantiationRequest: type: object required: @@ -1060,3 +1059,12 @@ components: sapName: sapName description: description address: 10.10.10.10 + NsInfo: + type: object + properties: + nsState: + type: string + sapInfo: + type: array + items: + $ref: "#/components/schemas/SapInfo" diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index b680671..91b06e6 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,7 +1,7 @@ version: '3.7' x-environment: &environment - IWFREPO: 'true' + IWFREPO: 'false' IWFREPO_HTTPS: 'false' IWFREPO_HOST: '192.168.1.75' IWFREPO_PORT: '8087' From cf5549d4e62eff2ea353118b56a6941f77d98d5e Mon Sep 17 00:00:00 2001 From: efabuba Date: Mon, 26 Oct 2020 12:38:44 +0100 Subject: [PATCH 07/60] Add SapData object in ever-openapi.yaml Fix EVER driver adding SapData in instantiated API --- adaptation_layer/driver/ever.py | 7 +- adaptation_layer/tests/ever-openapi.yaml | 95 +++++++++++++++++++----- adaptation_layer/tests/wait-for-it.sh | 0 3 files changed, 82 insertions(+), 20 deletions(-) mode change 100755 => 100644 adaptation_layer/tests/wait-for-it.sh diff --git a/adaptation_layer/driver/ever.py b/adaptation_layer/driver/ever.py index e56f8b9..cbe6107 100644 --- a/adaptation_layer/driver/ever.py +++ b/adaptation_layer/driver/ever.py @@ -158,9 +158,14 @@ def delete_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: def instantiate_ns(self, nsId: str, args=None) -> Tuple[None, Headers]: _url = '{0}/instantiate/{1}'.format(self._base_path, nsId) _url = self._build_url_query(_url, args) + instantiate_payload = {} + try: + instantiated_payload['SapData'] = args['payload']['SapData'] + except (TypeError, KeyError): + logger.info('no SapData') try: empty_body, resp_headers = self._exec_post( - _url, headers={}) + _url, json=instantiated_payload, headers={}) except ResourceNotFound: raise NsNotFound(ns_id=nsId) headers = self._build_headers(resp_headers) diff --git a/adaptation_layer/tests/ever-openapi.yaml b/adaptation_layer/tests/ever-openapi.yaml index 75010a8..e51d66d 100644 --- a/adaptation_layer/tests/ever-openapi.yaml +++ b/adaptation_layer/tests/ever-openapi.yaml @@ -119,19 +119,24 @@ paths: $ref: '#/components/responses/InternalServerError' # instantiate NS with given NsId '/instantiate/{ns_db_id}': - parameters: - - name: ns_db_id - in: path - required: true - description: NS Instance ID - schema: - type : string post: tags: - 'NS instances' summary: Instantiate NS with given NS ID description: Instantiate NS with given NS ID operationId: instantiateNS + parameters: + - name: ns_db_id + in: path + required: true + description: NS Instance ID + schema: + type : string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RanoNsInstantiateRequest' responses: '202': description: Accepted @@ -172,17 +177,7 @@ paths: responses: '202': description: Accepted - headers: - Location: - description: link with nsLcmOpOccId of the instantiated NS - schema: - type: string - format: uri - example: /ns_lcm_op_occs/4e462039-e57b-44e4-8431-bc586f31b4cb - Content-Type: - schema: - type: string - example: text/html + headers: {} '400': $ref: '#/components/responses/BadRequest' '404': @@ -352,6 +347,68 @@ components: # end of schemas in responses # END RESPONSES schemas: + RanoNsInstantiateRequest: + type: object + properties: + SapData: + type: array + items: + type: object + required: + - sapdId + - radioSliceProfile + properties: + sapdId: + type: string + description: ID reference to the SAPD for this SAP + example: sap_ext_mobile + sapName: + type: string + description: Human readable name for the SAP + example: External Mobile Sap + description: + type: string + description: Human readable description for the SAP + example: Sap description + radioSliceProfile: + type: object + description: Radio Slice Profile parameters + required: + - site + - coverageArea + - sST + properties: + site: + type: string + description: The target site + enum: [ ITALY_TURIN, SPAIN_5TONIC, FRANCE_PARIS, FRANCE_NICE, FRANCE_RENNES, GREECE_ATHENS ] + coverageArea: + type: string + description: The radio coverage area + example: ITALY.TIM_LAB + # TODO define enum + radioAccessTechnology: + type: string + description: The radio access technology + enum: [ 4G, 5GNSA , 5GSA , NB-IoT , LTE-M ] + sST: + type: string + description: The Slice/Service Type + enum: [ eMBB, URLLC and mMTC ] + latency: + type: integer + description: Desired latency in milliseconds (only for URLLC) + example: 10 + uLThptPerSlice: + type: integer + description: Up-Link throughput per slice in Mbps (only for eMBB) + example: 50 + dLThptPerSlice: + type: integer + description: Down-Link throughput per slice in Mbps (only for eMBB) + example: 50 + additionalParamsForNs: + type: object createNsId: # description: type: object @@ -465,7 +522,7 @@ components: id: type: string format: uuid - example: null #3fa85f64-5717-4562-b3fc-2c963f66afa6 + example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 vnfdId: type: string format: uuid diff --git a/adaptation_layer/tests/wait-for-it.sh b/adaptation_layer/tests/wait-for-it.sh old mode 100755 new mode 100644 From 8cf6f1679b50382a77f451135d8da1badf3680fb Mon Sep 17 00:00:00 2001 From: efabuba Date: Mon, 26 Oct 2020 14:05:44 +0100 Subject: [PATCH 08/60] Fix header in terminate API --- adaptation_layer/tests/ever-openapi.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/adaptation_layer/tests/ever-openapi.yaml b/adaptation_layer/tests/ever-openapi.yaml index e51d66d..6569a48 100644 --- a/adaptation_layer/tests/ever-openapi.yaml +++ b/adaptation_layer/tests/ever-openapi.yaml @@ -105,6 +105,10 @@ paths: type: string format: uri example: /instances/4e462039-e57b-44e4-8431-bc586f31b4cb + Content-Type: + schema: + type: string + example: text/html content: application/json: schema: @@ -407,8 +411,6 @@ components: type: integer description: Down-Link throughput per slice in Mbps (only for eMBB) example: 50 - additionalParamsForNs: - type: object createNsId: # description: type: object From e1d09be045b55abfad091fe13aa08b8ed58dc0fe Mon Sep 17 00:00:00 2001 From: Aitor Zabala Date: Mon, 26 Oct 2020 17:23:57 +0100 Subject: [PATCH 09/60] Fixed ifa013OperationStatus bug and removed unnecessary logs. --- adaptation_layer/driver/fivegr_so.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/adaptation_layer/driver/fivegr_so.py b/adaptation_layer/driver/fivegr_so.py index b1d7dad..92964e8 100644 --- a/adaptation_layer/driver/fivegr_so.py +++ b/adaptation_layer/driver/fivegr_so.py @@ -179,13 +179,9 @@ def get_ns(self, nsId: str, args: Dict = None) -> Tuple[Body, Headers]: _url = self._build_url_query(_url, args) try: nsInfoDict, resp_headers = self._exec_get(_url, headers=self._headers) - print(json.dumps(nsInfoDict, indent=2, sort_keys=True)) nsInfoDict = nsInfoDict["queryNsResult"][0] - # status = nsInfoDict.pop('status', None) - # nsInfoDict['nsState'] = status nsInfo = IFA013NsInfo(**nsInfoDict) nsInstance = ifa013nsinfo_to_sol005nsinstance(nsInfo) - # nsInstance.id = nsId # NSInfo does not contain the id of the NS instance except ResourceNotFound: raise NsNotFound(ns_id=nsId) headers = {} @@ -202,7 +198,6 @@ def instantiate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: sol005InstantiateNsRequest = SOL005InstantiateNsRequest(**args['payload']) ifa013InstantiateNsRequest = sol005InstantiateNsRequest_to_ifa013InstantiateNsRequest(sol005InstantiateNsRequest) ifa013InstantiateNsRequestDict = to_dict(ifa013InstantiateNsRequest) - print(json.dumps(ifa013InstantiateNsRequestDict, indent=2, sort_keys=True)) try: operationIdRaw, resp_headers = self._exec_put( _url, headers=self._headers, json=ifa013InstantiateNsRequestDict) @@ -210,6 +205,7 @@ def instantiate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: raise NsNotFound(ns_id=nsId) operationId = operationIdRaw["operationId"] headers = self._build_lcm_op_occs_header(operationId) + print("[DEBUG] operationId:" + operationId) return None, headers def terminate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: @@ -222,6 +218,7 @@ def terminate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: raise NsNotFound(ns_id=nsId) operationId = operationIdRaw["operationId"] headers = self._build_lcm_op_occs_header(operationId) + print("[DEBUG] operationId:" + operationId) return None, headers def scale_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: @@ -231,7 +228,6 @@ def scale_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: sol005ScaleNsRequest = SOL005ScaleNsRequest(**args['payload']) ifa013ScaleNsRequest = sol005ScaleNsRequest_to_ifa013ScaleNsRequest(nsId, sol005ScaleNsRequest) ifa013ScaleNsRequestDict = to_dict(ifa013ScaleNsRequest) - print(json.dumps(ifa013ScaleNsRequestDict, indent=2, sort_keys=True)) try: operationIdRaw, resp_headers = self._exec_put( _url, json=ifa013ScaleNsRequestDict, headers=self._headers) @@ -239,6 +235,7 @@ def scale_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: raise NsNotFound(ns_id=id) operationId = operationIdRaw["operationId"] headers = self._build_lcm_op_occs_header(operationId) + print("[DEBUG] operationId:" + operationId) return None, headers def get_op_list(self, args: Dict = None) -> Tuple[BodyList, Headers]: @@ -1426,7 +1423,7 @@ def ifa013OperationStatus_to_sol005NsLcmOpOcc(ifa013NSLCMOpId, ifa013OperationSt SOL: (1)PROCESSING, (2)COMPLETED, PARTIALLY_COMPLETED, FAILED_TEMP, (3)FAILED, ROLLING_BACK, ROLLED_BACK """ sol005NsLcmOpOcc = SOL005NsLcmOpOcc() - if ifa013OperationStatus == "SUCCESFULLY_DONE": + if ifa013OperationStatus == "SUCCESSFULLY_DONE": sol005NsLcmOpOcc.operationState = "COMPLETED" elif ifa013OperationStatus == "PROCESSING": sol005NsLcmOpOcc.operationState = "PROCESSING" From 4c7a5f90bc5039fd47da4a37994cf17df29a8bc0 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 27 Oct 2020 10:38:30 +0100 Subject: [PATCH 10/60] Fix indentation and variable name. --- adaptation_layer/driver/ever.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/adaptation_layer/driver/ever.py b/adaptation_layer/driver/ever.py index cbe6107..4d3696b 100644 --- a/adaptation_layer/driver/ever.py +++ b/adaptation_layer/driver/ever.py @@ -158,14 +158,14 @@ def delete_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: def instantiate_ns(self, nsId: str, args=None) -> Tuple[None, Headers]: _url = '{0}/instantiate/{1}'.format(self._base_path, nsId) _url = self._build_url_query(_url, args) - instantiate_payload = {} - try: - instantiated_payload['SapData'] = args['payload']['SapData'] + instantiate_payload = {} + try: + instantiate_payload['SapData'] = args['payload']['SapData'] except (TypeError, KeyError): logger.info('no SapData') try: empty_body, resp_headers = self._exec_post( - _url, json=instantiated_payload, headers={}) + _url, json=instantiate_payload, headers={}) except ResourceNotFound: raise NsNotFound(ns_id=nsId) headers = self._build_headers(resp_headers) From de0e9b7f7b35b24585e826280a2d40101cb69574 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 27 Oct 2020 10:38:51 +0100 Subject: [PATCH 11/60] Add missing logger object. --- adaptation_layer/driver/ever.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/adaptation_layer/driver/ever.py b/adaptation_layer/driver/ever.py index 4d3696b..d0c4149 100644 --- a/adaptation_layer/driver/ever.py +++ b/adaptation_layer/driver/ever.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import copy +import logging import os import re from typing import Dict, Tuple @@ -29,6 +30,7 @@ TESTING = os.environ.get("TESTING", False) PRISM_ALIAS = os.environ.get("PRISM_ALIAS", "prism-ever") +logger = logging.getLogger('app.driver.osm') class EVER(Driver): From 143aa28bd2a015022149d2f7f65242533f3969c4 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 27 Oct 2020 10:39:19 +0100 Subject: [PATCH 12/60] Check if content type header is present in the response. --- adaptation_layer/driver/ever.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/adaptation_layer/driver/ever.py b/adaptation_layer/driver/ever.py index d0c4149..b804214 100644 --- a/adaptation_layer/driver/ever.py +++ b/adaptation_layer/driver/ever.py @@ -76,7 +76,12 @@ def _exec_post(self, url=None, data=None, json=None, headers=None): raise ServerError(str(e)) if resp.status_code in (200, 201, 202, 206): - if 'application/json' in resp.headers['content-type']: + try: + ctype = resp.headers['content-type'] + except KeyError: + # success but no content + return None, resp.headers + if 'application/json' in ctype: return resp.json(), resp.headers else: return resp.text, resp.headers From 0449e6aa407c9993224c800584d3e889128e3758 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 27 Oct 2020 10:39:53 +0100 Subject: [PATCH 13/60] Add location header for the terminate 202 response. --- adaptation_layer/tests/ever-openapi.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/adaptation_layer/tests/ever-openapi.yaml b/adaptation_layer/tests/ever-openapi.yaml index 6569a48..494717d 100644 --- a/adaptation_layer/tests/ever-openapi.yaml +++ b/adaptation_layer/tests/ever-openapi.yaml @@ -181,7 +181,14 @@ paths: responses: '202': description: Accepted - headers: {} + headers: + Location: + description: | + It must point to the new "NS Lifecycle Operation Occurrence" + resource, i.e. an URI like ".../ns_lcm_op_occs/{nsLcmOpOccId}" + schema: + type: string + example: /ns_lcm_op_occs/d4888b76-d741-4387-b7ac-37813d513a5a '400': $ref: '#/components/responses/BadRequest' '404': From 887ccc71ebdcf114bcfda076f7136b032abe9932 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 27 Oct 2020 10:40:37 +0100 Subject: [PATCH 14/60] Reformat file with PEP8 --- adaptation_layer/tests/test_ever.py | 1 + 1 file changed, 1 insertion(+) diff --git a/adaptation_layer/tests/test_ever.py b/adaptation_layer/tests/test_ever.py index 660bf73..7801a1b 100644 --- a/adaptation_layer/tests/test_ever.py +++ b/adaptation_layer/tests/test_ever.py @@ -23,6 +23,7 @@ from .response_schemas import ns_lcm_op_occ_schema, \ ns_list_schema, ns_schema, ns_lcm_op_occ_list_schema + # AUTHORIZATION unsupported by EVER driver # scale a ns instance unsupported by EVER driver From a5015b2e25fe29255b6079f1b468d721ff207b0a Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 27 Oct 2020 11:03:39 +0100 Subject: [PATCH 15/60] Make wait-for-it executable. --- adaptation_layer/tests/wait-for-it.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 adaptation_layer/tests/wait-for-it.sh diff --git a/adaptation_layer/tests/wait-for-it.sh b/adaptation_layer/tests/wait-for-it.sh old mode 100644 new mode 100755 From a62ba438c8a546c3b23a988783844b548c335de0 Mon Sep 17 00:00:00 2001 From: Aitor Zabala Date: Tue, 27 Oct 2020 11:13:18 +0100 Subject: [PATCH 16/60] rollback docker compose initial values --- docker-compose.dev.yml | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 91b06e6..b680671 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,7 +1,7 @@ version: '3.7' x-environment: &environment - IWFREPO: 'false' + IWFREPO: 'true' IWFREPO_HTTPS: 'false' IWFREPO_HOST: '192.168.1.75' IWFREPO_PORT: '8087' diff --git a/docker-compose.yml b/docker-compose.yml index d22b8d1..a443eab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.7' x-environment: &environment - IWFREPO: 'false' + IWFREPO: 'true' IWFREPO_HTTPS: 'false' IWFREPO_HOST: '192.168.18.14' IWFREPO_PORT: '8087' From 7df55b00dde12e53d70a869422c4dcfe01a81c1f Mon Sep 17 00:00:00 2001 From: Aitor Zabala Date: Tue, 27 Oct 2020 16:58:24 +0100 Subject: [PATCH 17/60] Fix logging --- adaptation_layer/driver/fivegr_so.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/adaptation_layer/driver/fivegr_so.py b/adaptation_layer/driver/fivegr_so.py index 92964e8..655a2fe 100644 --- a/adaptation_layer/driver/fivegr_so.py +++ b/adaptation_layer/driver/fivegr_so.py @@ -30,6 +30,9 @@ from urllib.parse import urlencode +import logging +logger = logging.getLogger('app.driver.fivergr_so') + TESTING = os.environ.get("TESTING", False) PRISM_ALIAS = os.environ.get("PRISM_ALIAS", "prism-fivegr-so") @@ -47,7 +50,7 @@ def __init__(self, nfvo_cred): self._port = nfvo_cred["port"] if "port" in nfvo_cred else 8080 self._headers = {"Content-Type": "application/json", "Accept": "application/json"} - print("[DEBUG] _host:{} _port:{}".format(self._host, self._port)) + logger.debug("_host:{} _port:{}".format(self._host, self._port)) if TESTING is False: self._base_path = 'http://{0}:{1}/5gt/so/v1'.format(self._host, self._port) else: @@ -163,7 +166,7 @@ def create_ns(self, args: Dict = None) -> Tuple[Body, Headers]: nsIdRaw, resp_headers = self._exec_post( _url, json=args['payload'], headers=self._headers) nsId = nsIdRaw['nsId'] - print("[DEBUG] nsId:" + nsId) + logger.debug("nsId:{}".format(nsId)) # nsInstance, resp_headers = self.get_ns(nsId) # FIXME get_ns without instantiation does not work in 5gr-so sol005NsInstance = SOL005NSInstance(id=nsId, nsInstanceName=args['payload']['nsName'], nsInstanceDescription=args['payload']['nsDescription'], nsState="NOT_INSTANTIATED") @@ -205,7 +208,7 @@ def instantiate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: raise NsNotFound(ns_id=nsId) operationId = operationIdRaw["operationId"] headers = self._build_lcm_op_occs_header(operationId) - print("[DEBUG] operationId:" + operationId) + logger.debug("operationId:{}".format(operationId)) return None, headers def terminate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: @@ -218,7 +221,7 @@ def terminate_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: raise NsNotFound(ns_id=nsId) operationId = operationIdRaw["operationId"] headers = self._build_lcm_op_occs_header(operationId) - print("[DEBUG] operationId:" + operationId) + logger.debug("operationId:{}".format(operationId)) return None, headers def scale_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: @@ -235,7 +238,7 @@ def scale_ns(self, nsId: str, args: Dict = None) -> Tuple[None, Headers]: raise NsNotFound(ns_id=id) operationId = operationIdRaw["operationId"] headers = self._build_lcm_op_occs_header(operationId) - print("[DEBUG] operationId:" + operationId) + logger.debug("operationId:{}".format(operationId)) return None, headers def get_op_list(self, args: Dict = None) -> Tuple[BodyList, Headers]: From ad97d02e520ea767e18e653ddfe4b514fa0fe7f1 Mon Sep 17 00:00:00 2001 From: FabioUbaldi Date: Tue, 27 Oct 2020 17:43:57 +0000 Subject: [PATCH 18/60] Add print in EVER driver --- adaptation_layer/driver/ever.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/adaptation_layer/driver/ever.py b/adaptation_layer/driver/ever.py index b804214..f3be77d 100644 --- a/adaptation_layer/driver/ever.py +++ b/adaptation_layer/driver/ever.py @@ -47,7 +47,8 @@ def __init__(self, rano_cred): self._base_path = 'http://{0}:{1}'.format(PRISM_ALIAS, 9999) def _exec_delete(self, url=None, params=None, headers=None): - + print('#############execute delete######') + print('url= ' + url) try: resp = requests.delete(url, params=params, verify=False, headers=headers) except Exception as e: @@ -66,10 +67,14 @@ def _exec_delete(self, url=None, params=None, headers=None): raise ResourceNotFound() else: error = resp.json() + print('############') + print('error: ' + error) + print('###########') raise ServerError(error) def _exec_post(self, url=None, data=None, json=None, headers=None): - + print('#############execute post######') + print('url= ' + url) try: resp = requests.post(url, data=data, json=json, verify=False, headers=headers) except Exception as e: @@ -96,10 +101,14 @@ def _exec_post(self, url=None, data=None, json=None, headers=None): error = resp.json() else: error = resp.text + print('############') + print('error: ' + error) + print('###########') raise ServerError(error) def _exec_get(self, url=None, params=None, headers=None): - + print('#############execute get######') + print('url= ' + url) try: resp = requests.get(url, params=params, verify=False, headers=headers) except Exception as e: @@ -118,6 +127,9 @@ def _exec_get(self, url=None, params=None, headers=None): raise ResourceNotFound() else: error = resp.json() + print('############') + print('error: ' + error) + print('###########') raise ServerError(error) # all methods From a4ea8efde445b39fa6f6060ce40a196975db7342 Mon Sep 17 00:00:00 2001 From: FabioUbaldi Date: Tue, 27 Oct 2020 17:49:09 +0000 Subject: [PATCH 19/60] Add proxy in Dockerfile --- Dockerfile | 65 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4c0dcfb..fbb32de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,34 @@ -FROM python:3.6-slim as base -EXPOSE 5000 -RUN apt-get update && apt-get install -y build-essential -RUN ["pip3", "install", "pipenv==2020.6.2"] -WORKDIR /usr/src/app/ -# copy only pipfiles to install dependencies -COPY ./adaptation_layer/Pipfile* ./ -RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy"] -COPY ./adaptation_layer ./adaptation_layer -# setup env variables to initialize database -ARG DB_SEED_NFVO -ENV DB_SEED_NFVO $DB_SEED_NFVO -ARG DB_SEED_NFVO_CRED -ENV DB_SEED_NFVO_CRED $DB_SEED_NFVO_CRED -ARG DB_SEED_RANO -ENV DB_SEED_RANO $DB_SEED_RANO -ARG DB_SEED_RANO_CRED -ENV DB_SEED_RANO_CRED $DB_SEED_RANO_CRED -ENV FLASK_APP adaptation_layer -RUN ["rm", "-f", "adaptation_layer/data/mso-lo.db"] -RUN ["flask", "db", "upgrade"] -RUN ["flask", "seed"] - -FROM base as prod -COPY ./uWSGI . -CMD ["uwsgi", "--ini", "app.ini"] - -FROM base as test -RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy", "--dev"] -COPY ./openapi ./openapi - +FROM python:3.6-slim as base +ENV http_proxy http://10.42.137.126:8080 +ENV https_proxy http://10.42.137.126:8080 +EXPOSE 5000 +RUN apt-get update && apt-get install -y build-essential +RUN ["pip3", "install", "pipenv==2020.6.2"] +WORKDIR /usr/src/app/ +# copy only pipfiles to install dependencies +COPY ./adaptation_layer/Pipfile* ./ +RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy"] +COPY ./adaptation_layer ./adaptation_layer +# setup env variables to initialize database +ARG DB_SEED_NFVO +ENV DB_SEED_NFVO $DB_SEED_NFVO +ARG DB_SEED_NFVO_CRED +ENV DB_SEED_NFVO_CRED $DB_SEED_NFVO_CRED +ARG DB_SEED_RANO +ENV DB_SEED_RANO $DB_SEED_RANO +ARG DB_SEED_RANO_CRED +ENV DB_SEED_RANO_CRED $DB_SEED_RANO_CRED +ENV FLASK_APP adaptation_layer +RUN ["rm", "-f", "adaptation_layer/data/mso-lo.db"] +RUN ["flask", "db", "upgrade"] +RUN ["flask", "seed"] + +FROM base as prod +COPY ./uWSGI . +CMD ["uwsgi", "--ini", "app.ini"] + +FROM base as test +RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy", "--dev"] +COPY ./openapi ./openapi +ENV http_proxy= +ENV https_proxy= From c6d34f8eb0299dd2b4211d57233b03e82ee50b4d Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 27 Oct 2020 19:06:27 +0100 Subject: [PATCH 20/60] Fix typo in logger name --- adaptation_layer/driver/fivegr_so.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/driver/fivegr_so.py b/adaptation_layer/driver/fivegr_so.py index 655a2fe..23147ab 100644 --- a/adaptation_layer/driver/fivegr_so.py +++ b/adaptation_layer/driver/fivegr_so.py @@ -31,7 +31,7 @@ from urllib.parse import urlencode import logging -logger = logging.getLogger('app.driver.fivergr_so') +logger = logging.getLogger('app.driver.fivegr_so') TESTING = os.environ.get("TESTING", False) PRISM_ALIAS = os.environ.get("PRISM_ALIAS", "prism-fivegr-so") From 367cebe07b9166d166da782eaf1bf5351a462955 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 28 Oct 2020 10:08:08 +0100 Subject: [PATCH 21/60] Revert "Add proxy in Dockerfile" This reverts commit a4ea8efde445b39fa6f6060ce40a196975db7342. --- Dockerfile | 65 ++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/Dockerfile b/Dockerfile index fbb32de..4c0dcfb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,34 +1,31 @@ -FROM python:3.6-slim as base -ENV http_proxy http://10.42.137.126:8080 -ENV https_proxy http://10.42.137.126:8080 -EXPOSE 5000 -RUN apt-get update && apt-get install -y build-essential -RUN ["pip3", "install", "pipenv==2020.6.2"] -WORKDIR /usr/src/app/ -# copy only pipfiles to install dependencies -COPY ./adaptation_layer/Pipfile* ./ -RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy"] -COPY ./adaptation_layer ./adaptation_layer -# setup env variables to initialize database -ARG DB_SEED_NFVO -ENV DB_SEED_NFVO $DB_SEED_NFVO -ARG DB_SEED_NFVO_CRED -ENV DB_SEED_NFVO_CRED $DB_SEED_NFVO_CRED -ARG DB_SEED_RANO -ENV DB_SEED_RANO $DB_SEED_RANO -ARG DB_SEED_RANO_CRED -ENV DB_SEED_RANO_CRED $DB_SEED_RANO_CRED -ENV FLASK_APP adaptation_layer -RUN ["rm", "-f", "adaptation_layer/data/mso-lo.db"] -RUN ["flask", "db", "upgrade"] -RUN ["flask", "seed"] - -FROM base as prod -COPY ./uWSGI . -CMD ["uwsgi", "--ini", "app.ini"] - -FROM base as test -RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy", "--dev"] -COPY ./openapi ./openapi -ENV http_proxy= -ENV https_proxy= +FROM python:3.6-slim as base +EXPOSE 5000 +RUN apt-get update && apt-get install -y build-essential +RUN ["pip3", "install", "pipenv==2020.6.2"] +WORKDIR /usr/src/app/ +# copy only pipfiles to install dependencies +COPY ./adaptation_layer/Pipfile* ./ +RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy"] +COPY ./adaptation_layer ./adaptation_layer +# setup env variables to initialize database +ARG DB_SEED_NFVO +ENV DB_SEED_NFVO $DB_SEED_NFVO +ARG DB_SEED_NFVO_CRED +ENV DB_SEED_NFVO_CRED $DB_SEED_NFVO_CRED +ARG DB_SEED_RANO +ENV DB_SEED_RANO $DB_SEED_RANO +ARG DB_SEED_RANO_CRED +ENV DB_SEED_RANO_CRED $DB_SEED_RANO_CRED +ENV FLASK_APP adaptation_layer +RUN ["rm", "-f", "adaptation_layer/data/mso-lo.db"] +RUN ["flask", "db", "upgrade"] +RUN ["flask", "seed"] + +FROM base as prod +COPY ./uWSGI . +CMD ["uwsgi", "--ini", "app.ini"] + +FROM base as test +RUN ["pipenv", "install", "--system", "--ignore-pipfile", "--deploy", "--dev"] +COPY ./openapi ./openapi + From a222a40ca0dcef8c733eff8e5c25edcf17be8327 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 28 Oct 2020 10:10:16 +0100 Subject: [PATCH 22/60] User logger.debug instead of print(). --- adaptation_layer/driver/ever.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/adaptation_layer/driver/ever.py b/adaptation_layer/driver/ever.py index f3be77d..de409a9 100644 --- a/adaptation_layer/driver/ever.py +++ b/adaptation_layer/driver/ever.py @@ -30,7 +30,7 @@ TESTING = os.environ.get("TESTING", False) PRISM_ALIAS = os.environ.get("PRISM_ALIAS", "prism-ever") -logger = logging.getLogger('app.driver.osm') +logger = logging.getLogger('app.driver.ever') class EVER(Driver): @@ -47,8 +47,8 @@ def __init__(self, rano_cred): self._base_path = 'http://{0}:{1}'.format(PRISM_ALIAS, 9999) def _exec_delete(self, url=None, params=None, headers=None): - print('#############execute delete######') - print('url= ' + url) + logger.debug('#############execute delete######') + logger.debug('url= ' + url) try: resp = requests.delete(url, params=params, verify=False, headers=headers) except Exception as e: @@ -67,14 +67,14 @@ def _exec_delete(self, url=None, params=None, headers=None): raise ResourceNotFound() else: error = resp.json() - print('############') - print('error: ' + error) - print('###########') + logger.debug('############') + logger.debug('error: ' + error) + logger.debug('###########') raise ServerError(error) def _exec_post(self, url=None, data=None, json=None, headers=None): - print('#############execute post######') - print('url= ' + url) + logger.debug('#############execute post######') + logger.debug('url= ' + url) try: resp = requests.post(url, data=data, json=json, verify=False, headers=headers) except Exception as e: @@ -101,14 +101,14 @@ def _exec_post(self, url=None, data=None, json=None, headers=None): error = resp.json() else: error = resp.text - print('############') - print('error: ' + error) - print('###########') + logger.debug('############') + logger.debug('error: ' + error) + logger.debug('###########') raise ServerError(error) def _exec_get(self, url=None, params=None, headers=None): - print('#############execute get######') - print('url= ' + url) + logger.debug('#############execute get######') + logger.debug('url= ' + url) try: resp = requests.get(url, params=params, verify=False, headers=headers) except Exception as e: @@ -127,9 +127,9 @@ def _exec_get(self, url=None, params=None, headers=None): raise ResourceNotFound() else: error = resp.json() - print('############') - print('error: ' + error) - print('###########') + logger.debug('############') + logger.debug('error: ' + error) + logger.debug('###########') raise ServerError(error) # all methods From 42bfdd1731a2a9833390677562352267051b2137 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Mon, 2 Nov 2020 12:38:25 +0100 Subject: [PATCH 23/60] Fix wrong type in nsdId for creation request. --- openapi/MSO-LO-swagger-resolved.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index 3ff62da..ee08cdf 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1612,8 +1612,7 @@ definitions: type: object properties: nsdId: - type: object - properties: {} + type: string nsName: type: string nsDescription: From 9485622d3c6e76f1e887091b66daf9427693172b Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Fri, 6 Nov 2020 12:47:46 +0100 Subject: [PATCH 24/60] Remove the NSD id mapping. --- adaptation_layer/driver/osm.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/adaptation_layer/driver/osm.py b/adaptation_layer/driver/osm.py index d0209ae..9c44d11 100644 --- a/adaptation_layer/driver/osm.py +++ b/adaptation_layer/driver/osm.py @@ -200,10 +200,6 @@ def get_ns_list(self, args=None) -> Tuple[BodyList, Headers]: def create_ns(self, args=None) -> Tuple[Body, Headers]: _url = "{0}/nslcm/v1/ns_instances".format(self._base_path) _url = self._build_url_query(_url, args) - osm_nsdpkg, headers_nsdpkg = self._get_nsdpkg(args={"args": { - "id": args["payload"]["nsdId"]} - }) - args["payload"]["nsdId"] = osm_nsdpkg["_id"] args['payload']['vimAccountId'] = self._select_vim() osm_ns, osm_headers = self._request( post, _url, json=args['payload'], headers=self._headers) From e2e0573a011a4e871b7769edffb0826bd0de67cb Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Fri, 6 Nov 2020 12:48:07 +0100 Subject: [PATCH 25/60] Setup RF test to use NSD package ID. --- adaptation_layer/robotframework/environment/variables.robot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/environment/variables.robot b/adaptation_layer/robotframework/environment/variables.robot index 2fd1144..2fe9ad5 100644 --- a/adaptation_layer/robotframework/environment/variables.robot +++ b/adaptation_layer/robotframework/environment/variables.robot @@ -17,7 +17,7 @@ ${AUTH_USAGE} 1 ${WRONG_AUTHORIZATION} Bearer XXXXXWRONGXXXXX ${MAX_WAIT} 2 min ${INTERVAL_WAIT} 2 s -${nsdId} pingpong +${nsdId} 5821d426-4c51-4be0-a849-5218a09f0d72 ${nsInstanceId} cc256072-2001-434c-8be9-0bd8609cef9f ${nsInstanceIdinexistent} 6fc3539c-e602-4afa-8e13-962fb5a7d81xxxxxxx ${ConflictNsInstanceId} 007c111c-e602-4afa-8e13-962fb5a7d81d From 9a9490ea84ec1495e891a8c80204591b9f05d797 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Fri, 6 Nov 2020 12:48:41 +0100 Subject: [PATCH 26/60] Better description for VimNetworkNotFound. --- adaptation_layer/error_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/error_handler.py b/adaptation_layer/error_handler.py index 1c05a80..b515f54 100644 --- a/adaptation_layer/error_handler.py +++ b/adaptation_layer/error_handler.py @@ -82,7 +82,7 @@ def __init__(self): class VimNetworkNotFound(Error): def __init__(self, vim_network_name: str, site_name: str): - super().__init__(description=f'{vim_network_name} not found on site {site_name}.') + super().__init__(description=f'Network {vim_network_name} not found on site {site_name}.') class NsOpNotFound(Error): From 06060c767c56383836edb5e16ea7709e165e5783 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 18 Nov 2020 11:30:04 +0100 Subject: [PATCH 27/60] Bump openapi version to 1.5.0 --- openapi/MSO-LO-swagger-resolved.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index ee08cdf..e8107fa 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -2,7 +2,7 @@ swagger: '2.0' info: description: 5G-EVE Adaptation Layer API spec. - version: '1.4.0' + version: '1.5.0' title: 5G-EVE Adaptation Layer API contact: {} host: example.com From b51f9a6d1cdda969e34b64f8c6f7b9b8b3078d68 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 18 Nov 2020 11:30:47 +0100 Subject: [PATCH 28/60] Set required fields for NS Instance creation request. --- openapi/MSO-LO-swagger-resolved.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index e8107fa..555e8bf 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1610,6 +1610,10 @@ definitions: title: ErrorResponse_details NfvoNsInstancesRequest: type: object + required: + - nsdId + - nsName + - nsDescription properties: nsdId: type: string From 6d339752d6a819648a5dbbec54ec69a1b2c1348d Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 18 Nov 2020 11:31:08 +0100 Subject: [PATCH 29/60] Add vimAccountId to NS Instance create request body. --- openapi/MSO-LO-swagger-resolved.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index 555e8bf..8ea26f6 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1621,6 +1621,9 @@ definitions: type: string nsDescription: type: string + vimAccountId: + type: string + format: uuid title: NfvoNsInstancesRequest NfvoNsInstantiateRequest: type: object From 2805e44e80772c9556ac288ab4e8cdb307090dd8 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 18 Nov 2020 12:14:31 +0100 Subject: [PATCH 30/60] Try to get vimaccountid from body, set default if not found. --- adaptation_layer/driver/osm.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adaptation_layer/driver/osm.py b/adaptation_layer/driver/osm.py index 9c44d11..228cb8c 100644 --- a/adaptation_layer/driver/osm.py +++ b/adaptation_layer/driver/osm.py @@ -200,7 +200,11 @@ def get_ns_list(self, args=None) -> Tuple[BodyList, Headers]: def create_ns(self, args=None) -> Tuple[Body, Headers]: _url = "{0}/nslcm/v1/ns_instances".format(self._base_path) _url = self._build_url_query(_url, args) - args['payload']['vimAccountId'] = self._select_vim() + try: + args['payload']['vimAccountId'] + except (KeyError): + logger.info('no vimAccountId set, select first in NFVO') + args['payload']['vimAccountId'] = self._select_vim() osm_ns, osm_headers = self._request( post, _url, json=args['payload'], headers=self._headers) # Get location header from OSM From 683225d74a0c64f9b8d4bec1250ea2e85f3a2a07 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 18 Nov 2020 12:14:59 +0100 Subject: [PATCH 31/60] Make nsDescription not required. --- openapi/MSO-LO-swagger-resolved.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/openapi/MSO-LO-swagger-resolved.yaml b/openapi/MSO-LO-swagger-resolved.yaml index 8ea26f6..bc30b7f 100644 --- a/openapi/MSO-LO-swagger-resolved.yaml +++ b/openapi/MSO-LO-swagger-resolved.yaml @@ -1613,7 +1613,6 @@ definitions: required: - nsdId - nsName - - nsDescription properties: nsdId: type: string From afdf8bbb3cf11698272d8f60347593d717261483 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 18 Nov 2020 12:48:29 +0100 Subject: [PATCH 32/60] Reorder imports, refactor. --- adaptation_layer/driver/osm.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/adaptation_layer/driver/osm.py b/adaptation_layer/driver/osm.py index 228cb8c..eefe00d 100644 --- a/adaptation_layer/driver/osm.py +++ b/adaptation_layer/driver/osm.py @@ -19,22 +19,21 @@ import re from datetime import datetime from functools import wraps -from typing import Dict, Tuple, List +from typing import Dict, List, Tuple from urllib.parse import urlencode -import redis import urllib3 import yaml as YAML -from requests import ConnectionError, Timeout, TooManyRedirects, URLRequired, \ - api, HTTPError, get, post, delete +from requests import ConnectionError, HTTPError, Timeout, TooManyRedirects, URLRequired, api, delete, get, post from urllib3.exceptions import InsecureRequestWarning -from adaptation_layer.error_handler import ResourceNotFound, NsNotFound, \ - VnfNotFound, Unauthorized, ServerError, NsOpNotFound, VnfPkgNotFound, \ - VimNotFound, NsdNotFound, BadRequest, Forbidden, MethodNotAllowed, \ - Unprocessable, Conflict, VimNetworkNotFound +import redis +from adaptation_layer.error_handler import (BadRequest, Conflict, Forbidden, MethodNotAllowed, NsdNotFound, NsNotFound, + NsOpNotFound, ResourceNotFound, ServerError, Unauthorized, Unprocessable, + VimNetworkNotFound, VimNotFound, VnfNotFound, VnfPkgNotFound) from adaptation_layer.repository import iwf_repository -from .interface import Driver, Headers, BodyList, Body + +from .interface import Body, BodyList, Driver, Headers urllib3.disable_warnings(InsecureRequestWarning) TESTING = os.getenv('TESTING', 'false').lower() @@ -266,7 +265,8 @@ def instantiate_ns(self, nsId: str, args=None) -> Tuple[None, Headers]: if additional_params: if 'vld' in additional_params: instantiate_payload['vld'] = additional_params['vld'] - vnf_items = self._force_float_ip(additional_params['vld'], ns_res) + vnf_items = self._force_float_ip( + additional_params['vld'], ns_res) self._extend_vnf_add_params(instantiate_payload, vnf_items) if 'vnf' in additional_params: mapping = {v: str(i + 1) for i, v in From 12ca18d97ad9c4d76e866c80892c8750522dbfec Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 18 Nov 2020 13:15:34 +0100 Subject: [PATCH 33/60] Add unit test for vimAccountId parameter in create_ns --- adaptation_layer/tests/test_osm.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/adaptation_layer/tests/test_osm.py b/adaptation_layer/tests/test_osm.py index a08e062..f47bd61 100644 --- a/adaptation_layer/tests/test_osm.py +++ b/adaptation_layer/tests/test_osm.py @@ -50,6 +50,22 @@ def test_create_ns_201(self): except (ValidationError, SchemaError) as e: self.fail(msg=e.message) + # Check status codes 201, 401, 404, headers and payload for create_ns() + def test_create_ns_201_with_vim(self): + mock_ns_vim = mock_ns.copy() + mock_ns_vim['vimAccountId'] = '76782dbd-eaa1-48ba-bdc7-a6cbbe5d4e2e' + res = self.client().post('/nfvo/1/ns_instances?__code=201', json=mock_ns_vim) + self.assertEqual(201, res.status_code) + + self.assertIn('Location', res.headers) + validate_url = urlparse(res.headers["Location"]) + self.assertTrue(all([validate_url.scheme, validate_url.netloc, validate_url.path])) + + try: + validate(res.json, ns_schema) + except (ValidationError, SchemaError) as e: + self.fail(msg=e.message) + def test_create_ns_400(self): res = self.client().post('/nfvo/1/ns_instances?__code=400', json=mock_ns) self.assertEqual(400, res.status_code) From da79172bcc378a2c1c7ad1f2efb6e026aff8aa3f Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Tue, 24 Nov 2020 11:58:02 +0100 Subject: [PATCH 34/60] Redis memory problems. Reduce TTL for operations id. Increase maxmemory. --- adaptation_layer/tasks.py | 2 +- redis/redis.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adaptation_layer/tasks.py b/adaptation_layer/tasks.py index 4c9fff6..4eb6b6a 100644 --- a/adaptation_layer/tasks.py +++ b/adaptation_layer/tasks.py @@ -28,7 +28,7 @@ redis_host = os.getenv('REDIS_HOST') if os.getenv('REDIS_HOST') else 'redis' redis_port = int(os.getenv('REDIS_PORT')) if os.getenv('REDIS_PORT') else 6379 # TTL for key in redis -KEY_TTL = 86400 +KEY_TTL = 21600 # 6 hours celery = Celery('tasks', broker='redis://{0}:{1}/0'.format(redis_host, redis_port), diff --git a/redis/redis.conf b/redis/redis.conf index 5d36cb8..355a299 100644 --- a/redis/redis.conf +++ b/redis/redis.conf @@ -1,6 +1,6 @@ ############################## MEMORY MANAGEMENT ################################ -maxmemory 100mb +maxmemory 200mb # MAXMEMORY POLICY: how Redis will select what to remove when maxmemory # is reached. You can select one from the following behaviors: From b04b3a19a8752e95ad25216b2654e31bc43232eb Mon Sep 17 00:00:00 2001 From: grzesmich Date: Wed, 25 Nov 2020 13:04:31 +0100 Subject: [PATCH 35/60] passing vimShortId in create request --- adaptation_layer/driver/onap.py | 6 +- adaptation_layer/tests/onap-api.yaml | 208 ++++++++++----------------- 2 files changed, 82 insertions(+), 132 deletions(-) diff --git a/adaptation_layer/driver/onap.py b/adaptation_layer/driver/onap.py index 61db6ab..71e43c1 100644 --- a/adaptation_layer/driver/onap.py +++ b/adaptation_layer/driver/onap.py @@ -125,9 +125,13 @@ def get_ns_list(self, args=None) -> Tuple[BodyList, Headers]: def create_ns(self, args=None) -> Tuple[Body, Headers]: _url = '{0}/create'.format(self._base_path) _url = self._build_url_query(_url, args) + + request_body = args['payload'] + request_body["vimShortId"] = self._nfvoId + try: created_ns, resp_headers = self._exec_post( - _url, json=args['payload'], headers=self._headers) + _url, json=request_body, headers=self._headers) except ResourceNotFound: nsd_Id = args['payload']['nsdId'] raise NsdNotFound(nsd_id=nsd_Id) diff --git a/adaptation_layer/tests/onap-api.yaml b/adaptation_layer/tests/onap-api.yaml index 1f49caa..0d33362 100644 --- a/adaptation_layer/tests/onap-api.yaml +++ b/adaptation_layer/tests/onap-api.yaml @@ -1,15 +1,13 @@ openapi: 3.0.0 servers: - - description: ONAP Translation Component - url: https://github.com/chabimic/NS-InstantiationServer - description: Onap driver - url: https://github.com/TheWall89/adaptation-layer/tree/onap_driver + url: https://github.com/5GEVE/mso-lo info: description: ONAP Translation Component API - version with Celery and rabbitMQ with vnf info + version with Celery and rabbitMQ with vnf info and vims version: "2.1" title: ONAP Translation Component API contact: @@ -25,8 +23,9 @@ tags: description: NS LCM Operations - name: 'IWL Catalogue API' description: API to retrieve the list of service specification and .csar archives - -# paths + - name: 'VIM configuration' + description: Information about configured VIM/tenant in ONAP TC (ns-server) tool +# paths: # get all ns instances info '/instances': @@ -60,10 +59,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # get ns instnce info '/instances/{ns_db_id}': parameters: @@ -94,10 +89,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # create a ns instance ID '/create': post: @@ -133,10 +124,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # instantiate NS with given NsId '/instantiate/{ns_db_id}': parameters: @@ -174,10 +161,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # terminate NS '/terminate/{ns_db_id}': parameters: @@ -215,10 +198,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # delete NS Instance '/delete/{ns_db_id}': parameters: @@ -245,10 +224,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # get list of oll ns_lcm_op_occs '/ns_lcm_op_occs': get: @@ -270,10 +245,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # get a info lcm op occs with given ID '/ns_lcm_op_occs/{lcm_id}': parameters: @@ -304,10 +275,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # get a info lcm op occs for given ns_Id '/ns_lcm_op_occs/ns_id/{ns_db_id}': parameters: @@ -338,10 +305,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # get a list of service specifications '/service_specification': get: @@ -365,10 +328,6 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' # get a list of service specifications '/service_specification/{service_uuid}': parameters: @@ -386,11 +345,11 @@ paths: operationId: serviceSpecArchive responses: '200': - description: .csar archive - # content: - # application/pdf: - # schema: - # $ref: '#/components/schemas/ListServiceSpec' + description: .csar archive with service specification in TOSCA + content: + application/octet-stream: + schema: + format: binary '400': $ref: '#/components/responses/BadRequest' '404': @@ -399,10 +358,27 @@ paths: $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/InternalServerError' - # '5XX': - # $ref: '#/components/responses/UnexpectedError' - # default: - # $ref: '#/components/responses/UnexpectedError' +# get list of configured VIM tenants + '/vims': + get: + tags: + - 'VIM configuration' + summary: retrieve a list of all configured VIM in tool + description: retrieve a list of all configured VIM in ONAP TC (ns-server) tool + operationId: vimList + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListConfVims' + '400': + $ref: '#/components/responses/BadRequest' + '405': + $ref: '#/components/responses/MethodNotAllowed' + '500': + $ref: '#/components/responses/InternalServerError' # components responses components: responses: @@ -486,6 +462,12 @@ components: application/json: schema: $ref: '#/components/schemas/ListServiceSpec' + ListVim: + description: list of configured vim in tc (ns-server) + content: + application/json: + schema: + $ref: '#/components/schemas/ListConfVims' # end of schemas in responses # END RESPONSES schemas: @@ -496,12 +478,16 @@ components: nsdId: type: string format: uuid + example: c418cc62-f3b4-43c6-b684-d38bfbd2d7f6 nsName: # description: type: string nsDescription: # description: type: string + vimShortId: + type: integer + example: 1 required: - nsdId - nsName @@ -564,13 +550,13 @@ components: vnfdId: type: string format: uuid - example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + example: 8a585f64-5717-4562-b3fc-2c963f66afa6 vnfProductName: type: string vimId: type: string - format: uuid - example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + # format: uuid + example: 5e7c35e86c1a40bd89b6a61d34b9c21e instantiationState: type: string enum: @@ -586,6 +572,7 @@ components: type: array items: $ref: '#/components/schemas/VnfExtCpInfo' + example: [] # vnfInstanceCreated: type: object @@ -593,7 +580,7 @@ components: id: type: string format: uuid - example: null #3fa85f64-5717-4562-b3fc-2c963f66afa6 + example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 vnfdId: type: string format: uuid @@ -602,79 +589,15 @@ components: type: string vimId: type: string - format: uuid - example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + # format: uuid + example: "" instantiationState: type: string enum: - #- INSTANTIATED - NOT_INSTANTIATED -# instantiatedVnfInfo: -# type: object # VnfExtCpInfo: -# nullable: true type: object - # properties: - # id: - # type: string - # format: uuid - # example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 - # cpdId: - # type: string - # format: uuid - # example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 - # cpProtocolInfo: - # type: array - # items: - # $ref: '#/components/schemas/CpProtocolInfo' -# -# CpProtocolInfo: -# type: object -# required: -# - ipOverEthernet -# - layerProtocol -# properties: -# layerProtocol: -# type: string -# enum: -# - IP_OVER_ETHERNET -# ipOverEthernet: -# allOf: -# - $ref: '#/components/schemas/IpOverEthernetAddressInfo' -# # # -# IpOverEthernetAddressInfo: -# type: object -# required: -# - ipAddresses -# - macAddress -# properties: -# macAddress: -# type: string -# format: MAC -# ipAddresses: -# type: array -# items: -# $ref: '#/components/schemas/IpOverEthernetAddressInfo_ipAddresses' -# - # IpOverEthernetAddressInfo_ipAddresses: - # type: object - # required: - # - type - # properties: - # type: - # type: string - # enum: - # - IPV4 - # - IPV6 - # addresses: - # type: array - # items: - # $ref: '#/components/schemas/IpAddress' -# - # IpAddress: - # type: string - # format: IP # NsInstanceIdCreated: type: object @@ -754,6 +677,35 @@ components: example: 1de0e9c3-b238-44da-b01b-b249a7784b03 name: type: string + ListConfVims: + type: array + items: + $ref: '#/components/schemas/confVims' +# + confVims: + type: object + properties: + vimShortId: + type: integer + example: 1 + vimInfo: + $ref: '#/components/schemas/confVim' +# + confVim: + type: object + properties: + cloud_owner: + type: string + region_id: + type: string + tenant_name: + type: string + tenant_id: + type: string + type: + type: string + example: openstack +# # END SCHEMAS # start request bodies requestBodies: @@ -763,9 +715,3 @@ components: schema: $ref: '#/components/schemas/createNsId' # END REQUEST BODIES -# -# # commented -# securitySchemes: -# bearerAuth: -# type: http -# scheme: bearer From 5e04b5f8e76ec9e030e913492600cb82be8f2b49 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Mon, 30 Nov 2020 19:39:21 +0100 Subject: [PATCH 36/60] Add method to create a network for unit tests. --- adaptation_layer/repository/iwf_repository.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/adaptation_layer/repository/iwf_repository.py b/adaptation_layer/repository/iwf_repository.py index fe3ab70..0af4fb0 100644 --- a/adaptation_layer/repository/iwf_repository.py +++ b/adaptation_layer/repository/iwf_repository.py @@ -310,6 +310,15 @@ def add_orc_cred_test(orc_type: str, orc_id: int): resp.raise_for_status() +def add_network_test(json: Dict, site: int): + post_resp = post(f"{url}/networks", json=json) + post_resp.raise_for_status() + put_resp = put(post_resp.json()["_links"]["site"]["href"], + f"{url}/sites/{site}", + headers={"Content-Type": "text/uri-list"}) + put_resp.raise_for_status() + + @_server_error def get_site_network(vim_network_name: str, nfvo_id: int): nfvo = _get_nfvo(nfvo_id) From f0ed2d1d7b7c5b2690545858c65c3cc2e9971074 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Mon, 30 Nov 2020 19:40:03 +0100 Subject: [PATCH 37/60] Fix unit tests with class method. Fix network. --- adaptation_layer/tests/test_iwf_repository.py | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/adaptation_layer/tests/test_iwf_repository.py b/adaptation_layer/tests/test_iwf_repository.py index 0edaf13..f05d38b 100644 --- a/adaptation_layer/tests/test_iwf_repository.py +++ b/adaptation_layer/tests/test_iwf_repository.py @@ -20,7 +20,7 @@ get_rano_list, create_subscription, delete_subscription, get_subscription, \ get_subscription_list, \ search_subs_by_ns_instance, find_nfvos_by_type, post_vim_safe, \ - get_site_network + get_site_network, add_network_test class TestIwfRepository(unittest.TestCase): @@ -31,33 +31,44 @@ class TestIwfRepository(unittest.TestCase): and have a iwf-repository instance running locally. """ - def setUp(self) -> None: - self.nfvo_id = 1 - add_orc_cred_test('nfvo', self.nfvo_id) - self.rano_id = 1 - add_orc_cred_test('rano', self.rano_id) - self.ns_instance = "45f95003-4dd1-4e20-87cf-4373c9f4e946" - payload = { + nfvo_id = 1 + rano_id = 1 + ns_instance = "45f95003-4dd1-4e20-87cf-4373c9f4e946" + sub_id = "" + net_name = "osm-external" + net_site = 1 + + @classmethod + def setUpClass(cls) -> None: + add_orc_cred_test('nfvo', cls.nfvo_id) + add_orc_cred_test('rano', cls.rano_id) + sub = { "callbackUri": "http://127.0.0.1:8082/", - "nsInstanceId": self.ns_instance, + "nsInstanceId": cls.ns_instance, "notificationTypes": [ "NsLcmOperationOccurrenceNotification", "NsIdentifierDeletionNotification", "NsIdentifierCreationNotification" ] } - self.sub_id = create_subscription(self.nfvo_id, payload)['id'] - - def tearDown(self) -> None: - delete_subscription(self.sub_id) + cls.sub_id = create_subscription(cls.nfvo_id, sub)['id'] + site_network = { + "vim_network_name": cls.net_name, + "floating_ip": True, + "mgmt_net": False, + "external_net": True, + "cidr": "10.100.1.0/24", + "ip_mapping": None, + } + add_network_test(site_network, cls.net_site) def test_get_nfvo_by_id(self): - nfvo = get_nfvo_by_id(self.nfvo_id) + nfvo = get_nfvo_by_id(TestIwfRepository.nfvo_id) self.assertEqual({'id': 1, 'name': 'ITALY_TURIN', 'site': 'ITALY_TURIN', 'type': 'OSM'}, nfvo) def test_get_rano_by_id(self): rano = get_rano_by_id(self.rano_id) - self.assertEqual({'id': 1, 'name': 'italian_ever', 'site': 'ITALY_TURIN', 'type': 'EVER'}, rano) + self.assertEqual({'id': 1, 'name': 'ITALY_EVER', 'site': 'ITALY_TURIN', 'type': 'EVER'}, rano) def test_get_nfvo_cred(self): cred = get_nfvo_cred(self.nfvo_id) @@ -79,7 +90,7 @@ def test_get_rano_cred(self): def test_get_nfvo_list(self): length = len(get_nfvo_list()) - self.assertEqual(6, length) + self.assertEqual(8, length) def test_get_rano_list(self): length = len(get_rano_list()) @@ -153,14 +164,14 @@ def test_post_vim_safe(self): post_vim_safe(osm_vim, f'http://localhost:8087/nfvOrchestrators/{self.nfvo_id}') def test_get_site_network(self): - net = get_site_network('floating', self.nfvo_id) + net = get_site_network(self.net_name, self.nfvo_id) self.assertDictEqual({ "id": 1, - "vim_network_name": "floating", + "vim_network_name": self.net_name, "floating_ip": True, "mgmt_net": False, "external_net": True, - "cidr": "10.50.160.0/24", + "cidr": "10.100.1.0/24", "ip_mapping": None, "_links": { "self": { From cd8c9e6012f2df1b3867e89791671da1f5294948 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Mon, 30 Nov 2020 19:40:18 +0100 Subject: [PATCH 38/60] Fix docker-compose file. --- docker-compose.test-iwf-repository.yml | 31 ++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/docker-compose.test-iwf-repository.yml b/docker-compose.test-iwf-repository.yml index 2bb313e..ac0f63b 100644 --- a/docker-compose.test-iwf-repository.yml +++ b/docker-compose.test-iwf-repository.yml @@ -1,14 +1,23 @@ -version: '3.7' +--- +version: "3.7" services: - iwf-repository-app: + iwf-repository-app-test: image: 5geve/iwf-repository:latest depends_on: - - iwf-repository-db + - iwf-repository-db-test networks: iwf-repository-net: aliases: - iwf-repository-app - iwf-repository-db: + command: + [ + "java", + "-Dspring.profiles.active=dev", + "-Dspring.datasource.url=jdbc:postgresql://iwf-repository-db:5432/iwf-repository", + "-jar", + "app.jar", + ] + iwf-repository-db-test: image: postgres:12-alpine environment: POSTGRES_USER: iwf-repository @@ -27,12 +36,20 @@ services: DB_SEED_RANO: adaptation_layer/seed/rano_mock.json DB_SEED_RANO_CRED: adaptation_layer/seed/rano_credentials_mock.json depends_on: - - iwf-repository-app - - iwf-repository-db + - iwf-repository-app-test + - iwf-repository-db-test environment: IWFREPO: "True" IWFREPO_HOST: "iwf-repository-app" - command: ["adaptation_layer/tests/wait-for-it.sh", "iwf-repository-app:8087", "--", "pytest", "-v", "adaptation_layer/tests/test_iwf_repository.py"] + command: + [ + "adaptation_layer/tests/wait-for-it.sh", + "iwf-repository-app:8087", + "--", + "pytest", + "-v", + "adaptation_layer/tests/test_iwf_repository.py", + ] networks: iwf-repository-net: aliases: From 9741e6c501d413a27dd47fe492e6f41bad0af6a1 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Mon, 30 Nov 2020 20:06:54 +0100 Subject: [PATCH 39/60] Optimizing test setup. --- adaptation_layer/tests/test_ever.py | 10 ++++------ adaptation_layer/tests/test_fivegr_so.py | 10 ++++------ adaptation_layer/tests/test_nfvo.py | 7 ++++--- adaptation_layer/tests/test_onap.py | 10 ++++------ adaptation_layer/tests/test_osm.py | 10 ++++------ 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/adaptation_layer/tests/test_ever.py b/adaptation_layer/tests/test_ever.py index 7801a1b..031310a 100644 --- a/adaptation_layer/tests/test_ever.py +++ b/adaptation_layer/tests/test_ever.py @@ -29,14 +29,12 @@ class EverTestCase(unittest.TestCase): + client = None - def setUp(self): + @classmethod + def setUpClass(cls): """Define test variables and initialize app.""" - self.app = create_app() - self.client = self.app.test_client - - def tearDown(self): - """teardown all initialized variables.""" + cls.client = create_app().test_client # Check status codes 200, 404, headers and payload for get_ns_list() def test_get_ns_list_200(self): diff --git a/adaptation_layer/tests/test_fivegr_so.py b/adaptation_layer/tests/test_fivegr_so.py index fb69829..5523fa3 100644 --- a/adaptation_layer/tests/test_fivegr_so.py +++ b/adaptation_layer/tests/test_fivegr_so.py @@ -25,14 +25,12 @@ class fivegrSOTestCase(unittest.TestCase): + client = None - def setUp(self): + @classmethod + def setUpClass(cls): """Define test variables and initialize app.""" - self.app = create_app() - self.client = self.app.test_client - - def tearDown(self): - pass + cls.client = create_app().test_client # Check status codes 201, 401, 404, headers and payload for create_ns() def test_create_ns_201(self): diff --git a/adaptation_layer/tests/test_nfvo.py b/adaptation_layer/tests/test_nfvo.py index bc91d85..68865a3 100644 --- a/adaptation_layer/tests/test_nfvo.py +++ b/adaptation_layer/tests/test_nfvo.py @@ -24,11 +24,12 @@ class NFVOTestCase(unittest.TestCase): + client = None - def setUp(self): + @classmethod + def setUpClass(cls): """Define test variables and initialize app.""" - self.app = create_app() - self.client = self.app.test_client + cls.client = create_app().test_client def tearDown(self): """teardown all initialized variables.""" diff --git a/adaptation_layer/tests/test_onap.py b/adaptation_layer/tests/test_onap.py index f02727d..eb4e266 100644 --- a/adaptation_layer/tests/test_onap.py +++ b/adaptation_layer/tests/test_onap.py @@ -29,14 +29,12 @@ class OnapTestCase(unittest.TestCase): + client = None - def setUp(self): + @classmethod + def setUpClass(cls): """Define test variables and initialize app.""" - self.app = create_app() - self.client = self.app.test_client - - def tearDown(self): - """teardown all initialized variables.""" + cls.client = create_app().test_client # Check status codes 200, 404, headers and payload for get_ns_list() def test_get_ns_list_200(self): diff --git a/adaptation_layer/tests/test_osm.py b/adaptation_layer/tests/test_osm.py index f47bd61..198d9cf 100644 --- a/adaptation_layer/tests/test_osm.py +++ b/adaptation_layer/tests/test_osm.py @@ -27,14 +27,12 @@ class OSMTestCase(unittest.TestCase): + client = None - def setUp(self): + @classmethod + def setUpClass(cls): """Define test variables and initialize app.""" - self.app = create_app() - self.client = self.app.test_client - - def tearDown(self): - """teardown all initialized variables.""" + cls.client = create_app().test_client # Check status codes 201, 401, 404, headers and payload for create_ns() def test_create_ns_201(self): From 0b9faf5f19b7eb662c8a4baf3b2b2e7eb89000ec Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 2 Dec 2020 15:13:50 +0100 Subject: [PATCH 40/60] Improve readme, reorder variables. --- adaptation_layer/robotframework/README.md | 64 ++++++++++++++----- .../environment/variables.robot | 27 +++++--- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/adaptation_layer/robotframework/README.md b/adaptation_layer/robotframework/README.md index 59f5c45..81fb52e 100644 --- a/adaptation_layer/robotframework/README.md +++ b/adaptation_layer/robotframework/README.md @@ -1,23 +1,61 @@ -## Tests with Robot Framework +# Tests with Robot Framework The `.robot` scripts in this folder perform integration tests of the `mso-lo` application -against a real instance of a NFVO. +against a real instance of a NFVO or RANO. To execute the tests you need: - An instance of `mso-lo` up and running -- An instance of a real NFVO -- Correct communication between the two above (check your database) +- An instance of a real NFVO or RANO +- An instante of the [IWF Repository](https://github.com/5GEVE/iwf-repository) +- Correct communication between the components above + +## Configuration Check the file [variables.robot](./environment/variables.robot) and change the variables according -to your setup. The important variables to change are: +to your setup. + +Setup the protocol, host and port where mso-lo application is listening. + +``` +${MSO-LO_HOST} localhost +${MSO-LO_PORT} 80 +${HTTP} http +``` + +Choose if you want to test a `rano` or a `nfvo` and set its id. + +``` +${apiRoot} nfvo +${nfvoId} 1 +``` + +Select the id of the NSD you want to deploy for the test. +It must be available in your NFVO or RANO catalog. + +``` +${nsdId} 5821d426-4c51-4be0-a849-5218a09f0d72 +``` -- `${MSO-LO_HOST}` -- `${MSO-LO_PORT}` -- `${nfvoId}` -- `${nsdId}` (this is the NSD to be instantiated during the tests, pick something simple) +Select the name of the VIM Network and the name of the VLD to be associated to it. -Example of execution: +``` +${vimNetworkName} 'test' +${vldName} 'mgmt_vl' +``` + +``` +${vnfInstanceIds} [] +${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] +``` + +Script [MSO-LO-LCM-Workflow.robot](./MSO-LO-LCM-Workflow.robot) contains a workflow that +instantiates and terminates a Network Service on the configured NFVO. +Some test cases include features to wait for the NS to be deployed. Maximum waiting time is set to +2 minutes. You can increase it if it is not enough by changing `${MAXIMUM_WAIT}` variable in +[variables.robot](./environment/variables.robot). + +## Execution: ```shell script $ cd {project-dir}/adaptation_layer @@ -28,9 +66,3 @@ $ cd ./robotframework $ export OPENAPI_PATH=../../openapi/MSO-LO-swagger-resolved.yaml $ robot --outputdir output MSO-LO-LCM-Workflow.robot MSO-LO-NFVO-Workflow.robot ``` - -Script [MSO-LO-LCM-Workflow.robot](./MSO-LO-LCM-Workflow.robot) contains a workflow that -instantiates and terminates a Network Service on the configured NFVO. -Some test cases include features to wait for the NS to be deployed. Maximum waiting time is set to -2 minutes. You can increase it if it is not enough by changing `${MAXIMUM_WAIT}` variable in -[variables.robot](./environment/variables.robot). diff --git a/adaptation_layer/robotframework/environment/variables.robot b/adaptation_layer/robotframework/environment/variables.robot index 2fe9ad5..6e9f450 100644 --- a/adaptation_layer/robotframework/environment/variables.robot +++ b/adaptation_layer/robotframework/environment/variables.robot @@ -3,31 +3,38 @@ ${MSO-LO_HOST} localhost # Hostname of the MSO-LO ${MSO-LO_PORT} 80 # Listening port of the MSO-LO ${HTTP} http ${MSO-LO_BASE_API} ${HTTP}://${MSO-LO_HOST}:${MSO-LO_PORT} -${SCHEMAS_PATH} ../tests/response_schemas.py +${apiRoot} nfvo +${nfvoId} 1 + +${nsdId} 5821d426-4c51-4be0-a849-5218a09f0d72 + +${vimNetworkName} 'test' +${vldName} 'mgmt_vl' + +${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] + +${notificationUri} http://192.168.18.14:8083/ + +${MAX_WAIT} 2 min + +# This should not be changed +${SCHEMAS_PATH} ../tests/response_schemas.py ${AUTHORIZATION} Bearer QWxhZGRpbjpvcGVuIHNlc2FtZQ== ${CONTENT_TYPE} application/json ${CONTENT_TYPE_PATCH} application/merge-patch+json ${ACCEPT_JSON} application/json ${ACCEPT} application/json -${apiRoot} nfvo -${nfvoId} 1 ${nfvoIdinexistent} 80 ${AUTH_USAGE} 1 ${WRONG_AUTHORIZATION} Bearer XXXXXWRONGXXXXX -${MAX_WAIT} 2 min ${INTERVAL_WAIT} 2 s -${nsdId} 5821d426-4c51-4be0-a849-5218a09f0d72 ${nsInstanceId} cc256072-2001-434c-8be9-0bd8609cef9f +${vnfInstanceIds} [] ${nsInstanceIdinexistent} 6fc3539c-e602-4afa-8e13-962fb5a7d81xxxxxxx ${ConflictNsInstanceId} 007c111c-e602-4afa-8e13-962fb5a7d81d ${nsInstanceName} Test-nsInstance ${nsInstanceDescription} description ns -${vnfInstanceIds} [] -${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] -${vldName} 'mgmt_vl' -${vimNetworkName} 'test' -${notificationUri} http://192.168.18.14:8083/ ${SINGLE_FILE_VNFD} 1 # If VNFD is PLAIN TEXT ${ACCEPT_PLAIN} text/plain ${ACCEPT_ZIP} application/zip From 209978381ae09baa8209617e7c2048928bd21d35 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 2 Dec 2020 19:23:46 +0100 Subject: [PATCH 41/60] Add if statements to ignore some settings if not set. --- .../NSLCMOperationKeywords.robot | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index d224e88..4d92b38 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -184,14 +184,20 @@ POST Instantiate nsInstance with vnf/vld in additionalParamsForNs Set Headers {"Content-Type": "${CONTENT_TYPE}"} Run Keyword If ${AUTH_USAGE} == 1 Set Headers {"Authorization":"${AUTHORIZATION}"} ${body}= Load JSON From File jsons/InstantiateNsRequest.json - ${vnf}= set variable [] - ${vnf}= evaluate [{"vnfInstanceId": vnfId,"vimAccountId": random.choice(${vimAccountIds})} for vnfId in ${vnfInstanceIds}] random - Log ${vnf} - ${body}= Update Value To Json ${body} $.additionalParamsForNs.vnf ${vnf} - ${vld}= evaluate [{'name': ${vldName}, 'vim-network-name': ${vimNetworkName}}] - Log ${vld} - ${body}= Update Value To Json ${body} $.additionalParamsForNs.vld ${vld} - Log ${body} + ${vimAccountIds}= Get Variable Value ${vimAccountIds} + Run Keyword If "${vimAccountIds}" != "None" + ... Log ${vimAccountIds} + ... ${vnf}= set variable [] + ... ${vnf}= evaluate [{"vnfInstanceId": vnfId,"vimAccountId": random.choice(${vimAccountIds})} for vnfId in ${vnfInstanceIds}] random + ... Log ${vnf} + ... ${body}= Update Value To Json ${body} $.additionalParamsForNs.vnf ${vnf} + ${vimNetworkName}= Get Variable Value ${vimNetworkName} + Run Keyword If "${vimNetworkName}" != "None" + ... Log "${vimNetworkName}" + ... ${vld}= evaluate [{'name': ${vldName}, 'vim-network-name': ${vimNetworkName}}] + ... Log ${vld} + ... ${body}= Update Value To Json ${body} $.additionalParamsForNs.vld ${vld} + ... Log ${body} Post ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} ${outputResponse}= Output response Set Global Variable @{response} ${outputResponse} From f06f756726a6b49cd4ed1167e433d443a040fcac Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 2 Dec 2020 19:24:30 +0100 Subject: [PATCH 42/60] Explain variables that can be ignored. --- adaptation_layer/robotframework/README.md | 10 ++++++++-- .../robotframework/environment/variables.robot | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/adaptation_layer/robotframework/README.md b/adaptation_layer/robotframework/README.md index 81fb52e..d0c8d80 100644 --- a/adaptation_layer/robotframework/README.md +++ b/adaptation_layer/robotframework/README.md @@ -37,15 +37,21 @@ It must be available in your NFVO or RANO catalog. ${nsdId} 5821d426-4c51-4be0-a849-5218a09f0d72 ``` -Select the name of the VIM Network and the name of the VLD to be associated to it. +The following settings can be used to associate a Virtual Link of your NSD to a network existing on your VIM. +Please provide both names or **remove/comment the two lines**. + +> Note: If you want to use this you also need to register your network in the +> IWF repository. ``` ${vimNetworkName} 'test' ${vldName} 'mgmt_vl' ``` +The following setting is used to deploy the VNFs of your service on multiple VIMs available in your NFVO/RANO. +Please provide the UUIDs as shown below or **remove/comment the line**. + ``` -${vnfInstanceIds} [] ${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] ``` diff --git a/adaptation_layer/robotframework/environment/variables.robot b/adaptation_layer/robotframework/environment/variables.robot index 6e9f450..93f7f7b 100644 --- a/adaptation_layer/robotframework/environment/variables.robot +++ b/adaptation_layer/robotframework/environment/variables.robot @@ -7,12 +7,12 @@ ${MSO-LO_BASE_API} ${HTTP}://${MSO-LO_HOST}:${MSO-LO_PORT} ${apiRoot} nfvo ${nfvoId} 1 -${nsdId} 5821d426-4c51-4be0-a849-5218a09f0d72 +${nsdId} 4125ae83-6614-4bf6-be1a-b8aa16e7e42c -${vimNetworkName} 'test' -${vldName} 'mgmt_vl' +#${vimNetworkName} 'test' +#${vldName} 'mgmt_vl' -${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] +#${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] ${notificationUri} http://192.168.18.14:8083/ From c01f06b520b0c16ac239b94021a49ade1e5667bc Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 2 Dec 2020 19:27:35 +0100 Subject: [PATCH 43/60] Remove empty variables from instantiate request. --- .../robotframework/jsons/InstantiateNsRequest.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json b/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json index 2af96c5..19b1cdb 100644 --- a/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json +++ b/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json @@ -1,7 +1,4 @@ { - "additionalParamsForNs": { - "vnf": [], - "vld": [] } } From 7e49cc7bcd117e061652c17bffeccad8d9e3606d Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 3 Dec 2020 12:22:18 +0100 Subject: [PATCH 44/60] Add vld parameter only if some variables are set. --- .../robotframework/NSLCMOperationKeywords.robot | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index 4d92b38..8acadb6 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -191,13 +191,15 @@ POST Instantiate nsInstance with vnf/vld in additionalParamsForNs ... ${vnf}= evaluate [{"vnfInstanceId": vnfId,"vimAccountId": random.choice(${vimAccountIds})} for vnfId in ${vnfInstanceIds}] random ... Log ${vnf} ... ${body}= Update Value To Json ${body} $.additionalParamsForNs.vnf ${vnf} + ${vimNetworkName}= Get Variable Value ${vimNetworkName} - Run Keyword If "${vimNetworkName}" != "None" - ... Log "${vimNetworkName}" - ... ${vld}= evaluate [{'name': ${vldName}, 'vim-network-name': ${vimNetworkName}}] - ... Log ${vld} - ... ${body}= Update Value To Json ${body} $.additionalParamsForNs.vld ${vld} - ... Log ${body} + Log "${vimNetworkName}" + ${vldName}= Get Variable Value ${vldName} + Log "${vldName}" + ${vld}= Evaluate { 'vld': [{'name': ${vldName}, 'vim-network-name': ${vimNetworkName}}]} + ${body}= Run Keyword If "${vimNetworkName}" != "None" and "${vldName}" != "None" + ... Add Object To Json ${body} $.additionalParamsForNs ${vld} + Log ${body} Post ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} ${outputResponse}= Output response Set Global Variable @{response} ${outputResponse} From ac7ee7c285316a1a9ca3ec03783ac650ba65e185 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 3 Dec 2020 12:28:48 +0100 Subject: [PATCH 45/60] Add quotes to variables. --- adaptation_layer/robotframework/NSLCMOperationKeywords.robot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index 8acadb6..89378bc 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -196,7 +196,7 @@ POST Instantiate nsInstance with vnf/vld in additionalParamsForNs Log "${vimNetworkName}" ${vldName}= Get Variable Value ${vldName} Log "${vldName}" - ${vld}= Evaluate { 'vld': [{'name': ${vldName}, 'vim-network-name': ${vimNetworkName}}]} + ${vld}= Evaluate { 'vld': [{'name': '${vldName}', 'vim-network-name': '${vimNetworkName}'}]} ${body}= Run Keyword If "${vimNetworkName}" != "None" and "${vldName}" != "None" ... Add Object To Json ${body} $.additionalParamsForNs ${vld} Log ${body} From 36786b8318b5665ae38433a3fbf0e09da7563a0f Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 3 Dec 2020 12:40:09 +0100 Subject: [PATCH 46/60] Add ELSE to set the variable to default value. --- adaptation_layer/robotframework/NSLCMOperationKeywords.robot | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index 89378bc..3c81758 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -197,8 +197,11 @@ POST Instantiate nsInstance with vnf/vld in additionalParamsForNs ${vldName}= Get Variable Value ${vldName} Log "${vldName}" ${vld}= Evaluate { 'vld': [{'name': '${vldName}', 'vim-network-name': '${vimNetworkName}'}]} - ${body}= Run Keyword If "${vimNetworkName}" != "None" and "${vldName}" != "None" + Log ${body} + ${body}= Run Keyword If "${vimNetworkName}" != "None" ... Add Object To Json ${body} $.additionalParamsForNs ${vld} + ... ELSE + ... Set Variable ${body} Log ${body} Post ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} ${outputResponse}= Output response From dc407d66f7b471420bbd3f1af23c8e3a11c9f47e Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 3 Dec 2020 12:41:31 +0100 Subject: [PATCH 47/60] Remove quotes from variables. --- adaptation_layer/robotframework/environment/variables.robot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adaptation_layer/robotframework/environment/variables.robot b/adaptation_layer/robotframework/environment/variables.robot index 93f7f7b..cedabb0 100644 --- a/adaptation_layer/robotframework/environment/variables.robot +++ b/adaptation_layer/robotframework/environment/variables.robot @@ -9,8 +9,8 @@ ${nfvoId} 1 ${nsdId} 4125ae83-6614-4bf6-be1a-b8aa16e7e42c -#${vimNetworkName} 'test' -#${vldName} 'mgmt_vl' +#${vimNetworkName} test +#${vldName} mgmt_vl #${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] From 35f49ea922be564c5625c29e4f069d2d06275662 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 3 Dec 2020 12:57:03 +0100 Subject: [PATCH 48/60] Update readme with all custom variables. --- adaptation_layer/robotframework/README.md | 52 +++++++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/adaptation_layer/robotframework/README.md b/adaptation_layer/robotframework/README.md index d0c8d80..6a8adba 100644 --- a/adaptation_layer/robotframework/README.md +++ b/adaptation_layer/robotframework/README.md @@ -12,8 +12,10 @@ To execute the tests you need: ## Configuration -Check the file [variables.robot](./environment/variables.robot) and change the variables according -to your setup. +Check the file [variables.robot](./environment/variables.robot). +Variables that can be customized are provided at the beginning of the file. + +> Note: use at least 4 spaces between variable name and value, or use tabs Setup the protocol, host and port where mso-lo application is listening. @@ -23,20 +25,41 @@ ${MSO-LO_PORT} 80 ${HTTP} http ``` -Choose if you want to test a `rano` or a `nfvo` and set its id. +Choose what type of orchestrator you want to test, `nfvo` or `rano`, and provide its ID. +The ID comes from the IWF Repository. ``` ${apiRoot} nfvo ${nfvoId} 1 ``` -Select the id of the NSD you want to deploy for the test. +In the IWF Repository, set the credentials for your orchestrator. +Assuming the values above, and that the IWF Repository is hosted at `localhost:8087`: + +``` +curl --request PATCH \ + --url http://localhost:8087/nfvOrchestrators/1 \ + --header 'Content-Type: application/json' \ + --data '{ + "credentials": { + "host": "192.168.100.2", + "port": 9999, + "username": "admin", + "password": "admin", + "project": "admin" + } +}' +``` + +Select the UUID of the NSD you want to deploy for the test. It must be available in your NFVO or RANO catalog. ``` ${nsdId} 5821d426-4c51-4be0-a849-5218a09f0d72 ``` +### Optional + The following settings can be used to associate a Virtual Link of your NSD to a network existing on your VIM. Please provide both names or **remove/comment the two lines**. @@ -44,8 +67,8 @@ Please provide both names or **remove/comment the two lines**. > IWF repository. ``` -${vimNetworkName} 'test' -${vldName} 'mgmt_vl' +${vimNetworkName} test +${vldName} mgmt_vl ``` The following setting is used to deploy the VNFs of your service on multiple VIMs available in your NFVO/RANO. @@ -57,9 +80,20 @@ ${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] Script [MSO-LO-LCM-Workflow.robot](./MSO-LO-LCM-Workflow.robot) contains a workflow that instantiates and terminates a Network Service on the configured NFVO. -Some test cases include features to wait for the NS to be deployed. Maximum waiting time is set to -2 minutes. You can increase it if it is not enough by changing `${MAXIMUM_WAIT}` variable in -[variables.robot](./environment/variables.robot). +Some test cases include features to wait for the NS to be deployed. +Maximum waiting time is set to 2 minutes. +You can increase it if it is not enough: + +``` +${MAX_WAIT} 2 min +``` + +MSO-LO can send notifications about the operation status to an endpoint. +You can set it with: + +``` +${notificationUri} http://192.168.18.14:8083/ +``` ## Execution: From 83ed46a1feb00b06c8d32f187da2a73b408456cd Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 3 Dec 2020 14:29:41 +0100 Subject: [PATCH 49/60] Fix if-else. Restore request template. --- .../NSLCMOperationKeywords.robot | 32 +++++++++++++------ .../environment/variables.robot | 2 +- .../jsons/InstantiateNsRequest.json | 2 ++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index 3c81758..f4e3047 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -184,25 +184,37 @@ POST Instantiate nsInstance with vnf/vld in additionalParamsForNs Set Headers {"Content-Type": "${CONTENT_TYPE}"} Run Keyword If ${AUTH_USAGE} == 1 Set Headers {"Authorization":"${AUTHORIZATION}"} ${body}= Load JSON From File jsons/InstantiateNsRequest.json + ${vimAccountIds}= Get Variable Value ${vimAccountIds} - Run Keyword If "${vimAccountIds}" != "None" - ... Log ${vimAccountIds} - ... ${vnf}= set variable [] - ... ${vnf}= evaluate [{"vnfInstanceId": vnfId,"vimAccountId": random.choice(${vimAccountIds})} for vnfId in ${vnfInstanceIds}] random - ... Log ${vnf} - ... ${body}= Update Value To Json ${body} $.additionalParamsForNs.vnf ${vnf} + Log "${vimAccountIds}" + ${vnf}= Run Keyword If "${vimAccountIds}" != "None" + ... Evaluate [{"vnfInstanceId": vnfId,"vimAccountId": random.choice(${vimAccountIds})} for vnfId in ${vnfInstanceIds}] random + ... ELSE + ... Set Variable None + Log "${vnf}" + Log ${body} + ${body}= Run Keyword If "${vnf}" != "None" + ... Update Value To Json ${body} $.additionalParamsForNs.vnf ${vnf} + ... ELSE + ... Delete Object From Json ${body} $.additionalParamsForNs.vnf + Log ${body} ${vimNetworkName}= Get Variable Value ${vimNetworkName} Log "${vimNetworkName}" ${vldName}= Get Variable Value ${vldName} Log "${vldName}" - ${vld}= Evaluate { 'vld': [{'name': '${vldName}', 'vim-network-name': '${vimNetworkName}'}]} + ${vld}= Run Keyword If "${vimNetworkName}" != "None" and "${vldName}" != None + ... Evaluate [{'name': '${vldName}', 'vim-network-name': '${vimNetworkName}'}] + ... ELSE + ... Set Variable None + Log ${vld} Log ${body} - ${body}= Run Keyword If "${vimNetworkName}" != "None" - ... Add Object To Json ${body} $.additionalParamsForNs ${vld} + ${body}= Run Keyword If "${vld}" != "None" + ... Update Value To Json ${body} $.additionalParamsForNs.vld ${vld} ... ELSE - ... Set Variable ${body} + ... Delete Object From Json ${body} $.additionalParamsForNs.vld Log ${body} + Post ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} ${outputResponse}= Output response Set Global Variable @{response} ${outputResponse} diff --git a/adaptation_layer/robotframework/environment/variables.robot b/adaptation_layer/robotframework/environment/variables.robot index cedabb0..45509f7 100644 --- a/adaptation_layer/robotframework/environment/variables.robot +++ b/adaptation_layer/robotframework/environment/variables.robot @@ -12,7 +12,7 @@ ${nsdId} 4125ae83-6614-4bf6-be1a-b8aa16e7e42c #${vimNetworkName} test #${vldName} mgmt_vl -#${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] +#${vimAccountIds} ['64690905-0fe0-4dc4-967c-292eb497e46f', '444bd22e-dd1a-4672-b12b-2604f21f50e6'] ${notificationUri} http://192.168.18.14:8083/ diff --git a/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json b/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json index 19b1cdb..1bd2432 100644 --- a/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json +++ b/adaptation_layer/robotframework/jsons/InstantiateNsRequest.json @@ -1,4 +1,6 @@ { "additionalParamsForNs": { + "vnf": [], + "vld": [] } } From aac79436abf21fea995ccadb1059d7b9da045423 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 3 Dec 2020 14:36:24 +0100 Subject: [PATCH 50/60] Fix vimAccountIds documentation. --- adaptation_layer/robotframework/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/README.md b/adaptation_layer/robotframework/README.md index 6a8adba..233ab35 100644 --- a/adaptation_layer/robotframework/README.md +++ b/adaptation_layer/robotframework/README.md @@ -75,7 +75,7 @@ The following setting is used to deploy the VNFs of your service on multiple VIM Please provide the UUIDs as shown below or **remove/comment the line**. ``` -${vimAccountIds} ['c25ce403-b664-48e3-b790-9ed7635feffc'] +${vimAccountIds} ['64690905-0fe0-4dc4-967c-292eb497e46f', '444bd22e-dd1a-4672-b12b-2604f21f50e6'] ``` Script [MSO-LO-LCM-Workflow.robot](./MSO-LO-LCM-Workflow.robot) contains a workflow that From 740c254b2f1679d9df5a692e92efa370ed9952b6 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 10 Dec 2020 09:48:44 +0100 Subject: [PATCH 51/60] Add sapdata rf test --- .../robotframework/MSO-LO-LCM-Workflow.robot | 7 ++++++- .../NSLCMOperationKeywords.robot | 10 ++++++++++ .../jsons/InstantiateNsRequestSapData.json | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 adaptation_layer/robotframework/jsons/InstantiateNsRequestSapData.json diff --git a/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot b/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot index f57b39c..3dc99be 100644 --- a/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot +++ b/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot @@ -58,7 +58,12 @@ POST NS Instance Instantiate ... Post-Conditions: status code 202 Check resource existence Check resource not_instantiated - POST Instantiate nsInstance with vnf/vld in additionalParamsForNs + Run Keyword If "${apiRoot}" == "nfvo" + ... POST Instantiate nsInstance with vnf/vld in additionalParamsForNs + ... ELSE IF "${apiRoot}" == "rano" + ... POST Instantiate nsInstance with SapData + ... ELSE + ... Fatal Error Unknown value for variable apiRoot Check HTTP Response Status Code Is 202 Check HTTP Response Header Contains Location Check Operation Occurrence Id diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index f4e3047..4c654cc 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -219,6 +219,16 @@ POST Instantiate nsInstance with vnf/vld in additionalParamsForNs ${outputResponse}= Output response Set Global Variable @{response} ${outputResponse} +POST Instantiate nsInstance with SapData + Log Trying to Instantiate a ns Instance with SapData + Set Headers {"Accept":"${ACCEPT}"} + Set Headers {"Content-Type": "${CONTENT_TYPE}"} + Run Keyword If ${AUTH_USAGE} == 1 Set Headers {"Authorization":"${AUTHORIZATION}"} + ${body}= Load JSON From File jsons/InstantiateNsRequestSapData.json + Post ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} + ${outputResponse}= Output response + Set Global Variable @{response} ${outputResponse} + POST Instantiate nsInstance Log Trying to Instantiate a ns Instance Set Headers {"Accept":"${ACCEPT}"} diff --git a/adaptation_layer/robotframework/jsons/InstantiateNsRequestSapData.json b/adaptation_layer/robotframework/jsons/InstantiateNsRequestSapData.json new file mode 100644 index 0000000..7d7711e --- /dev/null +++ b/adaptation_layer/robotframework/jsons/InstantiateNsRequestSapData.json @@ -0,0 +1,18 @@ +{ + "SapData": [ + { + "sapdId": "sap_test_mobile", + "sapName": "External Test Mobile Sap", + "description": "Sap Test description", + "radioSliceProfile": { + "site": "ITALY_TURIN", + "coverageArea": "ITALY.TIM_LAB", + "radioAccessTechnology": "5GNSA", + "sST": "URLLC", + "latency": 10, + "uLThptPerSlice": 50, + "dLThptPerSlice": 50 + } + } + ] +} From 7abef0782925da49809d93c2fa59c61e9db4ab50 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Thu, 10 Dec 2020 12:11:29 +0100 Subject: [PATCH 52/60] Do not request VNF instances of rano. --- adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot b/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot index 3dc99be..7f73ae3 100644 --- a/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot +++ b/adaptation_layer/robotframework/MSO-LO-LCM-Workflow.robot @@ -22,7 +22,12 @@ POST NS Instance Creation Check HTTP Response Header Contains Location Check HTTP Response Body Json Schema Is ${ns_schema} Check NS Id - Check VNF Ids + Run Keyword If "${apiRoot}" == "nfvo" + ... Check VNF Ids + ... ELSE IF "${apiRoot}" == "rano" + ... Log No vnfInstance with rano + ... ELSE + ... Fatal Error Unknown value for variable apiRoot Check resource not_instantiated POST New Subscription Good Check Sub Id From ae16afb364d023928349a65c94242b410ed7a93a Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Fri, 11 Dec 2020 16:58:05 +0100 Subject: [PATCH 53/60] Use apiRoot in the regular expression. --- adaptation_layer/robotframework/NSLCMOperationKeywords.robot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index 4c654cc..dfe01a4 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -22,7 +22,7 @@ Check VNF Ids Check Operation Occurrence Id ${nsLcmOpOcc}= set variable ${response[0]['headers']['Location']} # using a basic regex, it can be improved - ${nsLcmOpOcc}= evaluate re.search(r'(/nfvo/.*/ns_lcm_op_occs/(.*))', '''${nsLcmOpOcc}''').group(2) re + ${nsLcmOpOcc}= evaluate re.search(r'(/${apiRoot}/.*/ns_lcm_op_occs/(.*))', '''${nsLcmOpOcc}''').group(2) re Set Global Variable ${nsLcmOpOccId} ${nsLcmOpOcc} Should Not Be Empty ${nsLcmOpOccId} Log ${nsLcmOpOccId} From 5de4e71dd30268023de96db21999aa10f392af22 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Fri, 11 Dec 2020 17:05:44 +0100 Subject: [PATCH 54/60] Increase timeout for SapData instantiation. --- adaptation_layer/robotframework/NSLCMOperationKeywords.robot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index dfe01a4..5d61944 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -225,7 +225,7 @@ POST Instantiate nsInstance with SapData Set Headers {"Content-Type": "${CONTENT_TYPE}"} Run Keyword If ${AUTH_USAGE} == 1 Set Headers {"Authorization":"${AUTHORIZATION}"} ${body}= Load JSON From File jsons/InstantiateNsRequestSapData.json - Post ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} + Post timeout=300 ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} ${outputResponse}= Output response Set Global Variable @{response} ${outputResponse} From e04edb4c36dc3e805e6f9832e593fdc8e11d2ff1 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Fri, 11 Dec 2020 17:08:41 +0100 Subject: [PATCH 55/60] Fix call. --- adaptation_layer/robotframework/NSLCMOperationKeywords.robot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot index 5d61944..919048c 100644 --- a/adaptation_layer/robotframework/NSLCMOperationKeywords.robot +++ b/adaptation_layer/robotframework/NSLCMOperationKeywords.robot @@ -225,7 +225,7 @@ POST Instantiate nsInstance with SapData Set Headers {"Content-Type": "${CONTENT_TYPE}"} Run Keyword If ${AUTH_USAGE} == 1 Set Headers {"Authorization":"${AUTHORIZATION}"} ${body}= Load JSON From File jsons/InstantiateNsRequestSapData.json - Post timeout=300 ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} + Post ${apiRoot}/${nfvoId}/ns_instances/${nsInstanceId}/instantiate ${body} timeout=300 ${outputResponse}= Output response Set Global Variable @{response} ${outputResponse} From d98f8a2f8baf0e1db3011eef2d62b9df2f108f88 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Mon, 14 Dec 2020 11:02:56 +0100 Subject: [PATCH 56/60] Increase uwsgi_read_timeout in nginx config. --- nginx/nginx.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nginx/nginx.conf b/nginx/nginx.conf index cd1ece7..90df183 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -10,5 +10,6 @@ server { location / { include uwsgi_params; uwsgi_pass uwsgicluster; + uwsgi_read_timeout 300s; } -} \ No newline at end of file +} From 13c8b0b04baf5b05b73ae42b404ca37f636a0df7 Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Mon, 14 Dec 2020 17:14:37 +0100 Subject: [PATCH 57/60] Add RF workflow for EVER. --- .../MSO-LO-LCM-EVER-Workflow.robot | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot diff --git a/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot b/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot new file mode 100644 index 0000000..3f4b7d9 --- /dev/null +++ b/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot @@ -0,0 +1,142 @@ +*** Settings *** +Resource environment/variables.robot +Variables ${SCHEMAS_PATH} +Resource NSLCMOperationKeywords.robot +Resource NFVOOperationKeywords.robot +Library REST ${MSO-LO_BASE_API} +Library OperatingSystem +Library JSONLibrary +Library JSONSchemaLibrary schemas/ + + +*** Test Cases *** +POST NS Instance Creation + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3.2 + ... Test title: POST NS Instance Creation + ... Test objective: The objective is to test the workflow for Creating a NS instance + ... Pre-conditions: none + ... Post-Conditions: The NS lifecycle management operation occurrence is in NOT_ISTANTIATED state + POST New nsInstance + Check HTTP Response Status Code Is 201 + Check HTTP Response Header Contains Location + Check HTTP Response Body Json Schema Is ${ns_schema} + Check NS Id + Run Keyword If "${apiRoot}" == "nfvo" + ... Check VNF Ids + ... ELSE IF "${apiRoot}" == "rano" + ... Log No vnfInstance with rano + ... ELSE + ... Fatal Error Unknown value for variable apiRoot + Check resource not_instantiated + POST New Subscription Good + Check Sub Id + +GET NS Instance List + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3.1 + ... Test title: GET NS Instance List + ... Test objective: The objective is to test the workflow for retriving the NS instance list + ... Pre-conditions: none + ... Post-Conditions: none + GET NsInstances + Check HTTP Response Status Code Is 200 + Check HTTP Response Body Json Schema Is ${ns_list_schema} + +GET Information about an individual NS Instance + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3.3 + ... Test title: GET Information about an individual NS Instance + ... Test objective: The objective is to test that GET method returns an individual NS instance + ... Pre-conditions: none + ... Post-Conditions: none + GET IndividualNSInstance + Check HTTP Response Status Code Is 200 + Check HTTP Response Body Json Schema Is ${ns_schema} + +POST NS Instance Instantiate + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3.4 + ... Test title: POST NS Instance Instantiate + ... Test objective: The objective is to test the workflow for Instantiate a NS instance + ... Pre-conditions: the resource is in NOT_INSTANTIATED state + ... Post-Conditions: status code 202 + Check resource existence + Check resource not_instantiated + Run Keyword If "${apiRoot}" == "nfvo" + ... POST Instantiate nsInstance with vnf/vld in additionalParamsForNs + ... ELSE IF "${apiRoot}" == "rano" + ... POST Instantiate nsInstance with SapData + ... ELSE + ... Fatal Error Unknown value for variable apiRoot + Check HTTP Response Status Code Is 202 + Check HTTP Response Header Contains Location + Check Operation Occurrence Id + +GET NS LCM OP Occurrence Instantiate COMPLETED + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3.6 + ... Test title: GET NS LCM OP Occurrence Instantiate COMPLETED + ... Test objective: The objective is to test the workflow for retrive NS LCM OP Occurrence + ... Pre-conditions: none + ... Post-Conditions: status code 200 + Wait Until Keyword Succeeds ${MAX_WAIT} ${INTERVAL_WAIT} Run Keywords + ... GET Individual NS LCM OP Occurrence + ... AND Check resource operationState is COMPLETED + +GET NS LCM OP Occurrences + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3.5 + ... Test title: GET LCM OP Occurrences + ... Test objective: The objective is to test the workflow for retrive NS LCM OP Occurrences + ... Pre-conditions: none + ... Post-Conditions: status code 200 + GET NS LCM OP Occurrences + Check HTTP Response Status Code Is 200 + Check HTTP Response Body Json Schema Is ${ns_lcm_op_occ_list_schema} + +POST NS Instance Terminate + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3. + ... Test title: POST Terminate NS Instance + ... Test objective: The objective is to test the workflow for Terminate a NS instance + ... Pre-conditions: the resource is in INSTANTIATED state + ... Post-Conditions: the resource is in NOT_INSTANTIATED state + Check resource existence + Check resource instantiated + POST Terminate NSInstance + Check HTTP Response Status Code Is 202 + Check Operation Occurrence Id + +POST NS Instance Delete + [Tags] instantiate-terminate-workflow + [Documentation] Test ID: mso-lo-test-3.6 + ... Test title: POST NS Instance Delete + ... Test objective: The objective is to test the workflow for Deleting a NS instance + ... Pre-conditions: the resource is in NOT_INSTANTIATED state + ... Post-Conditions: status code 204 + Sleep 5s + Check resource not_instantiated + DELETE IndividualNSInstance + Check HTTP Response Status Code Is 204 + DELETE Individual Subscription Good + +POST NS Instance Creation Bad Request + [Tags] standalone + [Documentation] Test ID: mso-lo-test-3.2.1 + ... Test title: POST Instance Creation Bad Request + ... Test objective: The objective is to test the workflow for Creating a NS instance with a bad request + ... Pre-conditions: none + ... Post-Conditions: Status code 400 + POST New nsInstance with invalid request body + Check HTTP Response Status Code Is 400 + +GET Information about an inexistent individual NS Instance + [Tags] standalone + [Documentation] Test ID: mso-lo-test-3.3.1 + ... Test title: GET Information about an inexistent individual NS Instance + ... Test objective: The objective is to test that GET method returns an inexistent individual NS instance + ... Pre-conditions: none + ... Post-Conditions: Status code 404 + GET IndividualNSInstance inexistent + Check HTTP Response Status Code Is 404 From ebdd32358065175cb000fd3872cd815ea388b04d Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 16 Dec 2020 12:36:10 +0100 Subject: [PATCH 58/60] Remove operations on subscriptions. --- adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot | 3 --- 1 file changed, 3 deletions(-) diff --git a/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot b/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot index 3f4b7d9..df27bb1 100644 --- a/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot +++ b/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot @@ -29,8 +29,6 @@ POST NS Instance Creation ... ELSE ... Fatal Error Unknown value for variable apiRoot Check resource not_instantiated - POST New Subscription Good - Check Sub Id GET NS Instance List [Tags] instantiate-terminate-workflow @@ -119,7 +117,6 @@ POST NS Instance Delete Check resource not_instantiated DELETE IndividualNSInstance Check HTTP Response Status Code Is 204 - DELETE Individual Subscription Good POST NS Instance Creation Bad Request [Tags] standalone From 7f36fb82f441860189b33c41905a1ee59816625c Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 16 Dec 2020 19:05:54 +0100 Subject: [PATCH 59/60] Rename file to RANO --- ...-LO-LCM-EVER-Workflow.robot => MSO-LO-LCM-RANO-Workflow.robot} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename adaptation_layer/robotframework/{MSO-LO-LCM-EVER-Workflow.robot => MSO-LO-LCM-RANO-Workflow.robot} (100%) diff --git a/adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot b/adaptation_layer/robotframework/MSO-LO-LCM-RANO-Workflow.robot similarity index 100% rename from adaptation_layer/robotframework/MSO-LO-LCM-EVER-Workflow.robot rename to adaptation_layer/robotframework/MSO-LO-LCM-RANO-Workflow.robot From 892c1d323bcd2eb5973500c87af699b597c90dbd Mon Sep 17 00:00:00 2001 From: Matteo Pergolesi Date: Wed, 16 Dec 2020 19:06:18 +0100 Subject: [PATCH 60/60] Small improvements to README --- adaptation_layer/robotframework/README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/adaptation_layer/robotframework/README.md b/adaptation_layer/robotframework/README.md index 233ab35..907f91d 100644 --- a/adaptation_layer/robotframework/README.md +++ b/adaptation_layer/robotframework/README.md @@ -3,12 +3,21 @@ The `.robot` scripts in this folder perform integration tests of the `mso-lo` application against a real instance of a NFVO or RANO. +The test suites included are: + +- [MSO-LO-NFVO-Workflow](MSO-LO-NFVO-Workflow.robot): tests the retrieval of information about NFVOs +- [MSO-LO-LCM-Workflow](MSO-LO-LCM-Workflow.robot): tests the complete LCM of a Network Service in a NFVO (includes subscriptions to notifications) +- [MSO-LO-LCM-RANO-Workflow](MSO-LO-LCM-RANO-Workflow.robot): tests the complete LCM of slice in a RANO +- [MSO-LO-SUBS](MSO-LO-SUBS.robot): tests the retrieval of information about subscriptions. + +## Prerequisites + To execute the tests you need: -- An instance of `mso-lo` up and running -- An instance of a real NFVO or RANO -- An instante of the [IWF Repository](https://github.com/5GEVE/iwf-repository) -- Correct communication between the components above +- An instance of `mso-lo` up and running +- An instance of a real NFVO or RANO +- An instante of the [IWF Repository](https://github.com/5GEVE/iwf-repository) +- Correct communication between the components above ## Configuration