pub struct InnerDoorPlan {
pub service: String,
pub mounts: Vec<InnerDoorMount>,
}Expand description
A service’s inner door, as configuration — everything but the addresses.
Fields§
§service: StringService name, for error messages and the workload name.
mounts: Vec<InnerDoorMount>Mounts in declaration order. Precedence is PathRouter’s (longest
mount wins), not this vector’s, so the order is presentational.
Implementations§
Source§impl InnerDoorPlan
impl InnerDoorPlan
Sourcepub fn units(&self) -> Vec<DeployedUnit>
pub fn units(&self) -> Vec<DeployedUnit>
Every distinct unit this door proxies to, in a stable order. What a caller resolving addresses has to answer for.
Sourcepub fn routes_file(
&self,
address: impl Fn(&DeployedUnit) -> Option<String>,
) -> Result<String>
pub fn routes_file( &self, address: impl Fn(&DeployedUnit) -> Option<String>, ) -> Result<String>
Render the JSON passway reads, resolving each unit to its address.
address is placement-time knowledge — which node the unit landed on
and which port kamaji gave it — so it arrives as a closure rather than
as config. Returning None from it is refused rather than skipped: a
mount whose upstream could not be resolved would be dropped from the
table, and the door would then serve that path from whichever shorter
mount matched — the root, usually — which is a wrong answer wearing a
200.
Source§impl InnerDoorPlan
impl InnerDoorPlan
Sourcepub fn workload_name(&self) -> String
pub fn workload_name(&self) -> String
The workload name / mesh identity for this service’s inner door.
Sourcepub fn routes_path(&self) -> PathBuf
pub fn routes_path(&self) -> PathBuf
Where this door’s route table is materialized on the node.
Sourcepub fn listen_port(&self) -> u16
pub fn listen_port(&self) -> u16
This door’s loopback port — listen_port of the service name.
Sourcepub fn unit_ident(&self, unit: &DeployedUnit, bundle_ident: &str) -> String
pub fn unit_ident(&self, unit: &DeployedUnit, bundle_ident: &str) -> String
The mesh identity whose ready service record carries unit’s address.
The two arms come from different places on purpose, and neither is
derivable from the other. A bundle’s ident is a mirror fact —
BundleSlot::workload_name, which a slot may rename with name = "…" —
so it is handed in. A workload-tier component has no slot to rename it,
so its ident is derived (component_workload_ident).
Sourcepub fn resolve_addresses(
&self,
bundle_ident: &str,
lookup: impl Fn(&str) -> Option<String>,
) -> BTreeMap<DeployedUnit, String>
pub fn resolve_addresses( &self, bundle_ident: &str, lookup: impl Fn(&str) -> Option<String>, ) -> BTreeMap<DeployedUnit, String>
Resolve every unit to a host:port, given a way to look an address up
by mesh identity.
The step between units and the address closure
routes_file and workload
take: those two ask “where is this unit”, this answers it from a
discovery read. Split out rather than folded in so the identity mapping
stays testable without a fleet.
A unit with no answer is simply absent from the map — the refusal lives
in routes_file, which is the single place a missing address is
reported and which already explains why a dropped mount is worse than a
failed apply.
Sourcepub fn workload(
&self,
listen_port: u16,
address: impl Fn(&DeployedUnit) -> Option<String>,
) -> Result<Workload>
pub fn workload( &self, listen_port: u16, address: impl Fn(&DeployedUnit) -> Option<String>, ) -> Result<Workload>
Render the supervisable workload: a passway process serving this service’s mount table on loopback.
§Cleartext, and the invariant that makes it safe
PASSWAY_TLS_MODE=plaintext (operator call, 2026-09-09 — see
passway::tls::parse_listener_tls_mode for the full argument). The
short version: no CA issues for 127.0.0.1, so “TLS everywhere” here
means a self-signed leaf plus a way to switch OFF upstream certificate
verification on the public door — a real trust-boundary knob traded
for encrypting a hop that never leaves the loopback interface.
This function cannot violate that invariant even if listen_port is
wrong, because it binds 127.0.0.1 literally and passway refuses the
mode on anything else. The bind is not a parameter.
§Why listen_port is an argument
It is placement-time knowledge, exactly like the upstream addresses: which port is free is a property of the node, not of the config. The caller allocates and passes it, so this stays a pure function of (plan, port, addresses) and is testable without a node.
§The route table travels IN the spec
Not written beside it: WorkloadSpec::files makes the table and the
process that reads it one deploy rather than two, so a redeploy cannot
leave a door serving a stale table. Only kamaji’s native backend
materializes those; every other backend refuses the spec by name rather
than starting the door against a file that is not there.
§Why Workload::Container and not a new Workload variant
TenantPasswayWorkload is a typed variant, so the precedent for one
exists — but it earns that by carrying config kamaji itself must act on
(a domain to match, a PEM pair to re-read on every cold start, an idle
TTL to reap against). An inner door carries none of it: its entire
configuration is an argv, three env vars and one file, all of which
WorkloadSpec already expresses. A variant would buy nothing but
exhaustive-match churn in peer-owned kamaji-proto, which is the trade
R572-F1 already made and recorded.
Trait Implementations§
Source§impl Clone for InnerDoorPlan
impl Clone for InnerDoorPlan
Source§impl Debug for InnerDoorPlan
impl Debug for InnerDoorPlan
impl Eq for InnerDoorPlan
Source§impl PartialEq for InnerDoorPlan
impl PartialEq for InnerDoorPlan
impl StructuralPartialEq for InnerDoorPlan
Auto Trait Implementations§
impl Freeze for InnerDoorPlan
impl RefUnwindSafe for InnerDoorPlan
impl Send for InnerDoorPlan
impl Sync for InnerDoorPlan
impl Unpin for InnerDoorPlan
impl UnsafeUnpin for InnerDoorPlan
impl UnwindSafe for InnerDoorPlan
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<K, Q> Equivalent<Q> for K
impl<K, Q> Equivalent<Q> for K
Source§fn equivalent(&self, key: &Q) -> bool
fn equivalent(&self, key: &Q) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
impl<T> Fruit for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more