Skip to content

Commit 2bdca88

Browse files
committed
Fix CI failures: black formatting, mypy types, integration test mock
- Run black on all 6 new/modified handler and test files - Fix gateway_portal_handler.py mypy errors: add dict[str, Any] type args on all 4 bare `dict` return/param annotations, add type: ignore for untyped DockerHandler() call, fix pgmq send() to two-arg form send("gateway_portal_events", event) - Add setup_dnssec to SimpleNamespace mock in test_phase_3_pki_inserts_ca_dns_record so the integration test survives phase_pki calling pki.setup_dnssec() when minimal.yaml has dnssec_enabled: true
1 parent a0625aa commit 2bdca88

7 files changed

Lines changed: 82 additions & 71 deletions

File tree

netengine/handlers/gateway_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,8 @@ def _mirrored_internet_rules(self, config: "RealInternetConfig") -> str:
230230
for mirror in config.service_mirrors:
231231
# Allow traffic destined for the in-world service counterpart
232232
mirror_accepts += (
233-
f'\n ip daddr {mirror.in_world_service} tcp dport {{ 80, 443 }}'
234-
' ct state new accept'
233+
f"\n ip daddr {mirror.in_world_service} tcp dport {{ 80, 443 }}"
234+
" ct state new accept"
235235
)
236236

237237
return f"""\

netengine/handlers/gateway_portal_handler.py

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ async def execute(self, context: PhaseContext) -> None:
5454
"deployed_at": datetime.utcnow().isoformat(),
5555
}
5656
context.runtime_state.save()
57-
await self._emit_event(context, "gateway_portal.ready", context.runtime_state.gateway_portal_output)
57+
await self._emit_event(
58+
context, "gateway_portal.ready", context.runtime_state.gateway_portal_output
59+
)
5860
return
5961

60-
docker = context.docker_client if context.docker_client is not None else DockerHandler()
62+
docker = context.docker_client if context.docker_client is not None else DockerHandler() # type: ignore[no-untyped-call]
6163
gateway = GatewayHandler(docker)
6264

6365
# ── Real Internet ───────────────────────────────────────────────────
@@ -100,7 +102,7 @@ async def _apply_internet_policy(
100102
context: PhaseContext,
101103
gateway: GatewayHandler,
102104
portal: GatewayPortal,
103-
) -> dict:
105+
) -> dict[str, Any]:
104106
config = portal.real_internet
105107
context.logger.info(f"Real-internet mode: {config.mode.value}")
106108

@@ -109,9 +111,7 @@ async def _apply_internet_policy(
109111
output: dict[str, Any] = {"mode": config.mode.value}
110112

111113
if config.upstream_resolver_enabled and config.upstream_resolver_ip:
112-
await self._configure_upstream_resolver(
113-
context, config.upstream_resolver_ip
114-
)
114+
await self._configure_upstream_resolver(context, config.upstream_resolver_ip)
115115
output["upstream_resolver"] = config.upstream_resolver_ip
116116

117117
if config.mode == GatewayRealInternetMode.MIRRORED and config.service_mirrors:
@@ -122,9 +122,7 @@ async def _apply_internet_policy(
122122

123123
return output
124124

125-
async def _configure_upstream_resolver(
126-
self, context: PhaseContext, resolver_ip: str
127-
) -> None:
125+
async def _configure_upstream_resolver(self, context: PhaseContext, resolver_ip: str) -> None:
128126
"""Inject an upstream forwarder into the CoreDNS root Corefile.
129127
130128
Adds a ``forward . <resolver_ip>`` directive so that names not
@@ -137,25 +135,21 @@ async def _configure_upstream_resolver(
137135

138136
try:
139137
corefile_patch = (
140-
f"\n# Upstream internet resolver (gateway portal)\n"
141-
f"forward . {resolver_ip}\n"
138+
f"\n# Upstream internet resolver (gateway portal)\n" f"forward . {resolver_ip}\n"
142139
)
143140
corefile_append_cmd = [
144-
"sh", "-c",
141+
"sh",
142+
"-c",
145143
f"echo '{corefile_patch}' >> /etc/coredns/Corefile",
146144
]
147145
exit_code, output = await context.docker_client.exec_command(
148146
"netengine_coredns", corefile_append_cmd
149147
)
150148
if exit_code != 0:
151-
context.logger.warning(
152-
f"Could not append upstream resolver to CoreDNS: {output}"
153-
)
149+
context.logger.warning(f"Could not append upstream resolver to CoreDNS: {output}")
154150
else:
155151
# Reload CoreDNS to pick up the change
156-
await context.docker_client.exec_command(
157-
"netengine_coredns", ["kill", "-HUP", "1"]
158-
)
152+
await context.docker_client.exec_command("netengine_coredns", ["kill", "-HUP", "1"])
159153
context.logger.info(f"Upstream resolver configured: {resolver_ip}")
160154
except Exception as exc:
161155
context.logger.warning(f"Upstream resolver setup skipped: {exc}")
@@ -170,16 +164,15 @@ async def _apply_cross_world(
170164
gateway: GatewayHandler,
171165
docker: DockerHandler,
172166
portal: GatewayPortal,
173-
) -> dict:
167+
) -> dict[str, Any]:
174168
cross_world = portal.cross_world
175169

