Fix keystone tls detection and verification

At present the check for which transport to use references a
configuration option that has been removed.

Update check to test for current configuration option plus
add a check for presence of `tls-certificates` relation.

Also remove insecure option and add verify option to allow
control of verification including providing own CA certificate
bundle.

Reference for verify option:
https://docs.openstack.org/keystoneauth/latest/api/keystoneauth1.html#keystoneauth1.session.Session
This commit is contained in:
Frode Nordahl
2018-07-04 12:32:30 +02:00
parent 8a1dd18cfa
commit 2a566b5e05
2 changed files with 100 additions and 15 deletions

View File

@@ -150,6 +150,77 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
self.get_current_os_versions.return_value = {"keystone": "mitaka"}
self.assertEqual(openstack_utils.get_keystone_scope(), "PROJECT")
def _test_get_overcloud_auth(self, tls_relation=False, ssl_cert=False,
v2_api=False):
self.patch_object(openstack_utils.model, 'get_relation_id')
self.patch_object(openstack_utils, 'get_application_config_option')
self.patch_object(openstack_utils, 'get_keystone_ip')
self.patch_object(openstack_utils, "get_current_os_versions")
self.get_keystone_ip.return_value = '127.0.0.1'
self.get_relation_id.return_value = None
self.get_application_config_option.return_value = None
if tls_relation or ssl_cert:
port = 35357
transport = 'https'
if tls_relation:
self.get_relation_id.return_value = 'tls-certificates:1'
if ssl_cert:
self.get_application_config_option.side_effect = [
'FAKECRTDATA',
None,
]
else:
port = 5000
transport = 'http'
if v2_api:
str_api = 'v2.0'
self.get_current_os_versions.return_value = {"keystone": "mitaka"}
expect = {
'OS_AUTH_URL': '{}://127.0.0.1:{}/{}'
.format(transport, port, str_api),
'OS_TENANT_NAME': 'admin',
'OS_USERNAME': 'admin',
'OS_PASSWORD': 'openstack',
'OS_REGION_NAME': 'RegionOne',
'API_VERSION': 2,
}
else:
str_api = 'v3'
self.get_current_os_versions.return_value = {"keystone": "queens"}
expect = {
'OS_AUTH_URL': '{}://127.0.0.1:{}/{}'
.format(transport, port, str_api),
'OS_USERNAME': 'admin',
'OS_PASSWORD': 'openstack',
'OS_REGION_NAME': 'RegionOne',
'OS_DOMAIN_NAME': 'admin_domain',
'OS_USER_DOMAIN_NAME': 'admin_domain',
'OS_PROJECT_NAME': 'admin',
'OS_PROJECT_DOMAIN_NAME': 'admin_domain',
'API_VERSION': 3,
}
self.assertEqual(openstack_utils.get_overcloud_auth(),
expect)
def test_get_overcloud_auth(self):
self._test_get_overcloud_auth()
def test_get_overcloud_auth_v2(self):
self._test_get_overcloud_auth(v2_api=True)
def test_get_overcloud_auth_tls_relation(self):
self._test_get_overcloud_auth(tls_relation=True)
def test_get_overcloud_auth_tls_relation_v2(self):
self._test_get_overcloud_auth(v2_api=True, tls_relation=True)
def test_get_overcloud_auth_ssl_cert(self):
self._test_get_overcloud_auth(ssl_cert=True)
def test_get_overcloud_auth_ssl_cert_v2(self):
self._test_get_overcloud_auth(v2_api=True, ssl_cert=True)
def test_get_overcloud_keystone_session(self):
self.patch_object(openstack_utils, "get_keystone_session")
self.patch_object(openstack_utils, "get_keystone_scope")
@@ -160,7 +231,8 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
self.get_overcloud_auth.return_value = _auth
openstack_utils.get_overcloud_keystone_session()
self.get_keystone_session.assert_called_once_with(_auth, scope=_scope)
self.get_keystone_session.assert_called_once_with(_auth, scope=_scope,
verify=None)
def test_get_undercloud_keystone_session(self):
self.patch_object(openstack_utils, "get_keystone_session")
@@ -172,7 +244,8 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
self.get_undercloud_auth.return_value = _auth
openstack_utils.get_undercloud_keystone_session()
self.get_keystone_session.assert_called_once_with(_auth, scope=_scope)
self.get_keystone_session.assert_called_once_with(_auth, scope=_scope,
verify=None)
def test_get_urllib_opener(self):
self.patch_object(openstack_utils.urllib.request, "ProxyHandler")

