From e79162423f4855c4bea601ec3e2175fd984a54ad Mon Sep 17 00:00:00 2001 From: Dharini Chandrasekar Date: Thu, 20 Oct 2016 00:00:19 +0000 Subject: [PATCH] Raise exc when using multi-tenant and swift+config When Swift multi-tenant store is used along with the scheme ``swift+config`` (the scheme that identifies the need to use the swift config), a reference to use swift objects from the swift config file set using the option ``swift_store_config_file`` is made resulting in the storage url for an accessible object being created from a swift auth_address. So is the case when the scheme is ``swift``. This behavior is suitable for single-tenant swift store and not multi-tenant store. The solution is to ensure that if deploying multi-tenant swift store, prohibit setting of swift_store_config_file. This patch does this by ensuring that multi-tenant and swift_store_config_file are not configured to work together. TODO: When somebody changes to multi-tenant from single-tenant store, and they were using the swift config for single-tenant, the operator will not be able to access those images any longer. Logic to ensure that multi-tenant uses the swift conf file if there is a need to access an image that was created using single-tenant and swift+config could be introduced. UpgradeImpact DocImpact Closes-Bug: 1625075 Change-Id: I8b5c31541d3c501ad7c2520b463f881599f4a28e Co-Authored-By: Hemanth Makkapati Co-Authored-By: Dharini Chandrasekar --- glance_store/_drivers/swift/store.py | 19 ++++++++++++++++++- glance_store/_drivers/swift/utils.py | 5 ++++- glance_store/tests/unit/test_swift_store.py | 19 +++++++++++++++++++ .../multi-tenant-store-058b67ce5b7f3bd0.yaml | 9 +++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/multi-tenant-store-058b67ce5b7f3bd0.yaml diff --git a/glance_store/_drivers/swift/store.py b/glance_store/_drivers/swift/store.py index 70d7e5b9..79063c1c 100644 --- a/glance_store/_drivers/swift/store.py +++ b/glance_store/_drivers/swift/store.py @@ -295,12 +295,16 @@ in tenant specific Swift accounts. If this is disabled, Glance stores all images in its own account. More details multi-tenant store can be found at https://wiki.openstack.org/wiki/GlanceSwiftTenantSpecificStorage +NOTE: If using multi-tenant swift store, please make sure +that you do not set a swift configuration file with the +'swift_store_config_file' option. + Possible values: * True * False Related options: - * None + * swift_store_config_file """)), cfg.IntOpt('swift_store_multiple_containers_seed', @@ -698,6 +702,19 @@ class StoreLocation(location.StoreLocation): def Store(conf): + # NOTE(dharinic): Multi-tenant store cannot work with swift config + if conf.glance_store.swift_store_multi_tenant: + if (conf.glance_store.default_store == 'swift+config' or + sutils.is_multiple_swift_store_accounts_enabled(conf)): + msg = _("Swift multi-tenant store cannot be configured to " + "work with swift+config. The options " + "'swift_store_multi_tenant' and " + "'swift_store_config_file' are mutually exclusive. " + "If you inted to use multi-tenant swift store, please " + "make sure that you have not set a swift configuration " + "file with the 'swift_store_config_file' option.") + raise exceptions.BadStoreConfiguration(store_name="swift", + reason=msg) try: conf.register_opts(_SWIFT_OPTS + sutils.swift_opts, group='glance_store') diff --git a/glance_store/_drivers/swift/utils.py b/glance_store/_drivers/swift/utils.py index 11ddce4f..1b8bff7c 100644 --- a/glance_store/_drivers/swift/utils.py +++ b/glance_store/_drivers/swift/utils.py @@ -87,12 +87,15 @@ and customized Swift referencing is disabled. Configuring this option is highly recommended while using Swift storage backend for image storage as it avoids storage of credentials in the database. +NOTE: Please do not configure this option if you have set +``swift_store_multi_tenant`` to ``True``. + Possible values: * String value representing an absolute path on the glance-api node Related options: - * None + * swift_store_multi_tenant """)), ] diff --git a/glance_store/tests/unit/test_swift_store.py b/glance_store/tests/unit/test_swift_store.py index 427f06a3..0dc9c70a 100644 --- a/glance_store/tests/unit/test_swift_store.py +++ b/glance_store/tests/unit/test_swift_store.py @@ -258,12 +258,26 @@ class SwiftTests(object): """Test that single tenant uris work with multi tenant on.""" uri = ("swift://%s:key@auth_address/glance/%s" % (self.swift_store_user, FAKE_UUID)) + self.config(swift_store_config_file=None) self.config(swift_store_multi_tenant=True) # NOTE(markwash): ensure the image is found ctxt = mock.MagicMock() size = backend.get_size_from_backend(uri, context=ctxt) self.assertEqual(5120, size) + def test_multi_tenant_with_swift_config(self): + """ + Test that Glance does not start when a config file is set on + multi-tenant mode + """ + schemes = ['swift', 'swift+config'] + for s in schemes: + self.config(default_store=s, + swift_store_config_file='not/none', + swift_store_multi_tenant=True) + self.assertRaises(exceptions.BadStoreConfiguration, + Store, self.conf) + def test_get(self): """Test a "normal" retrieval of an image in chunks.""" uri = "swift://%s:key@auth_address/glance/%s" % ( @@ -1053,6 +1067,7 @@ class SwiftTests(object): """ Test that we can set a public read acl. """ + self.config(swift_store_config_file=None) self.config(swift_store_multi_tenant=True) store = Store(self.conf) store.configure() @@ -1068,6 +1083,7 @@ class SwiftTests(object): """ Test that we can set read acl for tenants. """ + self.config(swift_store_config_file=None) self.config(swift_store_multi_tenant=True) store = Store(self.conf) store.configure() @@ -1085,6 +1101,7 @@ class SwiftTests(object): """ Test that we can set write acl for tenants. """ + self.config(swift_store_config_file=None) self.config(swift_store_multi_tenant=True) store = Store(self.conf) store.configure() @@ -1103,6 +1120,7 @@ class SwiftTests(object): def test_get_connection_manager_multi_tenant(self, manager_class): manager = mock.MagicMock() manager_class.return_value = manager + self.config(swift_store_config_file=None) self.config(swift_store_multi_tenant=True) store = Store(self.conf) store.configure() @@ -1131,6 +1149,7 @@ class SwiftTests(object): mock_client, mock_session, mock_v3): """Test that keystone client was initialized correctly""" # initialize store and connection parameters + self.config(swift_store_config_file=None) self.config(swift_store_multi_tenant=True) store = Store(self.conf) store.configure() diff --git a/releasenotes/notes/multi-tenant-store-058b67ce5b7f3bd0.yaml b/releasenotes/notes/multi-tenant-store-058b67ce5b7f3bd0.yaml new file mode 100644 index 00000000..4d002699 --- /dev/null +++ b/releasenotes/notes/multi-tenant-store-058b67ce5b7f3bd0.yaml @@ -0,0 +1,9 @@ +--- +upgrade: + - If using Swift in the multi-tenant mode for storing + images in Glance, please note that the configuration + options ``swift_store_multi_tenant`` and + ``swift_store_config_file`` are now mutually exclusive + and cannot be configured together. If you intend to + use multi-tenant store, please make sure that you have + not set a swift configuration file.