Drop the usage of nova extensions in python code

Part of the removal of OPENSTACK_NOVA_EXTENSIONS_BLACKLIST (1/3)

All references of nova extensions in the python code are cleaned up.
Note that the API layer is not touched yet as it is used by the
JavaScript side.

Change-Id: I66cd0a9629253a6462aace9902ef8200b94b2a21
This commit is contained in:
Akihiro Motoki 2020-09-12 04:41:14 +09:00
parent c9e47d6595
commit c45cc6b1c5
15 changed files with 179 additions and 792 deletions

View File

@ -16,7 +16,6 @@ from django.utils.translation import ugettext_lazy as _
import horizon import horizon
from openstack_dashboard import api
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -26,18 +25,3 @@ class Aggregates(horizon.Panel):
slug = 'aggregates' slug = 'aggregates'
policy_rules = (("compute", "compute_extension:aggregates"),) policy_rules = (("compute", "compute_extension:aggregates"),)
permissions = ('openstack.services.compute',) permissions = ('openstack.services.compute',)
def allowed(self, context):
# extend basic permission-based check with a check to see whether
# the Aggregates extension is even enabled in nova
try:
request = context['request']
if not (api.base.is_service_enabled(request, 'compute') and
api.nova.extension_supported('Aggregates', request)):
return False
except Exception:
LOG.error("Call to list supported extensions failed. This is "
"likely due to a problem communicating with the Nova "
"endpoint. Host Aggregates panel will not be displayed.")
return False
return super().allowed(context)

View File

@ -191,25 +191,6 @@ class CreateAggregateWorkflowTests(BaseAggregateWorkflowTests):
class AggregatesViewTests(test.BaseAdminViewTests): class AggregatesViewTests(test.BaseAdminViewTests):
@test.create_mocks({
api.keystone: ['tenant_list'],
api.nova: ['extension_supported']})
def test_panel_not_available(self):
self.mock_tenant_list.return_value = self.tenants.list()
self.mock_extension_supported.return_value = False
self.patchers['aggregates'].stop()
res = self.client.get(reverse('horizon:admin:overview:index'))
self.assertNotIn(b'Host Aggregates', res.content)
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
self.assertEqual(self.mock_extension_supported.call_count, 3)
expected_calls = [mock.call(a, test.IsHttpRequest())
for a in ['SimpleTenantUsage',
'SimpleTenantUsage',
'Aggregates']]
self.mock_extension_supported.assert_has_calls(
expected_calls)
@test.create_mocks({ @test.create_mocks({
api.nova: ['aggregate_details_list', api.nova: ['aggregate_details_list',
'availability_zone_list']}) 'availability_zone_list']})

View File

@ -34,9 +34,6 @@ class EvacuateHost(tables.LinkAction):
self.name = kwargs.get('name', self.name) self.name = kwargs.get('name', self.name)
def allowed(self, request, instance): def allowed(self, request, instance):
if not api.nova.extension_supported('AdminActions', request):
return False
return self.datum.state == "down" return self.datum.state == "down"
@ -48,9 +45,6 @@ class DisableService(policy.PolicyTargetMixin, tables.LinkAction):
policy_rules = (("compute", "os_compute_api:os-services"),) policy_rules = (("compute", "os_compute_api:os-services"),)
def allowed(self, request, service): def allowed(self, request, service):
if not api.nova.extension_supported('AdminActions', request):
return False
return service.status == "enabled" return service.status == "enabled"
@ -75,9 +69,6 @@ class EnableService(policy.PolicyTargetMixin, tables.BatchAction):
) )
def allowed(self, request, service): def allowed(self, request, service):
if not api.nova.extension_supported('AdminActions', request):
return False
return service.status == "disabled" return service.status == "disabled"
def action(self, request, obj_id): def action(self, request, obj_id):
@ -93,9 +84,6 @@ class MigrateMaintenanceHost(tables.LinkAction):
action_type = "danger" action_type = "danger"
def allowed(self, request, service): def allowed(self, request, service):
if not api.nova.extension_supported('AdminActions', request):
return False
return service.status == "disabled" return service.status == "disabled"

View File

