Skip to content

Commit a6a017b

Browse files
authored
Add: auto connect to mqtt broker as soon as one is available (#727)
In case ospd-openvas was started without a broker running, the connection fails and ospd-openvas prints that notus is unavailable. This patch solves this issue by trying to connect to the broker every 10 seconds in case the last try failed.
1 parent c10b8c2 commit a6a017b

File tree

3 files changed

+39
-24
lines changed

3 files changed

+39
-24
lines changed

ospd_openvas/daemon.py

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
from typing import Callable, Optional, Dict, List, Tuple, Iterator, Any
2929
from datetime import datetime
30-
from socket import gaierror
3130

3231
from pathlib import Path
3332
from os import geteuid, environ
@@ -527,24 +526,14 @@ def init(self, server: BaseServer) -> None:
527526
notus_handler = NotusResultHandler(self.report_results)
528527

529528
if self._mqtt_broker_address:
530-
try:
531-
client = MQTTClient(
532-
self._mqtt_broker_address, self._mqtt_broker_port, "ospd"
533-
)
534-
daemon = MQTTDaemon(client)
535-
subscriber = MQTTSubscriber(client)
529+
client = MQTTClient(
530+
self._mqtt_broker_address, self._mqtt_broker_port, "ospd"
531+
)
532+
daemon = MQTTDaemon(client)
533+
subscriber = MQTTSubscriber(client)
536534

537-
subscriber.subscribe(
538-
ResultMessage, notus_handler.result_handler
539-
)
540-
daemon.run()
541-
except (ConnectionRefusedError, gaierror, ValueError) as e:
542-
logger.error(
543-
"Could not connect to MQTT broker at %s, error was: %s."
544-
" Unable to get results from Notus.",
545-
self._mqtt_broker_address,
546-
e,
547-
)
535+
subscriber.subscribe(ResultMessage, notus_handler.result_handler)
536+
daemon.run()
548537
else:
549538
logger.info(
550539
"MQTT Broker Adress empty. MQTT disabled. Unable to get Notus"

ospd_openvas/messaging/mqtt.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import logging
2020

2121
from functools import partial
22+
from socket import gaierror, timeout
23+
from threading import Thread
24+
from time import sleep
2225
from typing import Callable, Type
2326

2427
import paho.mqtt.client as mqtt
@@ -156,9 +159,32 @@ def __init__(
156159
self,
157160
client: MQTTClient,
158161
):
159-
self._client = client
160-
161-
self._client.connect()
162+
self._client: MQTTClient = client
163+
164+
def _try_connect_loop(self):
165+
while True:
166+
try:
167+
self._client.connect()
168+
self._client.loop_start()
169+
logger.info("Successfully connected to MQTT broker")
170+
return
171+
except (gaierror, ValueError) as e:
172+
logger.error(
173+
"Could not connect to MQTT broker, error was: %s."
174+
" Unable to get results from Notus.",
175+
e,
176+
)
177+
return
178+
# ConnectionRefusedError - when mqtt declines connection
179+
# timeout - when address is not reachable
180+
# OSError - in container when address cannot be assigned
181+
except (ConnectionRefusedError, timeout, OSError) as e:
182+
logger.warning(
183+
"Could not connect to MQTT broker, error was: %s."
184+
" Trying again in 10s.",
185+
e,
186+
)
187+
sleep(10)
162188

163189
def run(self):
164-
self._client.loop_start()
190+
Thread(target=self._try_connect_loop, daemon=True).start()

tests/messaging/test_mqtt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ def test_connect(self):
9898
# pylint: disable=unused-variable
9999
daemon = MQTTDaemon(client)
100100

101-
client.connect.assert_called_with()
102-
103101
def test_run(self):
104102
client = mock.MagicMock()
105103

106104
daemon = MQTTDaemon(client)
107105

108106
daemon.run()
109107

108+
client.connect.assert_called_with()
109+
110110
client.loop_start.assert_called_with()

0 commit comments

Comments
 (0)