use std::collections::HashMap;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use bytes::Bytes;
use clap::crate_version;
use chrono::Duration;
use futures_util::future::try_join_all;
use log::info;
use rpki::{
ca::{
idexchange,
idexchange::{CaHandle, ChildHandle, ParentHandle, PublisherHandle},
},
repository::resources::ResourceSet,
uri,
};
use crate::daemon::http::auth::AuthInfo;
use crate::{
commons::{
actor::Actor,
crypto::KrillSignerBuilder,
error::Error,
KrillEmptyResult, KrillResult,
},
constants::*,
config::Config,
server::{
ca::{
self, CaManager, CaStatus,
},
mq::{now, Task, TaskQueue},
pubd::RepositoryManager,
scheduler::Scheduler,
},
};
use crate::api;
use crate::api::admin::{
AddChildRequest, CertAuthInit, ParentCaContact, ParentCaReq,
PublicationServerUris, PublisherDetails, RepoFileDeleteCriteria,
RepositoryContact, UpdateChildRequest,
};
use crate::api::aspa::{
AspaDefinitionList, AspaDefinitionUpdates, AspaProvidersUpdate,
CustomerAsn,
};
use crate::api::bgp::{BgpAnalysisReport, BgpAnalysisSuggestion};
use crate::api::bgpsec::{BgpSecCsrInfoList, BgpSecDefinitionUpdates};
use crate::api::ca::{
CaRepoDetails, CertAuthInfo, CertAuthIssues,
CertAuthList, CertAuthStats, ChildCaInfo, ChildrenConnectionStats,
IdCertInfo, RtaList, RtaName,
RtaPrepResponse,
};
use crate::api::history::{
CommandDetails, CommandHistory, CommandHistoryCriteria
};
use crate::api::import::ImportChild;
use crate::api::pubd::RepoStats;
use crate::api::roa::{
ConfiguredRoa, RoaConfiguration, RoaConfigurationUpdates, RoaPayload,
};
use crate::api::rta::{
ResourceTaggedAttestation, RtaContentRequest, RtaPrepareRequest,
};
use crate::api::ta::{
ApiTrustAnchorSignedRequest, TaCertDetails, TrustAnchorSignedResponse,
TrustAnchorSignerInfo,
};
use crate::constants::{TA_NAME, ta_handle};
use crate::server::bgp::BgpAnalyser;
pub struct KrillManager {
service_uri: uri::Https,
repo_manager: Arc<RepositoryManager>,
ca_manager: Arc<ca::CaManager>,
bgp_analyser: Arc<BgpAnalyser>,
mq: Arc<TaskQueue>,
system_actor: Actor,
pub config: Arc<Config>,
}
impl KrillManager {
pub async fn build(config: Arc<Config>) -> KrillResult<Self> {
let service_uri = config.service_uri();
info!("Starting {} v{}", KRILL_SERVER_APP, crate_version!());
info!("{KRILL_SERVER_APP} uses service uri: {service_uri}");
let probe_interval =
std::time::Duration::from_secs(config.signer_probe_retry_seconds);
let signer = KrillSignerBuilder::new(
&config.storage_uri,
probe_interval,
&config.signers,
)
.with_default_signer(config.default_signer())
.with_one_off_signer(config.one_off_signer())
.build()?;
let signer = Arc::new(signer);
let system_actor = ACTOR_DEF_KRILL;
let mq = Arc::new(TaskQueue::new(&config.storage_uri)?);
let repo_manager = Arc::new(RepositoryManager::build(
config.clone(),
mq.clone(),
signer.clone(),
)?);
let ca_manager = Arc::new(
ca::CaManager::build(
config.clone(),
mq.clone(),
signer,
system_actor.clone(),
)
.await?,
);
let bgp_analyser = Arc::new(BgpAnalyser::new(&config));
mq.reschedule_tasks_at_startup()?;
mq.schedule(Task::QueueStartTasks, now())?;
let server = KrillManager {
service_uri,
repo_manager,
ca_manager,
bgp_analyser,
mq,
system_actor,
config: config.clone(),
};
let testbed_handle = testbed_ca_handle();
if let Some(testbed) = config.testbed() {
if server.ca_manager.has_ca(&testbed_handle)? {
if config.benchmark.is_some() {
info!("Resuming BENCHMARK mode - will NOT recreate CAs. If you wanted this, then wipe the data dir and restart.");
} else {
info!("Resuming TESTBED mode - ONLY USE THIS FOR TESTING AND TRAINING!");
}
} else {
let testbed_ca = api::import::ImportCa {
handle: testbed_handle,
parents: vec![api::import::ImportParent {
handle: ta_handle().into_converted(),
resources: ResourceSet::all(),
}],
roas: vec![],
};
let mut import_cas = vec![testbed_ca];
match config.benchmark.as_ref() {
None => {
info!("Enabling TESTBED mode - ONLY USE THIS FOR TESTING AND TRAINING!");
}
Some(benchmark) => {
info!(
"Enabling BENCHMARK mode with {} CAs with {} ROas each - ONLY USE THIS FOR TESTING!",
benchmark.cas, benchmark.ca_roas
);
let testbed_parent: ParentHandle =
testbed_ca_handle().into_converted();
for nr in 0..benchmark.cas {
let handle = CaHandle::new(
format!("benchmark-{nr}").into(),
);
let byte_2_ipv4 = nr / 256;
let byte_3_ipv4 = nr % 256;
let prefix_str = format!(
"10.{byte_2_ipv4}.{byte_3_ipv4}.0/24"
);
let resources =
ResourceSet::from_strs("", &prefix_str, "")
.map_err(|e| {
Error::ResourceSetError(format!(
"cannot parse resources: {e}"
))
})?;
let mut roas: Vec<RoaConfiguration> = vec![];
let asn_range_start = 64512;
for asn in asn_range_start
..asn_range_start + benchmark.ca_roas
{
let payload = RoaPayload::from_str(&format!(
"{prefix_str} => {asn}"
))
.unwrap();
roas.push(payload.into());
}
import_cas.push(api::import::ImportCa {
handle,
parents: vec![api::import::ImportParent {
handle: testbed_parent.clone(),
resources,
}],
roas,
})
}
}
}
let startup_structure = api::import::Structure::for_testbed(
testbed.ta_aia().clone(),
testbed.ta_uri().clone(),
testbed.publication_server_uris(),
import_cas,
);
server.cas_import(startup_structure).await?;
}
}
Ok(server)
}
pub fn build_scheduler(&self) -> Scheduler {
Scheduler::build(
self.mq.clone(),
self.ca_manager.clone(),
self.repo_manager.clone(),
self.bgp_analyser.clone(),
self.config.clone(),
self.system_actor.clone(),
)
}
pub fn service_base_uri(&self) -> &uri::Https {
&self.service_uri
}
}
impl KrillManager {
pub fn system_actor(&self) -> &Actor {
&self.system_actor
}
pub fn testbed_enabled(&self) -> bool {
self.ca_manager.testbed_enabled()
}
pub fn resolve_rrdp_request_path(
&self, path: &str
) -> KrillResult<Option<PathBuf>> {
self.repo_manager.resolve_rrdp_request_path(path)
}
}
impl KrillManager {
pub fn repo_stats(&self) -> KrillResult<RepoStats> {
self.repo_manager.repo_stats()
}
pub fn publishers(&self) -> KrillResult<Vec<PublisherHandle>> {
self.repo_manager.publishers()
}
pub fn add_publisher(
&self,
req: idexchange::PublisherRequest,
actor: &Actor,
) -> KrillResult<idexchange::RepositoryResponse> {
let publisher_handle = req.publisher_handle().clone();
self.repo_manager.create_publisher(req, actor)?;
self.repository_response(&publisher_handle)
}
pub fn remove_publisher(
&self,
publisher: PublisherHandle,
actor: &Actor,
) -> KrillEmptyResult {
self.repo_manager.remove_publisher(publisher, actor)
}
pub fn delete_matching_files(
&self,
criteria: RepoFileDeleteCriteria,
) -> KrillEmptyResult {
self.repo_manager.delete_matching_files(criteria)
}
pub fn get_publisher(
&self,
publisher: PublisherHandle,
) -> KrillResult<PublisherDetails> {
self.repo_manager.get_publisher_details(publisher)
}
pub fn rrdp_base_path(&self) -> PathBuf {
let mut path = self.config.repo_dir().to_path_buf();
path.push("rrdp");
path.to_path_buf()
}
}
impl KrillManager {
pub fn repository_response(
&self,
publisher: &PublisherHandle,
) -> KrillResult<idexchange::RepositoryResponse> {
self.repo_manager.repository_response(publisher)
}
pub fn rfc8181(
&self,
publisher: PublisherHandle,
msg_bytes: Bytes,
) -> KrillResult<Bytes> {
self.repo_manager.rfc8181(publisher, msg_bytes)
}
}
impl KrillManager {
pub fn ta_proxy_enabled(&self) -> bool {
self.config.ta_proxy_enabled()
}
pub fn ta_proxy_init(&self) -> KrillResult<()> {
self.ca_manager.ta_proxy_init()
}
pub fn ta_proxy_id(&self) -> KrillResult<IdCertInfo> {
self.ca_manager.ta_proxy_id()
}
pub fn ta_proxy_publisher_request(
&self,
) -> KrillResult<idexchange::PublisherRequest> {
self.ca_manager.ta_proxy_publisher_request()
}
pub fn ta_proxy_repository_update(
&self,
contact: RepositoryContact,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager
.ta_proxy_repository_update(contact, actor)
}
pub fn ta_proxy_repository_contact(
&self,
) -> KrillResult<RepositoryContact> {
self.ca_manager.ta_proxy_repository_contact()
}
pub fn ta_proxy_signer_add(
&self,
info: TrustAnchorSignerInfo,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager.ta_proxy_signer_add(info, actor)
}
pub fn ta_proxy_signer_update(
&self,
info: TrustAnchorSignerInfo,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager.ta_proxy_signer_update(info, actor)
}
pub fn ta_proxy_signer_make_request(
&self,
actor: &Actor,
) -> KrillResult<ApiTrustAnchorSignedRequest> {
self.ca_manager.ta_proxy_signer_make_request(actor)
}
pub fn ta_proxy_signer_get_request(
&self,
) -> KrillResult<ApiTrustAnchorSignedRequest> {
self.ca_manager.ta_proxy_signer_get_request()
}
pub fn ta_proxy_signer_process_response(
&self,
response: TrustAnchorSignedResponse,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager
.ta_proxy_signer_process_response(response, actor)
}
pub fn ta_proxy_children_add(
&self,
child_request: AddChildRequest,
actor: &Actor,
) -> KrillResult<idexchange::ParentResponse> {
self.ca_manager.ca_add_child(
&ta_handle().convert(),
child_request,
&self.config.service_uri(),
actor,
)
}
pub fn ta_cert_details(&self) -> KrillResult<TaCertDetails> {
let proxy = self.ca_manager.get_trust_anchor_proxy()?;
Ok(proxy.get_ta_details()?.clone())
}
}
impl KrillManager {
pub fn ca_add_child(
&self,
ca: &CaHandle,
req: AddChildRequest,
actor: &Actor,
) -> KrillResult<idexchange::ParentResponse> {
self.ca_manager.ca_add_child(ca, req, &self.service_uri, actor)
}
pub async fn ca_parent_contact(
&self,
ca: &CaHandle,
child: ChildHandle,
) -> KrillResult<ParentCaContact> {
self.ca_manager.ca_parent_contact(ca, child, &self.service_uri)
}
pub fn ca_parent_response(
&self,
ca: &CaHandle,
child: ChildHandle,
) -> KrillResult<idexchange::ParentResponse> {
self.ca_manager.ca_parent_response(ca, child, &self.service_uri)
}
pub fn ca_child_update(
&self,
ca: &CaHandle,
child: ChildHandle,
req: UpdateChildRequest,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_child_update(ca, child, req, actor)
}
pub fn ca_child_remove(
&self,
ca: &CaHandle,
child: ChildHandle,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_child_remove(ca, child, actor)
}
pub fn ca_child_show(
&self,
ca: &CaHandle,
child: &ChildHandle,
) -> KrillResult<ChildCaInfo> {
self.ca_manager.ca_show_child(ca, child)
}
pub fn ca_child_export(
&self,
ca: &CaHandle,
child: &ChildHandle,
) -> KrillResult<ImportChild> {
self.ca_manager.ca_child_export(ca, child)
}
pub fn ca_child_import(
&self,
ca: &CaHandle,
child: ImportChild,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager.ca_child_import(ca, child, actor)
}
pub fn ca_stats_child_connections(
&self,
ca: &CaHandle,
) -> KrillResult<ChildrenConnectionStats> {
self.ca_manager
.get_ca_status(ca)
.map(|status| status.get_children_connection_stats())
}
}
impl KrillManager {
pub fn ca_child_req(
&self,
ca: &CaHandle,
) -> KrillResult<idexchange::ChildRequest> {
self.ca_manager
.get_ca(ca)
.map(|ca| ca.child_request())
}
pub async fn ca_parent_add_or_update(
&self,
ca: CaHandle,
parent_req: ParentCaReq,
actor: &Actor,
) -> KrillEmptyResult {
let contact = ParentCaContact::try_from_rfc8183_parent_response(
parent_req.response.clone(),
)
.map_err(|e| {
Error::CaParentResponseInvalid(ca.clone(), e.to_string())
})?;
self.ca_manager.get_entitlements_from_contact(
&ca, &parent_req.handle, &contact, false
).await?;
self.ca_manager.ca_parent_add_or_update(ca, parent_req, actor)
}
pub async fn ca_parent_remove(
&self,
handle: CaHandle,
parent: ParentHandle,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager
.ca_parent_remove(handle, parent, actor)
.await
}
}
impl KrillManager {
pub fn cas_stats(
&self,
) -> KrillResult<HashMap<CaHandle, CertAuthStats>> {
let mut res = HashMap::new();
for handle in self.ca_manager.ca_handles()? {
if let Ok(ca) = self.ca_manager.get_ca(&handle) {
let roas = ca.configured_roas();
let roa_count = roas.len();
let child_count = ca.children().count();
let bgp_report = if ca.handle().as_str() == "ta"
|| ca.handle().as_str() == "testbed"
{
BgpAnalysisReport::new(vec![])
}
else {
self.bgp_analyser.analyse(
roas.as_slice(), &ca.all_resources(), None
)
};
res.insert(
ca.handle().clone(),
CertAuthStats {
roa_count,
child_count,
bgp_stats: bgp_report.into(),
},
);
}
}
Ok(res)
}
pub async fn cas_import(
&self,
structure: api::import::Structure,
) -> KrillResult<()> {
let actor = Arc::new(self.system_actor().clone());
let mut existing_cas = HashMap::new();
for handle in self.ca_manager.ca_handles()? {
let parent_handle = handle.convert();
let resources =
self.ca_manager.get_ca(&handle)?.all_resources();
existing_cas.insert(parent_handle, resources);
}
structure.validate_ca_hierarchy(existing_cas)?;
if let Some(publication_server_uris) =
structure.publication_server.clone()
{
info!("Initialising publication server");
self.repo_manager.init(publication_server_uris)?;
}
if let Some(import_ta) = structure.ta.clone() {
if self.config.ta_proxy_enabled()
&& self.config.ta_signer_enabled()
{
info!("Creating embedded Trust Anchor");
self.ca_manager
.ta_init_fully_embedded(
import_ta.ta_aia,
vec![import_ta.ta_uri],
import_ta.ta_key_pem,
&self.repo_manager,
&actor,
)
.await?;
} else {
return Err(Error::custom(
"Import TA requires ta_support_enabled = true and ta_signer_enabled = true",
));
}
}
info!("Bulk import {} CAs", structure.cas.len());
let mut import_fns = vec![];
let service_uri = Arc::new(self.config.service_uri());
for ca in structure.cas {
import_fns.push(tokio::spawn(Self::import_ca(
ca,
self.ca_manager.clone(),
self.repo_manager.clone(),
service_uri.clone(),
actor.clone(),
)));
}
try_join_all(import_fns).await.map_err(|e| {
Error::Custom(format!("Could not import CAs: {e}"))
})?;
Ok(())
}
async fn import_ca(
import: api::import::ImportCa,
ca_manager: Arc<CaManager>,
repo_manager: Arc<RepositoryManager>,
service_uri: Arc<uri::Https>,
actor: Arc<Actor>,
) -> KrillEmptyResult {
info!("Importing CA: '{}'", import.handle);
ca_manager.init_ca(import.handle.clone())?;
let pub_req = {
let ca = ca_manager.get_ca(&import.handle)?;
idexchange::PublisherRequest::new(
ca.id_cert().base64.clone(),
import.handle.convert(),
None,
)
};
repo_manager.create_publisher(pub_req, &actor)?;
let repo_contact = {
let repo_response =
repo_manager.repository_response(&import.handle.convert())?;
RepositoryContact::try_from_response(repo_response)
.map_err(Error::rfc8183)?
};
ca_manager
.update_repo(
&repo_manager,
import.handle.clone(),
repo_contact,
false,
&actor,
)
.await?;
for import_parent in import.parents {
let wait_ms = 100;
let max_tries = 3000; let mut tried = 0;
let parent_as_ca: CaHandle = import_parent.handle.convert();
if import_parent.handle.as_str() != TA_NAME {
loop {
tried += 1;
if let Ok(parent) = ca_manager.get_ca(&parent_as_ca)
{
if parent.all_resources().contains(
&import_parent.resources
) {
break;
}
else {
info!(
"Parent {} does not (yet) have resources for {}. Will wait a bit and try again",
parent.handle(),
import.handle
);
}
} else {
info!(
"Parent {} for CA {} is not yet created. Will wait a bit and try again",
parent_as_ca, import.handle
);
}
tokio::time::sleep(std::time::Duration::from_millis(
wait_ms,
))
.await;
if tried >= max_tries {
return Err(Error::Custom(format!(
"Could not import CA {}. Parent: {} is not created",
import.handle, parent_as_ca
)));
}
}
}
let response = {
let ca = ca_manager.get_ca(&import.handle)?;
let id_cert =
ca.child_request().validate().map_err(Error::rfc8183)?;
let child_req = AddChildRequest {
handle: import.handle.convert(),
resources: import_parent.resources,
id_cert,
};
ca_manager
.ca_add_child(
&import_parent.handle.convert(),
child_req,
&service_uri,
&actor,
)?
};
{
let parent_req = ParentCaReq {
handle: import_parent.handle.clone(),
response
};
ca_manager.ca_parent_add_or_update(
import.handle.clone(),
parent_req,
&actor,
)?;
ca_manager.ca_sync_parent(
&import.handle, 0, &import_parent.handle, &actor
).await?;
ca_manager.ca_sync_parent(
&import.handle, 0, &import_parent.handle, &actor
).await?;
if import_parent.handle.as_str() == TA_NAME {
ca_manager.sync_ta_proxy_signer_if_possible()?;
ca_manager.ca_sync_parent(
&import.handle, 0, &import_parent.handle, &actor
).await?;
}
}
}
let roa_updates = RoaConfigurationUpdates {
added: import.roas,
removed: vec![]
};
ca_manager.ca_routes_update(import.handle, roa_updates, &actor)?;
Ok(())
}
pub fn ca_issues(
&self,
ca: &CaHandle,
) -> KrillResult<CertAuthIssues> {
self.ca_manager.get_ca_issues(ca)
}
}
impl KrillManager {
pub fn republish_all(&self, force: bool) -> KrillEmptyResult {
let cas = self.ca_manager.republish_all(force)?;
for ca in cas {
self.cas_repo_sync_single(&ca)?;
}
Ok(())
}
pub fn cas_repo_sync_all(&self) -> KrillEmptyResult {
self.ca_manager.cas_schedule_repo_sync_all()
}
pub fn cas_repo_sync_single(&self, ca: &CaHandle) -> KrillEmptyResult {
self.ca_manager.cas_schedule_repo_sync(ca.clone())
}
pub fn cas_refresh_all(&self) -> KrillEmptyResult {
self.ca_manager.cas_schedule_refresh_all()
}
pub fn cas_refresh_single(
&self,
ca_handle: CaHandle,
) -> KrillEmptyResult {
self.ca_manager.cas_schedule_refresh_single(ca_handle)
}
pub fn cas_schedule_suspend_all(&self) -> KrillEmptyResult {
self.ca_manager.cas_schedule_suspend_all()
}
}
impl KrillManager {
pub fn ca_handles(&self) -> KrillResult<impl Iterator<Item = CaHandle>> {
self.ca_manager.ca_handles().map(Vec::into_iter)
}
pub fn ca_list(&self, auth: &AuthInfo) -> KrillResult<CertAuthList> {
self.ca_manager.ca_list(auth)
}
pub fn ca_info(&self, ca: &CaHandle) -> KrillResult<CertAuthInfo> {
self.ca_manager.get_ca(ca).map(|ca| ca.as_ca_info())
}
pub fn ca_status(&self, ca: &CaHandle) -> KrillResult<CaStatus> {
self.ca_manager.get_ca_status(ca)
}
pub async fn ca_delete(
&self,
ca: &CaHandle,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager
.delete_ca(self.repo_manager.as_ref(), ca, actor)
.await
}
pub fn ca_my_parent_contact(
&self,
ca: &CaHandle,
parent: &ParentHandle,
) -> KrillResult<ParentCaContact> {
let ca = self.ca_manager.get_ca(ca)?;
ca.parent(parent).cloned()
}
pub fn ca_history(
&self,
ca: &CaHandle,
crit: CommandHistoryCriteria,
) -> KrillResult<CommandHistory> {
self.ca_manager.ca_history(ca, crit)
}
pub fn ca_command_details(
&self,
ca: &CaHandle,
version: u64,
) -> KrillResult<CommandDetails> {
self.ca_manager.ca_command_details(ca, version)
}
pub fn ca_publisher_req(
&self,
ca: &CaHandle,
) -> KrillResult<idexchange::PublisherRequest> {
self.ca_manager
.get_ca(ca)
.map(|ca| ca.publisher_request())
}
pub fn ca_init(&self, init: CertAuthInit) -> KrillEmptyResult {
self.ca_manager.init_ca(init.handle)
}
pub fn ca_repo_details(
&self,
ca_handle: &CaHandle,
) -> KrillResult<CaRepoDetails> {
let ca = self.ca_manager.get_ca(ca_handle)?;
let contact = ca.repository_contact()?;
Ok(CaRepoDetails { contact: contact.clone() })
}
pub async fn ca_repo_update(
&self,
ca: CaHandle,
contact: RepositoryContact,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager
.update_repo(self.repo_manager.as_ref(), ca, contact, true, actor)
.await
}
pub fn ca_update_id(
&self,
ca: CaHandle,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_update_id(ca, actor)
}
pub fn ca_keyroll_init(
&self,
ca: CaHandle,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_keyroll_init(ca, Duration::seconds(0), actor)
}
pub fn ca_keyroll_activate(
&self,
ca: CaHandle,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_keyroll_activate(ca, Duration::seconds(0), actor)
}
pub fn rfc6492(
&self,
ca: CaHandle,
msg_bytes: Bytes,
user_agent: Option<String>,
actor: &Actor,
) -> KrillResult<Bytes> {
self.ca_manager.rfc6492(&ca, msg_bytes, user_agent, actor)
}
}
impl KrillManager {
pub fn ca_aspas_definitions_show(
&self,
ca: &CaHandle,
) -> KrillResult<AspaDefinitionList> {
self.ca_manager.ca_aspas_definitions_show(ca)
}
pub fn ca_aspas_definitions_update(
&self,
ca: CaHandle,
updates: AspaDefinitionUpdates,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_aspas_definitions_update(ca, updates, actor)
}
pub fn ca_aspas_update_aspa(
&self,
ca: CaHandle,
customer: CustomerAsn,
update: AspaProvidersUpdate,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_aspas_update_aspa_providers(
ca, customer, update, actor
)
}
}
impl KrillManager {
pub fn ca_bgpsec_definitions_show(
&self,
ca: &CaHandle,
) -> KrillResult<BgpSecCsrInfoList> {
self.ca_manager.ca_bgpsec_definitions_show(ca)
}
pub fn ca_bgpsec_definitions_update(
&self,
ca: CaHandle,
updates: BgpSecDefinitionUpdates,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager.ca_bgpsec_definitions_update(ca, updates, actor)
}
}
impl KrillManager {
pub fn ca_routes_update(
&self,
ca: CaHandle,
updates: RoaConfigurationUpdates,
actor: &Actor,
) -> KrillEmptyResult {
self.ca_manager.ca_routes_update(ca, updates, actor)
}
pub fn ca_routes_show(
&self,
handle: &CaHandle,
) -> KrillResult<Vec<ConfiguredRoa>> {
let ca = self.ca_manager.get_ca(handle)?;
Ok(ca.configured_roas())
}
pub fn ca_routes_bgp_analysis(
&self,
handle: &CaHandle,
) -> KrillResult<BgpAnalysisReport> {
let ca = self.ca_manager.get_ca(handle)?;
let definitions = ca.configured_roas();
let resources_held = ca.all_resources();
Ok(self.bgp_analyser.analyse(
definitions.as_slice(), &resources_held, None
))
}
pub fn ca_routes_bgp_dry_run(
&self,
handle: &CaHandle,
mut updates: RoaConfigurationUpdates,
) -> KrillResult<BgpAnalysisReport> {
let ca = self.ca_manager.get_ca(handle)?;
updates.set_explicit_max_length();
let resources_held = ca.all_resources();
let limit = Some(updates.affected_prefixes());
let would_be_routes = ca.get_updated_authorizations(&updates)?;
let would_be_configurations = would_be_routes.roa_configurations();
let configured_roas =
ca.configured_roas_for_configs(would_be_configurations);
Ok(self.bgp_analyser.analyse(
&configured_roas, &resources_held, limit
))
}
pub fn ca_routes_bgp_suggest(
&self,
handle: &CaHandle,
limit: Option<ResourceSet>,
) -> KrillResult<BgpAnalysisSuggestion> {
let ca = self.ca_manager.get_ca(handle)?;
let configured_roas = ca.configured_roas();
let resources_held = ca.all_resources();
Ok(self.bgp_analyser.suggest(
configured_roas.as_slice(), &resources_held, limit
))
}
pub async fn force_renew_roas(&self) -> KrillResult<()> {
self.ca_manager.force_renew_roas_all(self.system_actor())
}
}
impl KrillManager {
pub fn repository_init(
&self,
uris: PublicationServerUris,
) -> KrillResult<()> {
self.repo_manager.init(uris)
}
pub fn repository_clear(&self) -> KrillResult<()> {
self.repo_manager.repository_clear()
}
pub fn repository_session_reset(&self) -> KrillResult<()> {
self.repo_manager.rrdp_session_reset()
}
}
impl KrillManager {
pub fn rta_list(&self, ca: CaHandle) -> KrillResult<RtaList> {
let ca = self.ca_manager.get_ca(&ca)?;
Ok(ca.rta_list())
}
pub fn rta_show(
&self,
ca: CaHandle,
name: RtaName,
) -> KrillResult<ResourceTaggedAttestation> {
let ca = self.ca_manager.get_ca(&ca)?;
ca.rta_show(&name)
}
pub async fn rta_sign(
&self,
ca: CaHandle,
name: RtaName,
request: RtaContentRequest,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager.rta_sign(ca, name, request, actor)
}
pub async fn rta_multi_prep(
&self,
ca: CaHandle,
name: RtaName,
request: RtaPrepareRequest,
actor: &Actor,
) -> KrillResult<RtaPrepResponse> {
self.ca_manager.rta_multi_prep(&ca, name.clone(), request, actor)?;
let ca = self.ca_manager.get_ca(&ca)?;
ca.rta_prep_response(&name)
}
pub async fn rta_multi_cosign(
&self,
ca: CaHandle,
name: RtaName,
rta: ResourceTaggedAttestation,
actor: &Actor,
) -> KrillResult<()> {
self.ca_manager.rta_multi_cosign(ca, name, rta, actor)
}
}