Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a755389
Add MQTT Reader enterprise workflow block
tewanchia Sep 18, 2026
ef36808
Add operator broker policy and keepalive to the MQTT blocks
tewanchia Sep 21, 2026
568db61
Add MQTT Reader and broker policy to the workflows changelog
tewanchia Sep 21, 2026
9de07ee
Keep the MQTT Writer on paho's default keepalive
tewanchia Sep 21, 2026
a0d3217
Drop the writer keepalive expectations and changelog line
tewanchia Sep 21, 2026
550aa48
Mention the MQTT Reader keepalive in its changelog entry
tewanchia Sep 21, 2026
2dbe9a9
Add TLS to the MQTT Reader and MQTT Writer blocks
tewanchia Sep 21, 2026
016a9c6
Harden MQTT TLS after review
tewanchia Sep 21, 2026
5712a02
Stabilise MQTT TLS integration tests on CI
tewanchia Sep 21, 2026
087d151
Add persistent sessions to the MQTT Reader via an optional client_id
tewanchia Sep 23, 2026
89a24ff
Mention persistent sessions in the MQTT Reader's HTTP restriction note
tewanchia Sep 23, 2026
e8a310c
Merge remote-tracking branch 'origin/main' into feat/enterprise-mqtt-…
tewanchia Sep 23, 2026
ed91bae
Stop the MQTT blocks from retrying a refused connection
tewanchia Sep 23, 2026
2d8528e
Repeat the MQTT Reader's last message while the broker is down
tewanchia Sep 23, 2026
7023a2a
Merge remote-tracking branch 'origin/main' into feat/enterprise-mqtt-…
tewanchia Sep 23, 2026
9175f65
Address the local review of the MQTT refusal and outage changes
tewanchia Sep 23, 2026
a945862
Merge branch 'main' into feat/enterprise-mqtt-reader-block
PawelPeczek-Roboflow Sep 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions inference/core/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,35 @@
for entry in KAFKA_WORKFLOWS_SINKS_WHITELISTED_BOOTSTRAP_SERVERS.split(",")
if entry.strip()
]
# Operator policy for the MQTT Reader / MQTT Writer Workflow blocks, which open
# an outbound connection to the `host`/`port` taken from the workflow definition
# or its inputs. When True (default, preserves behaviour) that value is
# honoured, subject to the allowlist below. When False the workflow-provided
# value is ignored and the blocks connect to the first entry of
# MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS instead; with no entry configured
# there, the MQTT blocks are disabled (every run reports an error).
MQTT_WORKFLOWS_BLOCKS_ALLOW_USER_PROVIDED_HOST = str2bool(
os.getenv("MQTT_WORKFLOWS_BLOCKS_ALLOW_USER_PROVIDED_HOST", True)
)
# Optional comma-separated list of `host[:port]` MQTT brokers the MQTT Workflow
# blocks may connect to. When set and a user-provided host is allowed, the
# workflow's `host:port` must match an entry or the run reports an error; an
# entry without a port matches that host on any port. When a user-provided host
# is not allowed, the first entry is what the blocks connect to (port 1883 when
# the entry has none). Hosts are compared after trimming whitespace, lowercasing
# and stripping IPv6 brackets; there is no DNS resolution. Empty entries are
# ignored. A variable that is set but holds no entries is an empty allowlist:
# nothing is permitted. Default None (no allowlist).
MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS = os.getenv(
"MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS"
)
if MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS is not None:
# a list, not a set: the first entry is the operator's broker
MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS = [
entry.strip()
for entry in MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS.split(",")
if entry.strip()
]

# List of allowed origins
ALLOW_ORIGINS = os.getenv("ALLOW_ORIGINS", "*")
Expand Down
8 changes: 8 additions & 0 deletions inference/core/interfaces/workflows_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ def build_configuration_from_env() -> WorkflowsConfiguration:
if env.KAFKA_WORKFLOWS_SINKS_WHITELISTED_BOOTSTRAP_SERVERS is None
else tuple(env.KAFKA_WORKFLOWS_SINKS_WHITELISTED_BOOTSTRAP_SERVERS)
),
allow_mqtt_blocks_user_provided_host=env.MQTT_WORKFLOWS_BLOCKS_ALLOW_USER_PROVIDED_HOST,
# NOT sorted: the first entry is the operator's broker when
# user-provided hosts are not allowed.
mqtt_blocks_whitelisted_hosts=(
None
if env.MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS is None
else tuple(env.MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS)
),
),
tensor=TensorConfiguration(
representation_enabled=env.ENABLE_TENSOR_DATA_REPRESENTATION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@
else list(c.engine.kafka_sinks_whitelisted_bootstrap_servers)
),
),
(
"MQTT_WORKFLOWS_BLOCKS_ALLOW_USER_PROVIDED_HOST",
lambda c: c.engine.allow_mqtt_blocks_user_provided_host,
),
(
"MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS",
lambda c: (
None
if c.engine.mqtt_blocks_whitelisted_hosts is None
else list(c.engine.mqtt_blocks_whitelisted_hosts)
),
),
("ENABLE_TENSOR_DATA_REPRESENTATION", lambda c: c.tensor.representation_enabled),
("WORKFLOWS_IMAGE_TENSOR_DEVICE", lambda c: c.tensor.image_tensor_device),
(
Expand Down Expand Up @@ -226,7 +238,7 @@ def test_the_field_table_matches_the_facade_exports() -> None:
"missing_from_table": sorted(exported - tabled),
"missing_from_facade": sorted(tabled - exported),
}
assert len(tabled) == 78, len(tabled)
assert len(tabled) == 80, len(tabled)


def test_every_name_workflows_imports_from_the_facade_is_exported() -> None:
Expand Down Expand Up @@ -291,6 +303,11 @@ def test_server_configuration_equals_env_field_by_field(name, reader) -> None:
"KAFKA_WORKFLOWS_SINKS_WHITELISTED_BOOTSTRAP_SERVERS",
["kafka-2:9092", "kafka-1:9092"],
),
("MQTT_WORKFLOWS_BLOCKS_ALLOW_USER_PROVIDED_HOST", False),
("MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS", None),
("MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS", []),
# order preserved, not sorted
("MQTT_WORKFLOWS_BLOCKS_WHITELISTED_HOSTS", ["broker-2:1883", "broker-1"]),
("LAMBDA", True),
],
)
Expand Down
Loading
Loading