summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAna Krivokapic <akrivoka@redhat.com>2014-04-08 14:23:45 +0200
committerAna Krivokapic <akrivoka@redhat.com>2014-04-08 14:26:40 +0200
commit1625b16b0404e8f01b2cc1e82f717dccf3bbb3bb (patch)
tree7ef7454200934fd3ffd84446506c193e79bf756b
parent883068ac5be231bfa7c1c07435635f634dc77730 (diff)
downloadtuskar-ui-1625b16b0404e8f01b2cc1e82f717dccf3bbb3bb.tar.gz
Prevent used flavor from being deleted
When a flavor deletion is attempted, two checks are necessary: * ensure the flavor is not deployed on an instance * ensure the flavor is not associated with a deployment role This patch adds the second check which was missing. Change-Id: I8c9610a4245b617cae281b44084d1a93b4699c2c Closes-bug: #1302019
-rw-r--r--tuskar_ui/api.py5
-rw-r--r--tuskar_ui/infrastructure/flavors/tests.py45
-rw-r--r--tuskar_ui/test/test_data/tuskar_data.py11
3 files changed, 52 insertions, 9 deletions
diff --git a/tuskar_ui/api.py b/tuskar_ui/api.py
index 11dcfbb1..bcc862cd 100644
--- a/tuskar_ui/api.py
+++ b/tuskar_ui/api.py
@@ -211,7 +211,10 @@ class Flavor(object):
def list_deployed_ids(cls, request):
"""Get and memoize ID's of deployed flavors."""
servers = nova.server_list(request)[0]
- return set(server.flavor['id'] for server in servers)
+ deployed_ids = set(server.flavor['id'] for server in servers)
+ roles = OvercloudRole.list(request)
+ deployed_ids |= set(role.flavor_id for role in roles)
+ return deployed_ids
class Overcloud(base.APIResourceWrapper):
diff --git a/tuskar_ui/infrastructure/flavors/tests.py b/tuskar_ui/infrastructure/flavors/tests.py
index 1b43d125..5145e27c 100644
--- a/tuskar_ui/infrastructure/flavors/tests.py
+++ b/tuskar_ui/infrastructure/flavors/tests.py
@@ -63,18 +63,20 @@ def _prepare_create():
class FlavorsTest(test.BaseAdminViewTests):
def test_index(self):
+ roles = TEST_DATA.tuskarclient_overcloud_roles.list()
with contextlib.nested(
patch('openstack_dashboard.api.nova.flavor_list',
return_value=TEST_DATA.novaclient_flavors.list()),
patch('openstack_dashboard.api.nova.server_list',
return_value=([], False)),
- ) as (flavors_mock, servers_mock):
+ patch('tuskar_ui.api.OvercloudRole.list', return_value=roles),
+ ) as (flavors_mock, servers_mock, role_list_mock):
res = self.client.get(INDEX_URL)
self.assertEqual(flavors_mock.call_count, 1)
self.assertEqual(servers_mock.call_count, 1)
+ self.assertEqual(role_list_mock.call_count, 1)
- self.assertTemplateUsed(res,
- 'infrastructure/flavors/index.html')
+ self.assertTemplateUsed(res, 'infrastructure/flavors/index.html')
def test_index_recoverable_failure(self):
with patch('openstack_dashboard.api.nova.flavor_list',
@@ -88,8 +90,7 @@ class FlavorsTest(test.BaseAdminViewTests):
return_value=([], False)) as mock:
res = self.client.get(CREATE_URL)
self.assertEqual(mock.call_count, 2)
- self.assertTemplateUsed(res,
- 'infrastructure/flavors/create.html')
+ self.assertTemplateUsed(res, 'infrastructure/flavors/create.html')
def test_create_get_recoverable_failure(self):
with patch('openstack_dashboard.api.glance.image_list_detailed',
@@ -125,18 +126,20 @@ class FlavorsTest(test.BaseAdminViewTests):
patch('openstack_dashboard.api.nova.flavor_delete'),
patch('openstack_dashboard.api.nova.server_list',
return_value=([], False)),
+ patch('tuskar_ui.api.OvercloudRole.list', return_value=[]),
patch('openstack_dashboard.api.glance.image_list_detailed',
return_value=([], False)),
patch('openstack_dashboard.api.nova.flavor_list',
return_value=TEST_DATA.novaclient_flavors.list())
- ) as (delete_mock, server_list_mock, glance_mock, flavors_mock):
+ ) as (delete_mock, server_list_mock, _role_list_mock, _glance_mock,
+ _flavors_mock):
res = self.client.post(INDEX_URL, data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, INDEX_URL)
self.assertEqual(delete_mock.call_count, 2)
self.assertEqual(server_list_mock.call_count, 1)
- def test_delete_deployed(self):
+ def test_delete_deployed_on_servers(self):
flavors = TEST_DATA.novaclient_flavors.list()
server = servers.Server(
servers.ServerManager(None),
@@ -152,11 +155,37 @@ class FlavorsTest(test.BaseAdminViewTests):
patch('openstack_dashboard.api.nova.flavor_delete'),
patch('openstack_dashboard.api.nova.server_list',
return_value=([server], False)),
+ patch('tuskar_ui.api.OvercloudRole.list', return_value=[]),
+ patch('openstack_dashboard.api.glance.image_list_detailed',
+ return_value=([], False)),
+ patch('openstack_dashboard.api.nova.flavor_list',
+ return_value=TEST_DATA.novaclient_flavors.list())
+ ) as (delete_mock, server_list_mock, _role_list_mock, _glance_mock,
+ _flavors_mock):
+ res = self.client.post(INDEX_URL, data)
+ self.assertMessageCount(error=1, warning=0)
+ self.assertNoFormErrors(res)
+ self.assertRedirectsNoFollow(res, INDEX_URL)
+ self.assertEqual(delete_mock.call_count, 1)
+ self.assertEqual(server_list_mock.call_count, 1)
+
+ def test_delete_deployed_on_roles(self):
+ flavors = TEST_DATA.novaclient_flavors.list()
+ roles = TEST_DATA.tuskarclient_roles_with_flavors.list()
+
+ data = {'action': 'flavors__delete',
+ 'object_ids': [flavors[0].id, flavors[1].id]}
+ with contextlib.nested(
+ patch('openstack_dashboard.api.nova.flavor_delete'),
+ patch('openstack_dashboard.api.nova.server_list',
+ return_value=([], False)),
+ patch('tuskar_ui.api.OvercloudRole.list', return_value=roles),
patch('openstack_dashboard.api.glance.image_list_detailed',
return_value=([], False)),
patch('openstack_dashboard.api.nova.flavor_list',
return_value=TEST_DATA.novaclient_flavors.list())
- ) as (delete_mock, server_list_mock, glance_mock, flavors_mock):
+ ) as (delete_mock, server_list_mock, _role_list_mock, _glance_mock,
+ _flavors_mock):
res = self.client.post(INDEX_URL, data)
self.assertMessageCount(error=1, warning=0)
self.assertNoFormErrors(res)
diff --git a/tuskar_ui/test/test_data/tuskar_data.py b/tuskar_ui/test/test_data/tuskar_data.py
index ea24b4f2..659b0931 100644
--- a/tuskar_ui/test/test_data/tuskar_data.py
+++ b/tuskar_ui/test/test_data/tuskar_data.py
@@ -441,3 +441,14 @@ def data(TEST):
'disk': 60})
flavor_2.get_keys = lambda: {'cpu_arch': 'i386'}
TEST.novaclient_flavors.add(flavor_1, flavor_2)
+
+ # OvercloudRoles with flavors associated
+ TEST.tuskarclient_roles_with_flavors = test_data_utils.TestDataContainer()
+ role_with_flavor = overcloud_roles.OvercloudRole(
+ overcloud_roles.OvercloudRoleManager(None),
+ {'id': 5,
+ 'name': 'Block Storage',
+ 'description': 'block storage overcloud role',
+ 'flavor_id': '1',
+ 'image_name': 'overcloud-block-storage'})
+ TEST.tuskarclient_roles_with_flavors.add(role_with_flavor)