Skip to main content

Crate floating_ip

Crate floating_ip 

Source
Expand description

Provider-abstracted floating/reserved-IP mobility and ingress failover (R594-F5, R859-F2).

FloatingIpProvider is the domain-level trait each vendor adapter implements; reconcile_assignment is the shared idempotent + zone-checked core all of them run through, so the “no-op when already assigned” / “reject a cross-zone move” behaviour is written and tested exactly once instead of once per vendor. plan_ingress_owner_effect is the pure decision layer above them: given a raft ingress_owner observation, what should public ingress do?

§Why this is its own crate

It was cloud::provider::floating_ip until 2026-09-08. R859-F2 landed plan_ingress_owner_effect with no production caller, because the caller belongs in yubaba’s scheduler tick and a runtime yubaba -> cloud dependency was not a courier’s call to make: cloud/Cargo.toml’s yah-local-driver comment records R374-F3 carving that crate out of cloud specifically to avoid such an edge, and taking it here would pull velveteen, velveteen-exec, yah-hetzner, yah-mesofact-bundle and yah-almanac into the release daemon shipped to every fleet node. The operator’s answer (2026-09-08) was to repeat R374-F3’s move rather than reverse it — hence this crate, which both cloud and yubaba depend on and neither owns.

So the dependency budget here is load-bearing, not tidiness: anyhow and async-trait, and nothing else, forever. A reqwest or a serde in this manifest ships to every node in the fleet.

§What is above this crate, and where

Two consumers, and this crate depends on neither:

  • yah-floating-ip-adapters — the Hetzner/OVH/Vultr HTTP clients that implement FloatingIpProvider. They were in cloud until R859-F3 moved them one layer down so yubaba’s ingress effector could actually issue a reassign rather than only decide on one. That crate carries the reqwest this one refuses to.
  • yah-cloud — the floating_ip.* envoy verb layer (cloud::provider::floating_ip_envoy) and the credentialed constructor cloud::provider::floating_ip::floating_ip_provider_for, which resolves vault slots through fob. Neither an envoy catalog nor a credential vault belongs on a fleet node, so neither moved.

This crate holds the seam, the shared core, and the decision logic.

§The machine facts this layer needs

FloatingIpMachine is a five-field value, not cloud’s MachineConfig. That is what makes the crate free of cloud: the adapters only ever read name, location, region, provider and ingress_floating_ip off a machine, so those five fields are the whole of the contract. cloud converts at the boundary (impl From<&MachineConfig> for FloatingIpMachine) and yubaba can build one from whatever it knows about a node without being able to construct a MachineConfig at all — which it cannot, since a fleet node has no .yah/infra/machines/ tree.

This mirrors, at the sovereign-ingress tier, the “external identity follows placement” property R591 names for Headscale via a Cloudflare Tunnel.

Structs§

FloatingIpAssignOutcome
Outcome of reconcile_assignment / on_ingress_owner_changed.
FloatingIpMachine
The machine facts floating-IP mobility actually needs — the whole contract between this crate and whatever declares machines.
FloatingIpState
Current provider-side state of a floating/reserved IP.
FloatingIpTarget
A resolved reassign target: provider-native attach id + the mobility zone it lives in.

Enums§

IngressOwnerEffect
What should happen to public ingress, given an ingress_owner observation.
OwnerLiveness
What a TransitionTracker-style hysteresis says about one machine, crossed into this crate as plain data.
QuorumHealth
Live consensus health, crossed into this crate as plain data.

Constants§

FLOATING_IP_PROVIDERS
Which providers ship a FloatingIpProvider adapter, and the credential each one authenticates with — (provider id, vault slot, env fallback).

Traits§

FloatingIpProvider
One provider’s floating/reserved-IP transport + mobility policy.

Functions§

on_ingress_owner_changed
Callable entry point: react to the raft ingress_owner seam naming machine as the box that now owns public ingress, by commanding ip_id to follow it.
plan_ingress_owner_effect
Decide what public ingress should do about an ingress_owner observation — pure, so the decision is testable as arithmetic and the I/O is somebody else’s problem.
provider_has_floating_ip_adapter
Does provider have a floating-IP adapter at all?
reconcile_assignment
Idempotent, zone-checked core shared by every provider adapter and by on_ingress_owner_changed.
resolve_ingress_owner
Resolve an ingress_owner string to the machine it names.
supported_floating_ip_providers
The provider ids that ship an adapter, for an error message that names what is supported rather than only what is not.