]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Allow backup-to-swift to take swift URL from service catalogue
authorOllie Leahy <oliver.leahy@hp.com>
Wed, 20 Aug 2014 17:31:36 +0000 (17:31 +0000)
committerOllie Leahy <oliver.leahy@hp.com>
Thu, 21 Aug 2014 08:01:26 +0000 (08:01 +0000)
Since the swift URL is usually in the service catalogue, there is
no need to configure it explicitly.

It can still be set explicitly where manual override is desired.

Change-Id: Ia6c08289b532faed3f6e718d4bbcc1f91978db21

cinder/backup/drivers/swift.py
cinder/context.py
cinder/tests/test_backup_swift.py
cinder/tests/test_context.py
etc/cinder/cinder.conf.sample

index 21c35b96a6c84fdd9345799c1f469eec7fe096d9..1c1035ef23c0e115341ef9ebfbab3a6f9a92e38a 100644 (file)
@@ -17,8 +17,9 @@
 
 **Related Flags**
 
-:backup_swift_url: The URL of the Swift endpoint (default:
-                                                        localhost:8080).
+:backup_swift_url: The URL of the Swift endpoint (default: None, use catalog).
+:swift_catalog_info: Info to match when looking for swift 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
@@ -53,8 +54,14 @@ LOG = logging.getLogger(__name__)
 
 swiftbackup_service_opts = [
     cfg.StrOpt('backup_swift_url',
-               default='http://localhost:8080/v1/AUTH_',
+               default=None,
                help='The URL of the Swift 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('backup_swift_auth',
                default='per_user',
                help='Swift authentication mechanism'),
@@ -117,8 +124,29 @@ class SwiftBackupDriver(BackupDriver):
 
     def __init__(self, context, db_driver=None):
         super(SwiftBackupDriver, self).__init__(context, db_driver)
-        self.swift_url = '%s%s' % (CONF.backup_swift_url,
-                                   self.context.project_id)
+        if CONF.backup_swift_url is None:
+            self.swift_url = None
+            info = CONF.swift_catalog_info
+            try:
+                service_type, service_name, endpoint_type = info.split(':')
+            except ValueError:
+                raise exception.BackupDriverException(_(
+                    "Failed to parse the configuration option "
+                    "'swift_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:
+                    self.swift_url = entry.get(
+                        'endpoints')[0].get(endpoint_type)
+        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'."))
+        LOG.debug("Using swift URL %s", self.swift_url)
         self.az = CONF.storage_availability_zone
         self.data_block_size_bytes = CONF.backup_swift_object_size
         self.swift_attempts = CONF.backup_swift_retry_attempts
index cfb6dd8aba5476736942b26c334ba2947d791dec..5a826891f9df7f5834fecba407ebdc8bd6baf78d 100644 (file)
@@ -91,7 +91,8 @@ class RequestContext(object):
         if service_catalog:
             # Only include required parts of service_catalog
             self.service_catalog = [s for s in service_catalog
-                                    if s.get('type') in ('compute',)]
+                                    if s.get('type') in ('compute',
+                                                         'object-store')]
         else:
             # if list is empty or none
             self.service_catalog = []
index 4a0834a7d3b9a1b06dbea49ac7d10d0b2a2eed94..87d1e018cd8b941d8ac0d76e6b54d0eb7b55c145 100644 (file)
@@ -23,6 +23,7 @@ import os
 import tempfile
 import zlib
 
+from oslo.config import cfg
 from swiftclient import client as swift
 
 from cinder.backup.drivers.swift import SwiftBackupDriver
@@ -37,6 +38,8 @@ from cinder.tests.backup.fake_swift_client import FakeSwiftClient
 
 LOG = logging.getLogger(__name__)
 
+CONF = cfg.CONF
+
 
 def fake_md5(arg):
     class result(object):
@@ -65,7 +68,11 @@ 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'}]}]
         self.ctxt = context.get_admin_context()
+        self.ctxt.service_catalog = service_catalog
 
         self.stubs.Set(swift, 'Connection', FakeSwiftClient.Connection)
         self.stubs.Set(hashlib, 'md5', fake_md5)
@@ -76,6 +83,35 @@ class BackupSwiftTestCase(test.TestCase):
         for i in xrange(0, 128):
             self.volume_file.write(os.urandom(1024))
 
+    def test_backup_swift_url(self):
+        self.ctxt.service_catalog = [{u'type': u'object-store',
+                                      u'name': u'swift',
+                                      u'endpoints': [{
+                                          u'adminURL': u'http://example.com'}]
+                                      }]
+        self.assertRaises(exception.BackupDriverException,
+                          SwiftBackupDriver,
+                          self.ctxt)
+
+    def test_backup_swift_url_conf(self):
+        self.ctxt.service_catalog = [{u'type': u'object-store',
+                                      u'name': u'swift',
+                                      u'endpoints': [{
+                                          u'adminURL': u'http://example.com'}]
+                                      }]
+        self.ctxt.project_id = "12345678"
+        CONF.set_override("backup_swift_url", "http://public.example.com/")
+        backup = SwiftBackupDriver(self.ctxt)
+        self.assertEqual("%s%s" % (CONF.backup_swift_url,
+                                   self.ctxt.project_id),
+                         backup.swift_url)
+
+    def test_backup_swift_info(self):
+        CONF.set_override("swift_catalog_info", "dummy")
+        self.assertRaises(exception.BackupDriverException,
+                          SwiftBackupDriver,
+                          self.ctxt)
+
     def test_backup_uncompressed(self):
         self._create_backup_db_entry()
         self.flags(backup_compression_algorithm='none')
index c32fd3ebe4829c1e9262e35ce66019b71f102092..bcb25859b86f0e100b66939a562f57b1d529d7ea 100644 (file)
@@ -54,7 +54,7 @@ class ContextTestCase(test.TestCase):
                           'read_deleted',
                           True)
 
-    def test_service_catalog_nova_only(self):
+    def test_service_catalog_nova_and_swift(self):
         service_catalog = [
             {u'type': u'compute', u'name': u'nova'},
             {u'type': u's3', u'name': u's3'},
@@ -67,9 +67,16 @@ class ContextTestCase(test.TestCase):
             {u'type': u'co', u'name': u'S_partofcompute'}]
 
         compute_catalog = [{u'type': u'compute', u'name': u'nova'}]
+        object_catalog = [{u'name': u'swift', u'type': u'object-store'}]
         ctxt = context.RequestContext('111', '222',
                                       service_catalog=service_catalog)
-        self.assertEqual(ctxt.service_catalog, compute_catalog)
+        self.assertEqual(len(ctxt.service_catalog), 2)
+        return_compute = [v for v in ctxt.service_catalog if
+                          v['type'] == u'compute']
+        return_object = [v for v in ctxt.service_catalog if
+                         v['type'] == u'object-store']
+        self.assertEqual(return_compute, compute_catalog)
+        self.assertEqual(return_object, object_catalog)
 
     def test_user_identity(self):
         ctx = context.RequestContext("user", "tenant",
index 7cc9b416843cc346e070fab74ad9bc5daddc844c..2cffc659848014ed181317cb71bd6a649e27b6bd 100644 (file)
 #
 
 # The URL of the Swift endpoint (string value)
-#backup_swift_url=http://localhost:8080/v1/AUTH_
+#backup_swift_url=<None>
+
+# 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 (string value)
+#swift_catalog_info=object-store:swift:publicURL
 
 # Swift authentication mechanism (string value)
 #backup_swift_auth=per_user