Skip to main content

ControlPlane

Struct ControlPlane 

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

Owns the runtime + registry + card-source ports and drives the deploy, undeploy, and recovery use-cases across them.

Implementations§

Source§

impl ControlPlane

Source

pub fn new( runtime: Arc<dyn AgentRuntime>, registry: Arc<dyn AgentRegistry>, cards: Arc<dyn CardSource>, ) -> Self

Assemble a control plane over concrete adapters.

cards reads a running agent’s published card; it is required rather than optional because recover needs it to put adopted agents back into discovery, and a control plane that silently skipped that step would come back from a restart supervising agents nobody can find.

The env allowlist is deny-all until set with with_allowed_env.

Source

pub fn with_allowed_env(self, allowed: EnvAllowlist) -> Self

Permit submitted configs to reference these host environment variables.

Give the runtime adapter the same allowlist at the composition edge: this one vets what the API accepts, the runtime’s decides what actually crosses into the agent. One policy value, two enforcement points — the runtime stays safe even when something other than this service drives it.

Source

pub fn prepare( &self, raw_toml: &str, ) -> Result<PreparedDeploy, ControlPlaneError>

Vet and parse a submitted config, yielding the token deploy requires.

The allowlist is checked against the raw text first. Parsing expands ${VAR} against this process’s environment and distinguishes a set from an unset variable in its error, so a config naming a forbidden secret must be rejected before it can be used to probe what secrets exist here.

Source

pub async fn deploy( &self, prepared: PreparedDeploy, config_path: PathBuf, ) -> Result<DeployedAgent, ControlPlaneError>

Deploy a prepared agent: provision + start it in the runtime, then register its card so peers discover it. The runtime and registry ids coincide (both the slug of the agent name).

The caller materializes the config on disk — at the path prepared.id() told it to use — and passes that config_path (the file the runtime reads). So the service orchestrates ports + pure config without itself touching the filesystem (hex rule 9a), and the TOML is parsed exactly once, during prepare.

Deploying onto a port another agent already holds is PortInUse, not a started agent — see check_port_free.

Source

pub async fn recover( &self, ) -> Result<Recovered<DeployedAgent>, ControlPlaneError>

Re-adopt the agents this platform was already running, and put the ones that answer back into discovery.

Call once at startup, before serving. Both halves of the control plane’s knowledge are process state — the runtime’s instance table and the registry’s cards — so without this a restarted control plane reports an empty fleet while the agents are still up: GET /agents says nothing is deployed, DELETE says NotFound, peers stop resolving each other by skill, and a Terraform Read concludes the agents were destroyed out-of-band and recreates them on top of the running ones.

Registration is attempted only for agents the runtime reports Healthy — that state means the card probe succeeded, so anything else would be a fetch known in advance to fail. An agent that is adopted but not registered is still managed (it can be stopped, and it will be registered by a later recovery once it answers); it is simply not yet discoverable.

Idempotent: adoption re-inserts by id and registration upserts by card name, so calling this twice changes nothing.

Source

pub async fn undeploy(&self, id: &AgentId) -> Result<(), ControlPlaneError>

Stop an agent in the runtime and deregister it. Idempotent on the registry side (a missing entry is not an error).

Source

pub async fn status( &self, id: &AgentId, ) -> Result<RuntimeHealth, ControlPlaneError>

Report an agent’s current runtime health.

Source

pub async fn logs( &self, id: &AgentId, tail: Option<usize>, ) -> Result<Vec<String>, ControlPlaneError>

An agent’s captured output, oldest line first, limited to the last tail lines when given.

Health says an agent is Unhealthy; this is where the reason is. Whether it can be answered at all depends on the backend — see AgentRuntime::logs.

Source

pub async fn list( &self, filter: ListFilter, ) -> Result<Vec<DeployedAgent>, ControlPlaneError>

List deployed agents with their endpoint and health, ordered by id.

Sorted because a runtime’s own order is its map’s, i.e. arbitrary and unstable between calls — which makes a2a ps shuffle between runs and makes the API’s response undiffable for no reason.

Trait Implementations§

Source§

impl Clone for ControlPlane

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

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<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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
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> 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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