Skip to main content

OverlayManager

Struct OverlayManager 

Source
pub struct OverlayManager { /* private fields */ }
Expand description

Manages overlay networks for a deployment by delegating all mechanics to the zlayer-overlayd daemon.

This struct holds only cluster-brain / cached state; the actual overlay machinery lives in overlayd and is reached through OverlayManager::client.

Implementations§

Source§

impl OverlayManager

Source

pub async fn new( deployment: String, instance_id: String, ) -> Result<Self, AgentError>

Create a new overlay manager for a deployment (legacy single-node path).

Uses the default cluster /16. Prefer OverlayManager::with_slice for cluster deployments. The overlayd IPC client is connected lazily on first use (via the socket under the system-default data dir).

§Errors

Infallible today; the Result is preserved for ABI parity with callers.

§Panics

Panics only if the compile-time-constant default CIDR 10.200.0.0/16 fails to parse (impossible).

Source

pub fn with_slice( deployment: String, cluster_cidr: IpNetwork, slice_cidr: IpNetwork, port: u16, instance_id: String, ) -> Self

Create an OverlayManager bound to a per-node slice.

slice_cidr is the per-node slice owned by this node; cluster_cidr is the full cluster CIDR. Both are forwarded to overlayd in SetupGlobalOverlay.

Source

pub fn with_overlay_port(self, port: u16) -> Self

Set the WireGuard listen port for the overlay network.

Source

pub fn with_nat_config(self, nat: NatConfig) -> Self

Set the NAT traversal configuration. overlayd owns the live NAT orchestrator; this records the toggle so SetupGlobalOverlay can carry nat_enabled and the daemon can decide whether to drive NatTick.

Source

pub fn with_relay_credential(self, credential: impl Into<String>) -> Self

Set the cluster-shared credential the built-in relay server derives its auth key from. Folded into NatConfigSpec.relay_server.auth_credential when SetupGlobalOverlay forwards the NAT config to overlayd, so every node’s relay client derives the same BLAKE2b key. An empty / whitespace credential is ignored (treated as “none supplied”).

Source

pub fn with_uapi_sock_dir(self, dir: impl Into<PathBuf>) -> Self

Override the WireGuard UAPI socket directory. Retained for API parity; overlayd owns the real transport’s socket directory.

Source

pub fn with_data_dir(self, dir: impl Into<PathBuf>) -> Self

Override the data directory used to resolve the overlayd IPC socket.

Source

pub fn with_local_node_id(self, node_id: u64) -> Self

Set the local raft node id (builder-style).

Source

pub fn with_host_adapter_mandatory(self, mandatory: bool) -> Self

Mark the node’s host overlay adapter (utun) as MANDATORY: a bringup failure becomes a hard error instead of a silent degrade. Set by the daemon for host-shared macOS runtimes where the utun is the data path.

Source

pub fn set_local_node_id(&mut self, node_id: u64)

Post-construction setter for the local raft node id. Forwards SetLocalNodeId to overlayd best-effort.

Source

pub async fn set_local_wg_pubkey(&self, pubkey: String)

Record this node’s cluster WireGuard public key (base64) and forward it to overlayd so service subnets can be added to the cluster transport’s local AllowedIPs.

Source

pub async fn service_count(&self) -> usize

Returns the number of services currently registered (cached Status).

Source

pub fn nat_enabled(&self) -> bool

Returns whether NAT traversal is enabled for this manager.

Source

pub fn nat_config(&self) -> Option<NatConfig>

Returns a clone of the configured NatConfig, or None.

Source

pub async fn start_nat_traversal(&self) -> Result<bool, AgentError>

Bootstrap NAT traversal. overlayd starts NAT lazily on its first NatTick, so this is a thin shim that reports whether NAT is enabled.

§Errors

Infallible today; preserved for ABI parity.

Source

pub async fn nat_maintenance_tick(&self) -> Result<(), AgentError>

Run one NAT-traversal maintenance tick by forwarding NatTick to overlayd.

§Errors

Returns an error when overlayd reports a NAT refresh failure.

Source

pub async fn nat_status_snapshot(&self) -> NatStatusSnapshot

Snapshot the current NAT traversal state for API consumers by asking overlayd (which owns the live orchestrator) over the NatStatus IPC.

Converts the wire NatStatusWire into the NatStatusSnapshot/NatPeerSnapshot the API layer maps. Returns an empty snapshot when NAT is disabled or overlayd is unreachable — callers surface that as “NAT disabled / no data” rather than an error.

Source

pub fn set_dns_config( &mut self, addr: Option<SocketAddr>, domain: Option<String>, )

Record the overlay DNS server address and zone domain (cached locally; forwarded to overlayd on each container attach).

Source