176170
if cross_world.mode == GatewayCrossWorldMode.NONE:
177171
context.logger.info("Cross-world mode: NONE — no peering configured")
178172
return {"mode": GatewayCrossWorldMode.NONE.value, "peers": []}
179173

180174
context.logger.info(
181-
f"Cross-world mode: {cross_world.mode.value} "
182-
f"({len(cross_world.peers)} peer(s))"
175+
f"Cross-world mode: {cross_world.mode.value} " f"({len(cross_world.peers)} peer(s))"
183176
)
184177

185178
peers_output = []
@@ -198,7 +191,7 @@ async def _setup_peer(
198191
gateway: GatewayHandler,
199192
docker: DockerHandler,
200193
peer: CrossWorldPeer,
201-
) -> dict:
194+
) -> dict[str, Any]:
202195
"""Wire up a single cross-world peer: trust anchor + routing + DNS."""
203196
context.logger.info(f"Setting up cross-world peer: {peer.name} ({peer.endpoint})")
204197
result: dict[str, Any] = {
@@ -213,9 +206,7 @@ async def _setup_peer(
213206
await self._install_trust_anchor(context, docker, peer.name, peer.trust_anchor_cert)
214207
result["trust_anchor_installed"] = True
215208
except Exception as exc:
216-
context.logger.warning(
217-
f"Trust anchor install failed for peer {peer.name}: {exc}"
218-
)
209+
context.logger.warning(f"Trust anchor install failed for peer {peer.name}: {exc}")
219210
result["trust_anchor_installed"] = False
220211
result["trust_anchor_error"] = str(exc)
221212
else:
@@ -272,15 +263,11 @@ async def _install_trust_anchor(
272263
"netengine_gateway", ["update-ca-certificates"]
273264
)
274265
if exit_code != 0:
275-
raise PKIError(
276-
f"update-ca-certificates failed for peer {peer_name}: {output}"
277-
)
266+
raise PKIError(f"update-ca-certificates failed for peer {peer_name}: {output}")
278267

279268
context.logger.info(f"Trust anchor installed for peer: {peer_name}")
280269

281-
async def _configure_peer_dns(
282-
self, context: PhaseContext, peer: CrossWorldPeer
283-
) -> None:
270+
async def _configure_peer_dns(self, context: PhaseContext, peer: CrossWorldPeer) -> None:
284271
"""Add a CoreDNS forwarding zone for the peer world's TLD.
285272
286273
Derives the peer TLD from ``<peer.name>.internal`` and adds a
@@ -304,9 +291,7 @@ async def _configure_peer_dns(
304291
["sh", "-c", f"echo '{corefile_stub}' >> /etc/coredns/Corefile"],
305292
)
306293
if exit_code != 0:
307-
raise GatewayError(
308-
f"Could not configure DNS forwarding for peer {peer.name}: {output}"
309-
)
294+
raise GatewayError(f"Could not configure DNS forwarding for peer {peer.name}: {output}")
310295

311296
# Signal CoreDNS to reload config
312297
await context.docker_client.exec_command("netengine_coredns", ["kill", "-HUP", "1"])
@@ -316,7 +301,9 @@ async def _configure_peer_dns(
316301
# Event emission
317302
# ─────────────────────────────────────────────
318303

319-
async def _emit_event(self, context: PhaseContext, event_type: str, payload: dict) -> None:
304+
async def _emit_event(
305+
self, context: PhaseContext, event_type: str, payload: dict[str, Any]
306+
) -> None:
320307
event = EventEnvelope.create(
321308
event_type=event_type,
322309
emitted_by="gateway_portal_handler",
@@ -327,6 +314,6 @@ async def _emit_event(self, context: PhaseContext, event_type: str, payload: dic
327314
context.logger.info(f"Event emitted: {event_type}")
328315
if context.pgmq_client is not None:
329316
try:
330-
await context.pgmq_client.send(event)
317+
await context.pgmq_client.send("gateway_portal_events", event)
331318
except Exception as exc:
332319
context.logger.warning(f"Failed to queue gateway portal event: {exc}")

netengine/handlers/phase_pki.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ def _register_rotation_worker(self, context: PhaseContext, pki: PKIHandler, spec
172172
rotation_interval_hours=interval,
173173
expiry_warning_days=warning,
174174
rotation_callback=(
175-
self._prepare_app_cert_rotation
176-
if cert_type in _callback_types
177-
else None
175+
self._prepare_app_cert_rotation if cert_type in _callback_types else None
178176
),
179177
)
180178
)

netengine/handlers/pki_handler.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -353,38 +353,39 @@ async def setup_dnssec(
353353
image=bind_image,
354354
command=[
355355
"dnssec-keygen",
356-
"-f", "KSK",
357-
"-a", "ECDSAP256SHA256",
358-
"-n", "ZONE",
356+
"-f",
357+
"KSK",
358+
"-a",
359+
"ECDSAP256SHA256",
360+
"-n",
361+
"ZONE",
359362
zone,
360363
],
361364
volumes=volumes,
362365
environment={},
363366
working_dir="/keys",
364367
)
365368
if ksk_result["exit_code"] != 0:
366-
raise PKIError(
367-
f"DNSSEC KSK generation failed for zone '{zone}': {ksk_result['logs']}"
368-
)
369+
raise PKIError(f"DNSSEC KSK generation failed for zone '{zone}': {ksk_result['logs']}")
369370
ksk_name = ksk_result["logs"].strip()
370371

371372
# ZSK — signs all other RRsets
372373
zsk_result = await self.docker.run_container_one_off(
373374
image=bind_image,
374375
command=[
375376
"dnssec-keygen",
376-
"-a", "ECDSAP256SHA256",
377-
"-n", "ZONE",
377+
"-a",
378+
"ECDSAP256SHA256",
379+
"-n",
380+
"ZONE",
378381
zone,
379382
],
380383
volumes=volumes,
381384
environment={},
382385
working_dir="/keys",
383386
)
384387
if zsk_result["exit_code"] != 0:
385-
raise PKIError(
386-
f"DNSSEC ZSK generation failed for zone '{zone}': {zsk_result['logs']}"
387-
)
388+
raise PKIError(f"DNSSEC ZSK generation failed for zone '{zone}': {zsk_result['logs']}")
388389
zsk_name = zsk_result["logs"].strip()
389390

390391
return {

tests/integration/test_dns_add_zone_record_callers.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ async def test_phase_3_pki_inserts_ca_dns_record(context_with_zone_files):
2929
ca_ip="10.0.0.6",
3030
ca_dns="ca.platform.internal",
3131
bootstrap=AsyncMock(),
32+
setup_dnssec=AsyncMock(
33+
return_value={
34+
"zone": "internal",
35+
"ksk_name": "Kinternal.+013+00001",
36+
"zsk_name": "Kinternal.+013+00002",
37+
"volume": "netengines_dnssec_keys",
38+
"algorithm": "ECDSAP256SHA256",
39+
"ksk_lifetime_days": 365,
40+
"zsk_lifetime_days": 30,
41+
}
42+
),
3243
)
3344

3445
with (

tests/test_gateway_portal.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616
from netengine.errors import GatewayError
1717
from netengine.handlers.gateway_handler import GatewayHandler
1818
from netengine.handlers.gateway_portal_handler import GatewayPortalHandler
19-
from netengine.spec.models import CrossWorldConfig, CrossWorldPeer, GatewayPortal, RealInternetConfig, ServiceMirror
19+
from netengine.spec.models import (
20+
CrossWorldConfig,
21+
CrossWorldPeer,
22+
GatewayPortal,
23+
RealInternetConfig,
24+
ServiceMirror,
25+
)
2026
from netengine.spec.types import GatewayCrossWorldMode, GatewayRealInternetMode
2127

22-
2328
# ─────────────────────────────────────────────
2429
# Fixtures
2530
# ─────────────────────────────────────────────
@@ -143,6 +148,7 @@ async def test_mirrored_passes_config_to_rule_generator(self, gateway, mock_dock
143148
def capture_open(path, mode="r", **kw):
144149
if isinstance(path, str) and path.endswith(".nft") and "w" in mode:
145150
import io
151+
146152
buf = io.StringIO()
147153
buf.name = path
148154
written_content.append(buf)
@@ -151,12 +157,15 @@ def capture_open(path, mode="r", **kw):
151157

152158
with patch("tempfile.NamedTemporaryFile") as mock_tmp, patch("os.unlink"):
153159
import io
160+
154161
buf = io.StringIO()
155162
buf.name = "/tmp/fake.nft"
156-
mock_tmp.return_value.__enter__ = MagicMock(return_value=MagicMock(
157-
write=lambda s: written_content.append(s),
158-
name="/tmp/fake.nft",
159-
))
163+
mock_tmp.return_value.__enter__ = MagicMock(
164+
return_value=MagicMock(
165+
write=lambda s: written_content.append(s),
166+
name="/tmp/fake.nft",
167+
)
168+
)
160169
mock_tmp.return_value.__exit__ = MagicMock(return_value=False)
161170
await gateway.apply_internet_policy(config)
162171

@@ -339,6 +348,7 @@ def test_intermediate_ca_cert_defaults_to_none(self):
339348

340349
def test_new_fields_survive_save_load_cycle(self, tmp_path, monkeypatch):
341350
import os
351+
342352
state_path = tmp_path / "state.json"
343353
monkeypatch.setenv("NETENGINE_STATE_FILE", str(state_path))
344354

tests/test_pki_features.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from netengine.handlers.pki_handler import PKIHandler
2121
from netengine.workers.pki_cert_rotation_worker import CertTypeRotationConfig
2222

23-
2423
# ─────────────────────────────────────────────
2524
# Fixtures
2625
# ─────────────────────────────────────────────
@@ -87,9 +86,7 @@ async def test_read_intermediate_uses_correct_path(self, pki_handler, mock_docke
8786
# _read_file_from_volume remaps /home/step → /data
8887
assert "intermediate_ca.crt" in " ".join(cmd)
8988

90-
async def test_bootstrap_stores_intermediate_cert_when_enabled(
91-
self, mock_docker, state
92-
):
89+
async def test_bootstrap_stores_intermediate_cert_when_enabled(self, mock_docker, state):
9390
spec = {
9491
"pki": {
9592
"acme": {"listen_ip": "10.0.0.6", "canonical_name": "ca.platform.internal"},
@@ -103,9 +100,15 @@ async def test_bootstrap_stores_intermediate_cert_when_enabled(
103100
def side_effect(**kwargs):
104101
cmd = kwargs.get("command", [])
105102
if "intermediate_ca.crt" in " ".join(cmd):
106-
return {"exit_code": 0, "logs": "-----BEGIN CERTIFICATE-----\nINTERMEDIATE\n-----END CERTIFICATE-----"}
103+
return {
104+
"exit_code": 0,
105+
"logs": "-----BEGIN CERTIFICATE-----\nINTERMEDIATE\n-----END CERTIFICATE-----",
106+
}
107107
if "ca.crt" in " ".join(cmd):
108-
return {"exit_code": 0, "logs": "-----BEGIN CERTIFICATE-----\nROOT\n-----END CERTIFICATE-----"}
108+
return {
109+
"exit_code": 0,
110+
"logs": "-----BEGIN CERTIFICATE-----\nROOT\n-----END CERTIFICATE-----",
111+
}
109112
if "password.txt" in " ".join(cmd) and cmd[0] == "cat":
110113
return {"exit_code": 0, "logs": "secret-password"}
111114
return {"exit_code": 0, "logs": ""}
@@ -178,9 +181,7 @@ def capture_write(**kwargs):
178181
return {"exit_code": 0, "logs": json.dumps(ca_config)}
179182
return {"exit_code": 0, "logs": ""}
180183

181-
mock_docker.run_container_one_off = AsyncMock(
182-
side_effect=lambda **kw: capture_write(**kw)
183-
)
184+
mock_docker.run_container_one_off = AsyncMock(side_effect=lambda **kw: capture_write(**kw))
184185

185186
with patch("tempfile.NamedTemporaryFile") as mock_tmp, patch("os.unlink"):
186187
mock_file = MagicMock()
@@ -220,7 +221,9 @@ async def test_setup_dnssec_returns_key_names(self, pki_handler, mock_docker):
220221
{"exit_code": 0, "logs": "Kinternal.+013+05678"},
221222
]
222223
)
223-
result = await pki_handler.setup_dnssec("internal", ksk_lifetime_days=365, zsk_lifetime_days=30)
224+
result = await pki_handler.setup_dnssec(
225+
"internal", ksk_lifetime_days=365, zsk_lifetime_days=30
226+
)
224227
assert result["zone"] == "internal"
225228
assert result["ksk_name"] == "Kinternal.+013+01234"
226229
assert result["zsk_name"] == "Kinternal.+013+05678"
@@ -262,6 +265,7 @@ async def test_setup_dnssec_raises_on_zsk_failure(self, pki_handler, mock_docker
262265

263266
async def test_pki_flag_reads_from_pydantic_model(self):
264267
from unittest.mock import MagicMock
268+
265269
spec = MagicMock()
266270
spec.pki.dnssec_enabled = True
267271
handler = PKIHandler(MagicMock(), RuntimeState(), spec)
@@ -331,9 +335,9 @@ def test_extra_cert_types_from_overrides_are_included(self):
331335
assert "mail" in types
332336

333337
def test_override_values_are_applied_to_cert_type(self):
334-
ctx, spec = self._make_context({
335-
"app": {"rotation_interval_hours": 6, "expiry_warning_days": 7}
336-
})
338+
ctx, spec = self._make_context(
339+
{"app": {"rotation_interval_hours": 6, "expiry_warning_days": 7}}
340+
)
337341
configs = self._run_and_capture(ctx, spec, PKIPhaseHandler())
338342
app_cfg = next(c for c in configs if c.cert_type == "app")
339343
assert app_cfg.rotation_interval_hours == 6

0 commit comments

Comments
 (0)