mirror of
https://github.com/NLnetLabs/krill.git
synced 2026-09-23 18:04:54 +02:00
Depend on latest rpki-rs with ASPA v1.
This commit is contained in:
Generated
+5
-16
@@ -1774,9 +1774,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.23.1"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea"
|
||||
checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -1960,16 +1960,6 @@ version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
||||
|
||||
[[package]]
|
||||
name = "routecore"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8e2f02d8dd21010b44bf2ca4502cca2fbb2a8ddfd982a18feff149279dc236c"
|
||||
dependencies = [
|
||||
"bcder",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpassword"
|
||||
version = "5.0.1"
|
||||
@@ -1982,18 +1972,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rpki"
|
||||
version = "0.16.1"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "207f773b99ae73e14f8e8ab0f789a5892fc46548b1b79caccec8f33e2d303c40"
|
||||
checksum = "98a05b958a41ba8c923cf14bd2ad5f1aca3f3509c8ffd147c36e094346a0290b"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"base64 0.21.0",
|
||||
"bcder",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"log",
|
||||
"quick-xml",
|
||||
"ring",
|
||||
"routecore",
|
||||
"serde",
|
||||
"untrusted",
|
||||
"uuid",
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ regex = { version = "1.5.5", optional = true, default_features = false, features
|
||||
] }
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
rpassword = { version = "^5.0", optional = true }
|
||||
rpki = { version = "0.16.1", features = ["ca", "compat", "rrdp"] }
|
||||
rpki = { version = "0.17.2", features = ["ca", "compat", "rrdp"] }
|
||||
# rpki = { version = "0.16.0-dev", git = "https://github.com/nLnetLabs/rpki-rs", branch = "csr-ca-repo-trailing-slash", features = [ "ca", "compat", "rrdp" ] }
|
||||
scrypt = { version = "^0.6", optional = true, default-features = false }
|
||||
serde = { version = "^1.0", features = ["derive", "rc"] }
|
||||
|
||||
+12
-14
@@ -19,7 +19,7 @@ use rpki::{
|
||||
},
|
||||
crypto::KeyIdentifier,
|
||||
repository::{
|
||||
aspa::{DuplicateProviderAs, ProviderAs},
|
||||
aspa::DuplicateProviderAs,
|
||||
resources::{Asn, ResourceSet},
|
||||
x509::Time,
|
||||
},
|
||||
@@ -30,8 +30,8 @@ use crate::{
|
||||
cli::report::{ReportError, ReportFormat},
|
||||
commons::{
|
||||
api::{
|
||||
self, import::ImportChild, AddChildRequest, AspaCustomer, AspaDefinition, AspaDefinitionFormatError,
|
||||
AspaProvidersUpdate, AuthorizationFmtError, BgpSecAsnKey, BgpSecDefinition, CertAuthInit, ParentCaReq,
|
||||
self, import::ImportChild, AddChildRequest, AspaDefinition, AspaDefinitionFormatError, AspaProvidersUpdate,
|
||||
AuthorizationFmtError, BgpSecAsnKey, BgpSecDefinition, CertAuthInit, CustomerAsn, ParentCaReq, ProviderAsn,
|
||||
PublicationServerUris, RepoFileDeleteCriteria, RoaConfiguration, RoaConfigurationUpdates, RoaPayload,
|
||||
RtaName, Token, UpdateChildRequest,
|
||||
},
|
||||
@@ -823,7 +823,7 @@ impl Options {
|
||||
sub = sub.arg(
|
||||
Arg::with_name("aspa")
|
||||
.long("aspa")
|
||||
.help("ASPA formatted like: 65000 => 65001, 65002(v4), 65003(v6)")
|
||||
.help("ASPA formatted like: 65000 => 65001, 65002, 65003")
|
||||
.value_name("definition")
|
||||
.required(true),
|
||||
);
|
||||
@@ -1979,8 +1979,6 @@ impl Options {
|
||||
Err(Error::general("Customer AS may not be used as provider."))
|
||||
} else if aspa.contains_duplicate_providers() {
|
||||
Err(Error::general("ASPA may not have duplicate providers."))
|
||||
} else if !aspa.providers_has_both_afis() {
|
||||
Err(Error::general("Definition has providers for one address family only. Please include an explicit AS0 provider for the missing address family if this is intentional."))
|
||||
} else if aspa.providers().is_empty() {
|
||||
Err(Error::general("At least one provider MUST be specified."))
|
||||
} else {
|
||||
@@ -1993,7 +1991,7 @@ impl Options {
|
||||
let general_args = GeneralArgs::from_matches(matches)?;
|
||||
let my_ca = Self::parse_my_ca(matches)?;
|
||||
let customer_str = matches.value_of("customer").unwrap();
|
||||
let customer = AspaCustomer::from_str(customer_str).map_err(|_| Error::invalid_asn(customer_str))?;
|
||||
let customer = CustomerAsn::from_str(customer_str).map_err(|_| Error::invalid_asn(customer_str))?;
|
||||
|
||||
let command = Command::CertAuth(CaCommand::AspasRemove(my_ca, customer));
|
||||
|
||||
@@ -2008,13 +2006,13 @@ impl Options {
|
||||
let mut removed = vec![];
|
||||
|
||||
let customer_str = matches.value_of("customer").unwrap();
|
||||
let customer = AspaCustomer::from_str(customer_str).map_err(|_| Error::invalid_asn(customer_str))?;
|
||||
let customer = CustomerAsn::from_str(customer_str).map_err(|_| Error::invalid_asn(customer_str))?;
|
||||
|
||||
if let Some(add) = matches.values_of("add") {
|
||||
for provider_str in add {
|
||||
let provider = ProviderAs::from_str(provider_str).map_err(|_| Error::invalid_asn(provider_str))?;
|
||||
let provider = ProviderAsn::from_str(provider_str).map_err(|_| Error::invalid_asn(provider_str))?;
|
||||
|
||||
if provider.provider() == customer {
|
||||
if provider == customer {
|
||||
return Err(Error::general("Customer AS may not be added as provider."));
|
||||
}
|
||||
|
||||
@@ -2025,9 +2023,9 @@ impl Options {
|
||||
if let Some(remove) = matches.values_of("remove") {
|
||||
for provider_as_str in remove {
|
||||
let provider_as =
|
||||
ProviderAs::from_str(provider_as_str).map_err(|_| Error::invalid_asn(provider_as_str))?;
|
||||
ProviderAsn::from_str(provider_as_str).map_err(|_| Error::invalid_asn(provider_as_str))?;
|
||||
|
||||
if added.iter().any(|added| added.provider() == provider_as.provider()) {
|
||||
if added.iter().any(|added| *added == provider_as) {
|
||||
return Err(Error::general("Do not add and remove the same AS in a single update."));
|
||||
}
|
||||
|
||||
@@ -2561,8 +2559,8 @@ pub enum CaCommand {
|
||||
// ASPAs
|
||||
AspasList(CaHandle),
|
||||
AspasAddOrReplace(CaHandle, AspaDefinition),
|
||||
AspasUpdate(CaHandle, AspaCustomer, AspaProvidersUpdate),
|
||||
AspasRemove(CaHandle, AspaCustomer),
|
||||
AspasUpdate(CaHandle, CustomerAsn, AspaProvidersUpdate),
|
||||
AspasRemove(CaHandle, CustomerAsn),
|
||||
|
||||
// BGPSec
|
||||
BgpSecList(CaHandle),
|
||||
|
||||
+34
-117
@@ -8,23 +8,23 @@
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use rpki::repository::aspa::*;
|
||||
use rpki::repository::resources::{AddressFamily, Asn};
|
||||
use rpki::repository::resources::Asn;
|
||||
|
||||
pub type AspaCustomer = Asn;
|
||||
pub type CustomerAsn = Asn;
|
||||
pub type ProviderAsn = Asn;
|
||||
|
||||
//------------ AspaDefinitionUpdates -------------------------------------
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct AspaDefinitionUpdates {
|
||||
add_or_replace: Vec<AspaDefinition>,
|
||||
remove: Vec<AspaCustomer>,
|
||||
remove: Vec<CustomerAsn>,
|
||||
}
|
||||
|
||||
impl AspaDefinitionUpdates {
|
||||
pub fn new(add_or_replace: Vec<AspaDefinition>, remove: Vec<AspaCustomer>) -> Self {
|
||||
pub fn new(add_or_replace: Vec<AspaDefinition>, remove: Vec<CustomerAsn>) -> Self {
|
||||
AspaDefinitionUpdates { add_or_replace, remove }
|
||||
}
|
||||
pub fn unpack(self) -> (Vec<AspaDefinition>, Vec<AspaCustomer>) {
|
||||
pub fn unpack(self) -> (Vec<AspaDefinition>, Vec<CustomerAsn>) {
|
||||
(self.add_or_replace, self.remove)
|
||||
}
|
||||
}
|
||||
@@ -72,24 +72,24 @@ impl fmt::Display for AspaDefinitionList {
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct AspaDefinition {
|
||||
customer: AspaCustomer,
|
||||
providers: Vec<ProviderAs>,
|
||||
customer: CustomerAsn,
|
||||
providers: Vec<ProviderAsn>,
|
||||
}
|
||||
|
||||
impl AspaDefinition {
|
||||
pub fn new(customer: AspaCustomer, providers: Vec<ProviderAs>) -> Self {
|
||||
pub fn new(customer: CustomerAsn, providers: Vec<ProviderAsn>) -> Self {
|
||||
AspaDefinition { customer, providers }
|
||||
}
|
||||
|
||||
pub fn unpack(self) -> (AspaCustomer, Vec<ProviderAs>) {
|
||||
pub fn unpack(self) -> (CustomerAsn, Vec<ProviderAsn>) {
|
||||
(self.customer, self.providers)
|
||||
}
|
||||
|
||||
pub fn customer(&self) -> AspaCustomer {
|
||||
pub fn customer(&self) -> CustomerAsn {
|
||||
self.customer
|
||||
}
|
||||
|
||||
pub fn providers(&self) -> &Vec<ProviderAs> {
|
||||
pub fn providers(&self) -> &Vec<ProviderAsn> {
|
||||
&self.providers
|
||||
}
|
||||
|
||||
@@ -97,14 +97,14 @@ impl AspaDefinition {
|
||||
/// This is not allowed by spec, and these definitions should
|
||||
/// be rejected by Krill.
|
||||
pub fn customer_used_as_provider(&self) -> bool {
|
||||
self.providers.iter().any(|p| p.provider() == self.customer)
|
||||
self.providers.contains(&self.customer)
|
||||
}
|
||||
|
||||
/// Returns true if there are duplicate provider ASNs. This
|
||||
/// is not allowed by spec and these definitions should be
|
||||
/// rejected by Krill.
|
||||
pub fn contains_duplicate_providers(&self) -> bool {
|
||||
let mut providers: Vec<Asn> = self.providers.iter().map(|p| p.provider()).collect();
|
||||
let mut providers: Vec<Asn> = self.providers.clone();
|
||||
|
||||
let len_before_duplicates = providers.len();
|
||||
|
||||
@@ -114,105 +114,25 @@ impl AspaDefinition {
|
||||
len_before_duplicates > providers.len()
|
||||
}
|
||||
|
||||
/// Returns true if this contains both IPv4 and IPv6 providers.
|
||||
///
|
||||
/// Technically,it is allowed to omit one address family entirely,
|
||||
/// but this will be interpreted as though the user specified an
|
||||
/// AS0 provider for the omitted AFI. This may be counterintuitive,
|
||||
/// so we'd better force people to make an explicit choice.
|
||||
pub fn providers_has_both_afis(&self) -> bool {
|
||||
let mut v4 = false;
|
||||
let mut v6 = false;
|
||||
for p in &self.providers {
|
||||
if !v4 {
|
||||
v4 = p.includes_v4();
|
||||
}
|
||||
if !v6 {
|
||||
v6 = p.includes_v6();
|
||||
}
|
||||
|
||||
if v4 && v6 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
v4 && v6
|
||||
}
|
||||
|
||||
/// Applies an update. This is a no-op in case there is no
|
||||
/// actual change needed (i.e. this is idempotent).
|
||||
pub fn apply_update(&mut self, update: &AspaProvidersUpdate) {
|
||||
for removed in update.removed() {
|
||||
// If the operators tries to remove a provider for a specific AFI limit
|
||||
// only, and we have an existing provider without limit, then we should
|
||||
// keep the provider with the remaining limit.
|
||||
if let Some(limit) = removed.afi_limit() {
|
||||
if let Some(existing) = self
|
||||
.providers
|
||||
.iter()
|
||||
.find(|existing| existing.provider() == removed.provider())
|
||||
{
|
||||
match existing.afi_limit() {
|
||||
None => {
|
||||
let remaining = match limit {
|
||||
AddressFamily::Ipv4 => ProviderAs::new_v6(existing.provider()),
|
||||
AddressFamily::Ipv6 => ProviderAs::new_v4(existing.provider()),
|
||||
};
|
||||
|
||||
self.providers.retain(|p| p.provider() != remaining.provider());
|
||||
self.providers.push(remaining);
|
||||
}
|
||||
Some(_) => {
|
||||
// retain all other ProviderAS, this will retain
|
||||
// a possible ProviderAS for the removed ASN if
|
||||
// its afiLimit was different.
|
||||
self.providers.retain(|p| p != removed);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// there is no limit in the removal, we should remove any existing
|
||||
// ProviderAS for the removed provider ASN regardless of limit.
|
||||
self.providers
|
||||
.retain(|provider| provider.provider() != removed.provider());
|
||||
}
|
||||
self.providers.retain(|provider| provider != removed);
|
||||
}
|
||||
|
||||
for added in update.added() {
|
||||
if let Some(existing) = self
|
||||
.providers
|
||||
.iter()
|
||||
.find(|e| e.provider() == added.provider())
|
||||
.copied()
|
||||
{
|
||||
// If there is any existing provider for the added, and if
|
||||
// that was using an afiLimit which was different, then we
|
||||
// need to merge this into an entry without a limit.
|
||||
//
|
||||
// In other words, if we hade provider listed for IPv4 and
|
||||
// the operator now adds the same provider for IPv6, then
|
||||
// we need to have this provider without afiLimit.
|
||||
//
|
||||
// And, if we hade provider listed for IPv4 and the operator
|
||||
// now adds the same provider without afiLimit, then we need
|
||||
// to have this provider without afiLimit.
|
||||
if existing.afi_limit().is_some() && existing.afi_limit() != added.afi_limit() {
|
||||
// remove the existing entry, then add a new entry without limit
|
||||
self.providers.retain(|p| p != &existing);
|
||||
self.providers.push(ProviderAs::new(added.provider()));
|
||||
}
|
||||
} else {
|
||||
// no entry for this new provider ASN, add it as-is
|
||||
if !self.providers.contains(added) {
|
||||
self.providers.push(*added);
|
||||
}
|
||||
}
|
||||
self.providers.sort_by_key(|p| p.provider());
|
||||
self.providers.sort();
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AspaDefinition {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// example: 65000 => 65001, 65002(v4), 65003(v6)
|
||||
// example: 65000 => 65001, 65002, 65003
|
||||
write!(f, "{} => ", self.customer)?;
|
||||
if self.providers.is_empty() {
|
||||
write!(f, "<none>")?;
|
||||
@@ -238,7 +158,7 @@ impl FromStr for AspaDefinition {
|
||||
|
||||
let customer = {
|
||||
let customer_str = parts.next().ok_or(AspaDefinitionFormatError::CustomerAsMissing)?;
|
||||
AspaCustomer::from_str(customer_str.trim())
|
||||
CustomerAsn::from_str(customer_str.trim())
|
||||
.map_err(|_| AspaDefinitionFormatError::CustomerAsInvalid(customer_str.trim().to_string()))?
|
||||
};
|
||||
|
||||
@@ -249,7 +169,7 @@ impl FromStr for AspaDefinition {
|
||||
if providers_str.trim() != "<none>" {
|
||||
let provider_parts = providers_str.split(',');
|
||||
for provider_part in provider_parts {
|
||||
let provider = ProviderAs::from_str(provider_part.trim())
|
||||
let provider = ProviderAsn::from_str(provider_part.trim())
|
||||
.map_err(|_| AspaDefinitionFormatError::ProviderAsInvalid(provider_part.trim().to_string()))?;
|
||||
providers.push(provider);
|
||||
}
|
||||
@@ -263,12 +183,9 @@ impl FromStr for AspaDefinition {
|
||||
Err(AspaDefinitionFormatError::ExtraParts)
|
||||
} else {
|
||||
// Ensure that the providers are sorted, and there are no duplicates
|
||||
providers.sort_by_key(|p| p.provider());
|
||||
providers.sort();
|
||||
|
||||
match providers
|
||||
.windows(2)
|
||||
.find(|pair| pair[0].provider() == pair[1].provider())
|
||||
{
|
||||
match providers.windows(2).find(|pair| pair[0] == pair[1]) {
|
||||
Some(dup) => Err(AspaDefinitionFormatError::ProviderAsDuplicate(dup[0], dup[1])),
|
||||
None => Ok(AspaDefinition::new(customer, providers)),
|
||||
}
|
||||
@@ -283,7 +200,7 @@ pub enum AspaDefinitionFormatError {
|
||||
CustomerAsMissing,
|
||||
CustomerAsInvalid(String),
|
||||
ProviderAsInvalid(String),
|
||||
ProviderAsDuplicate(ProviderAs, ProviderAs),
|
||||
ProviderAsDuplicate(ProviderAsn, ProviderAsn),
|
||||
ExtraParts,
|
||||
}
|
||||
|
||||
@@ -310,12 +227,12 @@ impl std::error::Error for AspaDefinitionFormatError {}
|
||||
/// AspaDefinition.
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct AspaProvidersUpdate {
|
||||
added: Vec<ProviderAs>,
|
||||
removed: Vec<ProviderAs>,
|
||||
added: Vec<ProviderAsn>,
|
||||
removed: Vec<ProviderAsn>,
|
||||
}
|
||||
|
||||
impl AspaProvidersUpdate {
|
||||
pub fn new(added: Vec<ProviderAs>, removed: Vec<ProviderAs>) -> Self {
|
||||
pub fn new(added: Vec<ProviderAsn>, removed: Vec<ProviderAsn>) -> Self {
|
||||
AspaProvidersUpdate { added, removed }
|
||||
}
|
||||
pub fn empty() -> Self {
|
||||
@@ -334,19 +251,19 @@ impl AspaProvidersUpdate {
|
||||
}
|
||||
|
||||
// Add a provider for both v4 and v6
|
||||
pub fn add(&mut self, provider: ProviderAs) {
|
||||
pub fn add(&mut self, provider: ProviderAsn) {
|
||||
self.added.push(provider);
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, provider: ProviderAs) {
|
||||
pub fn remove(&mut self, provider: ProviderAsn) {
|
||||
self.removed.push(provider);
|
||||
}
|
||||
|
||||
pub fn added(&self) -> &Vec<ProviderAs> {
|
||||
pub fn added(&self) -> &Vec<ProviderAsn> {
|
||||
&self.added
|
||||
}
|
||||
|
||||
pub fn removed(&self) -> &Vec<ProviderAs> {
|
||||
pub fn removed(&self) -> &Vec<ProviderAsn> {
|
||||
&self.removed
|
||||
}
|
||||
}
|
||||
@@ -379,17 +296,17 @@ mod tests {
|
||||
Asn::from_str(s).unwrap()
|
||||
}
|
||||
|
||||
fn provider(s: &str) -> ProviderAs {
|
||||
ProviderAs::from_str(s).unwrap()
|
||||
fn provider(s: &str) -> ProviderAsn {
|
||||
ProviderAsn::from_str(s).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aspa_configuration_to_from_str() {
|
||||
let config = AspaDefinition::new(
|
||||
customer("AS65000"),
|
||||
vec![provider("AS65001"), provider("AS65002(v4)"), provider("AS65003(v6)")],
|
||||
vec![provider("AS65001"), provider("AS65002"), provider("AS65003")],
|
||||
);
|
||||
let config_str = "AS65000 => AS65001, AS65002(v4), AS65003(v6)";
|
||||
let config_str = "AS65000 => AS65001, AS65002, AS65003";
|
||||
|
||||
let to_str = config.to_string();
|
||||
assert_eq!(config_str, to_str.as_str());
|
||||
|
||||
@@ -15,7 +15,7 @@ use rpki::{
|
||||
use crate::{
|
||||
commons::{
|
||||
api::{
|
||||
ArgKey, ArgVal, AspaCustomer, AspaProvidersUpdate, Message, RoaConfigurationUpdates, RtaName,
|
||||
ArgKey, ArgVal, AspaProvidersUpdate, CustomerAsn, Message, RoaConfigurationUpdates, RtaName,
|
||||
StorableParentContact,
|
||||
},
|
||||
eventsourcing::{Event, InitEvent, StoredCommand, StoredEffect, WithStorableDetails},
|
||||
@@ -445,11 +445,11 @@ pub enum CertAuthStorableCommand {
|
||||
updates: AspaDefinitionUpdates,
|
||||
},
|
||||
AspasUpdateExisting {
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
update: AspaProvidersUpdate,
|
||||
},
|
||||
AspaRemove {
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
},
|
||||
BgpSecDefinitionUpdates, // details in events
|
||||
RepoUpdate {
|
||||
|
||||
+7
-12
@@ -18,7 +18,7 @@ use rpki::{
|
||||
|
||||
use crate::{
|
||||
commons::{
|
||||
api::{rrdp::PublicationDeltaError, AspaCustomer, ErrorResponse, RoaPayload},
|
||||
api::{rrdp::PublicationDeltaError, CustomerAsn, ErrorResponse, RoaPayload},
|
||||
crypto::SignerError,
|
||||
eventsourcing::{AggregateStoreError, KeyValueError},
|
||||
util::httpclient,
|
||||
@@ -288,13 +288,12 @@ pub enum Error {
|
||||
//-----------------------------------------------------------------
|
||||
// Autonomous System Provider Authorization - ASPA
|
||||
//-----------------------------------------------------------------
|
||||
AspaCustomerAsNotEntitled(CaHandle, AspaCustomer),
|
||||
AspaCustomerAlreadyPresent(CaHandle, AspaCustomer),
|
||||
AspaCustomerUnknown(CaHandle, AspaCustomer),
|
||||
AspaCustomerAsProvider(CaHandle, AspaCustomer),
|
||||
AspaProvidersDuplicates(CaHandle, AspaCustomer),
|
||||
AspaProvidersEmpty(CaHandle, AspaCustomer),
|
||||
AspaProvidersSingleAfi(CaHandle, AspaCustomer),
|
||||
AspaCustomerAsNotEntitled(CaHandle, CustomerAsn),
|
||||
AspaCustomerAlreadyPresent(CaHandle, CustomerAsn),
|
||||
AspaCustomerUnknown(CaHandle, CustomerAsn),
|
||||
AspaCustomerAsProvider(CaHandle, CustomerAsn),
|
||||
AspaProvidersDuplicates(CaHandle, CustomerAsn),
|
||||
AspaProvidersEmpty(CaHandle, CustomerAsn),
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// BGP Sec
|
||||
@@ -485,7 +484,6 @@ impl fmt::Display for Error {
|
||||
Error::AspaCustomerAsProvider(_ca, asn) => write!(f, "ASPA for customer AS '{}' cannot have that AS as provider", asn),
|
||||
Error::AspaProvidersDuplicates(_ca, asn) => write!(f, "ASPA for customer AS '{}' cannot have duplicate providers", asn),
|
||||
Error::AspaCustomerUnknown(_ca, asn) => write!(f, "No current ASPA exists for customer AS '{}'", asn),
|
||||
Error::AspaProvidersSingleAfi(_ca, asn) => write!(f, "ASPA for customer AS '{}' only has providers for one address family. Please include an explicit AS0 provider for the missing address family if this is intentional.", asn),
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// BGPSec
|
||||
@@ -914,9 +912,6 @@ impl Error {
|
||||
Error::AspaCustomerUnknown(ca, asn) => ErrorResponse::new("ca-aspa-unknown-customer-as", self)
|
||||
.with_ca(ca)
|
||||
.with_asn(*asn),
|
||||
Error::AspaProvidersSingleAfi(ca, asn) => ErrorResponse::new("ca-aspa-providers-single-afi", self)
|
||||
.with_ca(ca)
|
||||
.with_asn(*asn),
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// BGP Sec
|
||||
|
||||
@@ -21,7 +21,7 @@ use rpki::{
|
||||
|
||||
use crate::{
|
||||
commons::{
|
||||
api::{AspaCustomer, AspaDefinition, AspaProvidersUpdate, ObjectName},
|
||||
api::{AspaDefinition, AspaProvidersUpdate, CustomerAsn, ObjectName},
|
||||
crypto::KrillSigner,
|
||||
error::Error,
|
||||
KrillResult,
|
||||
@@ -71,7 +71,7 @@ pub fn make_aspa_object(
|
||||
/// holds the ASN.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct AspaDefinitions {
|
||||
attestations: HashMap<AspaCustomer, AspaDefinition>,
|
||||
attestations: HashMap<CustomerAsn, AspaDefinition>,
|
||||
}
|
||||
|
||||
impl AspaDefinitions {
|
||||
@@ -82,12 +82,12 @@ impl AspaDefinitions {
|
||||
}
|
||||
|
||||
// Remove an existing definition (if it is present)
|
||||
pub fn remove(&mut self, customer: AspaCustomer) {
|
||||
pub fn remove(&mut self, customer: CustomerAsn) {
|
||||
self.attestations.remove(&customer);
|
||||
}
|
||||
|
||||
// Applies an update. This assumes that the update was verified beforehand.
|
||||
pub fn apply_update(&mut self, customer: AspaCustomer, update: &AspaProvidersUpdate) {
|
||||
pub fn apply_update(&mut self, customer: CustomerAsn, update: &AspaProvidersUpdate) {
|
||||
if let Some(current) = self.attestations.get_mut(&customer) {
|
||||
current.apply_update(update);
|
||||
|
||||
@@ -114,11 +114,11 @@ impl AspaDefinitions {
|
||||
/// # Set operations
|
||||
///
|
||||
impl AspaDefinitions {
|
||||
pub fn get(&self, customer: AspaCustomer) -> Option<&AspaDefinition> {
|
||||
pub fn get(&self, customer: CustomerAsn) -> Option<&AspaDefinition> {
|
||||
self.attestations.get(&customer)
|
||||
}
|
||||
|
||||
pub fn has(&self, customer: AspaCustomer) -> bool {
|
||||
pub fn has(&self, customer: CustomerAsn) -> bool {
|
||||
self.attestations.contains_key(&customer)
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ impl AspaDefinitions {
|
||||
|
||||
/// ASPA objects held by a resource class in a CA.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct AspaObjects(HashMap<AspaCustomer, AspaInfo>);
|
||||
pub struct AspaObjects(HashMap<CustomerAsn, AspaInfo>);
|
||||
|
||||
impl AspaObjects {
|
||||
pub fn make_aspa(
|
||||
@@ -292,7 +292,7 @@ impl AspaInfo {
|
||||
&self.definition
|
||||
}
|
||||
|
||||
pub fn customer(&self) -> AspaCustomer {
|
||||
pub fn customer(&self) -> CustomerAsn {
|
||||
self.definition.customer()
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,11 @@ use crate::{
|
||||
commons::{
|
||||
api::{
|
||||
import::{ExportChild, ImportChild, ImportChildCertificate},
|
||||
AspaCustomer, AspaDefinition, AspaDefinitionList, AspaDefinitionUpdates, AspaProvidersUpdate, BgpSecAsnKey,
|
||||
AspaDefinition, AspaDefinitionList, AspaDefinitionUpdates, AspaProvidersUpdate, BgpSecAsnKey,
|
||||
BgpSecCsrInfoList, BgpSecDefinitionUpdates, CertAuthInfo, CertAuthStorableCommand, ConfiguredRoa,
|
||||
IdCertInfo, ObjectName, ParentCaContact, ReceivedCert, RepositoryContact, ResourceClassNameMapping,
|
||||
Revocation, RoaConfiguration, RoaConfigurationUpdates, RtaList, RtaName, RtaPrepResponse,
|
||||
CustomerAsn, IdCertInfo, ObjectName, ParentCaContact, ReceivedCert, RepositoryContact,
|
||||
ResourceClassNameMapping, Revocation, RoaConfiguration, RoaConfigurationUpdates, RtaList, RtaName,
|
||||
RtaPrepResponse,
|
||||
},
|
||||
crypto::{CsrInfo, KrillSigner},
|
||||
error::{Error, RoaDeltaError},
|
||||
@@ -1877,10 +1878,6 @@ impl CertAuth {
|
||||
return Err(Error::AspaCustomerAsProvider(self.handle.clone(), customer));
|
||||
}
|
||||
|
||||
if !aspa_config.providers_has_both_afis() {
|
||||
return Err(Error::AspaProvidersSingleAfi(self.handle.clone(), customer));
|
||||
}
|
||||
|
||||
if aspa_config.contains_duplicate_providers() {
|
||||
return Err(Error::AspaProvidersDuplicates(self.handle.clone(), customer));
|
||||
}
|
||||
@@ -1926,7 +1923,7 @@ impl CertAuth {
|
||||
|
||||
pub fn aspas_update(
|
||||
&self,
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
update: AspaProvidersUpdate,
|
||||
config: &Config,
|
||||
signer: &KrillSigner,
|
||||
@@ -1992,7 +1989,7 @@ impl CertAuth {
|
||||
/// the configured AspaDefinition. I.e. this gives us idempotence and e.g. allows
|
||||
/// an operator just issue a command to add a provider for a customer ASN, and
|
||||
/// if it was already authorised then no work is needed.
|
||||
fn updated_allowed_and_needed(&self, customer: AspaCustomer, update: &AspaProvidersUpdate) -> KrillResult<bool> {
|
||||
fn updated_allowed_and_needed(&self, customer: CustomerAsn, update: &AspaProvidersUpdate) -> KrillResult<bool> {
|
||||
// The easiest way to check this is by getting the existing definition,
|
||||
// or a default empty one if we did not have one, then apply the update
|
||||
// on a copy and verify if it's actually changed, and if so if the
|
||||
@@ -2018,8 +2015,6 @@ impl CertAuth {
|
||||
Err(Error::AspaCustomerAsNotEntitled(self.handle().clone(), customer))
|
||||
} else if updated.customer_used_as_provider() {
|
||||
Err(Error::AspaCustomerAsProvider(self.handle().clone(), customer))
|
||||
} else if !updated.providers_has_both_afis() {
|
||||
Err(Error::AspaProvidersSingleAfi(self.handle().clone(), customer))
|
||||
} else {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ use crate::{
|
||||
commons::{
|
||||
actor::Actor,
|
||||
api::{
|
||||
import::ImportChild, AspaCustomer, AspaDefinitionUpdates, AspaProvidersUpdate, BgpSecDefinitionUpdates,
|
||||
CertAuthStorableCommand, IdCertInfo, ParentCaContact, ReceivedCert, RepositoryContact,
|
||||
import::ImportChild, AspaDefinitionUpdates, AspaProvidersUpdate, BgpSecDefinitionUpdates,
|
||||
CertAuthStorableCommand, CustomerAsn, IdCertInfo, ParentCaContact, ReceivedCert, RepositoryContact,
|
||||
ResourceClassNameMapping, RoaConfigurationUpdates, RtaName, StorableRcEntitlement,
|
||||
},
|
||||
crypto::KrillSigner,
|
||||
@@ -199,7 +199,7 @@ pub enum CertAuthCommandDetails {
|
||||
AspasUpdate(AspaDefinitionUpdates, Arc<Config>, Arc<KrillSigner>),
|
||||
|
||||
// Updates an existing AspaProviders for the given AspaCustomer
|
||||
AspasUpdateExisting(AspaCustomer, AspaProvidersUpdate, Arc<Config>, Arc<KrillSigner>),
|
||||
AspasUpdateExisting(CustomerAsn, AspaProvidersUpdate, Arc<Config>, Arc<KrillSigner>),
|
||||
|
||||
// Re-issue any and all ASPA objects which would otherwise expire in
|
||||
// some time (default 4 weeks, configurable). Note that this command
|
||||
@@ -690,7 +690,7 @@ impl CertAuthCommandDetails {
|
||||
|
||||
pub fn aspas_update_aspa(
|
||||
ca: &CaHandle,
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
update: AspaProvidersUpdate,
|
||||
config: Arc<Config>,
|
||||
signer: Arc<KrillSigner>,
|
||||
|
||||
@@ -12,7 +12,7 @@ use rpki::{
|
||||
use crate::{
|
||||
commons::{
|
||||
api::{
|
||||
AspaCustomer, AspaDefinition, AspaProvidersUpdate, BgpSecAsnKey, IdCertInfo, IssuedCertificate, ObjectName,
|
||||
AspaDefinition, AspaProvidersUpdate, BgpSecAsnKey, CustomerAsn, IdCertInfo, IssuedCertificate, ObjectName,
|
||||
ParentCaContact, ReceivedCert, RepositoryContact, ResourceClassNameMapping, RoaAggregateKey, RtaName,
|
||||
SuspendedCert, UnsuspendedCert,
|
||||
},
|
||||
@@ -236,11 +236,11 @@ pub struct AspaObjectsUpdates {
|
||||
updated: Vec<AspaInfo>,
|
||||
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
removed: Vec<AspaCustomer>,
|
||||
removed: Vec<CustomerAsn>,
|
||||
}
|
||||
|
||||
impl AspaObjectsUpdates {
|
||||
pub fn new(updated: Vec<AspaInfo>, removed: Vec<AspaCustomer>) -> Self {
|
||||
pub fn new(updated: Vec<AspaInfo>, removed: Vec<CustomerAsn>) -> Self {
|
||||
AspaObjectsUpdates { updated, removed }
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ impl AspaObjectsUpdates {
|
||||
self.updated.push(update)
|
||||
}
|
||||
|
||||
pub fn add_removed(&mut self, customer: AspaCustomer) {
|
||||
pub fn add_removed(&mut self, customer: CustomerAsn) {
|
||||
self.removed.push(customer)
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ impl AspaObjectsUpdates {
|
||||
!self.is_empty()
|
||||
}
|
||||
|
||||
pub fn unpack(self) -> (Vec<AspaInfo>, Vec<AspaCustomer>) {
|
||||
pub fn unpack(self) -> (Vec<AspaInfo>, Vec<CustomerAsn>) {
|
||||
(self.updated, self.removed)
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ impl AspaObjectsUpdates {
|
||||
&self.updated
|
||||
}
|
||||
|
||||
pub fn removed(&self) -> &Vec<AspaCustomer> {
|
||||
pub fn removed(&self) -> &Vec<CustomerAsn> {
|
||||
&self.removed
|
||||
}
|
||||
}
|
||||
@@ -588,11 +588,11 @@ pub enum CertAuthEvent {
|
||||
aspa_config: AspaDefinition,
|
||||
},
|
||||
AspaConfigUpdated {
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
update: AspaProvidersUpdate,
|
||||
},
|
||||
AspaConfigRemoved {
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
},
|
||||
AspaObjectsUpdated {
|
||||
// Tracks ASPA *object* which are (re-)issued in a resource class.
|
||||
|
||||
@@ -30,8 +30,8 @@ use crate::{
|
||||
RoaConfigurationUpdates, Timestamp,
|
||||
},
|
||||
api::{
|
||||
AddChildRequest, AspaCustomer, AspaDefinitionList, AspaDefinitionUpdates, AspaProvidersUpdate,
|
||||
CaCommandDetails, CertAuthList, CertAuthSummary, ChildCaInfo, CommandHistory, CommandHistoryCriteria,
|
||||
AddChildRequest, AspaDefinitionList, AspaDefinitionUpdates, AspaProvidersUpdate, CaCommandDetails,
|
||||
CertAuthList, CertAuthSummary, ChildCaInfo, CommandHistory, CommandHistoryCriteria, CustomerAsn,
|
||||
ParentCaContact, ParentCaReq, ReceivedCert, RepositoryContact, RtaName, UpdateChildRequest,
|
||||
},
|
||||
crypto::KrillSigner,
|
||||
@@ -2294,7 +2294,7 @@ impl CaManager {
|
||||
pub async fn ca_aspas_update_aspa(
|
||||
&self,
|
||||
ca: CaHandle,
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
update: AspaProvidersUpdate,
|
||||
actor: &Actor,
|
||||
) -> KrillResult<()> {
|
||||
|
||||
@@ -21,13 +21,13 @@ use crate::{
|
||||
api::{
|
||||
self,
|
||||
import::{ExportChild, ImportChild},
|
||||
AddChildRequest, AllCertAuthIssues, AspaCustomer, AspaDefinitionList, AspaDefinitionUpdates,
|
||||
AspaProvidersUpdate, BgpSecCsrInfoList, BgpSecDefinitionUpdates, CaCommandDetails, CaRepoDetails,
|
||||
CertAuthInfo, CertAuthInit, CertAuthIssues, CertAuthList, CertAuthStats, ChildCaInfo,
|
||||
ChildrenConnectionStats, CommandHistory, CommandHistoryCriteria, ConfiguredRoa, IdCertInfo,
|
||||
ParentCaContact, ParentCaReq, PublicationServerUris, PublisherDetails, ReceivedCert,
|
||||
RepoFileDeleteCriteria, RepositoryContact, RoaConfiguration, RoaConfigurationUpdates, RoaPayload, RtaList,
|
||||
RtaName, RtaPrepResponse, ServerInfo, Timestamp, UpdateChildRequest,
|
||||
AddChildRequest, AllCertAuthIssues, AspaDefinitionList, AspaDefinitionUpdates, AspaProvidersUpdate,
|
||||
BgpSecCsrInfoList, BgpSecDefinitionUpdates, CaCommandDetails, CaRepoDetails, CertAuthInfo, CertAuthInit,
|
||||
CertAuthIssues, CertAuthList, CertAuthStats, ChildCaInfo, ChildrenConnectionStats, CommandHistory,
|
||||
CommandHistoryCriteria, ConfiguredRoa, CustomerAsn, IdCertInfo, ParentCaContact, ParentCaReq,
|
||||
PublicationServerUris, PublisherDetails, ReceivedCert, RepoFileDeleteCriteria, RepositoryContact,
|
||||
RoaConfiguration, RoaConfigurationUpdates, RoaPayload, RtaList, RtaName, RtaPrepResponse, ServerInfo,
|
||||
Timestamp, UpdateChildRequest,
|
||||
},
|
||||
bgp::{BgpAnalyser, BgpAnalysisReport, BgpAnalysisSuggestion},
|
||||
crypto::KrillSignerBuilder,
|
||||
@@ -930,7 +930,7 @@ impl KrillServer {
|
||||
pub async fn ca_aspas_update_aspa(
|
||||
&self,
|
||||
ca: CaHandle,
|
||||
customer: AspaCustomer,
|
||||
customer: CustomerAsn,
|
||||
update: AspaProvidersUpdate,
|
||||
actor: &Actor,
|
||||
) -> KrillEmptyResult {
|
||||
|
||||
+7
-7
@@ -32,11 +32,11 @@ use crate::{
|
||||
},
|
||||
commons::{
|
||||
api::{
|
||||
self, AddChildRequest, AspaCustomer, AspaDefinition, AspaDefinitionList, AspaProvidersUpdate, BgpSecAsnKey,
|
||||
self, AddChildRequest, AspaDefinition, AspaDefinitionList, AspaProvidersUpdate, BgpSecAsnKey,
|
||||
BgpSecCsrInfoList, BgpSecDefinition, CertAuthInfo, CertAuthInit, CertifiedKeyInfo, ConfiguredRoa,
|
||||
ConfiguredRoas, ObjectName, ParentCaContact, ParentCaReq, ParentStatuses, PublicationServerUris,
|
||||
PublisherDetails, PublisherList, ResourceClassKeysInfo, RoaConfiguration, RoaConfigurationUpdates,
|
||||
RoaPayload, RtaList, RtaName, RtaPrepResponse, TypedPrefix, UpdateChildRequest,
|
||||
ConfiguredRoas, CustomerAsn, ObjectName, ParentCaContact, ParentCaReq, ParentStatuses,
|
||||
PublicationServerUris, PublisherDetails, PublisherList, ResourceClassKeysInfo, RoaConfiguration,
|
||||
RoaConfigurationUpdates, RoaPayload, RtaList, RtaName, RtaPrepResponse, TypedPrefix, UpdateChildRequest,
|
||||
},
|
||||
bgp::{Announcement, BgpAnalysisReport, BgpAnalysisSuggestion},
|
||||
crypto::SignSupport,
|
||||
@@ -612,15 +612,15 @@ pub async fn expect_aspa_definitions(ca: &CaHandle, expected_aspas: AspaDefiniti
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn ca_aspas_update(ca: &CaHandle, customer: AspaCustomer, update: AspaProvidersUpdate) {
|
||||
pub async fn ca_aspas_update(ca: &CaHandle, customer: CustomerAsn, update: AspaProvidersUpdate) {
|
||||
krill_admin(Command::CertAuth(CaCommand::AspasUpdate(ca.clone(), customer, update))).await;
|
||||
}
|
||||
|
||||
pub async fn ca_aspas_update_expect_error(ca: &CaHandle, customer: AspaCustomer, update: AspaProvidersUpdate) {
|
||||
pub async fn ca_aspas_update_expect_error(ca: &CaHandle, customer: CustomerAsn, update: AspaProvidersUpdate) {
|
||||
krill_admin_expect_error(Command::CertAuth(CaCommand::AspasUpdate(ca.clone(), customer, update))).await;
|
||||
}
|
||||
|
||||
pub async fn ca_aspas_remove(ca: &CaHandle, customer: AspaCustomer) {
|
||||
pub async fn ca_aspas_remove(ca: &CaHandle, customer: CustomerAsn) {
|
||||
krill_admin(Command::CertAuth(CaCommand::AspasRemove(ca.clone(), customer))).await;
|
||||
}
|
||||
|
||||
|
||||
+27
-71
@@ -8,10 +8,9 @@ use rpki::{
|
||||
};
|
||||
|
||||
use krill::{
|
||||
commons::api::{AspaCustomer, AspaDefinition, AspaDefinitionList, AspaProvidersUpdate, ObjectName},
|
||||
commons::api::{AspaDefinition, AspaDefinitionList, AspaProvidersUpdate, CustomerAsn, ObjectName, ProviderAsn},
|
||||
test::*,
|
||||
};
|
||||
use rpki::repository::aspa::ProviderAs;
|
||||
|
||||
#[tokio::test]
|
||||
async fn functional_aspa() {
|
||||
@@ -96,7 +95,7 @@ async fn functional_aspa() {
|
||||
info("##################################################################");
|
||||
info("");
|
||||
|
||||
let aspa_65000 = AspaDefinition::from_str("AS65000 => AS65000, AS65003(v4), AS65005(v6)").unwrap();
|
||||
let aspa_65000 = AspaDefinition::from_str("AS65000 => AS65000, AS65003, AS65005").unwrap();
|
||||
|
||||
ca_aspas_add_expect_error(&ca, aspa_65000.clone()).await;
|
||||
|
||||
@@ -105,23 +104,6 @@ async fn functional_aspa() {
|
||||
expect_aspa_definitions(&ca, AspaDefinitionList::new(aspas)).await;
|
||||
}
|
||||
|
||||
{
|
||||
info("##################################################################");
|
||||
info("# #");
|
||||
info("# Reject ASPA using one provider AFI only #");
|
||||
info("# #");
|
||||
info("##################################################################");
|
||||
info("");
|
||||
|
||||
let aspa_one_afi = AspaDefinition::from_str("AS65000 => AS65003(v4), AS65005(v4)").unwrap();
|
||||
|
||||
ca_aspas_add_expect_error(&ca, aspa_one_afi.clone()).await;
|
||||
|
||||
let aspas = vec![];
|
||||
expect_aspa_objects(&ca, &aspas).await;
|
||||
expect_aspa_definitions(&ca, AspaDefinitionList::new(aspas)).await;
|
||||
}
|
||||
|
||||
{
|
||||
info("##################################################################");
|
||||
info("# #");
|
||||
@@ -130,7 +112,7 @@ async fn functional_aspa() {
|
||||
info("##################################################################");
|
||||
info("");
|
||||
|
||||
let aspa_65000 = AspaDefinition::from_str("AS65000 => AS65002, AS65003(v4), AS65005(v6)").unwrap();
|
||||
let aspa_65000 = AspaDefinition::from_str("AS65000 => AS65002, AS65003, AS65005").unwrap();
|
||||
|
||||
ca_aspas_add(&ca, aspa_65000.clone()).await;
|
||||
|
||||
@@ -147,15 +129,15 @@ async fn functional_aspa() {
|
||||
info("##################################################################");
|
||||
info("");
|
||||
|
||||
let customer = AspaCustomer::from_str("AS65000").unwrap();
|
||||
let customer = CustomerAsn::from_str("AS65000").unwrap();
|
||||
let aspa_update = AspaProvidersUpdate::new(
|
||||
vec![ProviderAs::from_str("AS65006").unwrap()],
|
||||
vec![ProviderAs::from_str("AS65002").unwrap()],
|
||||
vec![ProviderAsn::from_str("AS65006").unwrap()],
|
||||
vec![ProviderAsn::from_str("AS65002").unwrap()],
|
||||
);
|
||||
|
||||
ca_aspas_update(&ca, customer, aspa_update).await;
|
||||
|
||||
let updated_aspa = AspaDefinition::from_str("AS65000 => AS65003(v4), AS65005(v6), AS65006").unwrap();
|
||||
let updated_aspa = AspaDefinition::from_str("AS65000 => AS65003, AS65005, AS65006").unwrap();
|
||||
let aspas = vec![updated_aspa.clone()];
|
||||
|
||||
expect_aspa_objects(&ca, &aspas).await;
|
||||
@@ -170,12 +152,12 @@ async fn functional_aspa() {
|
||||
info("##################################################################");
|
||||
info("");
|
||||
|
||||
let customer = AspaCustomer::from_str("AS65000").unwrap();
|
||||
let aspa_update = AspaProvidersUpdate::new(vec![ProviderAs::from_str("AS65000").unwrap()], vec![]);
|
||||
let customer = CustomerAsn::from_str("AS65000").unwrap();
|
||||
let aspa_update = AspaProvidersUpdate::new(vec![ProviderAsn::from_str("AS65000").unwrap()], vec![]);
|
||||
|
||||
ca_aspas_update_expect_error(&ca, customer, aspa_update).await;
|
||||
|
||||
let unmodified_aspa = AspaDefinition::from_str("AS65000 => AS65003(v4), AS65005(v6), AS65006").unwrap();
|
||||
let unmodified_aspa = AspaDefinition::from_str("AS65000 => AS65003, AS65005, AS65006").unwrap();
|
||||
let aspas = vec![unmodified_aspa.clone()];
|
||||
|
||||
expect_aspa_objects(&ca, &aspas).await;
|
||||
@@ -185,43 +167,17 @@ async fn functional_aspa() {
|
||||
{
|
||||
info("##################################################################");
|
||||
info("# #");
|
||||
info("# Reject update that removes one AFI from providers #");
|
||||
info("# Update ASPA and remove all providers, should amount to delete #");
|
||||
info("# #");
|
||||
info("##################################################################");
|
||||
info("");
|
||||
|
||||
let customer = AspaCustomer::from_str("AS65000").unwrap();
|
||||
let customer = CustomerAsn::from_str("AS65000").unwrap();
|
||||
let aspa_update = AspaProvidersUpdate::new(
|
||||
vec![],
|
||||
vec![
|
||||
ProviderAs::from_str("AS65003(v4)").unwrap(),
|
||||
ProviderAs::from_str("AS65006(v4)").unwrap(),
|
||||
],
|
||||
);
|
||||
|
||||
ca_aspas_update_expect_error(&ca, customer, aspa_update).await;
|
||||
|
||||
let unmodified_aspa = AspaDefinition::from_str("AS65000 => AS65003(v4), AS65005(v6), AS65006").unwrap();
|
||||
let aspas = vec![unmodified_aspa.clone()];
|
||||
|
||||
expect_aspa_objects(&ca, &aspas).await;
|
||||
expect_aspa_definitions(&ca, AspaDefinitionList::new(aspas)).await;
|
||||
}
|
||||
|
||||
{
|
||||
info("##################################################################");
|
||||
info("# #");
|
||||
info("# Update ASPA to have no providers #");
|
||||
info("# #");
|
||||
info("##################################################################");
|
||||
|
||||
let customer = AspaCustomer::from_str("AS65000").unwrap();
|
||||
let aspa_update = AspaProvidersUpdate::new(
|
||||
vec![],
|
||||
vec![
|
||||
ProviderAs::from_str("AS65003(v4)").unwrap(),
|
||||
ProviderAs::from_str("AS65005(v6)").unwrap(),
|
||||
ProviderAs::from_str("AS65006").unwrap(),
|
||||
ProviderAsn::from_str("AS65003").unwrap(),
|
||||
ProviderAsn::from_str("AS65005").unwrap(),
|
||||
ProviderAsn::from_str("AS65006").unwrap(),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -247,19 +203,19 @@ async fn functional_aspa() {
|
||||
info("# #");
|
||||
info("##################################################################");
|
||||
|
||||
let customer = AspaCustomer::from_str("AS65000").unwrap();
|
||||
let customer = CustomerAsn::from_str("AS65000").unwrap();
|
||||
let aspa_update = AspaProvidersUpdate::new(
|
||||
vec![
|
||||
ProviderAs::from_str("AS65003(v4)").unwrap(),
|
||||
ProviderAs::from_str("AS65005(v6)").unwrap(),
|
||||
ProviderAs::from_str("AS65006").unwrap(),
|
||||
ProviderAsn::from_str("AS65003").unwrap(),
|
||||
ProviderAsn::from_str("AS65005").unwrap(),
|
||||
ProviderAsn::from_str("AS65006").unwrap(),
|
||||
],
|
||||
vec![],
|
||||
);
|
||||
|
||||
ca_aspas_update(&ca, customer, aspa_update).await;
|
||||
|
||||
let updated_aspa = AspaDefinition::from_str("AS65000 => AS65003(v4), AS65005(v6), AS65006").unwrap();
|
||||
let updated_aspa = AspaDefinition::from_str("AS65000 => AS65003, AS65005, AS65006").unwrap();
|
||||
let aspas = vec![updated_aspa.clone()];
|
||||
|
||||
expect_aspa_objects(&ca, &aspas).await;
|
||||
@@ -274,21 +230,21 @@ async fn functional_aspa() {
|
||||
info("# #");
|
||||
info("##################################################################");
|
||||
|
||||
let customer = AspaCustomer::from_str("AS65000").unwrap();
|
||||
let customer = CustomerAsn::from_str("AS65000").unwrap();
|
||||
let aspa_update = AspaProvidersUpdate::new(
|
||||
vec![
|
||||
ProviderAs::from_str("AS65003(v6)").unwrap(), // should add v6 to existing v4
|
||||
ProviderAs::from_str("AS65005(v6)").unwrap(), // adding, but was already present
|
||||
ProviderAsn::from_str("AS65002").unwrap(), // add
|
||||
ProviderAsn::from_str("AS65005").unwrap(), // add, but was already present, so ignored
|
||||
],
|
||||
vec![
|
||||
ProviderAs::from_str("AS65006(v4)").unwrap(), // removing v4, should retain v6
|
||||
ProviderAs::from_str("AS65007").unwrap(), // removing, but was not present
|
||||
ProviderAsn::from_str("AS65006").unwrap(), // remove
|
||||
ProviderAsn::from_str("AS65007").unwrap(), // remove, but was not present, so ignored
|
||||
],
|
||||
);
|
||||
|
||||
ca_aspas_update(&ca, customer, aspa_update).await;
|
||||
|
||||
let updated_aspa = AspaDefinition::from_str("AS65000 => AS65003, AS65005(v6), AS65006(v6)").unwrap();
|
||||
let updated_aspa = AspaDefinition::from_str("AS65000 => AS65002, AS65003, AS65005").unwrap();
|
||||
let aspas = vec![updated_aspa.clone()];
|
||||
|
||||
expect_aspa_objects(&ca, &aspas).await;
|
||||
@@ -303,7 +259,7 @@ async fn functional_aspa() {
|
||||
info("##################################################################");
|
||||
info("");
|
||||
|
||||
let customer = AspaCustomer::from_str("AS65000").unwrap();
|
||||
let customer = CustomerAsn::from_str("AS65000").unwrap();
|
||||
ca_aspas_remove(&ca, customer).await;
|
||||
|
||||
expect_aspa_objects(&ca, &[]).await;
|
||||
|
||||
@@ -53,7 +53,7 @@ async fn functional_keyroll() {
|
||||
// be re-issued during the roll.
|
||||
let roa_payload = RoaPayload::from_str("10.0.0.0/16-16 => 64496").unwrap();
|
||||
let roa_configuration = RoaConfiguration::from(roa_payload);
|
||||
let aspa_def = AspaDefinition::from_str("AS65000 => AS65002, AS65003(v4), AS65005(v6)").unwrap();
|
||||
let aspa_def = AspaDefinition::from_str("AS65000 => AS65002, AS65003, AS65005").unwrap();
|
||||
let bgpsec_def = {
|
||||
let csr_bytes = include_bytes!("../test-resources/bgpsec/router-csr.der");
|
||||
let csr_bytes = Bytes::copy_from_slice(csr_bytes);
|
||||
|
||||
Reference in New Issue
Block a user