From db9cf2bca1cc6158ca129c7bfc6bead59ff1c7de Mon Sep 17 00:00:00 2001 From: Sam Morrison Date: Wed, 12 Dec 2012 10:54:54 +1100 Subject: [PATCH] Support glance servers over https Fixes bug 1089147 Updated glance.py from nova's version to support glance over ssl eg. glance_api_servers=https://glance.mydomain:9292 New Flag: glance_api_insecure Set to True to disable certificate checking Change-Id: I53e62900265fea2de9b0ec20bbff0c40f1b14c91 --- cinder/flags.py | 4 ++ cinder/image/glance.py | 62 ++++++++++++++++++++----------- cinder/tests/image/test_glance.py | 2 +- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/cinder/flags.py b/cinder/flags.py index 93ce443ee55..aae589a329e 100644 --- a/cinder/flags.py +++ b/cinder/flags.py @@ -123,6 +123,10 @@ global_opts = [ cfg.IntOpt('glance_num_retries', default=0, help='Number retries when downloading an image from glance'), + cfg.BoolOpt('glance_api_insecure', + default=False, + help='Allow to perform insecure SSL (https) requests to ' + 'glance'), cfg.StrOpt('scheduler_topic', default='cinder-scheduler', help='the topic scheduler nodes listen on'), diff --git a/cinder/image/glance.py b/cinder/image/glance.py index 890a4b4963f..1794a2a2f35 100644 --- a/cinder/image/glance.py +++ b/cinder/image/glance.py @@ -48,20 +48,25 @@ def _parse_image_ref(image_href): :raises ValueError """ - o = urlparse.urlparse(image_href) - port = o.port or 80 - host = o.netloc.split(':', 1)[0] - image_id = o.path.split('/')[-1] - return (image_id, host, port) + url = urlparse.urlparse(image_href) + port = url.port or 80 + host = url.netloc.split(':', 1)[0] + image_id = url.path.split('/')[-1] + use_ssl = (url.scheme == 'https') + return (image_id, host, port, use_ssl) -def _create_glance_client(context, host, port, version=1): +def _create_glance_client(context, host, port, use_ssl, version=1): """Instantiate a new glanceclient.Client object""" + if use_ssl: + scheme = 'https' + else: + scheme = 'http' params = {} + params['insecure'] = FLAGS.glance_api_insecure if FLAGS.auth_strategy == 'keystone': params['token'] = context.auth_token - endpoint = 'http://%s:%s' % (host, port) - + endpoint = '%s://%s:%s' % (scheme, host, port) return glanceclient.Client(str(version), endpoint, **params) @@ -73,8 +78,13 @@ def get_api_servers(): """ api_servers = [] for api_server in FLAGS.glance_api_servers: - host, port_str = api_server.split(':') - api_servers.append((host, int(port_str))) + if '//' not in api_server: + api_server = 'http://' + api_server + url = urlparse.urlparse(api_server) + port = url.port or 80 + host = url.netloc.split(':', 1)[0] + use_ssl = (url.scheme == 'https') + api_servers.append((host, port, use_ssl)) random.shuffle(api_servers) return itertools.cycle(api_servers) @@ -82,28 +92,34 @@ def get_api_servers(): class GlanceClientWrapper(object): """Glance client wrapper class that implements retries.""" - def __init__(self, context=None, host=None, port=None, version=None): + def __init__(self, context=None, host=None, port=None, use_ssl=False, + version=None): if host is not None: - self.client = self._create_static_client(context, host, port, - version) + self.client = self._create_static_client(context, + host, port, + use_ssl, version) else: self.client = None self.api_servers = None - def _create_static_client(self, context, host, port, version): + def _create_static_client(self, context, host, port, use_ssl, version): """Create a client that we'll use for every call.""" self.host = host self.port = port + self.use_ssl = use_ssl self.version = version - return _create_glance_client(context, self.host, self.port, - self.version) + return _create_glance_client(context, + self.host, self.port, + self.use_ssl, self.version) def _create_onetime_client(self, context, version): """Create a client that will be used for one call.""" if self.api_servers is None: self.api_servers = get_api_servers() - self.host, self.port = self.api_servers.next() - return _create_glance_client(context, self.host, self.port, version) + self.host, self.port, self.use_ssl = self.api_servers.next() + return _create_glance_client(context, + self.host, self.port, + self.use_ssl, version) def call(self, context, version, method, *args, **kwargs): """ @@ -167,9 +183,9 @@ class GlanceImageService(object): _params[param] = params.get(param) # ensure filters is a dict - params.setdefault('filters', {}) + _params.setdefault('filters', {}) # NOTE(vish): don't filter out private images - params['filters'].setdefault('is_public', 'none') + _params['filters'].setdefault('is_public', 'none') return _params @@ -419,10 +435,12 @@ def get_remote_image_service(context, image_href): return image_service, image_href try: - (image_id, glance_host, glance_port) = _parse_image_ref(image_href) + (image_id, glance_host, glance_port, use_ssl) = \ + _parse_image_ref(image_href) glance_client = GlanceClientWrapper(context=context, host=glance_host, - port=glance_port) + port=glance_port, + use_ssl=use_ssl) except ValueError: raise exception.InvalidImageRef(image_href=image_href) diff --git a/cinder/tests/image/test_glance.py b/cinder/tests/image/test_glance.py index 2bffc6ba84a..64cace1bd86 100644 --- a/cinder/tests/image/test_glance.py +++ b/cinder/tests/image/test_glance.py @@ -105,7 +105,7 @@ class TestGlanceImageService(test.TestCase): self.stubs.Set(glance.time, 'sleep', lambda s: None) def _create_image_service(self, client): - def _fake_create_glance_client(context, host, port, version): + def _fake_create_glance_client(context, host, port, use_ssl, version): return client self.stubs.Set(glance,