Allow backup-to-swift to take swift URL from service catalogue

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
This commit is contained in:
Ollie Leahy 2014-08-20 17:31:36 +00:00
parent 13ba71df27
commit 0bd6b99b9f
5 changed files with 87 additions and 9 deletions

View 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

View 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 = []

View 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')

View 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",

View File

@ -404,7 +404,13 @@
#
# 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