Skip to content

Commit e58ad3b

Browse files
authored
fix(forwader): catch response errors on key verification (#1141)
1 parent a4b6f16 commit e58ad3b

2 files changed

Lines changed: 85 additions & 15 deletions

File tree

aws/logs_monitoring/settings.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,24 +250,31 @@ def is_api_key_valid():
250250
# Validate the API key
251251
logger.debug("Validating the Datadog API key")
252252

253-
with requests.Session() as s:
254-
retries = requests.adapters.Retry(
255-
total=5, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504]
256-
)
253+
try:
254+
with requests.Session() as s:
255+
retries = requests.adapters.Retry(
256+
total=5, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504]
257+
)
257258

258-
s.mount("http://", requests.adapters.HTTPAdapter(max_retries=retries))
259-
s.mount("https://", requests.adapters.HTTPAdapter(max_retries=retries))
259+
s.mount("http://", requests.adapters.HTTPAdapter(max_retries=retries))
260+
s.mount("https://", requests.adapters.HTTPAdapter(max_retries=retries))
260261

261-
validation_res = s.get(
262-
"{}/api/v1/validate?api_key={}".format(DD_API_URL, DD_API_KEY),
263-
verify=(not DD_SKIP_SSL_VALIDATION),
264-
timeout=10,
265-
)
266-
if not validation_res.ok:
267-
logger.error(
268-
f"Datadog API key validation failed (HTTP {validation_res.status_code}). Verify your API key is correct and DD_SITE matches your Datadog account region (current: {DD_SITE}). See: https://docs.datadoghq.com/getting_started/site/"
262+
validation_res = s.get(
263+
"{}/api/v1/validate?api_key={}".format(DD_API_URL, DD_API_KEY),
264+
verify=(not DD_SKIP_SSL_VALIDATION),
265+
timeout=10,
269266
)
270-
return False
267+
if not validation_res.ok:
268+
logger.error(
269+
f"Datadog API key validation failed (HTTP {validation_res.status_code}). Verify your API key is correct and DD_SITE matches your Datadog account region (current: {DD_SITE}). See: https://docs.datadoghq.com/getting_started/site/"
270+
)
271+
return False
272+
except requests.exceptions.RequestException as e:
273+
logger.warning(
274+
f"Could not validate Datadog API key due to a network error: {e}. "
275+
"Proceeding without validation."
276+
)
277+
return False
271278

272279
return True
273280

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import unittest
2+
from unittest.mock import MagicMock, patch
3+
4+
from settings import is_api_key_valid
5+
6+
VALID_API_KEY = "11111111111111111111111111111111"
7+
8+
9+
# For the integration tests to work because of other tests set sys.modules["requests"] as a MagicMock.
10+
class _FakeNetworkError(Exception):
11+
pass
12+
13+
14+
class TestIsApiKeyValid(unittest.TestCase):
15+
@patch("settings.DD_API_KEY", VALID_API_KEY)
16+
@patch("settings.requests.Session")
17+
def test_valid_api_key(self, mock_session_cls):
18+
mock_response = MagicMock()
19+
mock_response.ok = True
20+
mock_session_cls.return_value.__enter__.return_value.get.return_value = (
21+
mock_response
22+
)
23+
self.assertTrue(is_api_key_valid())
24+
25+
@patch("settings.DD_API_KEY", "")
26+
def test_empty_api_key(self):
27+
with self.assertRaises(Exception):
28+
is_api_key_valid()
29+
30+
@patch("settings.DD_API_KEY", "shortapikey")
31+
def test_invalid_api_key_format(self):
32+
with self.assertRaises(Exception):
33+
is_api_key_valid()
34+
35+
@patch("settings.DD_API_KEY", VALID_API_KEY)
36+
@patch("settings.logger")
37+
@patch("settings.requests.exceptions.RequestException", _FakeNetworkError)
38+
@patch("settings.requests.Session")
39+
def test_on_connection_exception(self, mock_session_cls, mock_logger):
40+
mock_session_cls.return_value.__enter__.return_value.get.side_effect = (
41+
_FakeNetworkError("DNS resolution failed")
42+
)
43+
result = is_api_key_valid()
44+
self.assertFalse(result)
45+
mock_logger.warning.assert_called_once()
46+
self.assertIn("network error", mock_logger.warning.call_args[0][0].lower())
47+
48+
@patch("settings.DD_API_KEY", VALID_API_KEY)
49+
@patch("settings.logger")
50+
@patch("settings.requests.exceptions.RequestException", _FakeNetworkError)
51+
@patch("settings.requests.Session")
52+
def test_on_timeout_exception(self, mock_session_cls, mock_logger):
53+
mock_session_cls.return_value.__enter__.return_value.get.side_effect = (
54+
_FakeNetworkError("Request timed out")
55+
)
56+
result = is_api_key_valid()
57+
self.assertFalse(result)
58+
mock_logger.warning.assert_called_once()
59+
self.assertIn("network error", mock_logger.warning.call_args[0][0].lower())
60+
61+
62+
if __name__ == "__main__":
63+
unittest.main()

0 commit comments

Comments
 (0)