From feae197c5ad02fa0898a30d4ffaaba8a21d4f884 Mon Sep 17 00:00:00 2001
From: Felix Maurer <felix.maurer@est.tech>
Date: Wed, 29 Jul 2020 18:48:21 +0300
Subject: [PATCH] Use TLS for json_rpc when configured

The configuration for json_rpc contains the option use_ssl but its value
was not respected by the json_rpc client. Therefore the client tried to
connect to HTTPS endpoints using HTTP.

Change-Id: I4336d71f57bcfbde90fa7b62a5435a7f9d0a73d3
---
 ironic/common/json_rpc/client.py               |  5 ++++-
 ironic/tests/unit/common/test_json_rpc.py      | 18 ++++++++++++++++++
 ...x-json-rpc-client-ssl-2438a731beb3d5f9.yaml |  5 +++++
 3 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 releasenotes/notes/fix-json-rpc-client-ssl-2438a731beb3d5f9.yaml

diff --git a/ironic/common/json_rpc/client.py b/ironic/common/json_rpc/client.py
index f67c90ed9d..8979d6f029 100644
--- a/ironic/common/json_rpc/client.py
+++ b/ironic/common/json_rpc/client.py
@@ -167,7 +167,10 @@ class _CallContext(object):
             body['id'] = context.request_id or uuidutils.generate_uuid()
 
         LOG.debug("RPC %s with %s", method, strutils.mask_dict_password(body))
-        url = 'http://%s:%d' % (self.host, CONF.json_rpc.port)
+        scheme = 'http'
+        if CONF.json_rpc.use_ssl:
+            scheme = 'https'
+        url = '%s://%s:%d' % (scheme, self.host, CONF.json_rpc.port)
         result = _get_session().post(url, json=body)
         LOG.debug('RPC %s returned %s', method,
                   strutils.mask_password(result.text or '<None>'))
diff --git a/ironic/tests/unit/common/test_json_rpc.py b/ironic/tests/unit/common/test_json_rpc.py
index 8584c1fa09..bc0ccc5d67 100644
--- a/ironic/tests/unit/common/test_json_rpc.py
+++ b/ironic/tests/unit/common/test_json_rpc.py
@@ -385,6 +385,24 @@ class TestClient(test_base.TestCase):
                              'rpc.version': '1.42'},
                   'id': self.context.request_id})
 
+    def test_call_with_ssl(self, mock_session):
+        self.config(use_ssl=True, group='json_rpc')
+        response = mock_session.return_value.post.return_value
+        response.json.return_value = {
+            'jsonrpc': '2.0',
+            'result': 42
+        }
+        cctx = self.client.prepare('foo.example.com')
+        self.assertEqual('example.com', cctx.host)
+        result = cctx.call(self.context, 'do_something', answer=42)
+        self.assertEqual(42, result)
+        mock_session.return_value.post.assert_called_once_with(
+            'https://example.com:8089',
+            json={'jsonrpc': '2.0',
+                  'method': 'do_something',
+                  'params': {'answer': 42, 'context': self.ctx_json},
+                  'id': self.context.request_id})
+
     def test_cast_success(self, mock_session):
         cctx = self.client.prepare('foo.example.com')
         self.assertEqual('example.com', cctx.host)
diff --git a/releasenotes/notes/fix-json-rpc-client-ssl-2438a731beb3d5f9.yaml b/releasenotes/notes/fix-json-rpc-client-ssl-2438a731beb3d5f9.yaml
new file mode 100644
index 0000000000..5181f90510
--- /dev/null
+++ b/releasenotes/notes/fix-json-rpc-client-ssl-2438a731beb3d5f9.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    Fixes json_rpc client connections always using HTTP even if `use_ssl` was
+    set to True.