pub fn with_dns_config( self, addr: Option<SocketAddr>, domain: Option<String>, ) -> Self

Builder-style variant of OverlayManager::set_dns_config.

Source

pub fn dns_server_addr(&self) -> Option<SocketAddr>

Returns the overlay DNS server address if configured.

Source

pub fn dns_domain(&self) -> Option<&str>

Returns the overlay DNS zone domain, if configured.

Source

pub async fn setup_global_overlay(&mut self) -> Result<(), AgentError>

Setup the global overlay network by delegating to overlayd.

Forwards the local node id and wg pubkey first (so overlayd has the cluster-brain context), then issues SetupGlobalOverlay and caches the returned interface name plus the node IP / CIDRs reported by Status.

§Errors

Returns an error if overlayd fails to bring up the overlay.

Source

pub async fn setup_service_overlay( &self, service_name: &str, mode: OverlayMode, ) -> Result<ServiceOverlayInfo, AgentError>

Set up the per-service overlay segment by delegating to overlayd.

Returns a [ServiceOverlayInfo] describing the segment. The container-attach handle (bridge name on Linux, interface elsewhere) is info.name. In Dedicated mode the wg_public_key/wg_port/ overlay_ip/subnet fields carry the per-service WireGuard transport’s identity so the deploy path can publish it to Raft and mesh with the other hosting nodes; in Shared mode those fields are None.

mode is the service’s resolved [OverlayMode], read from its spec at the deploy call site. In Shared mode overlayd attaches the service to the cluster transport via a per-node bridge; in Dedicated mode it stands up a per-service WireGuard transport with its own crypto context and reports its identity via OverlaydResponse::ServiceOverlay.

§Errors

Returns an error if overlayd fails to create the segment.

Source

pub async fn attach_container( &self, container_pid: u32, service_name: &str, join_global: bool, ephemeral: bool, isolation_network: Option<String>, dns_domain_override: Option<String>, ) -> Result<IpAddr, AgentError>

Add a container to the appropriate overlay networks by delegating to overlayd (AttachContainer with a LinuxPid handle).

§Errors

Returns an error if overlayd cannot attach the container.

Source

pub async fn attach_container_guest( &self, id: &str, service_name: &str, join_global: bool, isolation_network: Option<String>, dns_domain_override: Option<String>, ) -> Result<GuestOverlayConfig, AgentError>

Attach a guest-managed container (a VM with no host netns/PID) to the overlay by asking overlayd to allocate the overlay identity (keypair + address + the current peer set) and register the generated public key in the mesh. The caller ships the returned [GuestOverlayConfig] into the guest (over vsock) where it brings up its own WireGuard device.

id is the opaque container id used to scope the allocation so a later detach_container_guest can release the address + remove the peer.

§Errors

Returns an error if overlayd cannot allocate/register the guest.

Source

pub async fn detach_container_guest(&self, id: &str) -> Result<(), AgentError>

Detach a guest-managed container: release its overlay IP and remove its registered mesh peer.

§Errors

Returns an error if overlayd cannot detach the container.

Source

pub async fn write_scoped_resolver( &self, zone: &str, node_ip: IpAddr, port: Option<u16>, ) -> Result<(), AgentError>

Ask the ROOT overlayd to write a macOS /etc/resolver/<zone> scoped resolver pointing at this node’s overlay DNS (privileged path the rootless daemon cannot perform itself).

§Errors

Returns an error if overlayd cannot write the resolver file.

Source

pub async fn remove_scoped_resolver(&self, zone: &str) -> Result<(), AgentError>

Ask the ROOT overlayd to remove a macOS /etc/resolver/<zone> scoped resolver file.

§Errors

Returns an error if overlayd cannot remove the resolver file.

Source

pub async fn attach_container_host_shared( &self, container_id: &str, service_name: &str, ephemeral: bool, isolation_network: Option<String>, dns_domain_override: Option<String>, ) -> Result<IpAddr, AgentError>

Attach a macOS host-shared / VM container (Seatbelt, native-VZ, libkrun) to the overlay as a FIRST-CLASS member: overlayd allocates a distinct overlay /32 from the node slice, adds it as a utun alias so it is locally deliverable, and applies isolation membership. Returns the allocated overlay IP (the caller surfaces it for DNS + zlayer ps). NEVER the node IP. The caller then forwards <overlay_ip>:port to the container’s local delivery address.

§Errors

Returns an error if overlayd cannot allocate/register the container.

Source

pub async fn detach_container_host_shared( &self, container_id: &str, ) -> Result<(), AgentError>

Detach a macOS host-shared / VM container: release its overlay IP and remove its utun alias + isolation membership.

§Errors

Returns an error if overlayd cannot detach the container.

Source

pub async fn detach_container(&self, pid: u32) -> Result<(), AgentError>

