From d4ec93ae55256e8ccf04eac45c5364c694a34759 Mon Sep 17 00:00:00 2001 From: Dmitriy Rabotyagov Date: Fri, 4 Sep 2020 09:48:15 +0300 Subject: [PATCH] Add options to choose endpoints and SSL verification In case of usage of self-signed SSL certificates for public endpoints, you will get stuck with senlin usage. So in case of such scenario it's essential to either choose endpoint type or disable SSL verification. Both of these options are implemented in most services and are expected. Change-Id: Ifa475ff146af8b49a762218ff244f0ff0fee9ac0 --- senlin/api/middleware/webhook.py | 5 ++++- senlin/conf/authentication.py | 6 +++++- senlin/drivers/os/keystone_v3.py | 5 ++++- senlin/engine/notifications/message.py | 5 ++++- senlin/engine/receivers/base.py | 5 ++++- senlin/policies/base.py | 5 ++++- senlin/tests/drivers/os_test/keystone_v3.py | 2 ++ senlin/tests/unit/api/middleware/test_webhook.py | 9 ++++++++- senlin/tests/unit/drivers/test_keystone_v3.py | 9 ++++++++- senlin/tests/unit/engine/receivers/test_receiver.py | 10 ++++++++-- senlin/tests/unit/policies/test_policy.py | 10 ++++++++-- 11 files changed, 59 insertions(+), 12 deletions(-) diff --git a/senlin/api/middleware/webhook.py b/senlin/api/middleware/webhook.py index dbdb77136..698e5e70c 100644 --- a/senlin/api/middleware/webhook.py +++ b/senlin/api/middleware/webhook.py @@ -58,7 +58,10 @@ class WebhookMiddleware(wsgi.Middleware): 'auth_url': svc_ctx['auth_url'], 'username': svc_ctx['username'], 'user_domain_name': svc_ctx['user_domain_name'], - 'password': svc_ctx['password'] + 'password': svc_ctx['password'], + 'project_domain_name': svc_ctx['project_domain_name'], + 'verify': svc_ctx['verify'], + 'interface': svc_ctx['interface'], } kwargs.update(receiver['actor']) diff --git a/senlin/conf/authentication.py b/senlin/conf/authentication.py index 7a02e303c..65547062f 100644 --- a/senlin/conf/authentication.py +++ b/senlin/conf/authentication.py @@ -16,7 +16,7 @@ from senlin.common.i18n import _ AUTHENTICATION_GROUP = cfg.OptGroup('authentication') AUTHENTICATION_OPTS = [ cfg.StrOpt('auth_url', default='', - help=_('Complete public identity V3 API endpoint.')), + help=_('Complete identity V3 API endpoint.')), cfg.StrOpt('service_username', default='senlin', help=_('Senlin service user name.')), cfg.StrOpt('service_password', default='', secret=True, @@ -27,6 +27,10 @@ AUTHENTICATION_OPTS = [ help=_('Name of the domain for the service user.')), cfg.StrOpt('service_project_domain', default='Default', help=_('Name of the domain for the service project.')), + cfg.BoolOpt('verify_ssl', default=True, + help=_('Verify HTTPS connections.')), + cfg.StrOpt('interface', default='public', + help=_('Interface to use for the API endpoints.')), ] diff --git a/senlin/drivers/os/keystone_v3.py b/senlin/drivers/os/keystone_v3.py index 91552a1d6..b86af9973 100644 --- a/senlin/drivers/os/keystone_v3.py +++ b/senlin/drivers/os/keystone_v3.py @@ -120,6 +120,8 @@ class KeystoneClient(base.DriverBase): 'user_domain_name': cfg.CONF.authentication.service_user_domain, 'project_domain_name': cfg.CONF.authentication.service_project_domain, + 'verify': cfg.CONF.authentication.verify_ssl, + 'interface': cfg.CONF.authentication.interface, } creds.update(**kwargs) return creds @@ -147,8 +149,9 @@ class KeystoneClient(base.DriverBase): def get_senlin_endpoint(self): """Get Senlin service endpoint.""" region = cfg.CONF.default_region_name + interface = cfg.CONF.authentication.interface base = self.conn.session.get_endpoint(service_type='clustering', - interface='public', + interface=interface, region_name=region) return base diff --git a/senlin/engine/notifications/message.py b/senlin/engine/notifications/message.py index e3f20e376..9bc9333db 100755 --- a/senlin/engine/notifications/message.py +++ b/senlin/engine/notifications/message.py @@ -62,7 +62,10 @@ class Message(object): 'username': service_creds.get('username'), 'password': service_creds.get('password'), 'auth_url': service_creds.get('auth_url'), - 'user_domain_name': service_creds.get('user_domain_name') + 'user_domain_name': service_creds.get('user_domain_name'), + 'project_domain_name': service_creds.get('project_domain_name'), + 'verify': service_creds.get('verify'), + 'interface': service_creds.get('interface'), } cred = co.Credential.get(oslo_context.get_current(), user, project) diff --git a/senlin/engine/receivers/base.py b/senlin/engine/receivers/base.py index f0e782782..e957240bd 100644 --- a/senlin/engine/receivers/base.py +++ b/senlin/engine/receivers/base.py @@ -234,7 +234,10 @@ class Receiver(object): 'username': service_creds.get('username'), 'password': service_creds.get('password'), 'auth_url': service_creds.get('auth_url'), - 'user_domain_name': service_creds.get('user_domain_name') + 'user_domain_name': service_creds.get('user_domain_name'), + 'project_domain_name': service_creds.get('project_domain_name'), + 'verify': service_creds.get('verify'), + 'interface': service_creds.get('interface'), } cred = co.Credential.get(oslo_context.get_current(), user, project) diff --git a/senlin/policies/base.py b/senlin/policies/base.py index c70b6f136..5e95331dd 100644 --- a/senlin/policies/base.py +++ b/senlin/policies/base.py @@ -233,7 +233,10 @@ class Policy(object): 'username': service_creds.get('username'), 'password': service_creds.get('password'), 'auth_url': service_creds.get('auth_url'), - 'user_domain_name': service_creds.get('user_domain_name') + 'user_domain_name': service_creds.get('user_domain_name'), + 'project_domain_name': service_creds.get('project_domain_name'), + 'verify': service_creds.get('verify'), + 'interface': service_creds.get('interface'), } cred = co.Credential.get(oslo_context.get_current(), user, project) diff --git a/senlin/tests/drivers/os_test/keystone_v3.py b/senlin/tests/drivers/os_test/keystone_v3.py index 501fe0d87..433ccae96 100644 --- a/senlin/tests/drivers/os_test/keystone_v3.py +++ b/senlin/tests/drivers/os_test/keystone_v3.py @@ -118,6 +118,8 @@ class KeystoneClient(base.DriverBase): 'user_domain_name': cfg.CONF.authentication.service_user_domain, 'project_domain_name': cfg.CONF.authentication.service_project_domain, + 'verify': cfg.CONF.authentication.verify_ssl, + 'interface': cfg.CONF.authentication.interface, } creds.update(**kwargs) return creds diff --git a/senlin/tests/unit/api/middleware/test_webhook.py b/senlin/tests/unit/api/middleware/test_webhook.py index dbe63ea3a..30915f861 100644 --- a/senlin/tests/unit/api/middleware/test_webhook.py +++ b/senlin/tests/unit/api/middleware/test_webhook.py @@ -148,8 +148,14 @@ class TestWebhookMiddleware(base.SenlinTestCase): group='authentication') cfg.CONF.set_override('service_user_domain', 'DOMAIN', group='authentication') + cfg.CONF.set_override('service_project_domain', 'DOMAIN1', + group='authentication') cfg.CONF.set_override('service_password', 'PASSWORD', group='authentication') + cfg.CONF.set_override('verify_ssl', False, + group='authentication') + cfg.CONF.set_override('interface', 'admin', + group='authentication') req = mock.Mock() req.method = 'POST' @@ -185,7 +191,8 @@ class TestWebhookMiddleware(base.SenlinTestCase): mock_extract.assert_called_once_with('http://url1/v1') mock_token.assert_called_once_with( auth_url='AUTH_URL', password='PASSWORD', username='USERNAME', - user_domain_name='DOMAIN', foo='bar') + user_domain_name='DOMAIN', foo='bar', verify=False, + project_domain_name='DOMAIN1', interface='admin') mock_parse.assert_called_once_with('ReceiverGetRequest', req, {'identity': 'WEBHOOK'}) diff --git a/senlin/tests/unit/drivers/test_keystone_v3.py b/senlin/tests/unit/drivers/test_keystone_v3.py index 0002d58b9..37d99f215 100644 --- a/senlin/tests/unit/drivers/test_keystone_v3.py +++ b/senlin/tests/unit/drivers/test_keystone_v3.py @@ -187,13 +187,20 @@ class TestKeystoneV3(base.SenlinTestCase): group='authentication') cfg.CONF.set_override('service_project_domain', 'FAKE_DOMAIN_2', group='authentication') + cfg.CONF.set_override('verify_ssl', False, + group='authentication') + cfg.CONF.set_override('interface', 'internal', + group='authentication') + expected = { 'auth_url': 'FAKE_URL', 'username': 'FAKE_USERNAME', 'password': 'FAKE_PASSWORD', 'project_name': 'FAKE_PROJECT', 'user_domain_name': 'FAKE_DOMAIN_1', - 'project_domain_name': 'FAKE_DOMAIN_2' + 'project_domain_name': 'FAKE_DOMAIN_2', + 'verify': False, + 'interface': 'internal', } actual = kv3.KeystoneClient.get_service_credentials() diff --git a/senlin/tests/unit/engine/receivers/test_receiver.py b/senlin/tests/unit/engine/receivers/test_receiver.py index 3433d8100..cbb180a55 100644 --- a/senlin/tests/unit/engine/receivers/test_receiver.py +++ b/senlin/tests/unit/engine/receivers/test_receiver.py @@ -345,7 +345,10 @@ class TestReceiver(base.SenlinTestCase): 'auth_url': 'AUTH_URL', 'username': 'senlin', 'user_domain_name': 'default', - 'password': '123' + 'password': '123', + 'project_domain_name': 'default', + 'verify': True, + 'interface': 'internal', } current_ctx = { 'auth_url': 'auth_url', @@ -372,7 +375,10 @@ class TestReceiver(base.SenlinTestCase): 'username': 'senlin', 'user_domain_name': 'default', 'password': '123', - 'trust_id': 'TRUST_ID' + 'trust_id': 'TRUST_ID', + 'project_domain_name': 'default', + 'verify': True, + 'interface': 'internal', } res = receiver._build_conn_params(user, project) self.assertEqual(expected_result, res) diff --git a/senlin/tests/unit/policies/test_policy.py b/senlin/tests/unit/policies/test_policy.py index 916263163..75fa8ba29 100644 --- a/senlin/tests/unit/policies/test_policy.py +++ b/senlin/tests/unit/policies/test_policy.py @@ -537,7 +537,10 @@ class TestPolicyBase(base.SenlinTestCase): 'auth_url': 'AUTH_URL', 'username': 'senlin', 'user_domain_name': 'default', - 'password': '123' + 'password': '123', + 'project_domain_name': 'Domain', + 'verify': True, + 'interface': 'Public', } current_ctx = { 'auth_url': 'auth_url', @@ -564,7 +567,10 @@ class TestPolicyBase(base.SenlinTestCase): 'username': 'senlin', 'user_domain_name': 'default', 'password': '123', - 'trust_id': 'TRUST_ID' + 'trust_id': 'TRUST_ID', + 'project_domain_name': 'Domain', + 'verify': True, + 'interface': 'Public', } self.assertEqual(expected_result, res) mock_get_service_creds.assert_called_once_with()