@ -12,8 +12,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from unittest import mock
from django.urls import reverse from django.urls import reverse
from openstack_dashboard import api from openstack_dashboard import api
@ -21,15 +19,13 @@ from openstack_dashboard.test import helpers as test
class HypervisorViewTest(test.BaseAdminViewTests): class HypervisorViewTest(test.BaseAdminViewTests):
@test.create_mocks({api.nova: ['extension_supported', @test.create_mocks({api.nova: ['hypervisor_list',
'hypervisor_list',
'hypervisor_stats', 'hypervisor_stats',
'service_list']}) 'service_list']})
def test_index(self): def test_index(self):
hypervisors = self.hypervisors.list() hypervisors = self.hypervisors.list()
compute_services = [service for service in self.services.list() compute_services = [service for service in self.services.list()
if service.binary == 'nova-compute'] if service.binary == 'nova-compute']
self.mock_extension_supported.return_value = True
self.mock_hypervisor_list.return_value = hypervisors self.mock_hypervisor_list.return_value = hypervisors
self.mock_hypervisor_stats.return_value = self.hypervisors.stats self.mock_hypervisor_stats.return_value = self.hypervisors.stats
self.mock_service_list.return_value = compute_services self.mock_service_list.return_value = compute_services
@ -61,9 +57,6 @@ class HypervisorViewTest(test.BaseAdminViewTests):
self.assertEqual('migrate_maintenance', self.assertEqual('migrate_maintenance',
actions_service_disabled[1].name) actions_service_disabled[1].name)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_extension_supported, 28,
mock.call('AdminActions', test.IsHttpRequest()))
self.mock_hypervisor_list.assert_called_once_with( self.mock_hypervisor_list.assert_called_once_with(
test.IsHttpRequest()) test.IsHttpRequest())
self.mock_hypervisor_stats.assert_called_once_with( self.mock_hypervisor_stats.assert_called_once_with(

View File

@ -30,7 +30,7 @@ INDEX_TEMPLATE = 'horizon/common/_data_table_view.html'
class InstanceViewTest(test.BaseAdminViewTests): class InstanceViewTest(test.BaseAdminViewTests):
@test.create_mocks({ @test.create_mocks({
api.nova: ['flavor_list', 'server_list_paged', 'extension_supported'], api.nova: ['flavor_list', 'server_list_paged'],
api.keystone: ['tenant_list'], api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'], api.glance: ['image_list_detailed_by_ids'],
}) })
@ -39,7 +39,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
# TODO(vmarkov) instances_img_ids should be in test_data # TODO(vmarkov) instances_img_ids should be in test_data
instances_img_ids = [instance.image.get('id') for instance in instances_img_ids = [instance.image.get('id') for instance in
servers if isinstance(instance.image, dict)] servers if isinstance(instance.image, dict)]
self.mock_extension_supported.return_value = True
self.mock_tenant_list.return_value = [self.tenants.list(), False] self.mock_tenant_list.return_value = [self.tenants.list(), False]
self.mock_image_list_detailed_by_ids.return_value = self.images.list() self.mock_image_list_detailed_by_ids.return_value = self.images.list()
self.mock_flavor_list.return_value = self.flavors.list() self.mock_flavor_list.return_value = self.flavors.list()
@ -50,11 +49,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
instances = res.context['table'].data instances = res.context['table'].data
self.assertCountEqual(instances, servers) self.assertCountEqual(instances, servers)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('Shelve', test.IsHttpRequest())] * 4)
self.assertEqual(15, self.mock_extension_supported.call_count)
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
self.mock_image_list_detailed_by_ids.assert_called_once_with( self.mock_image_list_detailed_by_ids.assert_called_once_with(
test.IsHttpRequest(), instances_img_ids) test.IsHttpRequest(), instances_img_ids)
@ -66,8 +60,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
search_opts=search_opts) search_opts=search_opts)
@test.create_mocks({ @test.create_mocks({
api.nova: ['flavor_list', 'flavor_get', 'server_list_paged', api.nova: ['flavor_list', 'flavor_get', 'server_list_paged'],
'extension_supported'],
api.keystone: ['tenant_list'], api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'], api.glance: ['image_list_detailed_by_ids'],
}) })
@ -78,7 +71,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
servers if hasattr(instance, 'image')] servers if hasattr(instance, 'image')]
full_flavors = OrderedDict([(f.id, f) for f in flavors]) full_flavors = OrderedDict([(f.id, f) for f in flavors])
self.mock_server_list_paged.return_value = [servers, False, False] self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_extension_supported.return_value = True
self.mock_flavor_list.side_effect = self.exceptions.nova self.mock_flavor_list.side_effect = self.exceptions.nova
self.mock_tenant_list.return_value = [self.tenants.list(), False] self.mock_tenant_list.return_value = [self.tenants.list(), False]
@ -99,11 +91,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), test.IsHttpRequest(),
sort_dir='desc', sort_dir='desc',
search_opts=search_opts) search_opts=search_opts)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('Shelve', test.IsHttpRequest())] * 4)
self.assertEqual(15, self.mock_extension_supported.call_count)
self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest()) self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
self.mock_flavor_get.assert_has_calls( self.mock_flavor_get.assert_has_calls(
@ -113,8 +100,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), instances_img_ids) test.IsHttpRequest(), instances_img_ids)
@test.create_mocks({ @test.create_mocks({
api.nova: ['flavor_list', 'flavor_get', 'server_list_paged', api.nova: ['flavor_list', 'flavor_get', 'server_list_paged'],
'extension_supported'],
api.keystone: ['tenant_list'], api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'], api.glance: ['image_list_detailed_by_ids'],
}) })
@ -130,7 +116,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_image_list_detailed_by_ids.return_value = self.images.list() self.mock_image_list_detailed_by_ids.return_value = self.images.list()
self.mock_flavor_list.return_value = self.flavors.list() self.mock_flavor_list.return_value = self.flavors.list()
self.mock_server_list_paged.return_value = [servers, False, False] self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_extension_supported.return_value = True
self.mock_tenant_list.return_value = [self.tenants.list(), False] self.mock_tenant_list.return_value = [self.tenants.list(), False]
self.mock_flavor_get.side_effect = self.exceptions.nova self.mock_flavor_get.side_effect = self.exceptions.nova
@ -151,11 +136,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), test.IsHttpRequest(),
sort_dir='desc', sort_dir='desc',
search_opts=search_opts) search_opts=search_opts)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('Shelve', test.IsHttpRequest())] * 4)
self.assertEqual(15, self.mock_extension_supported.call_count)
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
self.mock_flavor_get.assert_has_calls( self.mock_flavor_get.assert_has_calls(
[mock.call(test.IsHttpRequest(), s.flavor['id']) for s in servers]) [mock.call(test.IsHttpRequest(), s.flavor['id']) for s in servers])
@ -186,14 +166,12 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), []) test.IsHttpRequest(), [])
self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest()) self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
@test.create_mocks({api.nova: ['server_get', 'flavor_get', @test.create_mocks({api.nova: ['server_get', 'flavor_get'],
'extension_supported'],
api.network: ['servers_update_addresses'], api.network: ['servers_update_addresses'],
api.keystone: ['tenant_get']}) api.keystone: ['tenant_get']})
def test_ajax_loading_instances(self): def test_ajax_loading_instances(self):
server = self.servers.first() server = self.servers.first()
self.mock_server_get.return_value = server self.mock_server_get.return_value = server
self.mock_extension_supported.return_value = True
self.mock_flavor_get.return_value = self.flavors.first() self.mock_flavor_get.return_value = self.flavors.first()
self.mock_tenant_get.return_value = self.tenants.first() self.mock_tenant_get.return_value = self.tenants.first()
self.mock_servers_update_addresses.return_value = None self.mock_servers_update_addresses.return_value = None
@ -218,11 +196,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_server_get.assert_called_once_with( self.mock_server_get.assert_called_once_with(
test.IsHttpRequest(), server.id) test.IsHttpRequest(), server.id)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('Shelve', test.IsHttpRequest())])
self.assertEqual(3, self.mock_extension_supported.call_count)
self.mock_flavor_get.assert_called_once_with( self.mock_flavor_get.assert_called_once_with(
test.IsHttpRequest(), server.flavor['id']) test.IsHttpRequest(), server.flavor['id'])
self.mock_tenant_get.assert_called_once_with( self.mock_tenant_get.assert_called_once_with(
@ -231,7 +204,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), [server]) test.IsHttpRequest(), [server])
@test.create_mocks({ @test.create_mocks({
api.nova: ['flavor_list', 'server_list_paged', 'extension_supported'], api.nova: ['flavor_list', 'server_list_paged'],
api.keystone: ['tenant_list'], api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'], api.glance: ['image_list_detailed_by_ids'],
}) })
@ -244,7 +217,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_flavor_list.return_value = self.flavors.list() self.mock_flavor_list.return_value = self.flavors.list()
self.mock_server_list_paged.return_value = [ self.mock_server_list_paged.return_value = [
self.servers.list(), False, False] self.servers.list(), False, False]
self.mock_extension_supported.return_value = True
res = self.client.get(INDEX_URL) res = self.client.get(INDEX_URL)
self.assertContains(res, "instances__migrate") self.assertContains(res, "instances__migrate")
self.assertNotContains(res, "instances__confirm") self.assertNotContains(res, "instances__confirm")
@ -259,14 +231,9 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), test.IsHttpRequest(),
sort_dir='desc', sort_dir='desc',
search_opts=search_opts) search_opts=search_opts)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('Shelve', test.IsHttpRequest())] * 4)
self.assertEqual(15, self.mock_extension_supported.call_count)
@test.create_mocks({ @test.create_mocks({
api.nova: ['flavor_list', 'server_list_paged', 'extension_supported'], api.nova: ['flavor_list', 'server_list_paged'],
api.keystone: ['tenant_list'], api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'], api.glance: ['image_list_detailed_by_ids'],
}) })
@ -281,7 +248,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_tenant_list.return_value = [self.tenants.list(), False] self.mock_tenant_list.return_value = [self.tenants.list(), False]
self.mock_image_list_detailed_by_ids.return_value = self.images.list() self.mock_image_list_detailed_by_ids.return_value = self.images.list()
self.mock_flavor_list.return_value = self.flavors.list() self.mock_flavor_list.return_value = self.flavors.list()
self.mock_extension_supported.return_value = True
self.mock_server_list_paged.return_value = [servers, False, False] self.mock_server_list_paged.return_value = [servers, False, False]
res = self.client.get(INDEX_URL) res = self.client.get(INDEX_URL)
@ -293,11 +259,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_image_list_detailed_by_ids.assert_called_once_with( self.mock_image_list_detailed_by_ids.assert_called_once_with(
test.IsHttpRequest(), instances_img_ids) test.IsHttpRequest(), instances_img_ids)
self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest()) self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('Shelve', test.IsHttpRequest())] * 4)
self.assertEqual(15, self.mock_extension_supported.call_count)
search_opts = {'marker': None, 'paginate': True, 'all_tenants': True} search_opts = {'marker': None, 'paginate': True, 'all_tenants': True}
self.mock_server_list_paged.assert_called_once_with( self.mock_server_list_paged.assert_called_once_with(
test.IsHttpRequest(), test.IsHttpRequest(),
@ -490,8 +451,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
@test.create_mocks({ @test.create_mocks({
api.nova: ['flavor_list', api.nova: ['flavor_list',
'flavor_get', 'flavor_get',
'server_list_paged', 'server_list_paged'],
'extension_supported'],
api.keystone: ['tenant_list'], api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'], api.glance: ['image_list_detailed_by_ids'],
}) })
@ -509,7 +469,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_server_list_paged.return_value = [ self.mock_server_list_paged.return_value = [
servers, has_more, has_prev] servers, has_more, has_prev]
self.mock_extension_supported.return_value = True
self.mock_flavor_list.return_value = flavors self.mock_flavor_list.return_value = flavors
self.mock_image_list_detailed_by_ids.return_value = images self.mock_image_list_detailed_by_ids.return_value = images
self.mock_tenant_list.return_value = [tenants, False] self.mock_tenant_list.return_value = [tenants, False]
@ -523,11 +482,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertTemplateUsed(res, INDEX_TEMPLATE) self.assertTemplateUsed(res, INDEX_TEMPLATE)
self.assertEqual(res.status_code, 200) self.assertEqual(res.status_code, 200)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('Shelve', test.IsHttpRequest())])
self.assertEqual(3, self.mock_extension_supported.call_count)
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
self.mock_image_list_detailed_by_ids.assert_called_once_with( self.mock_image_list_detailed_by_ids.assert_called_once_with(
test.IsHttpRequest(), test.IsHttpRequest(),

View File

@ -17,7 +17,6 @@
# under the License. # under the License.
import datetime import datetime
from unittest import mock
from django.test.utils import override_settings from django.test.utils import override_settings
from django.urls import reverse from django.urls import reverse
@ -43,7 +42,10 @@ class UsageViewTests(test.BaseAdminViewTests):
def test_usage_1_day(self): def test_usage_1_day(self):
self._test_usage(nova_stu_enabled=True) self._test_usage(nova_stu_enabled=True)
@override_settings(OVERVIEW_DAYS_RANGE=None) @override_settings(
OVERVIEW_DAYS_RANGE=None,
OPENSTACK_USE_SIMPLE_TENANT_USAGE=False,
)
def test_usage_disabled(self): def test_usage_disabled(self):
self._test_usage(nova_stu_enabled=False, overview_days_range=None) self._test_usage(nova_stu_enabled=False, overview_days_range=None)
@ -58,12 +60,10 @@ class UsageViewTests(test.BaseAdminViewTests):
start_day = datetime.date(now.year, now.month, 1) start_day = datetime.date(now.year, now.month, 1)
return start_day, now return start_day, now
@test.create_mocks({api.nova: ('usage_list', @test.create_mocks({api.nova: ('usage_list',),
'extension_supported'),
api.keystone: ('tenant_list',)}) api.keystone: ('tenant_list',)})
def _test_usage(self, nova_stu_enabled=True, tenant_deleted=False, def _test_usage(self, nova_stu_enabled=True, tenant_deleted=False,
overview_days_range=1): overview_days_range=1):
self.mock_extension_supported.return_value = nova_stu_enabled
usage_list = [api.nova.NovaUsage(u) for u in self.usages.list()] usage_list = [api.nova.NovaUsage(u) for u in self.usages.list()]
if tenant_deleted: if tenant_deleted:
self.mock_tenant_list.return_value = [[self.tenants.first()], self.mock_tenant_list.return_value = [[self.tenants.first()],
@ -124,9 +124,6 @@ class UsageViewTests(test.BaseAdminViewTests):
else: else:
self.assertNotContains(res, usage_table, html=True) self.assertNotContains(res, usage_table, html=True)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_extension_supported, 2,
mock.call('SimpleTenantUsage', test.IsHttpRequest()))
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
if nova_stu_enabled: if nova_stu_enabled:
start_day, now = self._get_start_end_range(overview_days_range) start_day, now = self._get_start_end_range(overview_days_range)
@ -148,15 +145,16 @@ class UsageViewTests(test.BaseAdminViewTests):
def test_usage_csv_1_day(self): def test_usage_csv_1_day(self):
self._test_usage_csv(nova_stu_enabled=True) self._test_usage_csv(nova_stu_enabled=True)
@override_settings(OVERVIEW_DAYS_RANGE=None) @override_settings(
OVERVIEW_DAYS_RANGE=None,
OPENSTACK_USE_SIMPLE_TENANT_USAGE=False,
)
def test_usage_csv_disabled(self): def test_usage_csv_disabled(self):
self._test_usage_csv(nova_stu_enabled=False, overview_days_range=None) self._test_usage_csv(nova_stu_enabled=False, overview_days_range=None)
@test.create_mocks({api.nova: ('usage_list', @test.create_mocks({api.nova: ('usage_list',),
'extension_supported'),
api.keystone: ('tenant_list',)}) api.keystone: ('tenant_list',)})
def _test_usage_csv(self, nova_stu_enabled=True, overview_days_range=1): def _test_usage_csv(self, nova_stu_enabled=True, overview_days_range=1):
self.mock_extension_supported.return_value = nova_stu_enabled
self.mock_tenant_list.return_value = [self.tenants.list(), False] self.mock_tenant_list.return_value = [self.tenants.list(), False]
usage_obj = [api.nova.NovaUsage(u) for u in self.usages.list()] usage_obj = [api.nova.NovaUsage(u) for u in self.usages.list()]
self.mock_usage_list.return_value = usage_obj self.mock_usage_list.return_value = usage_obj
@ -178,9 +176,6 @@ class UsageViewTests(test.BaseAdminViewTests):
obj.vcpu_hours) obj.vcpu_hours)
self.assertContains(res, row) self.assertContains(res, row)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_extension_supported, 2,
mock.call('SimpleTenantUsage', test.IsHttpRequest()))
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest()) self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
if nova_stu_enabled: if nova_stu_enabled:
start_day, now = self._get_start_end_range(overview_days_range) start_day, now = self._get_start_end_range(overview_days_range)

