From 6833e23f5c0c641eda33716c0b91abe815cc71fd Mon Sep 17 00:00:00 2001 From: Bin Yang Date: Mon, 3 Sep 2018 15:02:14 +0000 Subject: Fix bug of region discovery Change-Id: I006fb0f8ab7a644369d0a03ed1b563db3f52afd7 Issue-ID: MULTICLOUD-311 Signed-off-by: Bin Yang --- share/newton_base/registration/registration.py | 1 + .../registration/tests/test_registration.py | 18 +-- .../registration/views/registration.py | 139 ++++++++++++++++----- windriver/titanium_cloud/urls.py | 6 +- 4 files changed, 117 insertions(+), 47 deletions(-) diff --git a/share/newton_base/registration/registration.py b/share/newton_base/registration/registration.py index 0a5f5e55..2ff798d2 100644 --- a/share/newton_base/registration/registration.py +++ b/share/newton_base/registration/registration.py @@ -14,6 +14,7 @@ import logging import json +import uuid import traceback from keystoneauth1.exceptions import HttpError diff --git a/windriver/titanium_cloud/registration/tests/test_registration.py b/windriver/titanium_cloud/registration/tests/test_registration.py index cc4bdd6c..5c31c4e8 100644 --- a/windriver/titanium_cloud/registration/tests/test_registration.py +++ b/windriver/titanium_cloud/registration/tests/test_registration.py @@ -234,7 +234,7 @@ class TestRegistration(test_base.TestRequest): }) response = self.client.post(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), TEST_REGISTER_ENDPOINT_REQUEST, HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -247,7 +247,7 @@ class TestRegistration(test_base.TestRequest): mock_delete_vim_info.return_value = 0 response = self.client.delete(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), "{}", content_type="application/json", HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -261,7 +261,7 @@ class TestRegistration(test_base.TestRequest): mock_delete_vim_info.return_value = 1 response = self.client.delete(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), "{}", content_type="application/json", HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -291,7 +291,7 @@ class TestRegistration(test_base.TestRequest): }) response = self.client.post(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), TEST_REGISTER_ENDPOINT_REQUEST, HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -321,7 +321,7 @@ class TestRegistration(test_base.TestRequest): }) response = self.client.post(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), TEST_REGISTER_ENDPOINT_REQUEST, HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -352,7 +352,7 @@ class TestRegistration(test_base.TestRequest): }) response = self.client.post(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), TEST_REGISTER_ENDPOINT_REQUEST, HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -382,7 +382,7 @@ class TestRegistration(test_base.TestRequest): }) response = self.client.post(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), TEST_REGISTER_ENDPOINT_REQUEST, HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -412,7 +412,7 @@ class TestRegistration(test_base.TestRequest): }) response = self.client.post(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), TEST_REGISTER_ENDPOINT_REQUEST, HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) @@ -442,7 +442,7 @@ class TestRegistration(test_base.TestRequest): }) response = self.client.post(( - "/api/multicloud-titaniumcloud/v0/windriver-hudson-dc_RegionOne/" + "/api/multicloud-titanium_cloud/v0/windriver-hudson-dc_RegionOne/" "registry"), TEST_REGISTER_ENDPOINT_REQUEST, HTTP_X_AUTH_TOKEN=mock_info.MOCK_TOKEN_ID) diff --git a/windriver/titanium_cloud/registration/views/registration.py b/windriver/titanium_cloud/registration/views/registration.py index 22ee55aa..584b263f 100644 --- a/windriver/titanium_cloud/registration/views/registration.py +++ b/windriver/titanium_cloud/registration/views/registration.py @@ -21,6 +21,8 @@ from django.conf import settings from newton_base.registration import registration as newton_registration from common.exceptions import VimDriverNewtonException +from rest_framework import status +from rest_framework.response import Response from common.msapi import extsys from keystoneauth1.exceptions import HttpError from newton_base.util import VimDriverUtils @@ -38,6 +40,7 @@ class Registry(newton_registration.Registry): self.aai_base_url = settings.AAI_BASE_URL # self._logger = logger + def _get_ovsdpdk_capabilities(self, extra_specs, viminfo): instruction_capability = {} feature_uuid = uuid.uuid4() @@ -54,7 +57,8 @@ class Registry(newton_registration.Registry): }) return instruction_capability -class APIv1Registry(Registry): + +class APIv1Registry(newton_registration.Registry): def __init__(self): super(APIv1Registry, self).__init__() @@ -62,6 +66,21 @@ class APIv1Registry(Registry): self.aai_base_url = settings.AAI_BASE_URL # self._logger = logger + def _get_ovsdpdk_capabilities(self, extra_specs, viminfo): + instruction_capability = {} + feature_uuid = uuid.uuid4() + + instruction_capability['hpa-capability-id'] = str(feature_uuid) + instruction_capability['hpa-feature'] = 'ovsDpdk' + instruction_capability['architecture'] = 'Intel64' + instruction_capability['hpa-version'] = 'v1' + + instruction_capability['hpa-feature-attributes'] = [] + instruction_capability['hpa-feature-attributes'].append({'hpa-attribute-key': 'dataProcessingAccelerationLibrary', + 'hpa-attribute-value': + '{{\"value\":\"{0}\"}}'.format("v17.02") + }) + return instruction_capability def _update_cloud_region(self, cloud_owner, cloud_region_id, openstack_region_id, viminfo, session=None): if cloud_owner and cloud_region_id: @@ -144,17 +163,27 @@ class APIv1Registry(Registry): try: regions = [] vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id) - for region in self._get_list_resources( + isDistributedCloud = False; + openstackregions = self._get_list_resources( "/regions", "identity", session, viminfo, vimid, - "regions"): + "regions") + + for region in openstackregions: if (region['id'] == 'SystemController'): + isDistributedCloud = True; + break; + else: continue - elif (region['id'] == 'RegionOne'): + + for region in openstackregions: + if (region['id'] == 'SystemController'): + continue + elif (region['id'] == 'RegionOne' and isDistributedCloud == True): continue else: regions.append(region['id']) - + self._logger.info("Discovered Regions :%s" % regions) return regions except HttpError as e: @@ -167,38 +196,58 @@ class APIv1Registry(Registry): def post(self, request, cloud_owner="", cloud_region_id=""): self._logger.info("registration with : %s, %s" % (cloud_owner, cloud_region_id)) - vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id) + try: + vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id) - viminfo = VimDriverUtils.get_vim_info(vimid) - cloud_extra_info = viminfo['cloud_extra_info'] - region_specified = cloud_extra_info["openstack-region-id"] if cloud_extra_info else None - multi_region_discovery = cloud_extra_info["multi-region-discovery"] if cloud_extra_info else None - - # discover the regions - region_ids = self._discover_regions(cloud_owner, cloud_region_id, None, viminfo) - - # compare the regions with region_specified and then cloud_region_id - if (region_specified in region_ids): - pass - elif (cloud_region_id in region_ids): - region_specified = cloud_region_id - pass - else: - # assume the first region be the primary region since we have no other way to determine it. - region_specified = region_ids[0] - - # update cloud region and discover/register resource - if (multi_region_discovery and multi_region_discovery.upper() == "TRUE"): - # no input for specified cloud region, so discover all cloud region? - for regionid in region_ids: - #create cloud region with composed AAI cloud_region_id except for the one onboarded externally (e.g. ESR) - gen_cloud_region_id = cloud_region_id + "." + regionid if region_specified != regionid else cloud_region_id - self._update_cloud_region(cloud_owner, gen_cloud_region_id, regionid, viminfo) + viminfo = VimDriverUtils.get_vim_info(vimid) + cloud_extra_info = viminfo['cloud_extra_info'] + region_specified = cloud_extra_info["openstack-region-id"] if cloud_extra_info else None + multi_region_discovery = cloud_extra_info["multi-region-discovery"] if cloud_extra_info else None + + # set the default tenant since there is no tenant info in the VIM yet + sess = VimDriverUtils.get_session( + viminfo, tenant_name=viminfo['tenant']) + + # discover the regions + region_ids = self._discover_regions(cloud_owner, cloud_region_id, sess, viminfo) + + if (len(region_ids) == 0): + self._logger.error("_discover_regions, return regions:%s" % (region_ids)) + return Response( + data={'error': "no region found for cloud region: %s,%s" % (cloud_owner, cloud_region_id)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + # compare the regions with region_specified and then cloud_region_id + if (region_specified in region_ids): + pass + elif (cloud_region_id in region_ids): + region_specified = cloud_region_id + pass + else: + # assume the first region be the primary region since we have no other way to determine it. + region_specified = region_ids.pop(); + + # update cloud region and discover/register resource + if (multi_region_discovery and multi_region_discovery.upper() == "TRUE"): + # no input for specified cloud region, so discover all cloud region? + for regionid in region_ids: + #create cloud region with composed AAI cloud_region_id except for the one onboarded externally (e.g. ESR) + gen_cloud_region_id = cloud_region_id + "." + regionid if region_specified != regionid else cloud_region_id + self._update_cloud_region(cloud_owner, gen_cloud_region_id, regionid, viminfo) + return super(APIv1Registry, self).post(request, vimid) + else: + self._update_cloud_region(cloud_owner, cloud_region_id, region_specified, viminfo) return super(APIv1Registry, self).post(request, vimid) - else: - self._update_cloud_region(cloud_owner, cloud_region_id, region_specified, viminfo) - return super(APIv1Registry, self).post(request, vimid) + except HttpError as e: + self._logger.error("HttpError: status:%s, response:%s" % (e.http_status, e.response.json())) + return Response(data=e.response.json(), status=e.http_status) + except Exception as e: + self._logger.error(traceback.format_exc()) + return Response( + data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) @@ -207,3 +256,25 @@ class APIv1Registry(Registry): vimid = extsys.encode_vim_id(cloud_owner, cloud_region_id) return super(APIv1Registry, self).delete(request, vimid) + + +### APIv0 handler upgrading: leverage APIv1 handler +class APIv0Registry(APIv1Registry): + + def __init__(self): + super(APIv0Registry, self).__init__() + self.proxy_prefix = settings.MULTICLOUD_PREFIX + self.aai_base_url = settings.AAI_BASE_URL + # self._logger = logger + + def post(self, request, vimid=""): + self._logger.info("registration with : %s" % (vimid)) + + cloud_owner, cloud_region_id = extsys.decode_vim_id(vimid) + return super(APIv0Registry, self).post(request, cloud_owner, cloud_region_id) + + def delete(self, request, vimid=""): + self._logger.debug("unregister cloud region: %s" % (vimid)) + + cloud_owner, cloud_region_id = extsys.decode_vim_id(vimid) + return super(APIv0Registry, self).delete(request, cloud_owner, cloud_region_id) diff --git a/windriver/titanium_cloud/urls.py b/windriver/titanium_cloud/urls.py index da5f66a7..bd5af421 100644 --- a/windriver/titanium_cloud/urls.py +++ b/windriver/titanium_cloud/urls.py @@ -66,9 +66,9 @@ urlpatterns = [ # API v0, new namespace due to MULTICLOUD-335 url(r'^api/multicloud-titaniumcloud/v0/(?P[0-9a-zA-Z_-]+)/registry/?$', - registration.Registry.as_view()), + registration.APIv0Registry.as_view()), url(r'^api/multicloud-titaniumcloud/v0/(?P[0-9a-zA-Z_-]+)/?$', - registration.Registry.as_view()), + registration.APIv0Registry.as_view()), url(r'^api/multicloud-titaniumcloud/v0/(?P[0-9a-zA-Z_-]+)/exten', include('titanium_cloud.extensions.urls')), url(r'^api/multicloud-titaniumcloud/v0/(?P[0-9a-zA-Z_-]+)/', @@ -104,5 +104,3 @@ urlpatterns = [ url(r'^api/multicloud-titaniumcloud/v1/(?P[0-9a-zA-Z_-]+)/(?P[0-9a-zA-Z_-]+)/infra_workload/?$', infra_workload.APIv1InfraWorkload.as_view()), ] - - -- cgit 1.2.3-korg