From 9b981a38100a05b10b5943bf7df8c8048700e531 Mon Sep 17 00:00:00 2001
From: Dmitry Tantsur <dtantsur@protonmail.com>
Date: Tue, 9 Jan 2024 16:38:46 +0100
Subject: [PATCH] Add missing headers to the inspection callback

Somehow, it has worked correctly for years, but now I've discovered that
the new inspection is (no longer?) tolerant to the missing header.

While here, copy all headers from the heartbeat code.

Change-Id: I9e5c609eb4435e520bc225dea08aedfdf169744b
(cherry picked from commit 2bb74523ae54e25038a8486e6569cd1015216352)
---
 ironic_python_agent/inspector.py                    |  9 ++++++++-
 ironic_python_agent/tests/unit/test_inspector.py    | 13 +++++++++----
 .../notes/content-type-f4d5ab15adf37252.yaml        |  6 ++++++
 3 files changed, 23 insertions(+), 5 deletions(-)
 create mode 100644 releasenotes/notes/content-type-f4d5ab15adf37252.yaml

diff --git a/ironic_python_agent/inspector.py b/ironic_python_agent/inspector.py
index 5d51be41c..2c0b730b3 100644
--- a/ironic_python_agent/inspector.py
+++ b/ironic_python_agent/inspector.py
@@ -132,6 +132,13 @@ def call_inspector(data, failures):
     data = encoder.encode(data)
     verify, cert = utils.get_ssl_client_options(CONF)
 
+    headers = {
+        'Content-Type': 'application/json',
+        'Accept': 'application/json',
+    }
+    if CONF.global_request_id:
+        headers["X-OpenStack-Request-ID"] = CONF.global_request_id
+
     @tenacity.retry(
         retry=tenacity.retry_if_exception_type(
             (requests.exceptions.ConnectionError,
@@ -142,7 +149,7 @@ def call_inspector(data, failures):
         reraise=True)
     def _post_to_inspector():
         inspector_resp = requests.post(
-            CONF.inspection_callback_url, data=data,
+            CONF.inspection_callback_url, data=data, headers=headers,
             verify=verify, cert=cert, timeout=CONF.http_request_timeout)
         if inspector_resp.status_code >= 500:
             raise requests.exceptions.HTTPError(response=inspector_resp)
diff --git a/ironic_python_agent/tests/unit/test_inspector.py b/ironic_python_agent/tests/unit/test_inspector.py
index 9aa04adb2..c765e1314 100644
--- a/ironic_python_agent/tests/unit/test_inspector.py
+++ b/ironic_python_agent/tests/unit/test_inspector.py
@@ -161,10 +161,12 @@ class TestCallInspector(base.IronicAgentTest):
 
         res = inspector.call_inspector(data, failures)
 
-        mock_post.assert_called_once_with('url',
-                                          cert=None, verify=True,
-                                          data='{"data": 42, "error": null}',
-                                          timeout=30)
+        mock_post.assert_called_once_with(
+            'url', data='{"data": 42, "error": null}',
+            cert=None, verify=True,
+            headers={'Content-Type': 'application/json',
+                     'Accept': 'application/json'},
+            timeout=30)
         self.assertEqual(mock_post.return_value.json.return_value, res)
 
     def test_send_failure(self, mock_post):
@@ -178,6 +180,7 @@ class TestCallInspector(base.IronicAgentTest):
         mock_post.assert_called_once_with('url',
                                           cert=None, verify=True,
                                           data='{"data": 42, "error": "boom"}',
+                                          headers=mock.ANY,
                                           timeout=30)
         self.assertEqual(mock_post.return_value.json.return_value, res)
 
@@ -191,6 +194,7 @@ class TestCallInspector(base.IronicAgentTest):
         mock_post.assert_called_once_with('url',
                                           cert=None, verify=True,
                                           data='{"data": 42, "error": null}',
+                                          headers=mock.ANY,
                                           timeout=30)
         self.assertIsNone(res)
 
@@ -230,6 +234,7 @@ class TestCallInspector(base.IronicAgentTest):
         mock_post.assert_called_with('url',
                                      cert=None, verify=True,
                                      data='{"data": 42, "error": null}',
+                                     headers=mock.ANY,
                                      timeout=30)
 
 
diff --git a/releasenotes/notes/content-type-f4d5ab15adf37252.yaml b/releasenotes/notes/content-type-f4d5ab15adf37252.yaml
new file mode 100644
index 000000000..fb6fbcc38
--- /dev/null
+++ b/releasenotes/notes/content-type-f4d5ab15adf37252.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Fixes missing ``Content-Type`` header when sending inspection data back
+    to ironic-inspector or ironic. While ironic-inspector tolerates the
+    missing header, it may cause issues with the new inspection implementation.