From cde42678b9aafdc3475457f716a7f3af17ae6995 Mon Sep 17 00:00:00 2001
From: Takashi Kajinami <tkajinam@redhat.com>
Date: Sun, 9 Jan 2022 22:35:48 +0900
Subject: [PATCH] Make account prefix of Swift confgurable

Account prefix is configurable in Swift and can be different. This
change introduces a configuration parameter to customize the prefix
so that users can customize the prefix consistently.

To allow setting a consistent value in Ironic and Swift, the prefix
value is automatically suffixed by '_' like;
 - AUTH  => AUTH_
 - AUTH_ => AUTH_

Story: 2009778
Task: 44259
Change-Id: I4862efa3af452f89f1dc4e15d2c3cc43b857f86d
---
 ironic/common/glance_service/image_service.py |  9 ++-
 ironic/conf/glance.py                         |  5 ++
 .../tests/unit/common/test_glance_service.py  | 56 +++++++++++++++++++
 ...swift_account_prefix-dbc9e68890bff47c.yaml |  6 ++
 4 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 releasenotes/notes/swift_account_prefix-dbc9e68890bff47c.yaml

diff --git a/ironic/common/glance_service/image_service.py b/ironic/common/glance_service/image_service.py
index 66ac693f84..0a32eaf0a8 100644
--- a/ironic/common/glance_service/image_service.py
+++ b/ironic/common/glance_service/image_service.py
@@ -303,15 +303,20 @@ class GlanceImageService(object):
                     'but it was not found in the service catalog. You must '
                     'provide "swift_endpoint_url" as a config option.'))
 
+        swift_account_prefix = CONF.glance.swift_account_prefix
+        if swift_account_prefix and not swift_account_prefix.endswith('_'):
+            swift_account_prefix = '%s_' % swift_account_prefix
+
         # Strip /v1/AUTH_%(tenant_id)s, if present
-        endpoint_url = re.sub('/v1/AUTH_[^/]+/?$', '', endpoint_url)
+        endpoint_url = re.sub('/v1/%s[^/]+/?$' % swift_account_prefix, '',
+                              endpoint_url)
 
         key = CONF.glance.swift_temp_url_key
         account = CONF.glance.swift_account
         if not account:
             swift_session = swift.get_swift_session()
             auth_ref = swift_session.auth.get_auth_ref(swift_session)
-            account = 'AUTH_%s' % auth_ref.project_id
+            account = '%s%s' % (swift_account_prefix, auth_ref.project_id)
 
         if not key:
             swift_api = swift.SwiftAPI()
diff --git a/ironic/conf/glance.py b/ironic/conf/glance.py
index c83fa92e17..a3286b1eb4 100644
--- a/ironic/conf/glance.py
+++ b/ironic/conf/glance.py
@@ -90,6 +90,11 @@ opts = [
                'of the project used to access Swift (as set in the [swift] '
                'section). Swift temporary URL format: '
                '"endpoint_url/api_version/account/container/object_id"')),
+    cfg.StrOpt(
+        'swift_account_prefix',
+        default='AUTH',
+        help=_('The prefix added to the project uuid to determine the swift '
+               'account.')),
     cfg.StrOpt(
         'swift_container',
         default='glance',
diff --git a/ironic/tests/unit/common/test_glance_service.py b/ironic/tests/unit/common/test_glance_service.py
index f0e9f10023..03cbb0a380 100644
--- a/ironic/tests/unit/common/test_glance_service.py
+++ b/ironic/tests/unit/common/test_glance_service.py
@@ -603,6 +603,62 @@ class TestGlanceSwiftTempURL(base.TestCase):
             method='GET')
         swift_mock.assert_called_once_with()
 
+    @mock.patch('ironic.common.swift.get_swift_session', autospec=True)
+    @mock.patch('swiftclient.utils.generate_temp_url', autospec=True)
+    def test_swift_temp_url_account_detected_with_prefix(self, tempurl_mock,
+                                                         swift_mock):
+        self.config(swift_account=None, group='glance')
+        self.config(swift_account_prefix='SWIFTPREFIX', group='glance')
+
+        path = ('/v1/SWIFTPREFIX_42/glance'
+                '/757274c4-2856-4bd2-bb20-9a4a231e187b')
+        tempurl_mock.return_value = (
+            path + '?temp_url_sig=hmacsig&temp_url_expires=1400001200')
+        auth_ref = swift_mock.return_value.auth.get_auth_ref.return_value
+        auth_ref.project_id = '42'
+
+        self.service._validate_temp_url_config = mock.Mock()
+
+        temp_url = self.service.swift_temp_url(image_info=self.fake_image)
+
+        self.assertEqual(CONF.glance.swift_endpoint_url
+                         + tempurl_mock.return_value,
+                         temp_url)
+        tempurl_mock.assert_called_with(
+            path=path,
+            seconds=CONF.glance.swift_temp_url_duration,
+            key=CONF.glance.swift_temp_url_key,
+            method='GET')
+        swift_mock.assert_called_once_with()
+
+    @mock.patch('ironic.common.swift.get_swift_session', autospec=True)
+    @mock.patch('swiftclient.utils.generate_temp_url', autospec=True)
+    def test_swift_temp_url_account_detected_with_prefix_underscore(
+            self, tempurl_mock, swift_mock):
+        self.config(swift_account=None, group='glance')
+        self.config(swift_account_prefix='SWIFTPREFIX_', group='glance')
+
+        path = ('/v1/SWIFTPREFIX_42/glance'
+                '/757274c4-2856-4bd2-bb20-9a4a231e187b')
+        tempurl_mock.return_value = (
+            path + '?temp_url_sig=hmacsig&temp_url_expires=1400001200')
+        auth_ref = swift_mock.return_value.auth.get_auth_ref.return_value
+        auth_ref.project_id = '42'
+
+        self.service._validate_temp_url_config = mock.Mock()
+
+        temp_url = self.service.swift_temp_url(image_info=self.fake_image)
+
+        self.assertEqual(CONF.glance.swift_endpoint_url
+                         + tempurl_mock.return_value,
+                         temp_url)
+        tempurl_mock.assert_called_with(
+            path=path,
+            seconds=CONF.glance.swift_temp_url_duration,
+            key=CONF.glance.swift_temp_url_key,
+            method='GET')
+        swift_mock.assert_called_once_with()
+
     @mock.patch('ironic.common.swift.SwiftAPI', autospec=True)
     @mock.patch('swiftclient.utils.generate_temp_url', autospec=True)
     def test_swift_temp_url_key_detected(self, tempurl_mock, swift_mock):
diff --git a/releasenotes/notes/swift_account_prefix-dbc9e68890bff47c.yaml b/releasenotes/notes/swift_account_prefix-dbc9e68890bff47c.yaml
new file mode 100644
index 0000000000..c0a458f7df
--- /dev/null
+++ b/releasenotes/notes/swift_account_prefix-dbc9e68890bff47c.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    The new ``[glance] swift_account_prefix`` parameter has been added. This
+    parameter be set according to the ``reseller_prefix`` parameter in
+    ``proxy-server.conf`` of Swift.