diff --git a/README.md b/README.md index 9d37eec..d752685 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ The application reads configuration using environment variables: | -------------------------- | ------------- | ----------- | | `QBITTORRENT_HOST` | | qbittorrent server hostname | | `QBITTORRENT_PORT` | | qbittorrent server port | +| `QBITTORRENT_SSL` | `False` | Whether to use SSL to connect or not. Will be forced to `True` when using port 443 | +| `QBITTORRENT_URL_BASE` | `""` | qbittorrent server path or base URL | | `QBITTORRENT_USER` | `""` | qbittorrent username | | `QBITTORRENT_PASS` | `""` | qbittorrent password | | `EXPORTER_PORT` | `8000` | Exporter listening port | diff --git a/qbittorrent_exporter/exporter.py b/qbittorrent_exporter/exporter.py index 15bef02..6bb5bd4 100644 --- a/qbittorrent_exporter/exporter.py +++ b/qbittorrent_exporter/exporter.py @@ -43,14 +43,20 @@ class Metric: class QbittorrentMetricsCollector: def __init__(self, config: dict) -> None: self.config = config + self.server = f"{config['host']}:{config['port']}" + self.protocol = "http" + + if config["url_base"]: + self.server = f"{self.server}/{config['url_base']}" + if config["ssl"] or config["port"] == "443": + self.protocol = "https" + self.connection_string = f"{self.protocol}://{self.server}" self.client = Client( - host=config["host"], - port=config["port"], + host=self.connection_string, username=config["username"], password=config["password"], VERIFY_WEBUI_CERTIFICATE=config["verify_webui_certificate"], ) - self.server = f"{config['host']}:{config['port']}" def collect(self) -> Iterable[GaugeMetricFamily | CounterMetricFamily]: """ @@ -269,6 +275,8 @@ def get_config() -> dict: return { "host": _get_config_value("QBITTORRENT_HOST", ""), "port": _get_config_value("QBITTORRENT_PORT", ""), + "ssl": (_get_config_value("QBITTORRENT_SSL", "False") == "True"), + "url_base": _get_config_value("QBITTORRENT_URL_BASE", ""), "username": _get_config_value("QBITTORRENT_USER", ""), "password": _get_config_value("QBITTORRENT_PASS", ""), "exporter_port": int(_get_config_value("EXPORTER_PORT", "8000")), diff --git a/tests/exporter_test.py b/tests/exporter_test.py index f1e5f50..f676da7 100644 --- a/tests/exporter_test.py +++ b/tests/exporter_test.py @@ -18,6 +18,8 @@ def setUp(self, mock_client): self.config = { "host": "localhost", "port": "8080", + "ssl": False, + "url_base": "qbt/", "username": "user", "password": "pass", "verify_webui_certificate": False, @@ -42,8 +44,7 @@ def setUp(self, mock_client): def test_init(self): self.assertEqual(self.collector.config, self.config) self.mock_client.assert_called_once_with( - host=self.config["host"], - port=self.config["port"], + host=f"http://{self.config['host']}:{self.config['port']}/qbt/", username=self.config["username"], password=self.config["password"], VERIFY_WEBUI_CERTIFICATE=self.config["verify_webui_certificate"], @@ -232,7 +233,7 @@ def test_get_qbittorrent_status_metrics(self): Metric( name="qbittorrent_up", value=True, - labels={"version": "1.2.3", "server": "localhost:8080"}, + labels={"version": "1.2.3", "server": "localhost:8080/qbt/"}, help_text=( "Whether the qBittorrent server is answering requests from this" " exporter. A `version` label with the server version is added." @@ -241,7 +242,7 @@ def test_get_qbittorrent_status_metrics(self): Metric( name="qbittorrent_connected", value=True, - labels={"server": "localhost:8080"}, + labels={"server": "localhost:8080/qbt/"}, help_text=( "Whether the qBittorrent server is connected to the Bittorrent" " network." @@ -250,7 +251,7 @@ def test_get_qbittorrent_status_metrics(self): Metric( name="qbittorrent_firewalled", value=False, - labels={"server": "localhost:8080"}, + labels={"server": "localhost:8080/qbt/"}, help_text=( "Whether the qBittorrent server is connected to the Bittorrent" " network but is behind a firewall." @@ -259,34 +260,34 @@ def test_get_qbittorrent_status_metrics(self): Metric( name="qbittorrent_dht_nodes", value=0, - labels={"server": "localhost:8080"}, + labels={"server": "localhost:8080/qbt/"}, help_text="Number of DHT nodes connected to.", ), Metric( name="qbittorrent_dl_info_data", value=0, - labels={"server": "localhost:8080"}, + labels={"server": "localhost:8080/qbt/"}, help_text="Data downloaded since the server started, in bytes.", metric_type=MetricType.COUNTER, ), Metric( name="qbittorrent_up_info_data", value=0, - labels={"server": "localhost:8080"}, + labels={"server": "localhost:8080/qbt/"}, help_text="Data uploaded since the server started, in bytes.", metric_type=MetricType.COUNTER, ), Metric( name="qbittorrent_alltime_dl", value=0, - labels={"server": "localhost:8080"}, + labels={"server": "localhost:8080/qbt/"}, help_text="Total historical data downloaded, in bytes.", metric_type=MetricType.COUNTER, ), Metric( name="qbittorrent_alltime_ul", value=0, - labels={"server": "localhost:8080"}, + labels={"server": "localhost:8080/qbt/"}, help_text="Total historical data uploaded, in bytes.", metric_type=MetricType.COUNTER, ), @@ -294,3 +295,56 @@ def test_get_qbittorrent_status_metrics(self): metrics = self.collector._get_qbittorrent_status_metrics() self.assertEqual(metrics, expected_metrics) + + def test_server_string_with_different_settings(self): + self.assertEqual(self.collector.server, "localhost:8080/qbt/") + self.assertEqual(self.collector.connection_string, "http://localhost:8080/qbt/") + + config = { + "host": "qbittorrent.example.com", + "port": "8081", + "ssl": False, + "url_base": "qbittorrent/", + "username": "user", + "password": "pass", + "verify_webui_certificate": False, + "metrics_prefix": "qbittorrent", + } + collector = QbittorrentMetricsCollector(config) + self.assertEqual(collector.server, "qbittorrent.example.com:8081/qbittorrent/") + self.assertEqual( + collector.connection_string, + "http://qbittorrent.example.com:8081/qbittorrent/", + ) + + config = { + "host": "qbittorrent2.example.com", + "port": "8084", + "ssl": True, + "url_base": "", + "username": "user", + "password": "pass", + "verify_webui_certificate": True, + "metrics_prefix": "qbittorrent", + } + collector = QbittorrentMetricsCollector(config) + self.assertEqual(collector.server, "qbittorrent2.example.com:8084") + self.assertEqual( + collector.connection_string, "https://qbittorrent2.example.com:8084" + ) + + config = { + "host": "qbittorrent3.example.com", + "port": "443", + "ssl": False, # Will be enforced to True because port is 443 + "url_base": "server/", + "username": "user", + "password": "pass", + "verify_webui_certificate": True, + "metrics_prefix": "qbittorrent", + } + collector = QbittorrentMetricsCollector(config) + self.assertEqual(collector.server, "qbittorrent3.example.com:443/server/") + self.assertEqual( + collector.connection_string, "https://qbittorrent3.example.com:443/server/" + )