use crate::{
InternalError,
dto::topology::{DirectoryProvenance, FleetDirectoryInput},
model::topology::TopologyDirectoryEntry,
ops::{
config::ConfigOps,
prelude::*,
storage::directory::{
ensure_allowed_roles, ensure_required_roles, ensure_unique_roles,
mapper::{DirectoryEntryMapper, FleetDirectoryDataMapper},
},
},
storage::stable::directory::fleet::{FleetDirectory, FleetDirectoryData},
view::topology::DirectoryEntryView,
};
pub struct FleetDirectoryOps;
pub struct PreparedFleetDirectoryImport(FleetDirectoryData);
impl FleetDirectoryOps {
#[must_use]
pub fn get(role: &CanisterRole) -> Option<Principal> {
FleetDirectory::export()
.entries
.iter()
.find_map(|entry| (&entry.role == role).then_some(entry.pid))
}
#[must_use]
pub(crate) fn data() -> FleetDirectoryData {
FleetDirectory::export()
}
#[must_use]
pub fn entry_projections() -> Vec<DirectoryEntryView> {
DirectoryEntryMapper::records_to_projections(FleetDirectory::export().entries)
}
#[must_use]
pub(crate) fn topology_entries() -> Vec<TopologyDirectoryEntry> {
DirectoryEntryMapper::records_to_topology_entries(&FleetDirectory::export().entries)
}
#[must_use]
pub fn snapshot_args(provenance: DirectoryProvenance) -> FleetDirectoryInput {
FleetDirectoryDataMapper::data_to_input(FleetDirectory::export(), provenance)
}
pub(crate) fn filter_args_for_local_config(
args: FleetDirectoryInput,
) -> Result<FleetDirectoryInput, InternalError> {
let allowed = ConfigOps::get()?.services.fleet.roles.clone();
Ok(FleetDirectoryInput {
provenance: args.provenance,
entries: args
.entries
.into_iter()
.filter(|entry| allowed.contains(&entry.role))
.collect(),
})
}
pub(crate) fn import_args_allow_incomplete(
args: FleetDirectoryInput,
) -> Result<(), InternalError> {
let prepared = Self::prepare_args_allow_incomplete(args)?;
Self::commit_prepared(prepared);
Ok(())
}
pub(crate) fn prepare_args_allow_incomplete(
args: FleetDirectoryInput,
) -> Result<PreparedFleetDirectoryImport, InternalError> {
let data = FleetDirectoryDataMapper::input_to_data(args);
ensure_unique_roles(&data.entries, "Fleet")?;
let allowed = ConfigOps::get()?.services.fleet.roles.clone();
ensure_allowed_roles(&data.entries, "Fleet", &allowed)?;
Ok(PreparedFleetDirectoryImport(data))
}
pub(crate) fn commit_prepared(prepared: PreparedFleetDirectoryImport) {
FleetDirectory::import(prepared.0);
}
pub(crate) fn import(data: FleetDirectoryData) -> Result<(), InternalError> {
ensure_unique_roles(&data.entries, "Fleet")?;
let required = ConfigOps::get()?.services.fleet.roles.clone();
ensure_allowed_roles(&data.entries, "Fleet", &required)?;
ensure_required_roles(&data.entries, "Fleet", &required)?;
FleetDirectory::import(data);
Ok(())
}
pub(crate) fn import_trusted_partial(data: FleetDirectoryData) -> Result<(), InternalError> {
ensure_unique_roles(&data.entries, "Fleet")?;
FleetDirectory::import(data);
Ok(())
}
}