summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Lynn <ethanlynnl@vmware.com>2017-09-20 16:27:44 +0800
committerEthan Lynn <ethanlynnl@vmware.com>2017-09-20 17:41:27 +0800
commit88f24efabca0667fe9fae2b7537044345dac2f79 (patch)
tree3ecee6074f0877eb5cfbb6c4d3463b409a66160d
parent87cae974439b871f545735fb93b740f6fdbd263d (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.py129
-rw-r--r--vio/vio/pub/vim/drivers/vimsdk/image_v2.py1
-rw-r--r--vio/vio/swagger/urls.py5
-rw-r--r--vio/vio/swagger/views/registry/views.py69
-rw-r--r--vio/vio/tests/tests_registry_view.py46
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)