From a69eee6e44807b37a19038ebab8ede4a1ffb2702 Mon Sep 17 00:00:00 2001 From: Aparna Date: Mon, 15 Feb 2016 11:19:26 +0000 Subject: [PATCH] Support for passing CA certificate in Ironic Glance Communication Currently Ironic doesn't pass any certificate down for verifying https connections in glance. New ironic config parameter 'glance_cafile' is added to [glance] section in ironic.conf to pass the certificate down for https connection in glance. Change-Id: I29e134d70addb16cd65dbd9c8038a23e76a57016 --- etc/ironic/ironic.conf.sample | 5 ++++ .../glance_service/base_image_service.py | 3 +++ ironic/common/image_service.py | 4 +++ .../tests/unit/common/test_glance_service.py | 27 ++++++++++++++++++- .../notes/bug-1548086-ed88646061b88faf.yaml | 9 +++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/bug-1548086-ed88646061b88faf.yaml diff --git a/etc/ironic/ironic.conf.sample b/etc/ironic/ironic.conf.sample index 35aa38b990..629baf5843 100644 --- a/etc/ironic/ironic.conf.sample +++ b/etc/ironic/ironic.conf.sample @@ -1096,6 +1096,11 @@ # Possible values: keystone, noauth #auth_strategy=keystone +# Optional path to a CA certificate bundle to be used to +# validate the SSL certificate served by glance. It is used +# when glance_api_insecure is set to False. (string value) +#glance_cafile= + [iboot] diff --git a/ironic/common/glance_service/base_image_service.py b/ironic/common/glance_service/base_image_service.py index e5d1de366f..9c78355f4e 100644 --- a/ironic/common/glance_service/base_image_service.py +++ b/ironic/common/glance_service/base_image_service.py @@ -80,6 +80,9 @@ def check_image_service(func): scheme = 'http' params = {} params['insecure'] = CONF.glance.glance_api_insecure + if (not params['insecure'] and CONF.glance.glance_cafile + and use_ssl): + params['cacert'] = CONF.glance.glance_cafile if CONF.glance.auth_strategy == 'keystone': params['token'] = self.context.auth_token endpoint = '%s://%s:%s' % (scheme, self.glance_host, self.glance_port) diff --git a/ironic/common/image_service.py b/ironic/common/image_service.py index 51fa74ffda..434e24fe08 100644 --- a/ironic/common/image_service.py +++ b/ironic/common/image_service.py @@ -71,6 +71,10 @@ glance_opts = [ choices=['keystone', 'noauth'], help=_('Authentication strategy to use when connecting to ' 'glance.')), + cfg.StrOpt('glance_cafile', + help=_('Optional path to a CA certificate bundle to be used to ' + 'validate the SSL certificate served by glance. It is ' + 'used when glance_api_insecure is set to False.')), ] CONF.register_opts(glance_opts, group='glance') diff --git a/ironic/tests/unit/common/test_glance_service.py b/ironic/tests/unit/common/test_glance_service.py index 6003022e91..30f6cfb658 100644 --- a/ironic/tests/unit/common/test_glance_service.py +++ b/ironic/tests/unit/common/test_glance_service.py @@ -627,7 +627,8 @@ class TestGlanceImageService(base.TestCase): 'token': self.context.auth_token}) @mock.patch.object(glance_client, 'Client', autospec=True) - def test_get_image_service__no_client_set_https(self, mock_gclient): + def test_get_image_service__no_client_set_https_insecure(self, + mock_gclient): def func(service, *args, **kwargs): return (self.endpoint, args, kwargs) @@ -637,6 +638,7 @@ class TestGlanceImageService(base.TestCase): params = {'image_href': '%s/image_uuid' % endpoint} self.config(auth_strategy='keystone', group='glance') + self.config(glance_api_insecure=True, group='glance') wrapped_func = base_image_service.check_image_service(func) self.assertEqual((endpoint, (), params), @@ -646,6 +648,29 @@ class TestGlanceImageService(base.TestCase): **{'insecure': CONF.glance.glance_api_insecure, 'token': self.context.auth_token}) + @mock.patch.object(glance_client, 'Client', autospec=True) + def test_get_image_service__no_client_set_https_secure(self, mock_gclient): + def func(service, *args, **kwargs): + return (self.endpoint, args, kwargs) + + endpoint = 'https://123.123.123.123:9292' + mock_gclient.return_value.endpoint = endpoint + self.service.client = None + + params = {'image_href': '%s/image_uuid' % endpoint} + self.config(auth_strategy='keystone', group='glance') + self.config(glance_api_insecure=False, group='glance') + self.config(glance_cafile='/path/to/certfile', group='glance') + wrapped_func = base_image_service.check_image_service(func) + + self.assertEqual((endpoint, (), params), + wrapped_func(self.service, **params)) + mock_gclient.assert_called_once_with( + 1, endpoint, + **{'cacert': CONF.glance.glance_cafile, + 'insecure': CONF.glance.glance_api_insecure, + 'token': self.context.auth_token}) + def _create_failing_glance_client(info): class MyGlanceStubClient(stubs.StubGlanceClient): diff --git a/releasenotes/notes/bug-1548086-ed88646061b88faf.yaml b/releasenotes/notes/bug-1548086-ed88646061b88faf.yaml new file mode 100644 index 0000000000..5836fc489c --- /dev/null +++ b/releasenotes/notes/bug-1548086-ed88646061b88faf.yaml @@ -0,0 +1,9 @@ +--- +features: + - Adds support to pass a optional CA certificate using [glance]glance_cafile + configuration option to validate the SSL certificate served by glance for + secured https communication between Glance and Ironic. +upgrade: + - Adds a [glance]glance_cafile configuration option to pass a optional + certificate for secured https communication. It is used when + [glance]glance_api_insecure configuration option is set to False.