diff options
author | Ethan Lynn <ethanlynnl@vmware.com> | 2017-09-20 16:27:44 +0800 |
---|---|---|
committer | Ethan Lynn <ethanlynnl@vmware.com> | 2017-09-20 17:41:27 +0800 |
commit | 88f24efabca0667fe9fae2b7537044345dac2f79 (patch) | |
tree | 3ecee6074f0877eb5cfbb6c4d3463b409a66160d | |
parent | 87cae974439b871f545735fb93b740f6fdbd263d (diff) |
Fix cloud unregistry
Need to delete childrens of cloud-region, then delete cloud-region.
Change-Id: Idf630ba47f4a34e8844033f99b4a259993832cbd
issue-id: MULTICLOUD-100
Signed-off-by: Ethan Lynn <ethanlynnl@vmware.com>
-rw-r--r-- | vio/vio/pub/utils/restcall.py | 129 | ||||
-rw-r--r-- | vio/vio/pub/vim/drivers/vimsdk/image_v2.py | 1 | ||||
-rw-r--r-- | vio/vio/swagger/urls.py | 5 | ||||
-rw-r--r-- | vio/vio/swagger/views/registry/views.py | 69 | ||||
-rw-r--r-- | vio/vio/tests/tests_registry_view.py | 46 |
5 files changed, 187 insertions, 63 deletions
diff --git a/vio/vio/pub/utils/restcall.py b/vio/vio/pub/utils/restcall.py index 99ed9d9..7434fcc 100644 --- a/vio/vio/pub/utils/restcall.py +++ b/vio/vio/pub/utils/restcall.py @@ -161,8 +161,22 @@ class AAIClient(object): return json.loads(resp[1]) def delete_vim(self): + resp = self.get_vim(get_all=True) + logger.debug('Delete tenants') + self._del_tenants(resp) + logger.debug('Delete images') + self._del_images(resp) + logger.debug('Delete flavors') + self._del_flavors(resp) + logger.debug('Delete networks') + self._del_networks(resp) + logger.debug('Delete availability zones') + self._del_azs(resp) + logger.debug('Delete cloud region') resource = ("/cloud-infrastructure/cloud-regions/cloud-region" - "/%s/%s" % (self.cloud_owner, self.cloud_region)) + "/%s/%s?resource-version=%s" % + (self.cloud_owner, self.cloud_region, + resp['resource-version'])) resp = call_req(self.base_url, self.username, self.password, rest_no_auth, resource, "DELETE", headers=self.default_headers) @@ -171,7 +185,6 @@ class AAIClient(object): status_code=400, content="Failed to delete cloud %s_%s: %s." % ( self.cloud_owner, self.cloud_region, resp[1])) - return json.loads(resp[1]) def update_vim(self, content): # update identity url @@ -182,6 +195,8 @@ class AAIClient(object): self.add_images(content) # update images self.add_flavors(content) + # update networks + self.add_networks(content) # update pservers self.add_pservers(content) @@ -250,6 +265,22 @@ class AAIClient(object): content=json.dumps(body), headers=self.default_headers) + def add_networks(self, content): + for network in content['networks']: + resource = ("/cloud-infrastructure/cloud-regions/cloud-region/" + "%s/%s/oam-networks/oam-network/%s" % ( + self.cloud_owner, self.cloud_region, + network['id'])) + body = { + 'network-uuid': network['id'], + 'network-name': network['name'], + 'cvlan-tag': network['segmentationId'] or 0, + } + call_req(self.base_url, self.username, self.password, + rest_no_auth, resource, "PUT", + content=json.dumps(body), + headers=self.default_headers) + def add_pservers(self, content): for hypervisor in content['hypervisors']: resource = ("/cloud-infrastructure/pservers/pserver/%s" % ( @@ -305,3 +336,97 @@ class AAIClient(object): rest_no_auth, resource, "PUT", content=json.dumps(body), headers=self.default_headers) + + def _del_tenants(self, rsp): + tenants = rsp.get("tenants", []) + if not tenants: + return + for tenant in tenants["tenant"]: + resource = ("/cloud-infrastructure/cloud-regions/cloud-region/" + "%s/%s/tenants/tenant/%s?resource-version=%s" % ( + self.cloud_owner, self.cloud_region, + tenant['tenant-id'], tenant['resource-version'])) + resp = call_req(self.base_url, self.username, self.password, + rest_no_auth, resource, "DELETE", + headers=self.default_headers) + if resp[0] != 0: + raise VimDriverVioException( + status_code=400, + content="Failed to delete tenant %s: %s." % ( + tenant['tenant-id'], resp[1])) + + def _del_flavors(self, rsp): + tenants = rsp.get("flavors", []) + if not tenants: + return + for tenant in tenants["flavor"]: + resource = ("/cloud-infrastructure/cloud-regions/cloud-region/" + "%s/%s/flavors/flavor/%s?resource-version=%s" % ( + self.cloud_owner, self.cloud_region, + tenant['flavor-id'], tenant['resource-version'])) + resp = call_req(self.base_url, self.username, self.password, + rest_no_auth, resource, "DELETE", + headers=self.default_headers) + if resp[0] != 0: + raise VimDriverVioException( + status_code=400, + content="Failed to delete flavor %s: %s." % ( + tenant['flavor-id'], resp[1])) + + def _del_images(self, rsp): + tenants = rsp.get("images", []) + if not tenants: + return + for tenant in tenants["image"]: + resource = ("/cloud-infrastructure/cloud-regions/cloud-region/" + "%s/%s/images/image/%s?resource-version=%s" % ( + self.cloud_owner, self.cloud_region, + tenant['image-id'], tenant['resource-version'])) + resp = call_req(self.base_url, self.username, self.password, + rest_no_auth, resource, "DELETE", + headers=self.default_headers) + if resp[0] != 0: + raise VimDriverVioException( + status_code=400, + content="Failed to delete image %s: %s." % ( + tenant['image-id'], resp[1])) + + def _del_networks(self, rsp): + networks = rsp.get("oam-networks", []) + if not networks: + return + for network in networks["oam-network"]: + resource = ("/cloud-infrastructure/cloud-regions/cloud-region/" + "%s/%s/oam-networks/oam-network/%s?" + "resource-version=%s" % ( + self.cloud_owner, self.cloud_region, + network['network-uuid'], + network['resource-version'])) + resp = call_req(self.base_url, self.username, self.password, + rest_no_auth, resource, "DELETE", + headers=self.default_headers) + if resp[0] != 0: + raise VimDriverVioException( + status_code=400, + content="Failed to delete network %s: %s." % ( + network['network-uuid'], resp[1])) + + def _del_azs(self, rsp): + azs = rsp.get("availability-zones", []) + if not azs: + return + for az in azs["availability-zone"]: + resource = ("/cloud-infrastructure/cloud-regions/cloud-region/" + "%s/%s/availability-zones/availability-zone/%s?" + "resource-version=%s" % ( + self.cloud_owner, self.cloud_region, + az['availability-zone-name'], + az['resource-version'])) + resp = call_req(self.base_url, self.username, self.password, + rest_no_auth, resource, "DELETE", + headers=self.default_headers) + if resp[0] != 0: + raise VimDriverVioException( + status_code=400, + content="Failed to delete availability zone %s: %s." % ( + az['availability-zone-name'], resp[1])) diff --git a/vio/vio/pub/vim/drivers/vimsdk/image_v2.py b/vio/vio/pub/vim/drivers/vimsdk/image_v2.py index 6d040c6..3ea0291 100644 --- a/vio/vio/pub/vim/drivers/vimsdk/image_v2.py +++ b/vio/vio/pub/vim/drivers/vimsdk/image_v2.py @@ -24,7 +24,6 @@ class GlanceClient(base.DriverBase): def __init__(self, params): super(GlanceClient, self).__init__(params) - LOG.info("%s", str(params)) self.conn = sdk.create_connection(params) self.session = self.conn.session self._proxy = self.conn.image diff --git a/vio/vio/swagger/urls.py b/vio/vio/swagger/urls.py index 2a6eb48..49d22d8 100644 --- a/vio/vio/swagger/urls.py +++ b/vio/vio/swagger/urls.py @@ -40,6 +40,7 @@ from vio.swagger.views.proxyplugin.heat.views import HeatServer # Registry from vio.swagger.views.registry.views import Registry +from vio.swagger.views.registry.views import UnRegistry # Extensions from vio.swagger.views.extensions.views import Extensions @@ -106,8 +107,8 @@ urlpatterns = [ # Registry url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-z-A-Z\-\_]+)/registry$', Registry.as_view()), - # url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-z-A-Z\-\_]+)$', - # Registry.as_view()), + url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-z-A-Z\-\_]+)$', + UnRegistry.as_view()), # proxy url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-z-A-Z\-\_]+)/identity/v3', diff --git a/vio/vio/swagger/views/registry/views.py b/vio/vio/swagger/views/registry/views.py index cde3b5d..7969ad1 100644 --- a/vio/vio/swagger/views/registry/views.py +++ b/vio/vio/swagger/views/registry/views.py @@ -24,6 +24,7 @@ from vio.pub.vim.vimapi.keystone import OperateTenant from vio.pub.vim.vimapi.glance import OperateImage from vio.pub.vim.vimapi.nova import OperateFlavors from vio.pub.vim.vimapi.nova import OperateHypervisor +from vio.pub.vim.vimapi.network import OperateNetwork logger = logging.getLogger(__name__) @@ -76,6 +77,20 @@ class Registry(APIView): rsp['flavors'].append(flavor[0].to_dict()) return rsp + def _get_networks(self, auth_info): + net_op = OperateNetwork.OperateNetwork() + try: + resp = net_op.list_networks( + auth_info['vimId'], auth_info['tenant']) + except Exception as e: + if hasattr(e, "http_status"): + return Response(data={'error': str(e)}, status=e.http_status) + else: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + rsp = {'networks': resp['networks']} + return rsp + def _get_hypervisors(self, auth_info): hypervisor_op = OperateHypervisor.OperateHypervisor() try: @@ -112,7 +127,7 @@ class Registry(APIView): rsp = {} # get tenants try: - print('Updating tenants') + logger.debug('Getting tenants') tenants = self._get_tenants(data) rsp.update(tenants) data['tenant'] = self._find_tenant_id( @@ -120,19 +135,23 @@ class Registry(APIView): data['project_id'] = data['tenant'] # set default tenant # get images - print('Updating images') + logger.debug('Getting images') images = self._get_images(data) rsp.update(images) # get flavors - print('Updating flavors') + logger.debug('Getting flavors') flavors = self._get_flavors(data) rsp.update(flavors) + # get networks + logger.debug('Getting networks') + networks = self._get_networks(data) + rsp.update(networks) # get hypervisors - print('Updating hypervisors') + logger.debug('Getting hypervisors') hypervisors = self._get_hypervisors(data) rsp.update(hypervisors) # update A&AI - print('Put data into A&AI') + logger.debug('Put data into A&AI') cloud_owner, cloud_region = extsys.split_vim_to_owner_region( vimid) aai_adapter = AAIClient(cloud_owner, cloud_region) @@ -142,38 +161,16 @@ class Registry(APIView): status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response(data="", status=status.HTTP_200_OK) - def delete(self, request, vimid): - try: - vim_info = extsys.get_vim_by_id(vimid) - except VimDriverVioException as e: - return Response(data={'error': str(e)}, status=e.status_code) - data = {} - data['vimId'] = vim_info['vimId'] - data['username'] = vim_info['userName'] - data['password'] = vim_info['password'] - data['url'] = vim_info['url'] - data['project_name'] = vim_info['tenant'] +class UnRegistry(APIView): - query = dict(request.query_params) - tenant_instance = OperateTenant.OperateTenant() + def delete(self, request, vimid): try: - projects = tenant_instance.get_projects(data, **query) + cloud_owner, cloud_region = extsys.split_vim_to_owner_region( + vimid) + aai_adapter = AAIClient(cloud_owner, cloud_region) + aai_adapter.delete_vim() except Exception as e: - if hasattr(e, "http_status"): - return Response(data={'error': str(e)}, status=e.http_status) - else: - return Response(data={'error': str(e)}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) - - rsp = {} - rsp['vimId'] = vim_info['vimId'] - rsp['vimName'] = vim_info['name'] - rsp['tenants'] = [] - - for project in projects: - tenant = {} - tenant['id'] = project.id - tenant['name'] = project.name - rsp['tenants'].append(tenant) - return Response(data=rsp, status=status.HTTP_200_OK) + return Response(data=e.message, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response(data="", status=status.HTTP_204_NO_CONTENT) diff --git a/vio/vio/tests/tests_registry_view.py b/vio/vio/tests/tests_registry_view.py index 45c8c05..31c2d78 100644 --- a/vio/vio/tests/tests_registry_view.py +++ b/vio/vio/tests/tests_registry_view.py @@ -14,9 +14,11 @@ import unittest import mock from rest_framework import status from vio.swagger.views.registry.views import Registry +from vio.swagger.views.registry.views import UnRegistry from vio.pub.msapi import extsys +from vio.pub.utils.restcall import AAIClient from vio.pub.vim.vimapi.keystone.OperateTenant import OperateTenant from vio.pub.vim.vimapi.glance.OperateImage import OperateImage from vio.pub.vim.vimapi.nova.OperateFlavors import OperateFlavors @@ -36,28 +38,6 @@ class RegistryViewTest(unittest.TestCase): @mock.patch.object(OperateTenant, 'get_projects') @mock.patch.object(extsys, 'get_vim_by_id') - def test_reg_delete_view(self, mock_vim_info, mock_projects): - mock_vim_info.return_value = VIM_INFO - - class Project: - def __init__(self, id, name): - self.id = id - self.name = name - p1 = Project(1, "p1") - p2 = Project(2, "p2") - projects = [p1, p2] - mock_projects.return_value = projects - - class Request: - def __init__(self, query_params): - self.query_params = query_params - req = Request({'k': 'v'}) - self.assertEqual( - status.HTTP_200_OK, - self.reg.delete(req, "vimid").status_code) - - @mock.patch.object(OperateTenant, 'get_projects') - @mock.patch.object(extsys, 'get_vim_by_id') def test_reg_get_tenants_view(self, mock_vim_info, mock_projects): mock_vim_info.return_value = VIM_INFO @@ -190,3 +170,25 @@ class RegistryViewTest(unittest.TestCase): tenants = {"tenants": [ {"name": "t1", "id": 1}, {"name": "t2", "id": 2}]} self.assertEqual(self.reg._find_tenant_id("t2", tenants), 2) + + +class UnRegistryViewTest(unittest.TestCase): + + def setUp(self): + self.reg = UnRegistry() + + def tearDown(self): + pass + + @mock.patch.object(AAIClient, 'delete_vim') + @mock.patch.object(extsys, 'get_vim_by_id') + def test_reg_delete_view(self, mock_vim_info, mock_del_vim): + mock_vim_info.return_value = VIM_INFO + + class Request: + def __init__(self, query_params): + self.query_params = query_params + req = Request({'k': 'v'}) + self.assertEqual( + status.HTTP_204_NO_CONTENT, + self.reg.delete(req, "vimid").status_code) |