]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add backup_swift_auth_url to swift backup driver
authorNathaniel Potter <nathaniel.potter@intel.com>
Mon, 28 Sep 2015 22:18:35 +0000 (17:18 -0500)
committerNathaniel Potter <nathaniel.potter@intel.com>
Tue, 6 Oct 2015 18:02:05 +0000 (12:02 -0600)
Currently the config parameter backup_swift_url expects a
keystone endpoint url in the swift backup driver if you're
using single_user mode, but if you're in per_user mode it
expects a swift endpoint url. This patch adds a parameter
called backup_swift_auth_url to differentiate the two.

Unit tests are also provided for testing
backup_swift_auth_url.

DocImpact: The config options "backup_swift_auth_url" and
"keystone_catalog_info" will need to be added to the Cinder
docs.
Change-Id: Iee466fe1404eef9402a19d529dba19c7d5a4ef2b
Closes-Bug: #1449972

cinder/backup/drivers/swift.py
cinder/tests/unit/test_backup_swift.py

index 8570ad2c5297c6170f547ac90c0c9be963cab41b..42ba716b35237ec7b087230360fdabc169dfddc0 100644 (file)
 **Related Flags**
 
 :backup_swift_url: The URL of the Swift endpoint (default: None, use catalog).
+:backup_swift_auth_url: The URL of the Keystone endpoint for authentication
+                                    (default: None, use catalog).
 :swift_catalog_info: Info to match when looking for swift in the service '
                      catalog.
+:keystone_catalog_info: Info to match when looking for keystone in the service
+                        catalog.
 :backup_swift_object_size: The size in bytes of the Swift objects used
                                     for volume backups (default: 52428800).
 :backup_swift_retry_attempts: The number of retries to make for Swift
@@ -57,12 +61,21 @@ swiftbackup_service_opts = [
     cfg.StrOpt('backup_swift_url',
                default=None,
                help='The URL of the Swift endpoint'),
+    cfg.StrOpt('backup_swift_auth_url',
+               default=None,
+               help='The URL of the Keystone endpoint'),
     cfg.StrOpt('swift_catalog_info',
                default='object-store:swift:publicURL',
                help='Info to match when looking for swift in the service '
                'catalog. Format is: separated values of the form: '
                '<service_type>:<service_name>:<endpoint_type> - '
                'Only used if backup_swift_url is unset'),
+    cfg.StrOpt('keystone_catalog_info',
+               default='identity:Identity Service:publicURL',
+               help='Info to match when looking for keystone in the service '
+               'catalog. Format is: separated values of the form: '
+               '<service_type>:<service_name>:<endpoint_type> - '
+               'Only used if backup_swift_auth_url is unset'),
     cfg.StrOpt('backup_swift_auth',
                default='per_user',
                help='Swift authentication mechanism'),
@@ -138,17 +151,48 @@ class SwiftBackupDriver(chunkeddriver.ChunkedBackupDriver):
                     "<service_type>:<service_name>:<endpoint_type>"))
             for entry in context.service_catalog:
                 if entry.get('type') == service_type:
+                    # It is assumed that service_types are unique within
+                    # the service catalog, so once the correct one is found
+                    # it is safe to break out of the loop
                     self.swift_url = entry.get(
                         'endpoints')[0].get(endpoint_type)
+                    break
         else:
             self.swift_url = '%s%s' % (CONF.backup_swift_url,
                                        context.project_id)
         if self.swift_url is None:
             raise exception.BackupDriverException(_(
                 "Could not determine which Swift endpoint to use. This can "
-                " either be set in the service catalog or with the "
-                " cinder.conf config option 'backup_swift_url'."))
+                "either be set in the service catalog or with the "
+                "cinder.conf config option 'backup_swift_url'."))
+        if CONF.backup_swift_auth_url is None:
+            self.auth_url = None
+            info = CONF.keystone_catalog_info
+            try:
+                service_type, service_name, endpoint_type = info.split(':')
+            except ValueError:
+                raise exception.BackupDriverException(_(
+                    "Failed to parse the configuration option "
+                    "'keystone_catalog_info', must be in the form "
+                    "<service_type>:<service_name>:<endpoint_type>"))
+            for entry in context.service_catalog:
+                if entry.get('type') == service_type:
+                    # It is assumed that service_types are unique within
+                    # the service catalog, so once the correct one is found
+                    # it is safe to break out of the loop
+                    self.auth_url = entry.get(
+                        'endpoints')[0].get(endpoint_type)
+                    break
+        else:
+            self.auth_url = '%s%s' % (CONF.backup_swift_auth_url,
+                                      context.project_id)
+        if self.auth_url is None:
+            raise exception.BackupDriverException(_(
+                "Could not determine which Keystone endpoint to use. This can "
+                "either be set in the service catalog or with the "
+                "cinder.conf config option 'backup_swift_auth_url'."))
         LOG.debug("Using swift URL %s", self.swift_url)
