Remove krillpubc - use 'pubserver' subcommand in krillc instead. (#527)

This commit is contained in:
Tim Bruijnzeels
2021-05-20 12:51:52 +02:00
parent 59eaac5624
commit ff1c7f74f6
7 changed files with 367 additions and 465 deletions
-41
View File
@@ -1,41 +0,0 @@
extern crate krill;
use krill::cli::options::KrillPubcOptions;
use krill::cli::report::ReportFormat;
use krill::cli::{Error, KrillPubdClient};
use krill::commons::util::httpclient;
#[tokio::main]
async fn main() {
match KrillPubcOptions::from_args() {
Ok(options) => {
let format = options.format;
match KrillPubdClient::report(options).await {
Ok(()) => {} //,
Err(e) => {
if format != ReportFormat::None {
match &e {
Error::HttpClientError(httpclient::Error::ErrorWithJson(_code, res)) => {
if format == ReportFormat::Json {
eprintln!("{}", e);
} else if let Some(delta_error) = res.delta_error() {
eprintln!("Delta rejected:\n\n{}", delta_error);
} else {
eprintln!("Error: {}", res.msg());
}
}
_ => {
eprintln!("{}", e);
}
}
}
::std::process::exit(1);
}
}
}
Err(e) => {
eprintln!("{}", e);
::std::process::exit(1);
}
}
}
+52 -77
View File
@@ -18,7 +18,7 @@ use crate::commons::util::{file, httpclient};
use crate::constants::KRILL_CLI_API_ENV;
use crate::daemon::config::Config;
use crate::{
cli::options::{BulkCaCommand, CaCommand, Command, KrillInitDetails, KrillPubcOptions, Options, PublishersCommand},
cli::options::{BulkCaCommand, CaCommand, Command, KrillInitDetails, Options, PubServerCommand},
commons::error::KrillIoError,
};
@@ -122,6 +122,7 @@ impl KrillClient {
Command::Info => client.info().await,
Command::Bulk(cmd) => client.bulk(cmd).await,
Command::CertAuth(cmd) => client.certauth(cmd).await,
Command::PubServer(cmd) => client.publishers(cmd).await,
Command::Init(details) => client.init_config(details),
#[cfg(feature = "multi-user")]
Command::User(cmd) => client.user(cmd),
@@ -397,6 +398,56 @@ impl KrillClient {
}
}
/// Processes the options, and returns a response ready for formatting.
/// Note that this function is public to help integration testing the API
/// and client.
pub async fn publishers(&self, command: PubServerCommand) -> Result<ApiResponse, Error> {
match command {
PubServerCommand::PublisherList => {
let list: PublisherList = get_json(&self.server, &self.token, "api/v1/pubd/publishers").await?;
Ok(ApiResponse::PublisherList(list))
}
PubServerCommand::StalePublishers(seconds) => {
let uri = format!("api/v1/pubd/stale/{}", seconds);
let stales = get_json(&self.server, &self.token, &uri).await?;
Ok(ApiResponse::PublisherList(stales))
}
PubServerCommand::RepositoryStats => {
let stats = get_json(&self.server, &self.token, "stats/repo").await?;
Ok(ApiResponse::RepoStats(stats))
}
PubServerCommand::RepositoryInit(uris) => {
let uri = "api/v1/pubd/init";
post_json(&self.server, &self.token, uri, uris).await?;
Ok(ApiResponse::Empty)
}
PubServerCommand::RepositoryClear => {
let uri = "api/v1/pubd/init";
delete(&self.server, &self.token, uri).await?;
Ok(ApiResponse::Empty)
}
PubServerCommand::AddPublisher(req) => {
let res = post_json_with_response(&self.server, &self.token, "api/v1/pubd/publishers", req).await?;
Ok(ApiResponse::Rfc8183RepositoryResponse(res))
}
PubServerCommand::RemovePublisher(handle) => {
let uri = format!("api/v1/pubd/publishers/{}", handle);
delete(&self.server, &self.token, &uri).await?;
Ok(ApiResponse::Empty)
}
PubServerCommand::ShowPublisher(handle) => {
let uri = format!("api/v1/pubd/publishers/{}", handle);
let details: PublisherDetails = get_json(&self.server, &self.token, &uri).await?;
Ok(ApiResponse::PublisherDetails(details))
}
PubServerCommand::RepositoryResponse(handle) => {
let uri = format!("api/v1/pubd/publishers/{}/response.json", handle);
let res = get_json(&self.server, &self.token, &uri).await?;
Ok(ApiResponse::Rfc8183RepositoryResponse(res))
}
}
}
fn init_config(&self, details: KrillInitDetails) -> Result<ApiResponse, Error> {
let defaults = include_str!("../../defaults/krill.conf");
let multi_add_on = include_str!("../../defaults/krill-multi-user.conf");
@@ -504,82 +555,6 @@ impl KrillClient {
}
}
//------------ KrillPubdClient -----------------------------------------------
pub struct KrillPubdClient;
impl KrillPubdClient {
/// Delegates the options to be processed, and reports the response
/// back to the user. Note that error reporting is handled by CLI.
pub async fn report(options: KrillPubcOptions) -> Result<(), Error> {
let format = options.format;
let res = Self::process(options).await?;
if let Some(string) = res.report(format)? {
println!("{}", string)
}
Ok(())
}
/// Processes the options, and returns a response ready for formatting.
/// Note that this function is public to help integration testing the API
/// and client.
pub async fn process(options: KrillPubcOptions) -> Result<ApiResponse, Error> {
let (server, token, _format, api, command) = options.unpack();
if api {
// passing the api option in the env, so that the call
// to the back-end will just print and exit.
env::set_var(KRILL_CLI_API_ENV, "1")
}
match command {
PublishersCommand::PublisherList => {
let list: PublisherList = get_json(&server, &token, "api/v1/pubd/publishers").await?;
Ok(ApiResponse::PublisherList(list))
}
PublishersCommand::StalePublishers(seconds) => {
let uri = format!("api/v1/pubd/stale/{}", seconds);
let stales = get_json(&server, &token, &uri).await?;
Ok(ApiResponse::PublisherList(stales))
}
PublishersCommand::RepositoryStats => {
let stats = get_json(&server, &token, "stats/repo").await?;
Ok(ApiResponse::RepoStats(stats))
}
PublishersCommand::RepositoryInit(uris) => {
let uri = "api/v1/pubd/init";
post_json(&server, &token, uri, uris).await?;
Ok(ApiResponse::Empty)
}
PublishersCommand::RepositoryClear => {
let uri = "api/v1/pubd/init";
delete(&server, &token, uri).await?;
Ok(ApiResponse::Empty)
}
PublishersCommand::AddPublisher(req) => {
let res = post_json_with_response(&server, &token, "api/v1/pubd/publishers", req).await?;
Ok(ApiResponse::Rfc8183RepositoryResponse(res))
}
PublishersCommand::RemovePublisher(handle) => {
let uri = format!("api/v1/pubd/publishers/{}", handle);
delete(&server, &token, &uri).await?;
Ok(ApiResponse::Empty)
}
PublishersCommand::ShowPublisher(handle) => {
let uri = format!("api/v1/pubd/publishers/{}", handle);
let details: PublisherDetails = get_json(&server, &token, &uri).await?;
Ok(ApiResponse::PublisherDetails(details))
}
PublishersCommand::RepositoryResponse(handle) => {
let uri = format!("api/v1/pubd/publishers/{}/response.json", handle);
let res = get_json(&server, &token, &uri).await?;
Ok(ApiResponse::Rfc8183RepositoryResponse(res))
}
}
}
}
//------------ Error ---------------------------------------------------------
#[derive(Debug)]
-1
View File
@@ -4,4 +4,3 @@ pub mod report;
mod client;
pub use self::client::Error;
pub use self::client::KrillClient;
pub use self::client::KrillPubdClient;
+293 -313
View File
@@ -957,6 +957,159 @@ impl Options {
app.subcommand(info)
}
fn make_publishers_list_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("list").about("List all publishers");
sub = Options::add_general_args(sub);
app.subcommand(sub)
}
fn make_publishers_stale_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("stale").about("List all publishers which have not published in a while");
sub = Options::add_general_args(sub);
sub = sub.arg(
Arg::with_name("seconds")
.value_name("seconds")
.long("seconds")
.help("The number of seconds since last publication")
.required(true),
);
app.subcommand(sub)
}
fn add_publisher_arg<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
app.arg(
Arg::with_name("publisher")
.value_name("handle")
.short("p")
.long("publisher")
.help("The handle (name) of the publisher")
.required(true),
)
}
fn add_rsync_base_arg<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
app.arg(
Arg::with_name("rsync")
.long("rsync")
.value_name("uri")
.help("Specify the base rsync URI for the repository, must end with '/'")
.required(true),
)
}
fn add_rrdp_base_uri_arg<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
app.arg(
Arg::with_name("rrdp")
.long("rrdp")
.value_name("uri")
.help(
"Specify the base https URI for the RRDP (excluding notification.xml), \
must \
end with '/'",
)
.required(true),
)
}
fn make_publishers_add_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("add").about("Add a publisher");
sub = Options::add_general_args(sub);
sub = sub
.arg(
Arg::with_name("request")
.value_name("file")
.long("request")
.short("r")
.help("The location of the RFC8183 Publisher Request XML file")
.required(true),
)
.arg(
Arg::with_name("publisher")
.value_name("handle")
.short("p")
.long("publisher")
.help("Override the publisher handle in the XML")
.required(false),
);
app.subcommand(sub)
}
fn make_publishers_remove_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("remove").about("Remove a publisher");
sub = Options::add_general_args(sub);
sub = Self::add_publisher_arg(sub);
app.subcommand(sub)
}
fn make_publishers_show_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("show").about("Show details for a publisher");
sub = Options::add_general_args(sub);
sub = Self::add_publisher_arg(sub);
app.subcommand(sub)
}
fn make_publishers_response_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("response").about("Show RFC8183 Repository Response XML");
sub = Options::add_general_args(sub);
sub = Self::add_publisher_arg(sub);
app.subcommand(sub)
}
fn make_publication_server_stats_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("stats").about("Show publication server stats");
sub = Options::add_general_args(sub);
app.subcommand(sub)
}
fn make_publication_server_init_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("init").about("Initialize publication server");
sub = Options::add_general_args(sub);
sub = Self::add_rsync_base_arg(sub);
sub = Self::add_rrdp_base_uri_arg(sub);
app.subcommand(sub)
}
fn make_publication_server_clear_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("clear").about("Clear the publication server so it can re-initialized");
sub = Options::add_general_args(sub);
app.subcommand(sub)
}
fn make_publication_server_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("server").about("Manage the Publication Server (init/stats)");
sub = Self::make_publication_server_stats_sc(sub);
sub = Self::make_publication_server_init_sc(sub);
sub = Self::make_publication_server_clear_sc(sub);
app.subcommand(sub)
}
fn make_publishers_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("publishers").about("Manage the publishers in your Publication Server");
sub = Self::make_publishers_list_sc(sub);
sub = Self::make_publishers_stale_sc(sub);
sub = Self::make_publishers_add_sc(sub);
sub = Self::make_publishers_remove_sc(sub);
sub = Self::make_publishers_show_sc(sub);
sub = Self::make_publishers_response_sc(sub);
app.subcommand(sub)
}
fn make_pubserver_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("pubserver")
.about("Manage your Publication Server (only needed if you run your own)");
sub = Self::make_publishers_sc(sub);
sub = Self::make_publication_server_sc(sub);
app.subcommand(sub)
}
fn make_matches<'a>() -> ArgMatches<'a> {
let mut app = App::new(KRILL_CLIENT_APP).version(KRILL_VERSION);
@@ -972,6 +1125,7 @@ impl Options {
app = Self::make_cas_routes_sc(app);
app = Self::make_cas_repo_sc(app);
app = Self::make_cas_issues_sc(app);
app = Self::make_pubserver_sc(app);
#[cfg(feature = "rta")]
{
@@ -1712,6 +1866,141 @@ impl Options {
Ok(Options::make(general_args, command))
}
fn parse_publisher_arg(matches: &ArgMatches) -> Result<PublisherHandle, Error> {
let publisher_str = matches.value_of("publisher").unwrap();
PublisherHandle::from_str(publisher_str).map_err(|_| Error::InvalidHandle)
}
fn parse_matches_publishers_list(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let command = Command::PubServer(PubServerCommand::PublisherList);
Ok(Options::make(general_args, command))
}
fn parse_matches_publishers_stale(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let seconds = i64::from_str(matches.value_of("seconds").unwrap()).map_err(|_| Error::InvalidSeconds)?;
let command = Command::PubServer(PubServerCommand::StalePublishers(seconds));
Ok(Options::make(general_args, command))
}
fn parse_matches_publishers_add(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let path = matches.value_of("request").unwrap();
let path = PathBuf::from(path);
let bytes = file::read(&path)?;
let mut req = rfc8183::PublisherRequest::validate(bytes.as_ref())?;
if let Some(publisher_str) = matches.value_of("publisher") {
let publisher = PublisherHandle::from_str(publisher_str).map_err(|_| Error::InvalidHandle)?;
let (tag, _, cert) = req.unpack();
req = rfc8183::PublisherRequest::new(tag, publisher, cert);
}
let command = Command::PubServer(PubServerCommand::AddPublisher(req));
Ok(Options::make(general_args, command))
}
fn parse_matches_publishers_remove(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let publisher = Self::parse_publisher_arg(matches)?;
let command = Command::PubServer(PubServerCommand::RemovePublisher(publisher));
Ok(Options::make(general_args, command))
}
fn parse_matches_publishers_show(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let publisher = Self::parse_publisher_arg(matches)?;
let command = Command::PubServer(PubServerCommand::ShowPublisher(publisher));
Ok(Options::make(general_args, command))
}
fn parse_matches_publishers_repo_response(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let publisher = Self::parse_publisher_arg(matches)?;
let command = Command::PubServer(PubServerCommand::RepositoryResponse(publisher));
Ok(Options::make(general_args, command))
}
fn parse_matches_publication_server_stats(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let command = Command::PubServer(PubServerCommand::RepositoryStats);
Ok(Options::make(general_args, command))
}
fn parse_matches_publication_server_init(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let rsync_str = matches.value_of("rsync").unwrap();
let rrdp_str = matches.value_of("rrdp").unwrap();
if !rsync_str.ends_with('/') {
return Err(Error::general("rsync base URI must end with '/'"));
}
if !rrdp_str.ends_with('/') {
return Err(Error::general("RRDP base URI must end with '/'"));
}
let rsync = uri::Rsync::from_str(rsync_str)
.map_err(|e| Error::GeneralArgumentError(format!("Invalid rsync URI: {}", e)))?;
let rrdp = uri::Https::from_str(rrdp_str)
.map_err(|e| Error::GeneralArgumentError(format!("Invalid RRDP URI: {}", e)))?;
let uris = PublicationServerUris::new(rrdp, rsync);
let command = Command::PubServer(PubServerCommand::RepositoryInit(uris));
Ok(Options::make(general_args, command))
}
fn parse_matches_publication_server_clear(matches: &ArgMatches) -> Result<Options, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let command = Command::PubServer(PubServerCommand::RepositoryClear);
Ok(Options::make(general_args, command))
}
fn parse_matches_publication_server(matches: &ArgMatches) -> Result<Options, Error> {
if let Some(m) = matches.subcommand_matches("stats") {
Self::parse_matches_publication_server_stats(m)
} else if let Some(m) = matches.subcommand_matches("init") {
Self::parse_matches_publication_server_init(m)
} else if let Some(m) = matches.subcommand_matches("clear") {
Self::parse_matches_publication_server_clear(m)
} else {
Err(Error::UnrecognizedSubCommand)
}
}
fn parse_matches_publishers(matches: &ArgMatches) -> Result<Options, Error> {
if let Some(m) = matches.subcommand_matches("list") {
Self::parse_matches_publishers_list(m)
} else if let Some(m) = matches.subcommand_matches("stale") {
Self::parse_matches_publishers_stale(m)
} else if let Some(m) = matches.subcommand_matches("add") {
Self::parse_matches_publishers_add(m)
} else if let Some(m) = matches.subcommand_matches("remove") {
Self::parse_matches_publishers_remove(m)
} else if let Some(m) = matches.subcommand_matches("show") {
Self::parse_matches_publishers_show(m)
} else if let Some(m) = matches.subcommand_matches("response") {
Self::parse_matches_publishers_repo_response(m)
} else {
Err(Error::UnrecognizedSubCommand)
}
}
fn parse_matches_pubserver(matches: &ArgMatches) -> Result<Options, Error> {
if let Some(m) = matches.subcommand_matches("publishers") {
Self::parse_matches_publishers(m)
} else if let Some(m) = matches.subcommand_matches("server") {
Self::parse_matches_publication_server(m)
} else {
Err(Error::UnrecognizedSubCommand)
}
}
fn parse_matches(matches: ArgMatches) -> Result<Options, Error> {
if let Some(m) = matches.subcommand_matches("config") {
Self::parse_matches_config(m)
@@ -1745,6 +2034,8 @@ impl Options {
Self::parse_matches_health(m)
} else if let Some(m) = matches.subcommand_matches("info") {
Self::parse_matches_info(m)
} else if let Some(m) = matches.subcommand_matches("pubserver") {
Self::parse_matches_pubserver(m)
} else {
Err(Error::UnrecognizedSubCommand)
}
@@ -1756,318 +2047,6 @@ impl Options {
}
}
/// This type holds all the necessary data to connect to a Krill daemon, and
/// authenticate, and perform a specific action.
pub struct KrillPubcOptions {
server: uri::Https,
token: Token,
pub format: ReportFormat,
api: bool,
command: PublishersCommand,
}
impl KrillPubcOptions {
fn make(general: GeneralArgs, command: PublishersCommand) -> Self {
KrillPubcOptions {
server: general.server,
token: general.token,
format: general.format,
api: general.api,
command,
}
}
pub fn new(server: uri::Https, token: Token, format: ReportFormat, api: bool, command: PublishersCommand) -> Self {
KrillPubcOptions {
server,
token,
format,
api,
command,
}
}
pub fn unpack(self) -> (uri::Https, Token, ReportFormat, bool, PublishersCommand) {
(self.server, self.token, self.format, self.api, self.command)
}
pub fn from_args() -> Result<KrillPubcOptions, Error> {
let matches = Self::make_matches();
Self::parse_matches(matches)
}
fn make_publishers_list_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("list").about("List all publishers");
sub = Options::add_general_args(sub);
app.subcommand(sub)
}
fn make_publishers_stale_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("stale").about("List all publishers which have not published in a while");
sub = Options::add_general_args(sub);
sub = sub.arg(
Arg::with_name("seconds")
.value_name("seconds")
.long("seconds")
.help("The number of seconds since last publication")
.required(true),
);
app.subcommand(sub)
}
fn add_publisher_arg<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
app.arg(
Arg::with_name("publisher")
.value_name("handle")
.short("p")
.long("publisher")
.help("The handle (name) of the publisher")
.required(true),
)
}
fn add_rsync_base_arg<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
app.arg(
Arg::with_name("rsync")
.long("rsync")
.value_name("uri")
.help("Specify the base rsync URI for the repository, must end with '/'")
.required(true),
)
}
fn add_rrdp_base_uri_arg<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
app.arg(
Arg::with_name("rrdp")
.long("rrdp")
.value_name("uri")
.help(
"Specify the base https URI for the RRDP (excluding notification.xml), \
must \
end with '/'",
)
.required(true),
)
}
fn make_publishers_add_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("add").about("Add a publisher");
sub = Options::add_general_args(sub);
sub = sub
.arg(
Arg::with_name("request")
.value_name("file")
.long("request")
.short("r")
.help("The location of the RFC8183 Publisher Request XML file")
.required(true),
)
.arg(
Arg::with_name("publisher")
.value_name("handle")
.short("p")
.long("publisher")
.help("Override the publisher handle in the XML")
.required(false),
);
app.subcommand(sub)
}
fn make_publishers_remove_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("remove").about("Remove a publisher");
sub = Options::add_general_args(sub);
sub = Self::add_publisher_arg(sub);
app.subcommand(sub)
}
fn make_publishers_show_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("show").about("Show details for a publisher");
sub = Options::add_general_args(sub);
sub = Self::add_publisher_arg(sub);
app.subcommand(sub)
}
fn make_publishers_response_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("response").about("Show RFC8183 Repository Response XML");
sub = Options::add_general_args(sub);
sub = Self::add_publisher_arg(sub);
app.subcommand(sub)
}
fn make_publication_server_stats_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("stats").about("Show publication server stats");
sub = Options::add_general_args(sub);
app.subcommand(sub)
}
fn make_publication_server_init_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("init").about("Initialize publication server");
sub = Options::add_general_args(sub);
sub = Self::add_rsync_base_arg(sub);
sub = Self::add_rrdp_base_uri_arg(sub);
app.subcommand(sub)
}
fn make_publication_server_clear_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("clear").about("Clear the publication server so it can re-initialized");
sub = Options::add_general_args(sub);
app.subcommand(sub)
}
fn make_publication_server_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
let mut sub = SubCommand::with_name("server").about("Manage the Publication Server (init/stats)");
sub = Self::make_publication_server_stats_sc(sub);
sub = Self::make_publication_server_init_sc(sub);
sub = Self::make_publication_server_clear_sc(sub);
app.subcommand(sub)
}
fn make_matches<'a>() -> ArgMatches<'a> {
let mut app = App::new(KRILL_PUBC_CLIENT_APP).version(KRILL_VERSION);
app = Self::make_publishers_list_sc(app);
app = Self::make_publishers_stale_sc(app);
app = Self::make_publishers_add_sc(app);
app = Self::make_publishers_remove_sc(app);
app = Self::make_publishers_show_sc(app);
app = Self::make_publishers_response_sc(app);
app = Self::make_publication_server_sc(app);
app.get_matches()
}
fn parse_publisher_arg(matches: &ArgMatches) -> Result<PublisherHandle, Error> {
let publisher_str = matches.value_of("publisher").unwrap();
PublisherHandle::from_str(publisher_str).map_err(|_| Error::InvalidHandle)
}
fn parse_matches_publishers_list(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let command = PublishersCommand::PublisherList;
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publishers_stale(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let seconds = i64::from_str(matches.value_of("seconds").unwrap()).map_err(|_| Error::InvalidSeconds)?;
let command = PublishersCommand::StalePublishers(seconds);
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publishers_add(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let path = matches.value_of("request").unwrap();
let path = PathBuf::from(path);
let bytes = file::read(&path)?;
let mut req = rfc8183::PublisherRequest::validate(bytes.as_ref())?;
if let Some(publisher_str) = matches.value_of("publisher") {
let publisher = PublisherHandle::from_str(publisher_str).map_err(|_| Error::InvalidHandle)?;
let (tag, _, cert) = req.unpack();
req = rfc8183::PublisherRequest::new(tag, publisher, cert);
}
let command = PublishersCommand::AddPublisher(req);
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publishers_remove(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let publisher = Self::parse_publisher_arg(matches)?;
let command = PublishersCommand::RemovePublisher(publisher);
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publishers_show(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let publisher = Self::parse_publisher_arg(matches)?;
let command = PublishersCommand::ShowPublisher(publisher);
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publishers_repo_response(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let publisher = Self::parse_publisher_arg(matches)?;
let command = PublishersCommand::RepositoryResponse(publisher);
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publication_server_stats(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let command = PublishersCommand::RepositoryStats;
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publication_server_init(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let rsync_str = matches.value_of("rsync").unwrap();
let rrdp_str = matches.value_of("rrdp").unwrap();
if !rsync_str.ends_with('/') {
return Err(Error::general("rsync base URI must end with '/'"));
}
if !rrdp_str.ends_with('/') {
return Err(Error::general("RRDP base URI must end with '/'"));
}
let rsync = uri::Rsync::from_str(rsync_str)
.map_err(|e| Error::GeneralArgumentError(format!("Invalid rsync URI: {}", e)))?;
let rrdp = uri::Https::from_str(rrdp_str)
.map_err(|e| Error::GeneralArgumentError(format!("Invalid RRDP URI: {}", e)))?;
let uris = PublicationServerUris::new(rrdp, rsync);
let command = PublishersCommand::RepositoryInit(uris);
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publication_server_clear(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
let general_args = GeneralArgs::from_matches(matches)?;
let command = PublishersCommand::RepositoryClear;
Ok(KrillPubcOptions::make(general_args, command))
}
fn parse_matches_publication_server(matches: &ArgMatches) -> Result<KrillPubcOptions, Error> {
if let Some(m) = matches.subcommand_matches("stats") {
Self::parse_matches_publication_server_stats(m)
} else if let Some(m) = matches.subcommand_matches("init") {
Self::parse_matches_publication_server_init(m)
} else if let Some(m) = matches.subcommand_matches("clear") {
Self::parse_matches_publication_server_clear(m)
} else {
Err(Error::UnrecognizedSubCommand)
}
}
fn parse_matches(matches: ArgMatches) -> Result<KrillPubcOptions, Error> {
if let Some(m) = matches.subcommand_matches("list") {
Self::parse_matches_publishers_list(m)
} else if let Some(m) = matches.subcommand_matches("stale") {
Self::parse_matches_publishers_stale(m)
} else if let Some(m) = matches.subcommand_matches("add") {
Self::parse_matches_publishers_add(m)
} else if let Some(m) = matches.subcommand_matches("remove") {
Self::parse_matches_publishers_remove(m)
} else if let Some(m) = matches.subcommand_matches("show") {
Self::parse_matches_publishers_show(m)
} else if let Some(m) = matches.subcommand_matches("response") {
Self::parse_matches_publishers_repo_response(m)
} else if let Some(m) = matches.subcommand_matches("server") {
Self::parse_matches_publication_server(m)
} else {
Err(Error::UnrecognizedSubCommand)
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[allow(clippy::large_enum_variant)]
pub enum Command {
@@ -2076,6 +2055,7 @@ pub enum Command {
Info,
Bulk(BulkCaCommand),
CertAuth(CaCommand),
PubServer(PubServerCommand),
Init(KrillInitDetails),
#[cfg(feature = "multi-user")]
User(KrillUserDetails),
@@ -2263,7 +2243,7 @@ impl Default for KrillUserDetails {
#[derive(Clone, Debug, Eq, PartialEq)]
#[allow(clippy::large_enum_variant)]
pub enum PublishersCommand {
pub enum PubServerCommand {
AddPublisher(rfc8183::PublisherRequest),
ShowPublisher(PublisherHandle),
RemovePublisher(PublisherHandle),
+14 -25
View File
@@ -17,11 +17,11 @@ use rpki::crypto::KeyIdentifier;
use rpki::uri;
use crate::cli::report::{ApiResponse, ReportFormat};
use crate::cli::{Error, KrillClient, KrillPubdClient};
use crate::cli::{Error, KrillClient};
use crate::commons::api::{
AddChildRequest, CertAuthInfo, CertAuthInit, CertifiedKeyInfo, ChildHandle, Handle, ParentCaContact, ParentCaReq,
ParentHandle, ParentStatuses, PublicationServerUris, PublisherDetails, PublisherHandle, PublisherList,
ResourceClassName, ResourceSet, RoaDefinition, RoaDefinitionUpdates, RtaList, RtaName, RtaPrepResponse, Token,
ResourceClassName, ResourceSet, RoaDefinition, RoaDefinitionUpdates, RtaList, RtaName, RtaPrepResponse,
TypedPrefix, UpdateChildRequest,
};
use crate::commons::bgp::{Announcement, BgpAnalysisReport, BgpAnalysisSuggestion};
@@ -32,7 +32,7 @@ use crate::commons::util::httpclient;
use crate::daemon::ca::{ta_handle, ResourceTaggedAttestation, RtaContentRequest, RtaPrepareRequest};
use crate::daemon::http::server;
use crate::{
cli::options::{BulkCaCommand, CaCommand, Command, KrillPubcOptions, Options, PublishersCommand},
cli::options::{BulkCaCommand, CaCommand, Command, Options, PubServerCommand},
commons::api::RepositoryContact,
};
@@ -149,7 +149,7 @@ pub async fn start_krill_pubd() -> PathBuf {
let rrdp_base_uri = uri::Https::from_str("https://localhost:3001/test-rrdp/").unwrap();
PublicationServerUris::new(rrdp_base_uri, rsync_base)
};
let command = PublishersCommand::RepositoryInit(uris);
let command = PubServerCommand::RepositoryInit(uris);
krill_dedicated_pubd_admin(command).await;
dir
@@ -163,29 +163,18 @@ pub async fn krill_admin(command: Command) -> ApiResponse {
}
}
pub async fn krill_embedded_pubd_admin(command: PublishersCommand) -> ApiResponse {
let options = KrillPubcOptions::new(
https(KRILL_SERVER_URI),
Token::from("secret"),
ReportFormat::Json,
false,
command,
);
match KrillPubdClient::process(options).await {
Ok(res) => res, // ok
Err(e) => panic!("{}", e),
}
pub async fn krill_embedded_pubd_admin(command: PubServerCommand) -> ApiResponse {
krill_admin(Command::PubServer(command)).await
}
pub async fn krill_dedicated_pubd_admin(command: PublishersCommand) -> ApiResponse {
let options = KrillPubcOptions::new(
pub async fn krill_dedicated_pubd_admin(command: PubServerCommand) -> ApiResponse {
let options = Options::new(
https(KRILL_PUBD_SERVER_URI),
Token::from("secret"),
"secret",
ReportFormat::Json,
false,
command,
Command::PubServer(command),
);
match KrillPubdClient::process(options).await {
match KrillClient::process(options).await {
Ok(res) => res, // ok
Err(e) => panic!("{}", e),
}
@@ -489,21 +478,21 @@ pub async fn ca_current_resources(handle: &Handle) -> ResourceSet {
}
pub async fn list_publishers() -> PublisherList {
match krill_embedded_pubd_admin(PublishersCommand::PublisherList).await {
match krill_embedded_pubd_admin(PubServerCommand::PublisherList).await {
ApiResponse::PublisherList(pub_list) => pub_list,
_ => panic!("Expected publisher list"),
}
}
pub async fn publisher_details(publisher: &PublisherHandle) -> PublisherDetails {
match krill_embedded_pubd_admin(PublishersCommand::ShowPublisher(publisher.clone())).await {
match krill_embedded_pubd_admin(PubServerCommand::ShowPublisher(publisher.clone())).await {
ApiResponse::PublisherDetails(pub_details) => pub_details,
_ => panic!("Expected publisher details"),
}
}
pub async fn dedicated_repo_publisher_details(publisher: &PublisherHandle) -> PublisherDetails {
match krill_dedicated_pubd_admin(PublishersCommand::ShowPublisher(publisher.clone())).await {
match krill_dedicated_pubd_admin(PubServerCommand::ShowPublisher(publisher.clone())).await {
ApiResponse::PublisherDetails(pub_details) => pub_details,
_ => panic!("Expected publisher details"),
}
+3 -3
View File
@@ -19,7 +19,7 @@ use krill::commons::remote::rfc8183;
use krill::daemon::ca::ta_handle;
use krill::test::*;
use krill::{
cli::options::{BulkCaCommand, CaCommand, Command, PublishersCommand},
cli::options::{BulkCaCommand, CaCommand, Command, PubServerCommand},
commons::api::RepositoryContact,
};
@@ -37,7 +37,7 @@ async fn repo_update(ca: &Handle, contact: RepositoryContact) {
}
async fn embedded_repository_response(publisher: &PublisherHandle) -> rfc8183::RepositoryResponse {
let command = PublishersCommand::RepositoryResponse(publisher.clone());
let command = PubServerCommand::RepositoryResponse(publisher.clone());
match krill_embedded_pubd_admin(command).await {
ApiResponse::Rfc8183RepositoryResponse(response) => response,
_ => panic!("Expected repository response."),
@@ -45,7 +45,7 @@ async fn embedded_repository_response(publisher: &PublisherHandle) -> rfc8183::R
}
async fn embedded_repo_add_publisher(req: rfc8183::PublisherRequest) {
let command = PublishersCommand::AddPublisher(req);
let command = PubServerCommand::AddPublisher(req);
krill_embedded_pubd_admin(command).await;
}
+5 -5
View File
@@ -16,7 +16,7 @@ use krill::commons::remote::rfc8183;
use krill::daemon::ca::ta_handle;
use krill::test::*;
use krill::{
cli::options::{CaCommand, Command, PublishersCommand},
cli::options::{CaCommand, Command, PubServerCommand},
commons::api::RepositoryContact,
};
use krill::{cli::report::ApiResponse, commons::api::RoaDefinition};
@@ -35,7 +35,7 @@ async fn repo_update(ca: &Handle, contact: RepositoryContact) {
}
async fn embedded_repository_response(publisher: &PublisherHandle) -> rfc8183::RepositoryResponse {
let command = PublishersCommand::RepositoryResponse(publisher.clone());
let command = PubServerCommand::RepositoryResponse(publisher.clone());
match krill_embedded_pubd_admin(command).await {
ApiResponse::Rfc8183RepositoryResponse(response) => response,
_ => panic!("Expected repository response."),
@@ -43,7 +43,7 @@ async fn embedded_repository_response(publisher: &PublisherHandle) -> rfc8183::R
}
async fn dedicated_repository_response(publisher: &PublisherHandle) -> rfc8183::RepositoryResponse {
let command = PublishersCommand::RepositoryResponse(publisher.clone());
let command = PubServerCommand::RepositoryResponse(publisher.clone());
match krill_dedicated_pubd_admin(command).await {
ApiResponse::Rfc8183RepositoryResponse(response) => response,
_ => panic!("Expected repository response."),
@@ -51,12 +51,12 @@ async fn dedicated_repository_response(publisher: &PublisherHandle) -> rfc8183::
}
async fn embedded_repo_add_publisher(req: rfc8183::PublisherRequest) {
let command = PublishersCommand::AddPublisher(req);
let command = PubServerCommand::AddPublisher(req);
krill_embedded_pubd_admin(command).await;
}
async fn dedicated_repo_add_publisher(req: rfc8183::PublisherRequest) {
let command = PublishersCommand::AddPublisher(req);
let command = PubServerCommand::AddPublisher(req);
krill_dedicated_pubd_admin(command).await;
}