Release the overlay resources held by a Linux container by delegating to overlayd (DetachContainer with a LinuxPid handle).

§Errors

Returns an error if overlayd reports a detach failure.

Source

pub async fn prune_orphan_bridges( &self, live_bridge_names: Vec<String>, ) -> Vec<String>

Reclaim orphaned per-service host bridges (and stale device veths) that no live deployment still owns, by delegating to overlayd. live_bridge_names is the full set of zl-…-b bridge names every currently-restored service SHOULD own (computed by the daemon from storage via OverlayManager::service_bridge_name); overlayd deletes every matching zl-…-b/-d link NOT in that set and releases its subnet/AllowedIPs.

Best-effort: a failure is logged, never propagated. Returns the names overlayd actually reclaimed (empty on failure or off Linux).

Source

pub fn service_bridge_name(&self, service: &str) -> String

Deterministic per-service bridge name for service, identical by construction to the name overlayd creates server-side (make_interface_name(&[deployment, instance_id, service], "b")). The daemon uses this to compute the live-bridge set it hands OverlayManager::prune_orphan_bridges.

Source

pub async fn teardown_service_overlay(&self, service_name: &str)

Tear down the per-service overlay segment for service_name.

Source

pub async fn cleanup(&mut self) -> Result<(), AgentError>

Cleanup all overlay networks (tears down the global overlay in overlayd).

§Errors

Returns an error if overlayd reports a teardown failure.

Source

pub fn node_ip(&self) -> Option<IpAddr>

Returns this node’s IP on the global overlay network (cached).

Source

pub fn deployment(&self) -> &str

Returns the deployment name this overlay manager was created for.

Source

pub fn global_interface(&self) -> Option<&str>

Returns the global overlay interface name (cached).

Source

pub fn overlay_port(&self) -> u16

Returns the WireGuard listen port for the overlay network.

Source

pub fn has_global_transport(&self) -> bool

Returns true if the global overlay transport is active (cached: an interface name has been recorded).

Source

pub async fn service_bridge_count(&self) -> usize

Returns the number of per-service overlay bridges currently active.

Source

pub async fn add_global_peer(&self, peer: &PeerInfo) -> Result<(), AgentError>

Add a peer to the live global overlay transport by delegating to overlayd.

The parameter type is preserved (&zlayer_overlay::PeerInfo) so the one caller (zlayer-api’s internal add-peer handler) compiles unchanged; the shim converts it to a wire-safe PeerSpec.

§Errors

Returns an error if overlayd rejects the peer (e.g. overlay not yet up).

Source

pub async fn add_global_peer_with_candidates( &self, peer: &PeerInfo, candidates: Vec<NatCandidateWire>, ) -> Result<(), AgentError>

Add a global-overlay peer along with the NAT candidates it advertised at join time. overlayd records the candidates and, on its next NAT tick, hole-punches / relays toward the peer when its direct endpoint does not establish a WireGuard handshake. The candidate-free OverlayManager::add_global_peer is the back-compat thin wrapper.

§Errors

Returns an error if overlayd rejects the peer (e.g. overlay not yet up).

Source

pub async fn add_service_peer( &self, service: &str, peer: &PeerInfo, subnet: &str, ) -> Result<(), AgentError>

Add a peer to a service’s dedicated per-service overlay transport.

Analogous to OverlayManager::add_global_peer but scoped to service’s [OverlayMode::Dedicated] device: first the peer itself (AddPeer with scope: Service), then the service subnet plumbed into that peer’s AllowedIPs (AddAllowedIp with the same scope).

§Errors

Returns an error if overlayd rejects the peer or the allowed-IP add (e.g. the service’s dedicated transport is not yet up).

Source

pub async fn remove_service_peer( &self, service: &str, pubkey: &str, ) -> Result<(), AgentError>

Remove a peer (by base64 public key) from a service’s dedicated per-service overlay transport.

§Errors

Returns an error if overlayd reports the removal failed.

Source

pub fn overlay_cidr(&self) -> String

Returns the CIDR string for the overlay IP allocator (cached cluster CIDR).

Source

pub fn slice_cidr(&self) -> Option<IpNetwork>

Returns the per-node slice CIDR this manager was built with, or None.

Source

pub fn cluster_cidr(&self) -> Option<IpNetwork>

Returns the full cluster CIDR, if known.

Source

pub async fn persist_ipam_state(&self, _path: &Path) -> Result<(), AgentError>

Persist the IPAM allocator state. overlayd owns IPAM; this is a no-op retained for ABI parity with callers.

§Errors

Infallible today.

Source

pub async fn restore_ipam_state( &mut self, _path: &Path, ) -> Result<(), AgentError>

Restore IPAM allocator state. overlayd owns IPAM; this is a no-op retained for ABI parity with callers.

