use std::{collections::HashMap, fmt};
use rpki::{
ca::{
idexchange::{CaHandle, ChildHandle, ParentHandle},
provisioning::{IssuanceRequest, ParentResourceClassName, ResourceClassName, RevocationRequest},
},
crypto::KeyIdentifier,
repository::resources::ResourceSet,
};
use crate::{
commons::{
api::{
AspaCustomer, AspaDefinition, AspaProvidersUpdate, BgpSecAsnKey, IdCertInfo, IssuedCertificate, ObjectName,
ParentCaContact, ReceivedCert, RepositoryContact, RoaAggregateKey, RtaName, SuspendedCert, TaCertDetails,
UnsuspendedCert,
},
crypto::KrillSigner,
eventsourcing::StoredEvent,
KrillResult,
},
daemon::ca::{AspaInfo, CertifiedKey, PreparedRta, RoaInfo, RoaPayloadJsonMapKey, SignedRta},
};
use super::{BgpSecCertInfo, StoredBgpSecCsr};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Rfc8183Id {
cert: IdCertInfo,
}
impl Rfc8183Id {
pub fn new(cert: IdCertInfo) -> Self {
Rfc8183Id { cert }
}
pub fn generate(signer: &KrillSigner) -> KrillResult<Self> {
let cert = signer.create_self_signed_id_cert()?;
let cert = IdCertInfo::from(&cert);
Ok(Rfc8183Id { cert })
}
pub fn cert(&self) -> &IdCertInfo {
&self.cert
}
}
pub type Ini = StoredEvent<IniDet>;
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct IniDet {
id: Rfc8183Id,
}
impl IniDet {
pub fn unpack(self) -> Rfc8183Id {
self.id
}
}
impl IniDet {
pub fn new(handle: &CaHandle, id: Rfc8183Id) -> Ini {
Ini::new(handle, 0, IniDet { id })
}
pub fn init(handle: &CaHandle, signer: &KrillSigner) -> KrillResult<Ini> {
let id = Rfc8183Id::generate(signer)?;
Ok(Self::new(handle, id))
}
}
impl fmt::Display for IniDet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Initialized with ID key hash: {}",
self.id.cert().public_key().key_identifier()
)?;
Ok(())
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct RoaUpdates {
#[serde(skip_serializing_if = "HashMap::is_empty", default = "HashMap::new")]
updated: HashMap<RoaPayloadJsonMapKey, RoaInfo>,
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")]
removed: Vec<RoaPayloadJsonMapKey>,
#[serde(skip_serializing_if = "HashMap::is_empty", default = "HashMap::new")]
aggregate_updated: HashMap<RoaAggregateKey, RoaInfo>,
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")]
aggregate_removed: Vec<RoaAggregateKey>,
}
impl RoaUpdates {
pub fn new(
updated: HashMap<RoaPayloadJsonMapKey, RoaInfo>,
removed: Vec<RoaPayloadJsonMapKey>,
aggregate_updated: HashMap<RoaAggregateKey, RoaInfo>,
aggregate_removed: Vec<RoaAggregateKey>,
) -> Self {
RoaUpdates {
updated,
removed,
aggregate_updated,
aggregate_removed,
}
}
pub fn is_empty(&self) -> bool {
self.updated.is_empty()
&& self.removed.is_empty()
&& self.aggregate_updated.is_empty()
&& self.aggregate_removed.is_empty()
}
pub fn contains_changes(&self) -> bool {
!self.is_empty()
}
pub fn update(&mut self, auth: RoaPayloadJsonMapKey, roa: RoaInfo) {
self.updated.insert(auth, roa);
}
pub fn remove(&mut self, auth: RoaPayloadJsonMapKey) {
self.removed.push(auth);
}
pub fn remove_aggregate(&mut self, key: RoaAggregateKey) {
self.aggregate_removed.push(key);
}
pub fn update_aggregate(&mut self, key: RoaAggregateKey, info: RoaInfo) {
self.aggregate_updated.insert(key, info);
}
pub fn added_roas(&self) -> HashMap<ObjectName, RoaInfo> {
let mut res = HashMap::new();
for (auth, info) in &self.updated {
let name = ObjectName::from(auth);
res.insert(name, info.clone());
}
for (agg_key, info) in &self.aggregate_updated {
let name = ObjectName::from(agg_key);
res.insert(name, info.clone());
}
res
}
pub fn removed_roas(&self) -> Vec<ObjectName> {
let mut res = vec![];
for simple in &self.removed {
res.push(ObjectName::from(simple))
}
for agg in &self.aggregate_removed {
res.push(ObjectName::from(agg))
}
res
}
#[allow(clippy::type_complexity)]
pub fn unpack(
self,
) -> (
HashMap<RoaPayloadJsonMapKey, RoaInfo>,
Vec<RoaPayloadJsonMapKey>,
HashMap<RoaAggregateKey, RoaInfo>,
Vec<RoaAggregateKey>,
) {
(
self.updated,
self.removed,
self.aggregate_updated,
self.aggregate_removed,
)
}
}
impl fmt::Display for RoaUpdates {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if !self.updated.is_empty() {
write!(f, "Updated single VRP ROAs: ")?;
for roa in self.updated.keys() {
write!(f, "{} ", ObjectName::from(roa))?;
}
}
if !self.removed.is_empty() {
write!(f, "Removed single VRP ROAs: ")?;
for roa in &self.removed {
write!(f, "{} ", ObjectName::from(roa))?;
}
}
if !self.aggregate_updated.is_empty() {
write!(f, "Updated ASN aggregated ROAs: ")?;
for roa in self.aggregate_updated.keys() {
write!(f, "{} ", ObjectName::from(roa))?;
}
}
if !self.aggregate_removed.is_empty() {
write!(f, "Removed ASN aggregated ROAs: ")?;
for roa in &self.aggregate_removed {
write!(f, "{} ", ObjectName::from(roa))?;
}
}
Ok(())
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct AspaObjectsUpdates {
#[serde(skip_serializing_if = "Vec::is_empty", default)]
updated: Vec<AspaInfo>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
removed: Vec<AspaCustomer>,
}
impl AspaObjectsUpdates {
pub fn new(updated: Vec<AspaInfo>, removed: Vec<AspaCustomer>) -> Self {
AspaObjectsUpdates { updated, removed }
}
pub fn for_new_aspa_info(new_aspa: AspaInfo) -> Self {
AspaObjectsUpdates {
updated: vec![new_aspa],
removed: vec![],
}
}
pub fn add_updated(&mut self, update: AspaInfo) {
self.updated.push(update)
}
pub fn add_removed(&mut self, customer: AspaCustomer) {
self.removed.push(customer)
}
pub fn is_empty(&self) -> bool {
self.updated.is_empty() && self.removed.is_empty()
}
pub fn contains_changes(&self) -> bool {
!self.is_empty()
}
pub fn unpack(self) -> (Vec<AspaInfo>, Vec<AspaCustomer>) {
(self.updated, self.removed)
}
pub fn updated(&self) -> &Vec<AspaInfo> {
&self.updated
}
pub fn removed(&self) -> &Vec<AspaCustomer> {
&self.removed
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct BgpSecCertificateUpdates {
#[serde(skip_serializing_if = "Vec::is_empty", default)]
updated: Vec<BgpSecCertInfo>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
removed: Vec<BgpSecAsnKey>,
}
impl BgpSecCertificateUpdates {
pub fn is_empty(&self) -> bool {
self.updated.is_empty() && self.removed.is_empty()
}
pub fn len(&self) -> usize {
self.updated.len() + self.removed.len()
}
pub fn contains_changes(&self) -> bool {
!self.is_empty()
}
pub fn updated(&self) -> &Vec<BgpSecCertInfo> {
&self.updated
}
pub fn removed(&self) -> &Vec<BgpSecAsnKey> {
&self.removed
}
pub fn unpack(self) -> (Vec<BgpSecCertInfo>, Vec<BgpSecAsnKey>) {
(self.updated, self.removed)
}
pub fn add_updated(&mut self, update: BgpSecCertInfo) {
self.updated.push(update);
}
pub fn add_removed(&mut self, remove: BgpSecAsnKey) {
self.removed.push(remove);
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct ChildCertificateUpdates {
#[serde(skip_serializing_if = "Vec::is_empty", default)]
issued: Vec<IssuedCertificate>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
removed: Vec<KeyIdentifier>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
suspended: Vec<SuspendedCert>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
unsuspended: Vec<UnsuspendedCert>,
}
impl ChildCertificateUpdates {
pub fn new(
issued: Vec<IssuedCertificate>,
removed: Vec<KeyIdentifier>,
suspended: Vec<SuspendedCert>,
unsuspended: Vec<UnsuspendedCert>,
) -> Self {
ChildCertificateUpdates {
issued,
removed,
suspended,
unsuspended,
}
}
pub fn is_empty(&self) -> bool {
self.issued.is_empty() && self.removed.is_empty() && self.suspended.is_empty() && self.unsuspended.is_empty()
}
pub fn issue(&mut self, new: IssuedCertificate) {
self.issued.push(new);
}
pub fn remove(&mut self, ki: KeyIdentifier) {
self.removed.push(ki);
}
pub fn issued(&self) -> &Vec<IssuedCertificate> {
&self.issued
}
pub fn removed(&self) -> &Vec<KeyIdentifier> {
&self.removed
}
pub fn suspend(&mut self, suspended_cert: SuspendedCert) {
self.suspended.push(suspended_cert);
}
pub fn suspended(&self) -> &Vec<SuspendedCert> {
&self.suspended
}
pub fn unsuspend(&mut self, unsuspended_cert: UnsuspendedCert) {
self.unsuspended.push(unsuspended_cert);
}
pub fn unsuspended(&self) -> &Vec<UnsuspendedCert> {
&self.unsuspended
}
pub fn unpack(
self,
) -> (
Vec<IssuedCertificate>,
Vec<KeyIdentifier>,
Vec<SuspendedCert>,
Vec<UnsuspendedCert>,
) {
(self.issued, self.removed, self.suspended, self.unsuspended)
}
}
pub type CaEvt = StoredEvent<CaEvtDet>;
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[allow(clippy::large_enum_variant)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type")]
pub enum CaEvtDet {
TrustAnchorMade {
ta_cert_details: TaCertDetails,
},
ChildAdded {
child: ChildHandle,
id_cert: IdCertInfo,
resources: ResourceSet,
},
ChildCertificateIssued {
child: ChildHandle,
resource_class_name: ResourceClassName,
ki: KeyIdentifier,
},
ChildKeyRevoked {
child: ChildHandle,
resource_class_name: ResourceClassName,
ki: KeyIdentifier,
},
ChildCertificatesUpdated {
resource_class_name: ResourceClassName,
updates: ChildCertificateUpdates,
},
ChildUpdatedIdCert {
child: ChildHandle,
id_cert: IdCertInfo,
},
ChildUpdatedResources {
child: ChildHandle,
resources: ResourceSet,
},
ChildRemoved {
child: ChildHandle,
},
ChildSuspended {
child: ChildHandle,
},
ChildUnsuspended {
child: ChildHandle,
},
IdUpdated {
id: Rfc8183Id,
},
ParentAdded {
parent: ParentHandle,
contact: ParentCaContact,
},
ParentUpdated {
parent: ParentHandle,
contact: ParentCaContact,
},
ParentRemoved {
parent: ParentHandle,
},
ResourceClassAdded {
resource_class_name: ResourceClassName,
parent: ParentHandle,
parent_resource_class_name: ParentResourceClassName,
pending_key: KeyIdentifier,
},
ResourceClassRemoved {
resource_class_name: ResourceClassName,
parent: ParentHandle,
revoke_requests: Vec<RevocationRequest>,
},
CertificateRequested {
resource_class_name: ResourceClassName,
req: IssuanceRequest,
ki: KeyIdentifier, },
CertificateReceived {
resource_class_name: ResourceClassName,
rcvd_cert: ReceivedCert,
ki: KeyIdentifier, },
KeyRollPendingKeyAdded {
resource_class_name: ResourceClassName,
pending_key_id: KeyIdentifier,
},
KeyPendingToNew {
resource_class_name: ResourceClassName,
new_key: CertifiedKey, },
KeyPendingToActive {
resource_class_name: ResourceClassName,
current_key: CertifiedKey, },
KeyRollActivated {
resource_class_name: ResourceClassName,
revoke_req: RevocationRequest,
},
KeyRollFinished {
resource_class_name: ResourceClassName,
},
UnexpectedKeyFound {
resource_class_name: ResourceClassName,
revoke_req: RevocationRequest,
},
RouteAuthorizationAdded {
auth: RoaPayloadJsonMapKey,
},
RouteAuthorizationComment {
auth: RoaPayloadJsonMapKey,
comment: Option<String>,
},
RouteAuthorizationRemoved {
auth: RoaPayloadJsonMapKey,
},
RoasUpdated {
resource_class_name: ResourceClassName,
updates: RoaUpdates,
},
AspaConfigAdded {
aspa_config: AspaDefinition,
},
AspaConfigUpdated {
customer: AspaCustomer,
update: AspaProvidersUpdate,
},
AspaConfigRemoved {
customer: AspaCustomer,
},
AspaObjectsUpdated {
resource_class_name: ResourceClassName,
updates: AspaObjectsUpdates,
},
BgpSecDefinitionAdded {
key: BgpSecAsnKey,
csr: StoredBgpSecCsr,
},
BgpSecDefinitionUpdated {
key: BgpSecAsnKey,
csr: StoredBgpSecCsr,
},
BgpSecDefinitionRemoved {
key: BgpSecAsnKey,
},
BgpSecCertificatesUpdated {
resource_class_name: ResourceClassName,
updates: BgpSecCertificateUpdates,
},
RepoUpdated {
contact: RepositoryContact,
},
RtaSigned {
name: RtaName,
rta: SignedRta,
},
RtaPrepared {
name: RtaName,
prepared: PreparedRta,
},
}
impl CaEvtDet {
pub(super) fn id_updated(handle: &CaHandle, version: u64, id: Rfc8183Id) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::IdUpdated { id })
}
pub(super) fn parent_added(
handle: &CaHandle,
version: u64,
parent: ParentHandle,
contact: ParentCaContact,
) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::ParentAdded { parent, contact })
}
pub(super) fn parent_updated(
handle: &CaHandle,
version: u64,
parent: ParentHandle,
contact: ParentCaContact,
) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::ParentUpdated { parent, contact })
}
pub(super) fn child_added(
handle: &CaHandle,
version: u64,
child: ChildHandle,
id_cert: IdCertInfo,
resources: ResourceSet,
) -> CaEvt {
StoredEvent::new(
handle,
version,
CaEvtDet::ChildAdded {
child,
id_cert,
resources,
},
)
}
pub(super) fn child_updated_cert(
handle: &CaHandle,
version: u64,
child: ChildHandle,
id_cert: IdCertInfo,
) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::ChildUpdatedIdCert { child, id_cert })
}
pub(super) fn child_updated_resources(
handle: &CaHandle,
version: u64,
child: ChildHandle,
resources: ResourceSet,
) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::ChildUpdatedResources { child, resources })
}
pub(super) fn child_certificate_issued(
handle: &CaHandle,
version: u64,
child: ChildHandle,
resource_class_name: ResourceClassName,
ki: KeyIdentifier,
) -> CaEvt {
StoredEvent::new(
handle,
version,
CaEvtDet::ChildCertificateIssued {
child,
resource_class_name,
ki,
},
)
}
pub(super) fn child_revoke_key(
handle: &CaHandle,
version: u64,
child: ChildHandle,
resource_class_name: ResourceClassName,
ki: KeyIdentifier,
) -> CaEvt {
StoredEvent::new(
handle,
version,
CaEvtDet::ChildKeyRevoked {
child,
resource_class_name,
ki,
},
)
}
pub(super) fn child_certificates_updated(
handle: &CaHandle,
version: u64,
resource_class_name: ResourceClassName,
updates: ChildCertificateUpdates,
) -> CaEvt {
StoredEvent::new(
handle,
version,
CaEvtDet::ChildCertificatesUpdated {
resource_class_name,
updates,
},
)
}
pub(super) fn child_removed(handle: &CaHandle, version: u64, child: ChildHandle) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::ChildRemoved { child })
}
pub(super) fn child_suspended(handle: &CaHandle, version: u64, child: ChildHandle) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::ChildSuspended { child })
}
pub(super) fn child_unsuspended(handle: &CaHandle, version: u64, child: ChildHandle) -> CaEvt {
StoredEvent::new(handle, version, CaEvtDet::ChildUnsuspended { child })
}
}
impl fmt::Display for CaEvtDet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CaEvtDet::TrustAnchorMade { ta_cert_details } => write!(
f,
"turn into TA with key (hash) {}",
ta_cert_details.cert().key_identifier()
),
CaEvtDet::ChildAdded {
child,
id_cert,
resources,
} => {
write!(
f,
"added child '{}' with resources '{}, id (hash): {}",
child,
resources,
id_cert.public_key().key_identifier()
)
}
CaEvtDet::ChildCertificateIssued {
child,
resource_class_name,
ki,
} => write!(
f,
"issued certificate to child '{}' for class '{}' and pub key '{}'",
child, resource_class_name, ki
),
CaEvtDet::ChildCertificatesUpdated {
resource_class_name,
updates,
} => {
write!(
f,
"updated child certificates in resource class {}",
resource_class_name
)?;
let issued = updates.issued();
if !issued.is_empty() {
write!(f, " issued keys: ")?;
for iss in issued {
write!(f, " {}", iss.key_identifier())?;
}
}
let revoked = updates.removed();
if !revoked.is_empty() {
write!(f, " revoked keys: ")?;
for rev in revoked {
write!(f, " {}", rev)?;
}
}
let suspended = updates.suspended();
if !suspended.is_empty() {
write!(f, " suspended keys: ")?;
for cert in suspended {
write!(f, " {}", cert.key_identifier())?;
}
}
let unsuspended = updates.unsuspended();
if !unsuspended.is_empty() {
write!(f, " unsuspended keys: ")?;
for cert in unsuspended {
write!(f, " {}", cert.key_identifier())?;
}
}
Ok(())
}
CaEvtDet::ChildKeyRevoked {
child,
resource_class_name,
ki,
} => write!(
f,
"revoked certificate for child '{}' in resource class '{}' with key(hash) '{}'",
child, resource_class_name, ki
),
CaEvtDet::ChildUpdatedIdCert { child, id_cert } => {
write!(
f,
"updated child '{}' id (hash) '{}'",
child,
id_cert.public_key().key_identifier()
)
}
CaEvtDet::ChildUpdatedResources { child, resources } => {
write!(f, "updated child '{}' resources to '{}'", child, resources)
}
CaEvtDet::ChildRemoved { child } => write!(f, "removed child '{}'", child),
CaEvtDet::ChildSuspended { child } => write!(f, "suspended child '{}'", child),
CaEvtDet::ChildUnsuspended { child } => write!(f, "unsuspended child '{}'", child),
CaEvtDet::IdUpdated { id } => write!(
f,
"updated RFC8183 id to key '{}'",
id.cert().public_key().key_identifier()
),
CaEvtDet::ParentAdded { parent, contact } => {
let contact_str = match contact {
ParentCaContact::Ta(_) => "TA proxy",
ParentCaContact::Rfc6492(_) => "RFC6492",
};
write!(f, "added {} parent '{}' ", contact_str, parent)
}
CaEvtDet::ParentUpdated { parent, contact } => {
let contact_str = match contact {
ParentCaContact::Ta(_) => "TA proxy",
ParentCaContact::Rfc6492(_) => "RFC6492",
};
write!(f, "updated parent '{}' contact to '{}' ", parent, contact_str)
}
CaEvtDet::ParentRemoved { parent } => write!(f, "removed parent '{}'", parent),
CaEvtDet::ResourceClassAdded {
resource_class_name, ..
} => write!(f, "added resource class with name '{}'", resource_class_name),
CaEvtDet::ResourceClassRemoved {
resource_class_name,
parent,
..
} => write!(
f,
"removed resource class with name '{}' under parent '{}'",
resource_class_name, parent
),
CaEvtDet::CertificateRequested {
resource_class_name,
ki,
..
} => write!(
f,
"requested certificate for key (hash) '{}' under resource class '{}'",
ki, resource_class_name
),
CaEvtDet::CertificateReceived {
resource_class_name,
ki,
..
} => write!(
f,
"received certificate for key (hash) '{}' under resource class '{}'",
ki, resource_class_name
),
CaEvtDet::KeyRollPendingKeyAdded {
resource_class_name,
pending_key_id,
} => {
write!(
f,
"key roll: added pending key '{}' under resource class '{}'",
pending_key_id, resource_class_name
)
}
CaEvtDet::KeyPendingToNew {
resource_class_name,
new_key,
} => write!(
f,
"key roll: moving pending key '{}' to new state under resource class '{}'",
new_key.key_id(),
resource_class_name
),
CaEvtDet::KeyPendingToActive {
resource_class_name,
current_key,
} => write!(
f,
"activating pending key '{}' under resource class '{}'",
current_key.key_id(),
resource_class_name
),
CaEvtDet::KeyRollActivated {
resource_class_name,
revoke_req,
} => write!(
f,
"key roll: activated new key, requested revocation of '{}' under resource class '{}'",
revoke_req.key(),
resource_class_name
),
CaEvtDet::KeyRollFinished { resource_class_name } => {
write!(f, "key roll: finished for resource class '{}'", resource_class_name)
}
CaEvtDet::UnexpectedKeyFound {
resource_class_name,
revoke_req,
} => write!(
f,
"Found unexpected key in resource class '{}', will try to revoke key id: '{}'",
resource_class_name,
revoke_req.key()
),
CaEvtDet::RouteAuthorizationAdded { auth } => write!(f, "added ROA: '{}'", auth),
CaEvtDet::RouteAuthorizationComment { auth, comment } => {
if let Some(comment) = comment {
write!(f, "added comment to ROA: '{}' => {}", auth, comment)
} else {
write!(f, "removed comment from ROA: '{}'", auth)
}
}
CaEvtDet::RouteAuthorizationRemoved { auth } => write!(f, "removed ROA: '{}'", auth),
CaEvtDet::RoasUpdated {
resource_class_name,
updates,
} => {
write!(f, "updated ROA objects under resource class '{}'", resource_class_name)?;
if !updates.updated.is_empty() || !updates.aggregate_updated.is_empty() {
write!(f, " added: ")?;
for auth in updates.updated.keys() {
write!(f, "{} ", ObjectName::from(auth))?;
}
for agg_key in updates.aggregate_updated.keys() {
write!(f, "{} ", ObjectName::from(agg_key))?;
}
}
if !updates.removed.is_empty() || !updates.aggregate_removed.is_empty() {
write!(f, " removed: ")?;
for auth in &updates.removed {
write!(f, "{} ", ObjectName::from(auth))?;
}
for agg_key in &updates.aggregate_removed {
write!(f, "{} ", ObjectName::from(agg_key))?;
}
}
Ok(())
}
CaEvtDet::AspaConfigAdded { aspa_config: addition } => write!(f, "{}", addition),
CaEvtDet::AspaConfigUpdated { customer, update } => {
write!(f, "updated ASPA config for customer ASN: {} {}", customer, update)
}
CaEvtDet::AspaConfigRemoved { customer } => write!(f, "removed ASPA config for customer ASN: {}", customer),
CaEvtDet::AspaObjectsUpdated {
resource_class_name,
updates,
} => {
write!(f, "updated ASPA objects under resource class '{}'", resource_class_name)?;
if !updates.updated().is_empty() {
write!(f, " updated:")?;
for upd in updates.updated() {
write!(f, " {}", ObjectName::aspa(upd.customer()))?;
}
}
if !updates.removed().is_empty() {
write!(f, " removed:")?;
for rem in updates.removed() {
write!(f, " {}", ObjectName::aspa(*rem))?;
}
}
Ok(())
}
CaEvtDet::BgpSecDefinitionAdded { key, .. } => {
write!(
f,
"added BGPSec definition for ASN: {} and key id: {}",
key.asn(),
key.key_identifier()
)
}
CaEvtDet::BgpSecDefinitionUpdated { key, .. } => {
write!(
f,
"updated CSR for BGPSec definition for ASN: {} and key id: {}",
key.asn(),
key.key_identifier()
)
}
CaEvtDet::BgpSecDefinitionRemoved { key } => {
write!(
f,
"removed BGPSec definition for ASN: {} and key id: {}",
key.asn(),
key.key_identifier()
)
}
CaEvtDet::BgpSecCertificatesUpdated {
resource_class_name,
updates,
} => {
write!(
f,
"updated BGPSec certificates under resource class '{}'",
resource_class_name
)?;
let updated = updates.updated();
if !updated.is_empty() {
write!(f, " added: ")?;
for cert in updated {
write!(f, "{} ", ObjectName::from(cert))?;
}
}
let removed = updates.removed();
if !removed.is_empty() {
write!(f, " removed: ")?;
for key in removed {
write!(f, "{} ", ObjectName::from(key))?;
}
}
Ok(())
}
CaEvtDet::RepoUpdated { contact } => {
write!(
f,
"updated repository to remote server: {}",
contact.server_info().service_uri()
)
}
CaEvtDet::RtaPrepared { name, prepared } => {
write!(f, "Prepared RTA '{}' for resources: {}", name, prepared.resources())
}
CaEvtDet::RtaSigned { name, rta } => {
write!(f, "Signed RTA '{}' for resources: {}", name, rta.resources())
}
}
}
}