pub struct CanopyClient { /* private fields */ }Expand description
HTTP client with auth configured for talking to a canopy server.
Tries two auth paths in order of preference:
- Tailscale: if the canopy tailnet endpoint is reachable, plain HTTPS works (auth is implicit via tailscale identity).
- mTLS: a fresh self-signed cert from the device key, short-lived
([
CERT_VALIDITY_DAYS]); for long-running daemons,Self::renewshould tick onCERT_RENEW_AFTERto swap in a fresh cert before expiry.
Self::refresh re-probes tailscale and swaps modes on reload.
Implementations§
Source§impl CanopyClient
impl CanopyClient
Sourcepub async fn new(
device_key_pem: Option<&str>,
make_builder: impl Fn() -> ClientBuilder + Send + Sync + 'static,
) -> Result<Option<Self>>
pub async fn new( device_key_pem: Option<&str>, make_builder: impl Fn() -> ClientBuilder + Send + Sync + 'static, ) -> Result<Option<Self>>
Build a canopy client against the default public (DEFAULT_CANOPY_URL)
and tailscale (TAILSCALE_URL) endpoints. Use Self::with_urls to
override them.
Probes the tailscale endpoint first; if reachable, uses it. Otherwise, if
a device key PEM is provided, builds an mTLS client. Returns Ok(None) if
neither path is available.
make_builder supplies the base reqwest::ClientBuilder — see
ClientBuilderFactory.
Sourcepub async fn with_urls(
base_url: Url,
tailscale_url: Url,
device_key_pem: Option<&str>,
make_builder: impl Fn() -> ClientBuilder + Send + Sync + 'static,
) -> Result<Option<Self>>
pub async fn with_urls( base_url: Url, tailscale_url: Url, device_key_pem: Option<&str>, make_builder: impl Fn() -> ClientBuilder + Send + Sync + 'static, ) -> Result<Option<Self>>
Build a canopy client against explicit endpoints.
base_url is canopy’s public API URL (the registration’s api_url),
used on the mTLS path; tailscale_url is the tailnet endpoint used on
the tailscale path. Both are fixed for the client’s lifetime. See
Self::new for the other arguments and the default-endpoint form.
Sourcepub async fn is_tailscale(&self) -> bool
pub async fn is_tailscale(&self) -> bool
Returns true if the client is currently using the tailscale path.
Source§impl CanopyClient
impl CanopyClient
Sourcepub async fn artifacts(
&self,
version: &str,
artifact_type: &str,
platform: &str,
) -> Result<Artifact>
pub async fn artifacts( &self, version: &str, artifact_type: &str, platform: &str, ) -> Result<Artifact>
POST /artifacts/{version}/{artifact_type}/{platform}
Sourcepub async fn backup_capabilities(&self, body: &CapabilitiesArgs) -> Result<()>
pub async fn backup_capabilities(&self, body: &CapabilitiesArgs) -> Result<()>
POST /backup-capabilities
Sourcepub async fn backup_credentials(
&self,
body: &CredentialsArgs,
) -> Result<CredentialProcessOutput>
pub async fn backup_credentials( &self, body: &CredentialsArgs, ) -> Result<CredentialProcessOutput>
POST /backup-credentials
Sourcepub async fn backup_report(&self, body: &ReportArgs) -> Result<()>
pub async fn backup_report(&self, body: &ReportArgs) -> Result<()>
POST /backup-report
Sourcepub async fn backup_target(&self) -> Result<BackupTarget>
pub async fn backup_target(&self) -> Result<BackupTarget>
GET /backup-target
Sourcepub async fn bestool_snippets(&self) -> Result<Value>
pub async fn bestool_snippets(&self) -> Result<Value>
GET /bestool/snippets
Sourcepub async fn restore_capabilities(&self, body: &CapabilitiesArgs) -> Result<()>
pub async fn restore_capabilities(&self, body: &CapabilitiesArgs) -> Result<()>
POST /restore-capabilities
Sourcepub async fn restore_credentials(
&self,
body: &CredentialsArgs,
) -> Result<RestoreCredentials>
pub async fn restore_credentials( &self, body: &CredentialsArgs, ) -> Result<RestoreCredentials>
POST /restore-credentials
Sourcepub async fn restore_verification(&self, body: &VerificationArgs) -> Result<()>
pub async fn restore_verification(&self, body: &VerificationArgs) -> Result<()>
POST /restore-verification
Sourcepub async fn restore_worklist(&self) -> Result<Vec<WorklistEntry>>
pub async fn restore_worklist(&self) -> Result<Vec<WorklistEntry>>
GET /restore-worklist
Sourcepub async fn servers(&self) -> Result<Vec<PublicServer>>
pub async fn servers(&self) -> Result<Vec<PublicServer>>
GET /servers
Sourcepub async fn servers_register_begin(
&self,
body: &BeginArgs,
) -> Result<BeginResponse>
pub async fn servers_register_begin( &self, body: &BeginArgs, ) -> Result<BeginResponse>
POST /servers/register/begin
Sourcepub async fn servers_register_complete(
&self,
body: &CompleteArgs,
) -> Result<CompleteResponse>
pub async fn servers_register_complete( &self, body: &CompleteArgs, ) -> Result<CompleteResponse>
POST /servers/register/complete
Sourcepub async fn status(
&self,
server_id: &str,
body: &Value,
) -> Result<StatusResponse>
pub async fn status( &self, server_id: &str, body: &Value, ) -> Result<StatusResponse>
POST /status/{server_id}
Merged tags for the calling device’s server.
The device authenticates with its certificate; we resolve the (unique)
server backed by that device, then overlay the server’s tags onto the
group’s tags (server wins on key collision). For ungrouped servers,
returns just the server’s own tags.
On top of the stored tags we inject synthetic, read-only tags describing
the server under the reserved canopy: namespace: canopy:kind,
canopy:rank (when set), and canopy:group-id / canopy:group-name
(when grouped). Operator-set tags can’t use that prefix, so they never
collide. See [Server::tags_for_device].
- 401: no certificate / cert doesn’t match a known device.
- 412: device is registered but isn’t attached to a server yet.
- 409: device is somehow attached to multiple servers (shouldn’t
happen — the
servers.device_idunique index guarantees this can’t occur, but the handler still surfaces the case rather than silently picking one).
GET /tags
Sourcepub async fn get_versions(&self) -> Result<Vec<Version>>
pub async fn get_versions(&self) -> Result<Vec<Version>>
GET /versions
Sourcepub async fn versions_update_for(
&self,
version: &str,
) -> Result<Vec<ViewVersion>>
pub async fn versions_update_for( &self, version: &str, ) -> Result<Vec<ViewVersion>>
GET /versions/update-for/{version}
Sourcepub async fn delete_versions(&self, version: &str) -> Result<()>
pub async fn delete_versions(&self, version: &str) -> Result<()>
DELETE /versions/{version}
Sourcepub async fn post_versions(&self, version: &str) -> Result<Version>
pub async fn post_versions(&self, version: &str) -> Result<Version>
POST /versions/{version}
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for CanopyClient
impl !RefUnwindSafe for CanopyClient
impl !UnwindSafe for CanopyClient
impl Send for CanopyClient
impl Sync for CanopyClient
impl Unpin for CanopyClient
impl UnsafeUnpin for CanopyClient
Blanket Implementations§
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> 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 moreSource§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more