From 4e617b8e9fe89560d8bcdf7db8af7db4abfcc953 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Mon, 2 Mar 2026 12:10:15 +0100 Subject: [PATCH] Add a command to create a CA with a local parent krillc. --- src/cli/options/mod.rs | 6 +++ src/cli/options/test.rs | 102 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/cli/options/test.rs diff --git a/src/cli/options/mod.rs b/src/cli/options/mod.rs index 32ab9654..10c6ec34 100644 --- a/src/cli/options/mod.rs +++ b/src/cli/options/mod.rs @@ -14,6 +14,7 @@ mod pubserver; pub mod repo; mod roas; mod server; +mod test; //------------ Content ------------------------------------------------------- @@ -154,6 +155,10 @@ pub enum Command { /// Manually trigger refresh/republish/resync for all CAs #[command(subcommand)] Bulk(bulk::Command), + + /// Complex commands for testing. + #[command(subcommand)] + Test(test::Command), } impl Command { @@ -177,6 +182,7 @@ impl Command { Self::Aspas(cmd) => cmd.run(client).await, Self::Pubserver(cmd) => cmd.run(client).await, Self::Bulk(cmd) => cmd.run(client).await, + Self::Test(cmd) => cmd.run(client).await, } } } diff --git a/src/cli/options/test.rs b/src/cli/options/test.rs new file mode 100644 index 00000000..235bc15b --- /dev/null +++ b/src/cli/options/test.rs @@ -0,0 +1,102 @@ +//! Commands performing more complex tasks useful during testing. + +use std::fmt; +use rpki::ca::idexchange::CaHandle; +use crate::api; +use crate::cli::client::KrillClient; +use crate::cli::report::Report; +use crate::commons::httpclient; +use super::children::ChildResources; + + +//------------ Command ------------------------------------------------------- + +#[derive(clap::Subcommand)] +pub enum Command { + /// Add a CA with a local parent and local publishing. + AddCa(AddCa), +} + +impl Command { + pub async fn run(self, client: &KrillClient) -> Report { + match self { + Self::AddCa(cmd) => cmd.run(client).await.into(), + } + } +} + + +//------------ AddCa --------------------------------------------------------- + +#[derive(clap::Args)] +pub struct AddCa { + /// Name of the CA to add. + #[arg(long, short)] + pub ca: CaHandle, + + /// Name of the parent CA. + #[arg(long, short)] + pub parent: CaHandle, + + #[command(flatten)] + resources: ChildResources, +} + +impl AddCa { + async fn run( + self, client: &KrillClient + ) -> Result { + // Create the CA + client.ca_add(self.ca.clone()).await?; + + // Add the CA as a publisher + let request = client.repo_request(&self.ca).await?; + client.publishers_add(request).await?; + + // Get a Repository Response for the CA. + let response = client.publisher_response( + &self.ca.convert() + ).await?; + + // Update the repo for the CA. + client.repo_update(&self.ca, response).await?; + + let request = client.child_request(&self.ca).await?; + let id_cert = request.validate()?; + let response = client.child_add( + &self.parent, self.ca.convert(), self.resources.into(), + id_cert + ).await?; + client.parent_add( + &self.ca, + api::admin::ParentCaReq { + handle: self.parent.convert(), response + } + ).await?; + Ok(api::status::Success) + } +} + + +//------------ Error --------------------------------------------------------- + +struct Error(Box); + +impl From for Error { + fn from(src: httpclient::Error) -> Self { + Self(Box::new(src)) + } +} + +impl From for Error { + fn from(src: rpki::ca::idexchange::Error) -> Self { + Self(Box::new(src)) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} +