View File

@@ -172,13 +172,16 @@ def get_keystone_scope():
return scope
def get_keystone_session(opentackrc_creds, insecure=True, scope='PROJECT'):
def get_keystone_session(opentackrc_creds, scope='PROJECT', verify=None):
"""Return keystone session.
:param openrc_creds: Openstack RC credentials
:type openrc_creds: dict
:param insecure: Allow insecure HTTPS connections
:type insecure: boolean
:param verify: Control TLS certificate verification behaviour
:type verify: any (True - use system certs,
False - do not verify,
None - defer to requests library to find certs,
str - path to a CA cert bundle)
:param scope: Authentication scope: PROJECT or DOMAIN
:type scope: string
:returns: Keystone session object
@@ -189,27 +192,33 @@ def get_keystone_session(opentackrc_creds, insecure=True, scope='PROJECT'):
auth = v2.Password(**keystone_creds)
else:
auth = v3.Password(**keystone_creds)
return session.Session(auth=auth, verify=not insecure)
return session.Session(auth=auth, verify=verify)
def get_overcloud_keystone_session():
def get_overcloud_keystone_session(verify=None):
"""Return Over cloud keystone session.
:param verify: Control TLS certificate verification behaviour
:type verify: any
:returns keystone_session: keystoneauth1.session.Session object
:rtype: keystoneauth1.session.Session
"""
return get_keystone_session(get_overcloud_auth(),
scope=get_keystone_scope())
scope=get_keystone_scope(),
verify=verify)
def get_undercloud_keystone_session():
def get_undercloud_keystone_session(verify=None):
"""Return Under cloud keystone session.
:param verify: Control TLS certificate verification behaviour
:type verify: any
:returns keystone_session: keystoneauth1.session.Session object
:rtype: keystoneauth1.session.Session
"""
return get_keystone_session(get_undercloud_auth(),
scope=get_keystone_scope())
scope=get_keystone_scope(),
verify=verify)
def get_keystone_session_client(session):
@@ -223,17 +232,17 @@ def get_keystone_session_client(session):
return keystoneclient_v3.Client(session=session)
def get_keystone_client(opentackrc_creds, insecure=True):
def get_keystone_client(opentackrc_creds, verify=None):
"""Return authenticated keystoneclient and set auth_ref for service_catalog.
:param openrc_creds: Openstack RC credentials
:type openrc_creds: dict
:param insecure: Allow insecure HTTPS connections
:type insecure: boolean
:param verify: Control TLS certificate verification behaviour
:type verify: any
:returns: Authenticated keystoneclient
:rtype: keystoneclient.v3.Client object
"""
session = get_keystone_session(opentackrc_creds, insecure)
session = get_keystone_session(opentackrc_creds, verify=verify)
client = get_keystone_session_client(session)
keystone_creds = get_ks_creds(opentackrc_creds)
if opentackrc_creds.get('API_VERSION', 2) == 2:
@@ -1190,7 +1199,10 @@ def get_overcloud_auth():
:returns: Dictionary of authentication settings
:rtype: dict
"""
if get_application_config_option('keystone', 'use-https').lower() == 'yes':
tls_rid = model.get_relation_id('keystone', 'vault',
remote_interface_name='tls-certificates')
ssl_config = get_application_config_option('keystone', 'ssl_cert')
if tls_rid or ssl_config:
transport = 'https'
port = 35357
else: