From daccc439d794f54874ccc49d3a674637abedbeef Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Mon, 2 Feb 2026 23:49:48 +0900 Subject: [PATCH] Prometheus: Add timeout for HTTP requests ... to avoid processes from getting stuck due to the server not responding in a timely manner (or even dying during handling requests). This is the recommended approach[1] and is a call without timeout is detected as an issue by bandit[2]. [1] https://requests.readthedocs.io/en/latest/user/advanced/#timeouts [2] Issue: [B113:request_without_timeout] Call to requests without timeout Severity: Medium Confidence: Low CWE: CWE-400 (https://cwe.mitre.org/data/definitions/400.html) More Info: https://bandit.readthedocs.io/en/1.9.2/plugins/ Change-Id: I4e2672eecb27f79d102d58fbe9e985ee251bb683 Signed-off-by: Takashi Kajinami --- cloudkitty/collector/prometheus.py | 7 +++++++ cloudkitty/common/prometheus_client.py | 4 +++- cloudkitty/fetcher/prometheus.py | 7 +++++++ .../notes/prometheus-timeout-f5b23661559fe675.yaml | 8 ++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/prometheus-timeout-f5b23661559fe675.yaml diff --git a/cloudkitty/collector/prometheus.py b/cloudkitty/collector/prometheus.py index e57b3443..cd6cc734 100644 --- a/cloudkitty/collector/prometheus.py +++ b/cloudkitty/collector/prometheus.py @@ -59,6 +59,12 @@ collector_prometheus_opts = [ default=False, help='Explicitly trust untrusted HTTPS responses', ), + cfg.FloatOpt( + 'timeout', + default=60, + min=0, + help='Timeout value for http requests', + ), ] cfg.CONF.register_opts(collector_prometheus_opts, PROMETHEUS_COLLECTOR_OPTS) @@ -110,6 +116,7 @@ class PrometheusCollector(collector.BaseCollector): url, auth=(user, password) if user and password else None, verify=verify, + timeout=CONF.collector_prometheus.timeout ) @staticmethod diff --git a/cloudkitty/common/prometheus_client.py b/cloudkitty/common/prometheus_client.py index b37b7b1b..e5997a69 100644 --- a/cloudkitty/common/prometheus_client.py +++ b/cloudkitty/common/prometheus_client.py @@ -23,10 +23,11 @@ class PrometheusClient(object): INSTANT_QUERY_ENDPOINT = 'query' RANGE_QUERY_ENDPOINT = 'query_range' - def __init__(self, url, auth=None, verify=True): + def __init__(self, url, auth=None, verify=True, timeout=60): self.url = url self.auth = auth self.verify = verify + self.timeout = timeout def _get(self, endpoint, params): return requests.get( @@ -34,6 +35,7 @@ class PrometheusClient(object): params=params, auth=self.auth, verify=self.verify, + timeout=self.timeout, ) def get_instant(self, query, time=None, timeout=None): diff --git a/cloudkitty/fetcher/prometheus.py b/cloudkitty/fetcher/prometheus.py index 3f88eedb..1cab1e2d 100644 --- a/cloudkitty/fetcher/prometheus.py +++ b/cloudkitty/fetcher/prometheus.py @@ -58,6 +58,12 @@ fetcher_prometheus_opts = [ default=False, help='Explicitly trust untrusted HTTPS responses', ), + cfg.FloatOpt( + 'timeout', + default=60, + min=0, + help='Timeout value for http requests', + ), cfg.DictOpt( 'filters', default=dict(), @@ -92,6 +98,7 @@ class PrometheusFetcher(fetcher.BaseFetcher): url, auth=(user, password) if user and password else None, verify=verify, + timeout=CONF.fetcher_prometheus.timeout ) def get_tenants(self): diff --git a/releasenotes/notes/prometheus-timeout-f5b23661559fe675.yaml b/releasenotes/notes/prometheus-timeout-f5b23661559fe675.yaml new file mode 100644 index 00000000..aa4c5253 --- /dev/null +++ b/releasenotes/notes/prometheus-timeout-f5b23661559fe675.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Introduced timeout for HTTP requests sent to Prometheus. Timeout thresholds + are 60 seconds by default and can be customized by the following options. + + - ``[collector_prometheus] timeout`` + - ``[fetcher_prometheus] timeout``