+        LOG.debug("Using auth URL %s", self.auth_url)
         self.swift_attempts = CONF.backup_swift_retry_attempts
         self.swift_backoff = CONF.backup_swift_retry_backoff
         LOG.debug('Connect to %s in "%s" mode', CONF.backup_swift_url,
@@ -160,7 +204,7 @@ class SwiftBackupDriver(chunkeddriver.ChunkedBackupDriver):
                           {'param': 'backup_swift_user'})
                 raise exception.ParameterNotFound(param='backup_swift_user')
             self.conn = swift.Connection(
-                authurl=CONF.backup_swift_url,
+                authurl=self.auth_url,
                 auth_version=CONF.backup_swift_auth_version,
                 tenant_name=CONF.backup_swift_tenant,
                 user=CONF.backup_swift_user,
index c5d639923a8305d35c468c6420bf457413529221..c1915b24f37e2e1ac85386dc979125df1a742a2d 100644 (file)
@@ -78,6 +78,9 @@ class BackupSwiftTestCase(test.TestCase):
     def setUp(self):
         super(BackupSwiftTestCase, self).setUp()
         service_catalog = [{u'type': u'object-store', u'name': u'swift',
+                            u'endpoints': [{
+                                u'publicURL': u'http://example.com'}]},
+                           {u'type': u'identity', u'name': u'keystone',
                             u'endpoints': [{
                                 u'publicURL': u'http://example.com'}]}]
         self.ctxt = context.get_admin_context()
@@ -100,8 +103,28 @@ class BackupSwiftTestCase(test.TestCase):
         self.ctxt.service_catalog = [{u'type': u'object-store',
                                       u'name': u'swift',
                                       u'endpoints': [{
-                                          u'adminURL': u'http://example.com'}]
-                                      }]
+                                          u'adminURL':
+                                              u'http://example.com'}]},
+                                     {u'type': u'identity',
+                                      u'name': u'keystone',
+                                      u'endpoints': [{
+                                          u'publicURL':
+                                              u'http://example.com'}]}]
+        self.assertRaises(exception.BackupDriverException,
+                          swift_dr.SwiftBackupDriver,
+                          self.ctxt)
+
+    def test_backup_swift_auth_url(self):
+        self.ctxt.service_catalog = [{u'type': u'object-store',
+                                      u'name': u'swift',
+                                      u'endpoints': [{
+                                          u'publicURL':
+                                              u'http://example.com'}]},
+                                     {u'type': u'identity',
+                                      u'name': u'keystone',
+                                      u'endpoints': [{
+                                          u'adminURL':
+                                              u'http://example.com'}]}]
         self.assertRaises(exception.BackupDriverException,
                           swift_dr.SwiftBackupDriver,
                           self.ctxt)
@@ -110,15 +133,40 @@ class BackupSwiftTestCase(test.TestCase):
         self.ctxt.service_catalog = [{u'type': u'object-store',
                                       u'name': u'swift',
                                       u'endpoints': [{
-                                          u'adminURL': u'http://example.com'}]
-                                      }]
+                                          u'adminURL':
+                                              u'http://example.com'}]},
+                                     {u'type': u'identity',
+                                     u'name': u'keystone',
+                                      u'endpoints': [{
+                                          u'publicURL':
+                                              u'http://example.com'}]}]
         self.ctxt.project_id = "12345678"
-        self.override_config("backup_swift_url", "http://public.example.com/")
+        self.override_config("backup_swift_url",
+                             "http://public.example.com/")
         backup = swift_dr.SwiftBackupDriver(self.ctxt)
         self.assertEqual("%s%s" % (CONF.backup_swift_url,
                                    self.ctxt.project_id),
                          backup.swift_url)
 
+    def test_backup_swift_auth_url_conf(self):
+        self.ctxt.service_catalog = [{u'type': u'object-store',
+                                      u'name': u'swift',
+                                      u'endpoints': [{
+                                          u'publicURL':
+                                              u'http://example.com'}]},
+                                     {u'type': u'identity',
+                                      u'name': u'keystone',
+                                      u'endpoints': [{
+                                          u'adminURL':
+                                              u'http://example.com'}]}]
+        self.ctxt.project_id = "12345678"
+        self.override_config("backup_swift_auth_url",
+                             "http://public.example.com/")
+        backup = swift_dr.SwiftBackupDriver(self.ctxt)
+        self.assertEqual("%s%s" % (CONF.backup_swift_auth_url,
+                                   self.ctxt.project_id),
+                         backup.auth_url)
+
     def test_backup_swift_info(self):
         self.override_config("swift_catalog_info", "dummy")
         self.assertRaises(exception.BackupDriverException,