From 2c68a0a84d2a62598b9379529008c2ae1c849ca6 Mon Sep 17 00:00:00 2001 From: Sheel Rana Date: Sun, 4 Apr 2021 22:26:47 +0530 Subject: [PATCH] Updated vnflcm api output with host-path Currently vnflcm api operations do not return host-path in their output inside '_links' href field. For ex, "_links": { "self": { "href": "/vnflcm/v1/vnf_instances/" } } This patch updates '_links' href field in vnflcm api output with host-path. For ex, "_links": { "self": { "href": "http://localhost:9890/vnflcm/v1/vnf_instances/" } } *here "http://localhost:9890/" is just an example of host-path. Related operations: 1. Creates a new VNF instance. 2. Show VNF Instance. 3. List VNF Instances. 4. Show VNF LCM operation occurrence. 5. List VNF LCM operation occurrences. Co-Authored-By: Navum Gupta Closes-Bug: #1923360 Change-Id: I245cd2626fac1112d6a9fef3c51bf5ef6b679e05 --- tacker/api/views/vnf_lcm.py | 76 ++++++++++++++++------------ tacker/api/views/vnf_lcm_op_occs.py | 43 +++++++++------- tacker/api/vnflcm/v1/controller.py | 10 ++-- tacker/conductor/conductor_server.py | 8 ++- tacker/tests/unit/vnflcm/fakes.py | 63 ++++++++++++++--------- 5 files changed, 121 insertions(+), 79 deletions(-) diff --git a/tacker/api/views/vnf_lcm.py b/tacker/api/views/vnf_lcm.py index 8f1fb0fae..274eac092 100644 --- a/tacker/api/views/vnf_lcm.py +++ b/tacker/api/views/vnf_lcm.py @@ -35,7 +35,10 @@ class ViewBuilder(base.BaseViewBuilder): def _get_links(self, vnf_instance): links = { "self": { - "href": '/vnflcm/v1/vnf_instances/%s' % vnf_instance.id + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance.id) } } @@ -43,8 +46,10 @@ class ViewBuilder(base.BaseViewBuilder): fields.VnfInstanceState.NOT_INSTANTIATED): instantiate_link = { "instantiate": { - "href": '/vnflcm/v1/vnf_instances/%s/instantiate' - % vnf_instance.id + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}/instantiate' + .format(endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance.id) } } @@ -54,16 +59,22 @@ class ViewBuilder(base.BaseViewBuilder): fields.VnfInstanceState.INSTANTIATED): instantiated_state_links = { "terminate": { - "href": '/vnflcm/v1/vnf_instances/%s/terminate' - % vnf_instance.id + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}/terminate' + .format(endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance.id) }, "heal": { - "href": '/vnflcm/v1/vnf_instances/%s/heal' - % vnf_instance.id + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}/heal' + .format(endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance.id) }, "changeExtConn": { - "href": '/vnflcm/v1/vnf_instances/%s/change_ext_conn' - % vnf_instance.id + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}/change_ext_conn' + .format(endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance.id) } } @@ -98,37 +109,40 @@ class ViewBuilder(base.BaseViewBuilder): def _get_lcm_op_occs_links(self, vnf_lcm_op_occs): _links = { "self": { - "href": '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + "href": + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "vnfInstance": { - "href": '%(endpoint)s/vnflcm/v1/vnf_instances/%(id)s' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.vnf_instance_id} + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.vnf_instance_id) }, "retry": { "href": - '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/retry' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/retry'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "rollback": { "href": - '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/rollback' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/rollback'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "grant": { - "href": '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/grant' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + "href": + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/grant'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "fail": { "href": - '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/fail' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/fail'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) } } @@ -178,10 +192,10 @@ class ViewBuilder(base.BaseViewBuilder): return { "_links": { "self": { - "href": '%(endpoint)s/vnflcm/v1/subscriptions/%(id)s' % - { - "endpoint": CONF.vnf_lcm.endpoint_url, - "id": decode_id}}}} + "href": + '{endpoint}/vnflcm/v1/subscriptions/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=decode_id)}}} def _basic_subscription_info(self, vnf_lcm_subscription, filter=None): if not filter: diff --git a/tacker/api/views/vnf_lcm_op_occs.py b/tacker/api/views/vnf_lcm_op_occs.py index d5d0d6373..cd2ec4f07 100644 --- a/tacker/api/views/vnf_lcm_op_occs.py +++ b/tacker/api/views/vnf_lcm_op_occs.py @@ -32,37 +32,44 @@ class ViewBuilder(base.BaseViewBuilder): def _get_lcm_op_occs_links(self, vnf_lcm_op_occs): _links = { "self": { - "href": '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + "href": + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "vnfInstance": { - "href": '%(endpoint)s/vnflcm/v1/vnf_instances/%(id)s' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.vnf_instance_id} + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.vnf_instance_id) }, "retry": { "href": - '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/retry' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/retry'. + format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "rollback": { "href": - '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/rollback' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/rollback'. + format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "grant": { - "href": '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/grant' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + "href": + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/grant'. + format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) }, "fail": { "href": - '%(endpoint)s/vnflcm/v1/vnf_lcm_op_occs/%(id)s/fail' - % {"endpoint": CONF.vnf_lcm.endpoint_url, - "id": vnf_lcm_op_occs.id} + '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}/fail'. + format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs.id) } } diff --git a/tacker/api/vnflcm/v1/controller.py b/tacker/api/vnflcm/v1/controller.py index 7cc4db55e..2e468256e 100644 --- a/tacker/api/vnflcm/v1/controller.py +++ b/tacker/api/vnflcm/v1/controller.py @@ -919,7 +919,7 @@ class VnfLcmController(wsgi.Controller): # make response res = webob.Response(content_type='application/json') res.status_int = 202 - loc_url = CONF.vnf_lcm.endpoint_url + \ + loc_url = CONF.vnf_lcm.endpoint_url.rstrip("/") + \ '/vnflcm/v1/vnf_lcm_op_occs/' + op_occs_uuid location = ('Location', loc_url) res.headerlist.append(location) @@ -966,7 +966,7 @@ class VnfLcmController(wsgi.Controller): "See Other", 303, title='See Other') link = ( 'LINK', - CONF.vnf_lcm.endpoint_url + + CONF.vnf_lcm.endpoint_url.rstrip("/") + "/vnflcm/v1/subscriptions/" + str(e)[ 3:]) @@ -1242,9 +1242,9 @@ class VnfLcmController(wsgi.Controller): vnf_instance.task_state = fields.VnfInstanceTaskState.SCALING vnf_instance.save() - vnflcm_url = CONF.vnf_lcm.endpoint_url + \ + vnflcm_url = CONF.vnf_lcm.endpoint_url.rstrip("/") + \ "/vnflcm/v1/vnf_lcm_op_occs/" + vnf_lcm_op_occs_id - insta_url = CONF.vnf_lcm.endpoint_url + \ + insta_url = CONF.vnf_lcm.endpoint_url.rstrip("/") + \ "/vnflcm/v1/vnf_instances/" + inst_vnf_info.vnf_instance_id vnf_info['vnflcm_id'] = vnf_lcm_op_occs_id @@ -1324,7 +1324,7 @@ class VnfLcmController(wsgi.Controller): operation_params) vnf_info['vnf_lcm_op_occ'] = vnf_lcm_op_occs - vnflcm_url = CONF.vnf_lcm.endpoint_url + \ + vnflcm_url = CONF.vnf_lcm.endpoint_url.rstrip("/") + \ "/vnflcm/v1/vnf_lcm_op_occs/" + vnf_lcm_op_occs.id res = webob.Response() res.status_int = 202 diff --git a/tacker/conductor/conductor_server.py b/tacker/conductor/conductor_server.py index 6d3e2f577..8d12d7771 100644 --- a/tacker/conductor/conductor_server.py +++ b/tacker/conductor/conductor_server.py @@ -320,10 +320,14 @@ class Conductor(manager.Manager): self._basic_config_check() def _get_vnf_instance_href(self, vnf_instance_id): - return '/vnflcm/v1/vnf_instances/%s' % vnf_instance_id + return '{endpoint}/vnflcm/v1/vnf_instances/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance_id) def _get_vnf_lcm_op_occs_href(self, vnf_lcm_op_occs_id): - return '/vnflcm/v1/vnf_lcm_op_occs/%s' % vnf_lcm_op_occs_id + return '{endpoint}/vnflcm/v1/vnf_lcm_op_occs/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_lcm_op_occs_id) def _basic_config_check(self): if not os.path.isdir(CONF.vnf_package.vnf_package_csar_path): diff --git a/tacker/tests/unit/vnflcm/fakes.py b/tacker/tests/unit/vnflcm/fakes.py index 57e074302..2d6d12894 100644 --- a/tacker/tests/unit/vnflcm/fakes.py +++ b/tacker/tests/unit/vnflcm/fakes.py @@ -228,14 +228,22 @@ def return_vnf_instance( def _instantiated_vnf_links(vnf_instance_id): links = { - "self": {"href": "/vnflcm/v1/vnf_instances/%s" % vnf_instance_id}, - "terminate": {"href": "/vnflcm/v1/vnf_instances/%s/terminate" % - vnf_instance_id}, - "heal": {"href": "/vnflcm/v1/vnf_instances/%s/heal" % - vnf_instance_id}, + "self": {"href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance_id)}, + "terminate": {"href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}/terminate'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance_id)}, + "heal": {"href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}/heal'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance_id)}, "changeExtConn": {"href": - "/vnflcm/v1/vnf_instances/%s/change_ext_conn" % - vnf_instance_id}} + '{endpoint}/vnflcm/v1/vnf_instances/{id}/change_ext_conn' + .format(endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=vnf_instance_id)}} return links @@ -248,14 +256,16 @@ def _fake_vnf_instance_not_instantiated_response( 'vnfProductName': 'Sample VNF', '_links': { 'self': { - 'href': os.path.join( - '/vnflcm/v1/vnf_instances/', - uuidsentinel.vnf_instance_id)}, + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=uuidsentinel.vnf_instance_id)}, 'instantiate': { - 'href': os.path.join( - '/vnflcm/v1/vnf_instances', - uuidsentinel.vnf_instance_id, - 'instantiate')}}, + "href": + '{endpoint}/vnflcm/v1/vnf_instances/{id}/{op}'.format( + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/"), + id=uuidsentinel.vnf_instance_id, + op='instantiate')}}, 'instantiationState': 'NOT_INSTANTIATED', 'vnfProvider': 'Vnf provider', 'vnfdId': uuidsentinel.vnfd_id, @@ -1322,27 +1332,33 @@ def wsgi_app_v1(fake_auth_context=None): VNFLCMOPOCC_RESPONSE = { '_links': { "self": { - "href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/' + "href": CONF.vnf_lcm.endpoint_url.rstrip("/") + + '/vnflcm/v1/vnf_lcm_op_occs/' 'f26f181d-7891-4720-b022-b074ec1733ef' }, "vnfInstance": { - "href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_instances/' + "href": CONF.vnf_lcm.endpoint_url.rstrip("/") + + '/vnflcm/v1/vnf_instances/' 'f26f181d-7891-4720-b022-b074ec1733ef' }, "retry": { - "href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/' + "href": CONF.vnf_lcm.endpoint_url.rstrip("/") + + '/vnflcm/v1/vnf_lcm_op_occs/' 'f26f181d-7891-4720-b022-b074ec1733ef/retry' }, "rollback": { - "href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/' + "href": CONF.vnf_lcm.endpoint_url.rstrip("/") + + '/vnflcm/v1/vnf_lcm_op_occs/' 'f26f181d-7891-4720-b022-b074ec1733ef/rollback' }, "grant": { - "href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/' + "href": CONF.vnf_lcm.endpoint_url.rstrip("/") + + '/vnflcm/v1/vnf_lcm_op_occs/' 'f26f181d-7891-4720-b022-b074ec1733ef/grant', }, "fail": { - "href": CONF.vnf_lcm.endpoint_url + '/vnflcm/v1/vnf_lcm_op_occs/' + "href": CONF.vnf_lcm.endpoint_url.rstrip("/") + + '/vnflcm/v1/vnf_lcm_op_occs/' 'f26f181d-7891-4720-b022-b074ec1733ef/fail'}}, 'operationState': 'COMPLETED', 'stateEnteredTime': datetime.datetime(1900, 1, 1, 1, 1, 1, @@ -1737,9 +1753,10 @@ def _subscription_links(subscription_dict): links = { "_links": { "self": { - "href": "%(endpoint)s/vnflcm/v1/subscriptions/%(id)s" - % {'id': subscription_dict['id'], - 'endpoint': CONF.vnf_lcm.endpoint_url} + "href": + "{endpoint}/vnflcm/v1/subscriptions/{id}".format( + id=subscription_dict['id'], + endpoint=CONF.vnf_lcm.endpoint_url.rstrip("/")) } } }