View File

@ -1167,6 +1167,8 @@ class UsageViewTests(test.BaseAdminViewTests):
def test_usage_csv(self): def test_usage_csv(self):
self._test_usage_csv(nova_stu_enabled=True) self._test_usage_csv(nova_stu_enabled=True)
# nova_stu_enable=False is specified below, so we need this.
@override_settings(OPENSTACK_USE_SIMPLE_TENANT_USAGE=False)
def test_usage_csv_disabled(self): def test_usage_csv_disabled(self):
self._test_usage_csv(nova_stu_enabled=False) self._test_usage_csv(nova_stu_enabled=False)
@ -1174,12 +1176,10 @@ class UsageViewTests(test.BaseAdminViewTests):
def test_usage_csv_1_day(self): def test_usage_csv_1_day(self):
self._test_usage_csv(nova_stu_enabled=True, overview_days_range=1) self._test_usage_csv(nova_stu_enabled=True, overview_days_range=1)
@test.create_mocks({api.nova: ('usage_get', @test.create_mocks({api.nova: ('usage_get',)})
'extension_supported')})
def _test_usage_csv(self, nova_stu_enabled=True, overview_days_range=None): def _test_usage_csv(self, nova_stu_enabled=True, overview_days_range=None):
now = timezone.now() now = timezone.now()
usage_obj = api.nova.NovaUsage(self.usages.first()) usage_obj = api.nova.NovaUsage(self.usages.first())
self.mock_extension_supported.return_value = nova_stu_enabled
if overview_days_range: if overview_days_range:
start_day = now - datetime.timedelta(days=overview_days_range) start_day = now - datetime.timedelta(days=overview_days_range)
else: else:
@ -1201,9 +1201,6 @@ class UsageViewTests(test.BaseAdminViewTests):
'"Usage (Hours)","Age (Seconds)","State"') '"Usage (Hours)","Age (Seconds)","State"')
self.assertContains(res, '%s\r\n' % hdr) self.assertContains(res, '%s\r\n' % hdr)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_extension_supported, 2,
mock.call('SimpleTenantUsage', test.IsHttpRequest()))
if nova_stu_enabled: if nova_stu_enabled:
self.mock_usage_get.assert_called_once_with(test.IsHttpRequest(), self.mock_usage_get.assert_called_once_with(test.IsHttpRequest(),
self.tenant.id, self.tenant.id,
@ -1211,8 +1208,7 @@ class UsageViewTests(test.BaseAdminViewTests):
else: else:
self.mock_usage_get.assert_not_called() self.mock_usage_get.assert_not_called()
@test.create_mocks({api.nova: ('usage_get', @test.create_mocks({api.nova: ('usage_get',)})
'extension_supported')})
def test_usage_csv_quoting(self): def test_usage_csv_quoting(self):
# Explicitly test the values of the third usage for correct quoting # Explicitly test the values of the third usage for correct quoting
usage_obj = api.nova.NovaUsage(self.usages.list()[2]) usage_obj = api.nova.NovaUsage(self.usages.list()[2])

View File

@ -56,8 +56,11 @@ class RebuildInstanceForm(forms.SelfHandlingForm):
required=False, required=False,
strip=False, strip=False,
widget=forms.PasswordInput(render_value=False)) widget=forms.PasswordInput(render_value=False))
disk_config = forms.ChoiceField(label=_("Disk Partition"), disk_config = forms.ChoiceField(
required=False) label=_("Disk Partition"),
choices=[("AUTO", _("Automatic")),
("MANUAL", _("Manual"))],
required=False)
description = forms.CharField( description = forms.CharField(
label=_("Description"), label=_("Description"),
widget=forms.Textarea(attrs={'rows': 4}), widget=forms.Textarea(attrs={'rows': 4}),
@ -85,18 +88,6 @@ class RebuildInstanceForm(forms.SelfHandlingForm):
del self.fields['password'] del self.fields['password']
del self.fields['confirm_password'] del self.fields['confirm_password']
try:
if not api.nova.extension_supported("DiskConfig", request):
del self.fields['disk_config']
else:
# Set our disk_config choices
config_choices = [("AUTO", _("Automatic")),
("MANUAL", _("Manual"))]
self.fields['disk_config'].choices = config_choices
except Exception:
exceptions.handle(request, _('Unable to retrieve extensions '
'information.'))
def clean(self): def clean(self):
cleaned_data = super().clean() cleaned_data = super().clean()
if 'password' in cleaned_data: if 'password' in cleaned_data:

View File

@ -254,9 +254,6 @@ class TogglePause(tables.BatchAction):
) )
def allowed(self, request, instance=None): def allowed(self, request, instance=None):
if not api.nova.extension_supported('AdminActions',
request):
return False
if not instance: if not instance:
return False return False
self.paused = instance.status == "PAUSED" self.paused = instance.status == "PAUSED"
@ -321,9 +318,6 @@ class ToggleSuspend(tables.BatchAction):
) )
def allowed(self, request, instance=None): def allowed(self, request, instance=None):
if not api.nova.extension_supported('AdminActions',
request):
return False
if not instance: if not instance:
return False return False
self.suspended = instance.status == "SUSPENDED" self.suspended = instance.status == "SUSPENDED"
@ -388,8 +382,6 @@ class ToggleShelve(tables.BatchAction):
) )
def allowed(self, request, instance=None): def allowed(self, request, instance=None):
if not api.nova.extension_supported('Shelve', request):
return False
if not instance: if not instance:
return False return False
if not request.user.is_superuser and getattr( if not request.user.is_superuser and getattr(
@ -903,8 +895,6 @@ class LockInstance(policy.PolicyTargetMixin, tables.BatchAction):
def allowed(self, request, instance): def allowed(self, request, instance):
if getattr(instance, 'locked', False): if getattr(instance, 'locked', False):
return False return False
if not api.nova.extension_supported('AdminActions', request):
return False
if not api.nova.is_feature_available(request, "locked_attribute"): if not api.nova.is_feature_available(request, "locked_attribute"):
return False return False
return True return True
@ -937,8 +927,6 @@ class UnlockInstance(policy.PolicyTargetMixin, tables.BatchAction):
def allowed(self, request, instance): def allowed(self, request, instance):
if not getattr(instance, 'locked', True): if not getattr(instance, 'locked', True):
return False return False
if not api.nova.extension_supported('AdminActions', request):
return False
if not api.nova.is_feature_available(request, "locked_attribute"): if not api.nova.is_feature_available(request, "locked_attribute"):
return False return False
return True return True

File diff suppressed because it is too large Load Diff

View File

@ -157,21 +157,13 @@ class SetInstanceDetailsAction(workflows.Action):
("instance_snapshot_id", _("Boot from snapshot")), ("instance_snapshot_id", _("Boot from snapshot")),
] ]
if cinder.is_volume_service_enabled(request): if cinder.is_volume_service_enabled(request):
source_type_choices.append(("volume_id", _("Boot from volume"))) source_type_choices += [
("volume_id", _("Boot from volume")),
try: ("volume_image_id",
if api.nova.extension_supported("BlockDeviceMappingV2Boot", _("Boot from image (creates a new volume)")),
request):
source_type_choices.append(
("volume_image_id",
_("Boot from image (creates a new volume)")))
except Exception:
exceptions.handle(request, _('Unable to retrieve extensions '
'information.'))
source_type_choices.append(
("volume_snapshot_id", ("volume_snapshot_id",
_("Boot from volume snapshot (creates a new volume)"))) _("Boot from volume snapshot (creates a new volume)")),
]
self.fields['source_type'].choices = source_type_choices self.fields['source_type'].choices = source_type_choices
@memoized.memoized_method @memoized.memoized_method
@ -806,26 +798,18 @@ class SetAdvancedAction(workflows.Action):
def __init__(self, request, context, *args, **kwargs): def __init__(self, request, context, *args, **kwargs):
super().__init__(request, context, *args, **kwargs) super().__init__(request, context, *args, **kwargs)
try: try:
if not api.nova.extension_supported("DiskConfig", request): config_choices = [("AUTO", _("Automatic")),
del self.fields['disk_config'] ("MANUAL", _("Manual"))]
else: self.fields['disk_config'].choices = config_choices
# Set our disk_config choices
config_choices = [("AUTO", _("Automatic")),
("MANUAL", _("Manual"))]
self.fields['disk_config'].choices = config_choices
# Only show the Config Drive option for the Launch Instance # Only show the Config Drive option for the Launch Instance
# workflow (not Resize Instance) and only if the extension
# is supported. # is supported.
if context.get('workflow_slug') != 'launch_instance' or ( if context.get('workflow_slug') != 'launch_instance':
not api.nova.extension_supported("ConfigDrive", request)):
del self.fields['config_drive'] del self.fields['config_drive']
if not api.nova.extension_supported("ServerGroups", request): server_group_choices = instance_utils.server_group_field_data(
del self.fields['server_group'] request)
else: self.fields['server_group'].choices = server_group_choices
server_group_choices = instance_utils.server_group_field_data(
request)
self.fields['server_group'].choices = server_group_choices
except Exception: except Exception:
exceptions.handle(request, _('Unable to retrieve extensions ' exceptions.handle(request, _('Unable to retrieve extensions '
'information.')) 'information.'))
@ -888,38 +872,24 @@ class LaunchInstance(workflows.Workflow):
if source_type in ['image_id', 'instance_snapshot_id']: if source_type in ['image_id', 'instance_snapshot_id']:
image_id = context['source_id'] image_id = context['source_id']
elif source_type in ['volume_id', 'volume_snapshot_id']: elif source_type in ['volume_id', 'volume_snapshot_id']:
try: # Volume source id is extracted from the source
if api.nova.extension_supported("BlockDeviceMappingV2Boot", volume_source_id = context['source_id'].split(':')[0]
request): device_name = context.get('device_name', '').strip() or None
# Volume source id is extracted from the source dev_source_type_mapping = {
volume_source_id = context['source_id'].split(':')[0] 'volume_id': 'volume',
device_name = context.get('device_name', '') \ 'volume_snapshot_id': 'snapshot'
.strip() or None }
dev_source_type_mapping = { dev_mapping_2 = [
'volume_id': 'volume', {'device_name': device_name,
'volume_snapshot_id': 'snapshot' 'source_type': dev_source_type_mapping[source_type],
} 'destination_type': 'volume',
dev_mapping_2 = [ 'delete_on_termination':
{'device_name': device_name, bool(context['vol_delete_on_instance_delete']),
'source_type': dev_source_type_mapping[source_type], 'uuid': volume_source_id,
'destination_type': 'volume', 'boot_index': '0',
'delete_on_termination': 'volume_size': context['volume_size']
bool(context['vol_delete_on_instance_delete']), }
'uuid': volume_source_id, ]
'boot_index': '0',
'volume_size': context['volume_size']
}
]
else:
dev_mapping_1 = {
context['device_name']: '%s::%s' %
(context['source_id'],
bool(context['vol_delete_on_instance_delete']))
}
except Exception:
msg = _('Unable to retrieve extensions information')
exceptions.handle(request, msg)
elif source_type == 'volume_image_id': elif source_type == 'volume_image_id':
device_name = context.get('device_name', '').strip() or None device_name = context.get('device_name', '').strip() or None
dev_mapping_2 = [ dev_mapping_2 = [

View File

@ -18,7 +18,6 @@
import datetime import datetime
import logging import logging
from unittest import mock
from django.test.utils import override_settings from django.test.utils import override_settings
from django.urls import reverse from django.urls import reverse
@ -35,7 +34,7 @@ INDEX_URL = reverse('horizon:project:overview:index')
class UsageViewTests(test.TestCase): class UsageViewTests(test.TestCase):
@test.create_mocks({ @test.create_mocks({
api.nova: ('usage_get', 'extension_supported',), api.nova: ('usage_get',),
api.neutron: ('is_quotas_extension_supported',) api.neutron: ('is_quotas_extension_supported',)
}) })
def _stub_api_calls(self, nova_stu_enabled=True, def _stub_api_calls(self, nova_stu_enabled=True,
@ -44,8 +43,6 @@ class UsageViewTests(test.TestCase):
quota_extension_support=True): quota_extension_support=True):
self.mock_is_quotas_extension_supported.return_value = \ self.mock_is_quotas_extension_supported.return_value = \
quota_extension_support quota_extension_support
self.mock_extension_supported.side_effect = [nova_stu_enabled,
nova_stu_enabled]
if nova_stu_enabled: if nova_stu_enabled:
self._nova_stu_enabled(stu_exception, self._nova_stu_enabled(stu_exception,
overview_days_range=overview_days_range) overview_days_range=overview_days_range)
@ -54,9 +51,6 @@ class UsageViewTests(test.TestCase):
def _check_api_calls(self, nova_stu_enabled=True, def _check_api_calls(self, nova_stu_enabled=True,
stu_exception=False, overview_days_range=1): stu_exception=False, overview_days_range=1):
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_extension_supported, 2,
mock.call('SimpleTenantUsage', test.IsHttpRequest()))
if nova_stu_enabled: if nova_stu_enabled:
self._check_stu_enabled(stu_exception, self._check_stu_enabled(stu_exception,
overview_days_range=overview_days_range) overview_days_range=overview_days_range)
@ -140,7 +134,10 @@ class UsageViewTests(test.TestCase):
def test_usage_1_day(self): def test_usage_1_day(self):
self._test_usage(nova_stu_enabled=True) self._test_usage(nova_stu_enabled=True)
@override_settings(OVERVIEW_DAYS_RANGE=None) @override_settings(
OVERVIEW_DAYS_RANGE=None,
OPENSTACK_USE_SIMPLE_TENANT_USAGE=False,
)
def test_usage_disabled(self): def test_usage_disabled(self):
self._test_usage(nova_stu_enabled=False, overview_days_range=None) self._test_usage(nova_stu_enabled=False, overview_days_range=None)
@ -171,6 +168,7 @@ class UsageViewTests(test.TestCase):
def test_usage_csv_1_day(self): def test_usage_csv_1_day(self):
self._test_usage_csv(nova_stu_enabled=True, overview_days_range=1) self._test_usage_csv(nova_stu_enabled=True, overview_days_range=1)
@override_settings(OPENSTACK_USE_SIMPLE_TENANT_USAGE=False)
def test_usage_csv_disabled(self): def test_usage_csv_disabled(self):
self._test_usage_csv(nova_stu_enabled=False) self._test_usage_csv(nova_stu_enabled=False)
@ -257,6 +255,8 @@ class UsageViewTests(test.TestCase):
self._check_api_calls(nova_stu_enabled=True) self._check_api_calls(nova_stu_enabled=True)
# nova_stu_enable=False is specified below, so we need this.
@override_settings(OPENSTACK_USE_SIMPLE_TENANT_USAGE=False)
def _test_usage_charts(self, quota_usage_overrides=None, def _test_usage_charts(self, quota_usage_overrides=None,
quota_extension_support=True): quota_extension_support=True):
self._stub_api_calls(nova_stu_enabled=False, self._stub_api_calls(nova_stu_enabled=False,

View File

@ -97,7 +97,6 @@ def create_mocks(target_methods):
api.nova: [ api.nova: [
'usage_get', 'usage_get',
('tenant_absolute_limits', 'nova_tenant_absolute_limits'), ('tenant_absolute_limits', 'nova_tenant_absolute_limits'),
'extension_supported',
], ],
api.cinder: [ api.cinder: [
('tenant_absolute_limits', 'cinder_tenant_absolute_limits'), ('tenant_absolute_limits', 'cinder_tenant_absolute_limits'),
@ -109,7 +108,6 @@ def create_mocks(target_methods):
self.mock_nova_tenant_absolute_limits.return_value = ... self.mock_nova_tenant_absolute_limits.return_value = ...
self.mock_cinder_tenant_absolute_limits.return_value = ... self.mock_cinder_tenant_absolute_limits.return_value = ...
... ...
self.mock_extension_supported.assert_has_calls(....)
""" """
def wrapper(function): def wrapper(function):

View File

@ -112,9 +112,7 @@ class BaseUsage(object):
return [] return []
def summarize(self, start, end): def summarize(self, start, end):
if not (settings.OPENSTACK_USE_SIMPLE_TENANT_USAGE and if not settings.OPENSTACK_USE_SIMPLE_TENANT_USAGE:
api.nova.extension_supported('SimpleTenantUsage',
self.request)):
return return
if start <= end and start <= self.today: if start <= end and start <= self.today:

View File

@ -68,8 +68,7 @@ class UsageView(tables.DataTableView):
try: try:
context['simple_tenant_usage_enabled'] = ( context['simple_tenant_usage_enabled'] = (
settings.OPENSTACK_USE_SIMPLE_TENANT_USAGE and settings.OPENSTACK_USE_SIMPLE_TENANT_USAGE
api.nova.extension_supported('SimpleTenantUsage', self.request)
) )
except Exception: except Exception:
context['simple_tenant_usage_enabled'] = True context['simple_tenant_usage_enabled'] = True