refactor(egress): EgressRoute inherits Route from egress_addon_core
test / unit (pull_request) Successful in 32s
test / unit (push) Successful in 31s
test / integration (push) Successful in 38s
test / integration (pull_request) Successful in 47s

EgressRoute now extends egress_addon_core.Route, which holds the four
wire-visible fields (host, path_allowlist, auth_scheme, token_env).
EgressRoute adds only the three host-side fields (token_ref, roles,
tls_passthrough) that are never serialised to the sidecar.

_route_to_yaml_fields is typed as Route -> dict, making the host→wire
boundary explicit: only fields declared on the base class cross into the
YAML the addon reads.
This commit was merged in pull request #121.
This commit is contained in:
2026-06-02 05:58:59 +00:00
parent f15721b424
commit 07c8593999
+11 -18
View File
@@ -30,6 +30,7 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from .egress_addon_core import Route
from .log import die from .log import die
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -54,21 +55,17 @@ EGRESS_ROUTES_IN_CONTAINER = "/etc/egress/routes.yaml"
@dataclass(frozen=True) @dataclass(frozen=True)
class EgressRoute: class EgressRoute(Route):
"""One resolved route on the egress sidecar. """Host-side extension of the addon's `Route`.
`host` matches the request's hostname (case-insensitive). The Inherits `host`, `path_allowlist`, `auth_scheme`, and `token_env`
optional `path_allowlist` constrains the URL path; empty tuple from `egress_addon_core.Route` — those are the fields that cross the
means no path-level filtering. The `auth_scheme` / `token_env` / YAML wire into the sidecar. The three fields below are host-only and
`token_ref` triple is the credential-injection config; empty are never serialised to the addon.
strings mean "no auth injection" (the manifest's nested `auth`
block was omitted).
`token_env` is the env-var slot inside the egress container `token_ref` is the host env var the CLI reads at launch and forwards
(e.g. `EGRESS_TOKEN_0`); `token_ref` is the host env var into the container's environ under `token_env`. Routes that share a
the CLI reads at launch and forwards into the container's environ `token_ref` coalesce to one `token_env` slot.
under `token_env`. Routes that share a `token_ref` coalesce to
one `token_env` slot.
`roles` carries the manifest route's role tuple (reserved for `roles` carries the manifest route's role tuple (reserved for
future use; always empty today). future use; always empty today).
@@ -79,10 +76,6 @@ class EgressRoute:
route set it (e.g. egress injects its own Bearer on that host route set it (e.g. egress injects its own Bearer on that host
after the agent boundary and pipelock's header DLP would block it).""" after the agent boundary and pipelock's header DLP would block it)."""
host: str
path_allowlist: tuple[str, ...] = ()
auth_scheme: str = ""
token_env: str = ""
token_ref: str = "" token_ref: str = ""
roles: tuple[str, ...] = () roles: tuple[str, ...] = ()
tls_passthrough: bool = False tls_passthrough: bool = False
@@ -223,7 +216,7 @@ def egress_token_env_map(
return out return out
def _route_to_yaml_fields(r: EgressRoute) -> dict: def _route_to_yaml_fields(r: Route) -> dict:
"""Return the addon-visible fields for one route. """Return the addon-visible fields for one route.
Single authoritative mapping between EgressRoute (host-side) and Single authoritative mapping between EgressRoute (host-side) and