From 6639b9e5643aeaee7a17b7995fddc2fb6288b926 Mon Sep 17 00:00:00 2001 From: Jill Rouleau Date: Tue, 11 Sep 2018 12:01:01 -0600 Subject: [PATCH] Handle tls endpoint for zaqar websocket client When creating zaqar websocket client, if the endpoint has tls enabled provide the CA to the client. Closes-Bug: 1791970 Change-Id: I09fca4ea80ae8246f136ea6998dfc7ad1c6bb4d2 --- tripleoclient/constants.py | 3 +++ tripleoclient/plugin.py | 9 ++++++++- tripleoclient/tests/fakes.py | 1 + tripleoclient/tests/test_plugin.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/tripleoclient/constants.py b/tripleoclient/constants.py index 9ee7b967b..f3d4c3224 100644 --- a/tripleoclient/constants.py +++ b/tripleoclient/constants.py @@ -79,3 +79,6 @@ ENABLE_SSH_ADMIN_SSH_PORT_TIMEOUT = 300 ADDITIONAL_ARCHITECTURES = ['ppc64le'] ANSIBLE_VALIDATION_DIR = '/usr/share/openstack-tripleo-validations/validations' + +# The path to the local CA certificate installed on the undercloud +LOCAL_CACERT_PATH = '/etc/pki/ca-trust/source/anchors/cm-local-ca.pem' diff --git a/tripleoclient/plugin.py b/tripleoclient/plugin.py index bb05c9fef..1242192f7 100644 --- a/tripleoclient/plugin.py +++ b/tripleoclient/plugin.py @@ -26,6 +26,8 @@ import websocket from tripleoclient import exceptions +from tripleoclient import constants + LOG = logging.getLogger(__name__) DEFAULT_TRIPLEOCLIENT_API_VERSION = '1' @@ -83,7 +85,12 @@ class WebsocketClient(object): LOG.debug('Instantiating messaging websocket client: %s', endpoint) try: - self._ws = websocket.create_connection(endpoint) + if 'wss:' in endpoint: + OS_CACERT = {"ca_certs": constants.LOCAL_CACERT_PATH} + self._ws = websocket.create_connection(endpoint, + sslopt=OS_CACERT) + else: + self._ws = websocket.create_connection(endpoint) except socket.error: LOG.error("Could not establish a connection to the Zaqar " "websocket. The command was sent but the answer " diff --git a/tripleoclient/tests/fakes.py b/tripleoclient/tests/fakes.py index 3c550d557..95844dbe5 100644 --- a/tripleoclient/tests/fakes.py +++ b/tripleoclient/tests/fakes.py @@ -20,6 +20,7 @@ import sys AUTH_TOKEN = "foobar" AUTH_URL = "http://0.0.0.0" WS_URL = "ws://0.0.0.0" +WSS_URL = "wss://0.0.0.0" class FakeApp(object): diff --git a/tripleoclient/tests/test_plugin.py b/tripleoclient/tests/test_plugin.py index 5e808960b..951c716b9 100644 --- a/tripleoclient/tests/test_plugin.py +++ b/tripleoclient/tests/test_plugin.py @@ -106,3 +106,31 @@ class TestPlugin(base.TestCase): with mock.patch('tripleoclient.plugin.LOG') as mock_log: self.assertRaises(socket.error, client.messaging_websocket) mock_log.error.assert_called_once_with(msg) + + @mock.patch("websocket.create_connection") + def test_make_tls_client(self, ws_create_connection): + clientmgr = mock.MagicMock() + clientmgr.get_endpoint_for_service_type.return_value = fakes.WSS_URL + + clientmgr.auth.get_token.return_value = "TOKEN" + clientmgr.auth_ref.project_id = "ID" + ws_create_connection.return_value.recv.return_value = json.dumps({ + "headers": { + "status": 200 + } + }) + client = plugin.make_client(clientmgr) + + websocket = client.messaging_websocket() + # The second access should not return the same client: + self.assertIsNot(client.messaging_websocket(), websocket) + + plugin.make_client(clientmgr) + + # And the functions should only be called when the client is created: + self.assertEqual(clientmgr.auth.get_token.call_count, 2) + self.assertEqual(clientmgr.get_endpoint_for_service_type.call_count, 2) + ws_create_connection.assert_called_with( + "wss://0.0.0.0", + sslopt={'ca_certs': + '/etc/pki/ca-trust/source/anchors/cm-local-ca.pem'})