From a774fa30dd41c12eacad154adb40605025a165e2 Mon Sep 17 00:00:00 2001 From: Ivan Kolodyazhny Date: Wed, 13 Dec 2017 21:21:48 +0200 Subject: [PATCH] Use Cinder API v3 by default Cinder API v3 was introduced several releases ago and is backward compatible with API v2 so it's safe to swith to use it. Change-Id: I550e6c59bb14c17da78d7b2abcde5783b2b6825d Closes-Bug: #1728761 --- openstack_dashboard/api/cinder.py | 9 ++++--- .../dashboards/admin/info/tabs.py | 3 ++- .../dashboards/admin/snapshots/panel.py | 3 ++- .../dashboards/admin/volume_types/panel.py | 3 ++- .../dashboards/admin/volumes/panel.py | 3 ++- .../dashboards/project/backups/panel.py | 3 ++- .../dashboards/project/cg_snapshots/panel.py | 3 ++- .../dashboards/project/cg_snapshots/tables.py | 3 ++- .../dashboards/project/cgroups/panel.py | 3 ++- .../dashboards/project/snapshots/panel.py | 3 ++- .../dashboards/project/snapshots/tables.py | 3 ++- .../dashboards/project/snapshots/tests.py | 4 ++-- .../dashboards/project/snapshots/views.py | 20 ++++++++-------- .../dashboards/project/volumes/panel.py | 3 ++- .../test/test_data/keystone_data.py | 24 ++++++++++++++----- .../test/unit/api/test_base.py | 12 +++++----- .../test/unit/api/test_cinder.py | 8 +++++-- ...er-api-v3-by-default-d6e3c12760fdf655.yaml | 11 +++++++++ 18 files changed, 81 insertions(+), 40 deletions(-) create mode 100644 releasenotes/notes/cinder-api-v3-by-default-d6e3c12760fdf655.yaml diff --git a/openstack_dashboard/api/cinder.py b/openstack_dashboard/api/cinder.py index 5242a936c3..ad80de6a9d 100644 --- a/openstack_dashboard/api/cinder.py +++ b/openstack_dashboard/api/cinder.py @@ -55,12 +55,15 @@ CONSUMER_CHOICES = ( ('both', pgettext_lazy('Both of front-end and back-end', u'both')), ) -VERSIONS = base.APIVersionManager("volume", preferred_version='2') +VERSIONS = base.APIVersionManager("volume", preferred_version='3') try: from cinderclient.v2 import client as cinder_client_v2 VERSIONS.load_supported_version('2', {"client": cinder_client_v2, "version": '2'}) + from cinderclient.v3 import client as cinder_client_v3 + VERSIONS.load_supported_version('3', {"client": cinder_client_v3, + "version": '3'}) except ImportError: pass @@ -1071,9 +1074,9 @@ def message_list(request, search_opts=None): def is_volume_service_enabled(request): return bool( - base.is_service_enabled(request, 'volume') or + base.is_service_enabled(request, 'volumev3') or base.is_service_enabled(request, 'volumev2') or - base.is_service_enabled(request, 'volumev3') + base.is_service_enabled(request, 'volume') ) diff --git a/openstack_dashboard/dashboards/admin/info/tabs.py b/openstack_dashboard/dashboards/admin/info/tabs.py index 5cd265fd1f..a2ee03e930 100644 --- a/openstack_dashboard/dashboards/admin/info/tabs.py +++ b/openstack_dashboard/dashboards/admin/info/tabs.py @@ -78,7 +78,8 @@ class CinderServicesTab(tabs.TableTab): slug = tables.CinderServicesTable.Meta.name template_name = constants.INFO_DETAIL_TEMPLATE_NAME permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) def get_cinder_services_data(self): diff --git a/openstack_dashboard/dashboards/admin/snapshots/panel.py b/openstack_dashboard/dashboards/admin/snapshots/panel.py index b5ed7d4978..f69ee798a7 100644 --- a/openstack_dashboard/dashboards/admin/snapshots/panel.py +++ b/openstack_dashboard/dashboards/admin/snapshots/panel.py @@ -21,6 +21,7 @@ class Snapshots(horizon.Panel): name = _("Snapshots") slug = 'snapshots' permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "context_is_admin"),) diff --git a/openstack_dashboard/dashboards/admin/volume_types/panel.py b/openstack_dashboard/dashboards/admin/volume_types/panel.py index 28686cc173..b6b31fa5cb 100644 --- a/openstack_dashboard/dashboards/admin/volume_types/panel.py +++ b/openstack_dashboard/dashboards/admin/volume_types/panel.py @@ -21,6 +21,7 @@ class VolumeTypes(horizon.Panel): name = _("Volume Types") slug = 'volume_types' permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "volume_extension:types_manage"),) diff --git a/openstack_dashboard/dashboards/admin/volumes/panel.py b/openstack_dashboard/dashboards/admin/volumes/panel.py index 6abf038ba3..c907b83079 100644 --- a/openstack_dashboard/dashboards/admin/volumes/panel.py +++ b/openstack_dashboard/dashboards/admin/volumes/panel.py @@ -19,6 +19,7 @@ class Volumes(horizon.Panel): name = _("Volumes") slug = "volumes" permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "context_is_admin"),) diff --git a/openstack_dashboard/dashboards/project/backups/panel.py b/openstack_dashboard/dashboards/project/backups/panel.py index 5f896c4e91..efd7939d99 100644 --- a/openstack_dashboard/dashboards/project/backups/panel.py +++ b/openstack_dashboard/dashboards/project/backups/panel.py @@ -21,6 +21,7 @@ class Backups(horizon.Panel): name = _("Backups") slug = 'backups' permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "backup:get_all"),) diff --git a/openstack_dashboard/dashboards/project/cg_snapshots/panel.py b/openstack_dashboard/dashboards/project/cg_snapshots/panel.py index 69319a5930..1defa39265 100644 --- a/openstack_dashboard/dashboards/project/cg_snapshots/panel.py +++ b/openstack_dashboard/dashboards/project/cg_snapshots/panel.py @@ -21,6 +21,7 @@ class CGSnapshots(horizon.Panel): name = _("Consistency Group Snapshots") slug = 'cg_snapshots' permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "consistencygroup:get_all_cgsnapshots"),) diff --git a/openstack_dashboard/dashboards/project/cg_snapshots/tables.py b/openstack_dashboard/dashboards/project/cg_snapshots/tables.py index 5af5dc90c1..05a374d4db 100644 --- a/openstack_dashboard/dashboards/project/cg_snapshots/tables.py +++ b/openstack_dashboard/dashboards/project/cg_snapshots/tables.py @@ -113,5 +113,6 @@ class CGSnapshotsTable(tables.DataTable): row_class = UpdateRow status_columns = ("status",) permissions = [ - ('openstack.services.volume', 'openstack.services.volumev2') + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3') ] diff --git a/openstack_dashboard/dashboards/project/cgroups/panel.py b/openstack_dashboard/dashboards/project/cgroups/panel.py index 6085936b7f..f4650d29b4 100644 --- a/openstack_dashboard/dashboards/project/cgroups/panel.py +++ b/openstack_dashboard/dashboards/project/cgroups/panel.py @@ -21,6 +21,7 @@ class CGroups(horizon.Panel): name = _("Consistency Groups") slug = 'cgroups' permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "consistencygroup:get_all"),) diff --git a/openstack_dashboard/dashboards/project/snapshots/panel.py b/openstack_dashboard/dashboards/project/snapshots/panel.py index a14e176c33..22ba56dd85 100644 --- a/openstack_dashboard/dashboards/project/snapshots/panel.py +++ b/openstack_dashboard/dashboards/project/snapshots/panel.py @@ -21,6 +21,7 @@ class Snapshots(horizon.Panel): name = _("Snapshots") slug = 'snapshots' permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "volume:get_all_snapshots"),) diff --git a/openstack_dashboard/dashboards/project/snapshots/tables.py b/openstack_dashboard/dashboards/project/snapshots/tables.py index 683d90e9ff..068f9653f5 100644 --- a/openstack_dashboard/dashboards/project/snapshots/tables.py +++ b/openstack_dashboard/dashboards/project/snapshots/tables.py @@ -208,7 +208,8 @@ class VolumeDetailsSnapshotsTable(volume_tables.VolumesTableBase): row_class = UpdateRow status_columns = ("status",) permissions = [ - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ] diff --git a/openstack_dashboard/dashboards/project/snapshots/tests.py b/openstack_dashboard/dashboards/project/snapshots/tests.py index 3e2b6c39c4..ec3a0511cc 100644 --- a/openstack_dashboard/dashboards/project/snapshots/tests.py +++ b/openstack_dashboard/dashboards/project/snapshots/tests.py @@ -41,9 +41,9 @@ class VolumeSnapshotsViewTests(test.TestCase): api.base: ('is_service_enabled',)}) def _test_snapshots_index_paginated(self, marker, sort_dir, snapshots, url, has_more, has_prev): - api.base.is_service_enabled(IsA(http.HttpRequest), 'volumev2') \ + api.base.is_service_enabled(IsA(http.HttpRequest), 'volumev3') \ .AndReturn(True) - api.base.is_service_enabled(IsA(http.HttpRequest), 'volume') \ + api.base.is_service_enabled(IsA(http.HttpRequest), 'volumev3') \ .AndReturn(True) api.cinder.volume_snapshot_list_paged( IsA(http.HttpRequest), marker=marker, sort_dir=sort_dir, diff --git a/openstack_dashboard/dashboards/project/snapshots/views.py b/openstack_dashboard/dashboards/project/snapshots/views.py index 00d6b94c4e..b7517dcb6a 100644 --- a/openstack_dashboard/dashboards/project/snapshots/views.py +++ b/openstack_dashboard/dashboards/project/snapshots/views.py @@ -21,7 +21,7 @@ from horizon import tables from horizon import tabs from horizon.utils import memoized -from openstack_dashboard import api +from openstack_dashboard.api import cinder from openstack_dashboard.dashboards.project.snapshots \ import forms as vol_snapshot_forms @@ -38,14 +38,14 @@ class SnapshotsView(tables.PagedTableMixin, tables.DataTableView): def get_data(self): snapshots = [] volumes = {} - if api.base.is_service_enabled(self.request, 'volumev2'): + if cinder.is_volume_service_enabled(self.request): try: marker, sort_dir = self._get_marker() snapshots, self._has_more_data, self._has_prev_data = \ - api.cinder.volume_snapshot_list_paged( + cinder.volume_snapshot_list_paged( self.request, paginate=True, marker=marker, sort_dir=sort_dir) - volumes = api.cinder.volume_list(self.request) + volumes = cinder.volume_list(self.request) volumes = dict((v.id, v) for v in volumes) except Exception: exceptions.handle(self.request, _("Unable to retrieve " @@ -71,8 +71,8 @@ class UpdateView(forms.ModalFormView): def get_object(self): snap_id = self.kwargs['snapshot_id'] try: - self._object = api.cinder.volume_snapshot_get(self.request, - snap_id) + self._object = cinder.volume_snapshot_get(self.request, + snap_id) except Exception: msg = _('Unable to retrieve volume snapshot.') url = reverse('horizon:project:snapshots:index') @@ -123,10 +123,10 @@ class DetailView(tabs.TabView): def get_data(self): try: snapshot_id = self.kwargs['snapshot_id'] - snapshot = api.cinder.volume_snapshot_get(self.request, - snapshot_id) - snapshot._volume = api.cinder.volume_get(self.request, - snapshot.volume_id) + snapshot = cinder.volume_snapshot_get(self.request, + snapshot_id) + snapshot._volume = cinder.volume_get(self.request, + snapshot.volume_id) except Exception: redirect = self.get_redirect_url() exceptions.handle(self.request, diff --git a/openstack_dashboard/dashboards/project/volumes/panel.py b/openstack_dashboard/dashboards/project/volumes/panel.py index 88380610b1..9b0d2e106f 100644 --- a/openstack_dashboard/dashboards/project/volumes/panel.py +++ b/openstack_dashboard/dashboards/project/volumes/panel.py @@ -21,6 +21,7 @@ class Volumes(horizon.Panel): name = _("Volumes") slug = 'volumes' permissions = ( - ('openstack.services.volume', 'openstack.services.volumev2'), + ('openstack.services.volume', 'openstack.services.volumev2', + 'openstack.services.volumev3'), ) policy_rules = (("volume", "volume:get_all"),) diff --git a/openstack_dashboard/test/test_data/keystone_data.py b/openstack_dashboard/test/test_data/keystone_data.py index a43d56565d..f2eabd8a0a 100644 --- a/openstack_dashboard/test/test_data/keystone_data.py +++ b/openstack_dashboard/test/test_data/keystone_data.py @@ -56,13 +56,25 @@ SERVICE_CATALOG = [ "endpoints_links": [], "endpoints": [ {"region": "RegionOne", - "adminURL": "http://admin.nova.example.com:8776/v2", - "internalURL": "http://int.nova.example.com:8776/v2", - "publicURL": "http://public.nova.example.com:8776/v2"}, + "adminURL": "http://admin.cinder.example.com:8776/v2", + "internalURL": "http://int.cinder.example.com:8776/v2", + "publicURL": "http://public.cinder.example.com:8776/v2"}, {"region": "RegionTwo", - "adminURL": "http://admin.nova.example.com:8776/v2", - "internalURL": "http://int.nova.example.com:8776/v2", - "publicURL": "http://public.nova.example.com:8776/v2"}]}, + "adminURL": "http://admin.cinder.example.com:8776/v2", + "internalURL": "http://int.cinder.example.com:8776/v2", + "publicURL": "http://public.cinder.example.com:8776/v2"}]}, + {"type": "volumev3", + "name": "cinderv3", + "endpoints_links": [], + "endpoints": [ + {"region": "RegionOne", + "adminURL": "http://admin.cinder.example.com:8776/v3", + "internalURL": "http://int.cinder.example.com:8776/v3", + "publicURL": "http://public.cinder.example.com:8776/v3"}, + {"region": "RegionTwo", + "adminURL": "http://admin.cinder.example.com:8776/v3", + "internalURL": "http://int.cinder.example.com:8776/v3", + "publicURL": "http://public.cinder.example.com:8776/v3"}]}, {"type": "image", "name": "glance", "endpoints_links": [], diff --git a/openstack_dashboard/test/unit/api/test_base.py b/openstack_dashboard/test/unit/api/test_base.py index 1e297dadcf..3d9f8dc8bc 100644 --- a/openstack_dashboard/test/unit/api/test_base.py +++ b/openstack_dashboard/test/unit/api/test_base.py @@ -249,16 +249,16 @@ class ApiHelperTests(test.TestCase): endpoint_type='adminURL') self.assertEqual('http://admin.nova.example.com:8774/v2', url) - url = api_base.url_for(self.request, 'volumev2') - self.assertEqual('http://public.nova.example.com:8776/v2', url) + url = api_base.url_for(self.request, 'volumev3') + self.assertEqual('http://public.cinder.example.com:8776/v3', url) - url = api_base.url_for(self.request, 'volumev2', + url = api_base.url_for(self.request, 'volumev3', endpoint_type="internalURL") - self.assertEqual('http://int.nova.example.com:8776/v2', url) + self.assertEqual('http://int.cinder.example.com:8776/v3', url) - url = api_base.url_for(self.request, 'volumev2', + url = api_base.url_for(self.request, 'volumev3', endpoint_type='adminURL') - self.assertEqual('http://admin.nova.example.com:8776/v2', url) + self.assertEqual('http://admin.cinder.example.com:8776/v3', url) self.assertNotIn('notAnApi', self.request.user.service_catalog, 'Select a new nonexistent service catalog key') diff --git a/openstack_dashboard/test/unit/api/test_cinder.py b/openstack_dashboard/test/unit/api/test_cinder.py index b9ffa0fbdc..999d474519 100644 --- a/openstack_dashboard/test/unit/api/test_cinder.py +++ b/openstack_dashboard/test/unit/api/test_cinder.py @@ -458,12 +458,16 @@ class CinderApiVersionTests(test.TestCase): # versions. api.cinder.VERSIONS._active = None - def test_default_client_is_v2(self): + def test_default_client_is_v3(self): client = api.cinder.cinderclient(self.request) - self.assertIsInstance(client, cinder_client.v2.client.Client) + self.assertIsInstance(client, cinder_client.v3.client.Client) @override_settings(OPENSTACK_API_VERSIONS={'volume': 2}) def test_v2_setting_returns_v2_client(self): + # FIXME(e0ne): this is a temporary workaround to bypass + # @memoized_with_request decorator caching. We have to find a better + # solution instead this hack. + self.request.user.username = 'test_user_cinder_v2' client = api.cinder.cinderclient(self.request) self.assertIsInstance(client, cinder_client.v2.client.Client) diff --git a/releasenotes/notes/cinder-api-v3-by-default-d6e3c12760fdf655.yaml b/releasenotes/notes/cinder-api-v3-by-default-d6e3c12760fdf655.yaml new file mode 100644 index 0000000000..18e3a0a0a4 --- /dev/null +++ b/releasenotes/notes/cinder-api-v3-by-default-d6e3c12760fdf655.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Cinder API v3 is used by default now. It was introduced in Mitaka release + and has all features from API v2. +upgrade: + - | + If your deployment doesn't have Cinder API v3 endpoint like ``volumev3`` + you should create new endpoint or use Cinder API v2 via setting + OPENSTACK_API_VERSIONS['volume'] = 2 in your OpenStack Dashboard (Horizon) + configuration file.