§Errors

Infallible today.

Source

pub fn ip_alloc_stats(&self) -> (u64, IpAddr)

Returns IP allocation statistics: (allocated_count, base_addr).

overlayd owns IPAM and does not surface allocation counters over IPC, so this reports (0, base) derived from the cached cluster CIDR.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> OptionalSend for T
where T: Send + ?Sized,

Source§

impl<T> OptionalSync for T
where T: Sync + ?Sized,

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ServiceExt for T

Source§

fn propagate_header(self, header: HeaderName) -> PropagateHeader<Self>
where Self: Sized,

Propagate a header from the request to the response. Read more
Source§

fn add_extension<T>(self, value: T) -> AddExtension<Self, T>
where Self: Sized,

Add some shareable value to request extensions. Read more
Source§

fn map_request_body<F>(self, f: F) -> MapRequestBody<Self, F>
where Self: Sized,

Apply a transformation to the request body. Read more
Source§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Apply a transformation to the response body. Read more
Source§

fn compression(self) -> Compression<Self>
where Self: Sized,

Compresses response bodies. Read more
Source§

fn decompression(self) -> Decompression<Self>
where Self: Sized,

Decompress response bodies. Read more
Source§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
Source§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
Source§

fn follow_redirects(self) -> FollowRedirect<Self>
where Self: Sized,

Follow redirect resposes using the Standard policy. Read more
Source§

fn sensitive_headers( self, headers: impl IntoIterator<Item = HeaderName>, ) -> SetSensitiveRequestHeaders<SetSensitiveResponseHeaders<Self>>
where Self: Sized,

Mark headers as sensitive on both requests and responses. Read more
Source§

fn sensitive_request_headers( self, headers: impl IntoIterator<Item = HeaderName>, ) -> SetSensitiveRequestHeaders<Self>
where Self: Sized,

Mark headers as sensitive on requests. Read more
Source§

fn sensitive_response_headers( self, headers: impl IntoIterator<Item = HeaderName>, ) -> SetSensitiveResponseHeaders<Self>
where Self: Sized,

Mark headers as sensitive on responses. Read more
Source§

fn override_request_header<M>( self, header_name: HeaderName, make: M, ) -> SetRequestHeader<Self, M>
where Self: Sized,

Insert a header into the request. Read more
Source§

fn append_request_header<M>( self, header_name: HeaderName, make: M, ) -> SetRequestHeader<Self, M>
where Self: Sized,

Append a header into the request. Read more
Source§

fn insert_request_header_if_not_present<M>( self, header_name: HeaderName, make: M, ) -> SetRequestHeader<Self, M>
where Self: Sized,

Insert a header into the request, if the header is not already present. Read more
Source§

fn override_response_header<M>( self, header_name: HeaderName, make: M, ) -> SetResponseHeader<Self, M>
where Self: Sized,

Insert a header into the response. Read more
Source§

fn append_response_header<M>( self, header_name: HeaderName, make: M, ) -> SetResponseHeader<Self, M>
where Self: Sized,

Append a header into the response. Read more
Source§

fn insert_response_header_if_not_present<M>( self, header_name: HeaderName, make: M, ) -> SetResponseHeader<Self, M>
where Self: Sized,

Insert a header into the response, if the header is not already present. Read more
Source§

fn set_request_id<M>( self, header_name: HeaderName, make_request_id: M, ) -> SetRequestId<Self, M>
where Self: Sized, M: MakeRequestId,

Add request id header and extension. Read more
Source§

fn set_x_request_id<M>(self, make_request_id: M) -> SetRequestId<Self, M>
where Self: Sized, M: MakeRequestId,

Add request id header and extension, using x-request-id as the header name. Read more
Source§

fn propagate_request_id( self, header_name: HeaderName, ) -> PropagateRequestId<Self>
where Self: Sized,

Propgate request ids from requests to responses. Read more
Source§

fn propagate_x_request_id(self) -> PropagateRequestId<Self>
where Self: Sized,

Propgate request ids from requests to responses, using x-request-id as the header name. Read more
Source§

fn catch_panic(self) -> CatchPanic<Self, DefaultResponseForPanic>
where Self: Sized,

Catch panics and convert them into 500 Internal Server responses. Read more
Source§

fn request_body_limit(self, limit: usize) -> RequestBodyLimit<Self>
where Self: Sized,

Intercept requests with over-sized payloads and convert them into 413 Payload Too Large responses. Read more
Source§

fn trim_trailing_slash(self) -> NormalizePath<Self>
where Self: Sized,

Remove trailing slashes from paths. Read more
Source§

fn append_trailing_slash(self) -> NormalizePath<Self>
where Self: Sized,

Append trailing slash to paths. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more