commit d4ec93ae55256e8ccf04eac45c5364c694a34759 Author: Dmitriy Rabotyagov Date: Fri Sep 4 09:48:15 2020 +0300 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 diff --git a/senlin/api/middleware/webhook.py b/senlin/api/middleware/webhook.py index dbdb771..698e5e7 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 7a02e30..6554706 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 91552a1..b86af99 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 e3f20e3..9bc9333 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 f0e7827..e957240 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 c70b6f1..5e95331 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 501fe0d..433ccae 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 dbe63ea..30915f8 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 0002d58..37d99f2 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 3433d81..cbb180a 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 9162631..75fa8ba 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()