mirror of
https://github.com/NLnetLabs/krill.git
synced 2026-09-28 12:24:52 +02:00
Show parents in list, and parent contact only as separate call in API and CLI (Closes #138)
This commit is contained in:
+9
-3
@@ -8,12 +8,12 @@ use rpki::uri;
|
||||
use crate::cli::options::{BulkCaCommand, CaCommand, Command, Options, PublishersCommand};
|
||||
use crate::cli::report::{ApiResponse, ReportError};
|
||||
use crate::commons::api::{
|
||||
CaRepoDetails, CertAuthInfo, ParentCaContact, PublisherDetails, PublisherList, Token,
|
||||
CaRepoDetails, CertAuthInfo, ChildCaInfo, ParentCaContact, PublisherDetails, PublisherList,
|
||||
Token,
|
||||
};
|
||||
use crate::commons::remote::rfc8183;
|
||||
use crate::commons::util::httpclient;
|
||||
use crate::constants::KRILL_CLI_API_ENV;
|
||||
use commons::api::ChildCaInfo;
|
||||
|
||||
/// Command line tool for Krill admin tasks
|
||||
pub struct KrillClient {
|
||||
@@ -94,7 +94,7 @@ impl KrillClient {
|
||||
}
|
||||
|
||||
CaCommand::ParentResponse(handle, child) => {
|
||||
let uri = format!("api/v1/cas/{}/parent_contact/{}", handle, child);
|
||||
let uri = format!("api/v1/cas/{}/children/{}/contact", handle, child);
|
||||
let info: ParentCaContact = self.get_json(&uri)?;
|
||||
Ok(ApiResponse::ParentCaContact(info))
|
||||
}
|
||||
@@ -142,6 +142,12 @@ impl KrillClient {
|
||||
Ok(ApiResponse::Empty)
|
||||
}
|
||||
|
||||
CaCommand::MyParentCaContact(handle, parent) => {
|
||||
let uri = format!("api/v1/cas/{}/parents/{}", handle, parent);
|
||||
let parent: ParentCaContact = self.get_json(&uri)?;
|
||||
Ok(ApiResponse::ParentCaContact(parent))
|
||||
}
|
||||
|
||||
CaCommand::ChildInfo(handle, child) => {
|
||||
let uri = format!("api/v1/cas/{}/children/{}", handle, child);
|
||||
let info: ChildCaInfo = self.get_json(&uri)?;
|
||||
|
||||
+27
-1
@@ -386,6 +386,17 @@ impl Options {
|
||||
app.subcommand(sub)
|
||||
}
|
||||
|
||||
fn make_cas_parents_contact_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
|
||||
let mut sub =
|
||||
SubCommand::with_name("contact").about("Show contact information for parent.");
|
||||
|
||||
sub = Self::add_general_args(sub);
|
||||
sub = Self::add_my_ca_arg(sub);
|
||||
sub = Self::add_parent_arg(sub);
|
||||
|
||||
app.subcommand(sub)
|
||||
}
|
||||
|
||||
fn make_cas_parents_remove_sc<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
|
||||
let mut sub =
|
||||
SubCommand::with_name("remove").about("Remove an existing parent from this CA.");
|
||||
@@ -403,6 +414,7 @@ impl Options {
|
||||
sub = Self::make_cas_parents_myid_sc(sub);
|
||||
sub = Self::make_cas_parents_add_sc(sub);
|
||||
sub = Self::make_cas_parents_update_sc(sub);
|
||||
sub = Self::make_cas_parents_contact_sc(sub);
|
||||
sub = Self::make_cas_parents_remove_sc(sub);
|
||||
|
||||
app.subcommand(sub)
|
||||
@@ -875,6 +887,16 @@ impl Options {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_matches_cas_parents_info(matches: &ArgMatches) -> Result<Options, Error> {
|
||||
let general_args = GeneralArgs::from_matches(matches)?;
|
||||
let my_ca = Self::parse_my_ca(matches)?;
|
||||
let parent = matches.value_of("parent").unwrap();
|
||||
let parent = Handle::from_str(parent).map_err(|_| Error::InvalidHandle)?;
|
||||
|
||||
let command = Command::CertAuth(CaCommand::MyParentCaContact(my_ca, parent));
|
||||
Ok(Options::make(general_args, command))
|
||||
}
|
||||
|
||||
fn parse_matches_cas_parents_remove(matches: &ArgMatches) -> Result<Options, Error> {
|
||||
let general_args = GeneralArgs::from_matches(matches)?;
|
||||
let my_ca = Self::parse_my_ca(matches)?;
|
||||
@@ -892,6 +914,8 @@ impl Options {
|
||||
Self::parse_matches_cas_parents_add(m)
|
||||
} else if let Some(m) = matches.subcommand_matches("update") {
|
||||
Self::parse_matches_cas_parents_update(m)
|
||||
} else if let Some(m) = matches.subcommand_matches("contact") {
|
||||
Self::parse_matches_cas_parents_info(m)
|
||||
} else if let Some(m) = matches.subcommand_matches("remove") {
|
||||
Self::parse_matches_cas_parents_remove(m)
|
||||
} else {
|
||||
@@ -1165,7 +1189,7 @@ pub enum CaCommand {
|
||||
// Update CA id
|
||||
UpdateId(Handle),
|
||||
|
||||
// Get an RFC8183 parent response
|
||||
// Get an RFC8183 parent response for a child
|
||||
ParentResponse(Handle, ChildHandle),
|
||||
|
||||
// Get the RFC8183 child request
|
||||
@@ -1178,6 +1202,8 @@ pub enum CaCommand {
|
||||
|
||||
// Add a parent to this CA
|
||||
AddParent(Handle, ParentCaReq),
|
||||
// Show my parent's contact
|
||||
MyParentCaContact(Handle, ParentHandle),
|
||||
|
||||
// Update parent contact
|
||||
UpdateParentContact(Handle, ParentHandle, ParentCaContact),
|
||||
|
||||
+11
-7
@@ -1,12 +1,12 @@
|
||||
use std::str::{from_utf8_unchecked, FromStr};
|
||||
|
||||
use crate::commons::api::{
|
||||
CaRepoDetails, CertAuthHistory, CertAuthInfo, CertAuthList, CurrentObjects, CurrentRepoState,
|
||||
ParentCaContact, PublisherDetails, PublisherList, RepositoryContact, RoaDefinition,
|
||||
CaRepoDetails, CertAuthHistory, CertAuthInfo, CertAuthList, ChildCaInfo, CurrentObjects,
|
||||
CurrentRepoState, ParentCaContact, PublisherDetails, PublisherList, RepositoryContact,
|
||||
RoaDefinition,
|
||||
};
|
||||
use crate::commons::remote::api::ClientInfo;
|
||||
use crate::commons::remote::rfc8183;
|
||||
use commons::api::ChildCaInfo;
|
||||
|
||||
//------------ ApiResponse ---------------------------------------------------
|
||||
|
||||
@@ -162,10 +162,14 @@ impl Report for CertAuthInfo {
|
||||
}
|
||||
}
|
||||
|
||||
for (name, kind) in self.parents().iter() {
|
||||
res.push_str(&format!("Parent: {}, Kind: {}\n", name, kind));
|
||||
res.push_str("Parents:\n");
|
||||
if !self.parents().is_empty() {
|
||||
for parent in self.parents().iter() {
|
||||
res.push_str(&format!("{}\n", parent));
|
||||
}
|
||||
} else {
|
||||
res.push_str("<none>\n")
|
||||
}
|
||||
res.push_str("\n");
|
||||
|
||||
for (name, rc) in self.resources() {
|
||||
res.push_str(&format!("Resource Class: {}\n", name,));
|
||||
@@ -183,7 +187,7 @@ impl Report for CertAuthInfo {
|
||||
res.push_str(&format!("{}\n", child_handle));
|
||||
}
|
||||
} else {
|
||||
res.push_str("<none>");
|
||||
res.push_str("<none>\n");
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
|
||||
+47
-10
@@ -19,12 +19,11 @@ use rpki::roa::Roa;
|
||||
use rpki::uri;
|
||||
use rpki::x509::{Serial, Time};
|
||||
|
||||
use crate::commons::api::admin::{Handle, ParentCaContact};
|
||||
use crate::commons::api::publication;
|
||||
use crate::commons::api::publication::Publish;
|
||||
use crate::commons::api::{
|
||||
Base64, ChildHandle, HexEncodedHash, IssuanceRequest, ListReply, ParentHandle,
|
||||
RepositoryContact, RequestResourceLimit, RoaDefinition,
|
||||
Base64, ChildHandle, Handle, HexEncodedHash, IssuanceRequest, ListReply, ParentCaContact,
|
||||
ParentHandle, RepositoryContact, RequestResourceLimit, RoaDefinition,
|
||||
};
|
||||
use crate::commons::eventsourcing::AggregateHistory;
|
||||
use crate::commons::remote::id::IdCert;
|
||||
@@ -1416,6 +1415,43 @@ impl CertAuthSummary {
|
||||
}
|
||||
}
|
||||
|
||||
//------------ ParentKindInfo ------------------------------------------------
|
||||
#[derive(Clone, Debug, Deserialize, Display, Eq, PartialEq, Serialize)]
|
||||
pub enum ParentKindInfo {
|
||||
#[display(fmt = "This CA is a TA")]
|
||||
Ta,
|
||||
|
||||
#[display(fmt = "Embedded parent")]
|
||||
Embedded,
|
||||
|
||||
#[display(fmt = "RFC 6492 Parent")]
|
||||
Rfc6492,
|
||||
}
|
||||
|
||||
//------------ ParentInfo ----------------------------------------------------
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct ParentInfo {
|
||||
handle: ParentHandle,
|
||||
kind: ParentKindInfo,
|
||||
}
|
||||
|
||||
impl ParentInfo {
|
||||
pub fn new(handle: ParentHandle, contact: ParentCaContact) -> Self {
|
||||
let kind = match contact {
|
||||
ParentCaContact::Ta(_) => ParentKindInfo::Ta,
|
||||
ParentCaContact::Embedded => ParentKindInfo::Embedded,
|
||||
ParentCaContact::Rfc6492(_) => ParentKindInfo::Rfc6492,
|
||||
};
|
||||
ParentInfo { handle, kind }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ParentInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {}", self.handle, self.kind)
|
||||
}
|
||||
}
|
||||
|
||||
//------------ CertAuthInfo --------------------------------------------------
|
||||
|
||||
/// This type represents the details of a CertAuth that need
|
||||
@@ -1424,7 +1460,7 @@ impl CertAuthSummary {
|
||||
pub struct CertAuthInfo {
|
||||
handle: Handle,
|
||||
repo_info: RepoInfo,
|
||||
parents: HashMap<Handle, ParentCaContact>,
|
||||
parents: Vec<ParentInfo>,
|
||||
resources: HashMap<ResourceClassName, ResourceClassInfo>,
|
||||
children: Vec<ChildHandle>,
|
||||
roa_definitions: HashSet<RoaDefinition>,
|
||||
@@ -1434,11 +1470,16 @@ impl CertAuthInfo {
|
||||
pub fn new(
|
||||
handle: Handle,
|
||||
repo_info: RepoInfo,
|
||||
parents: HashMap<Handle, ParentCaContact>,
|
||||
parents: HashMap<ParentHandle, ParentCaContact>,
|
||||
resources: HashMap<ResourceClassName, ResourceClassInfo>,
|
||||
children: Vec<ChildHandle>,
|
||||
roa_definitions: HashSet<RoaDefinition>,
|
||||
) -> Self {
|
||||
let parents = parents
|
||||
.into_iter()
|
||||
.map(|(handle, contact)| ParentInfo::new(handle, contact))
|
||||
.collect();
|
||||
|
||||
CertAuthInfo {
|
||||
handle,
|
||||
repo_info,
|
||||
@@ -1457,14 +1498,10 @@ impl CertAuthInfo {
|
||||
&self.repo_info
|
||||
}
|
||||
|
||||
pub fn parents(&self) -> &HashMap<Handle, ParentCaContact> {
|
||||
pub fn parents(&self) -> &Vec<ParentInfo> {
|
||||
&self.parents
|
||||
}
|
||||
|
||||
pub fn parent(&self, parent: &Handle) -> Option<&ParentCaContact> {
|
||||
self.parents.get(parent)
|
||||
}
|
||||
|
||||
pub fn resources(&self) -> &HashMap<ResourceClassName, ResourceClassInfo> {
|
||||
&self.resources
|
||||
}
|
||||
|
||||
@@ -318,6 +318,20 @@ pub fn ca_info(server: web::Data<AppServer>, auth: Auth, handle: Path<Handle>) -
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ca_my_parent_contact(
|
||||
server: web::Data<AppServer>,
|
||||
auth: Auth,
|
||||
ca_and_parent: Path<(Handle, Handle)>,
|
||||
) -> HttpResponse {
|
||||
let (ca, parent) = ca_and_parent.into_inner();
|
||||
if_api_allowed(&server, &auth, || {
|
||||
match server.read().ca_my_parent_contact(&ca, &parent) {
|
||||
Some(info) => render_json(info),
|
||||
None => api_not_found(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ca_history(server: web::Data<AppServer>, auth: Auth, handle: Path<Handle>) -> HttpResponse {
|
||||
if_api_allowed(&server, &auth, || {
|
||||
match server.read().ca_history(&handle.into_inner()) {
|
||||
|
||||
@@ -82,11 +82,12 @@ pub fn start(config: &Config) -> Result<(), Error> {
|
||||
.route("/cas/{ca}/repo/request", get().to(ca_publisher_req))
|
||||
.route("/cas/{ca}/repo/", post().to(ca_repo_update))
|
||||
.route("/cas/{ca}/parents", post().to(ca_add_parent))
|
||||
.route("/cas/{ca}/parents/{parent}", get().to(ca_my_parent_contact))
|
||||
.route("/cas/{ca}/parents/{parent}", post().to(ca_update_parent))
|
||||
.route("/cas/{ca}/parents/{parent}", delete().to(ca_remove_parent))
|
||||
.route("/cas/{ca}/children", post().to(ca_add_child))
|
||||
.route(
|
||||
"/cas/{ca}/parent_contact/{child}",
|
||||
"/cas/{ca}/children/{child}/contact",
|
||||
get().to(ca_parent_contact),
|
||||
)
|
||||
.route("/cas/{ca}/children/{child}", get().to(ca_show_child))
|
||||
|
||||
@@ -326,6 +326,21 @@ impl KrillServer {
|
||||
self.caserver.get_ca(handle).map(|ca| ca.as_ca_info()).ok()
|
||||
}
|
||||
|
||||
/// Returns the parent contact for a CA and parent, or NONE if either the CA or the parent cannot be found.
|
||||
pub fn ca_my_parent_contact(
|
||||
&self,
|
||||
handle: &Handle,
|
||||
parent: &ParentHandle,
|
||||
) -> Option<ParentCaContact> {
|
||||
match self.caserver.get_ca(handle) {
|
||||
Err(_) => None,
|
||||
Ok(ca) => match ca.parent(parent) {
|
||||
Err(_) => None,
|
||||
Ok(parent) => Some(parent.clone()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the history for a CA, or NONE in case of issues (i.e. it does not exist).
|
||||
pub fn ca_history(&self, handle: &Handle) -> Option<CertAuthHistory> {
|
||||
self.caserver.get_ca_history(handle).ok()
|
||||
|
||||
Reference in New Issue
Block a user