use bytes::Bytes;
use hyper::Method;
use rpki::ca::idexchange::{
CaHandle, ChildHandle, ParentHandle, ParentResponse,
RepositoryResponse,
};
use crate::api::admin::{ApiRepositoryContact, ParentCaReq, RepositoryContact};
use crate::api::aspa::AspaDefinitionUpdates;
use crate::api::bgp::BgpAnalysisAdvice;
use crate::api::ca::{CertAuthList, CertAuthSummary};
use crate::api::import::ImportChild;
use crate::api::history::CommandHistoryCriteria;
use crate::api::roa::RoaConfigurationUpdates;
use crate::commons::error::Error;
use crate::commons::eventsourcing::AggregateStoreError;
use super::super::auth::Permission;
use super::super::request::{PathIter, Request};
use super::super::response::HttpResponse;
use super::error::DispatchError;
pub async fn dispatch(
request: Request<'_>,
mut path: PathIter<'_>,
) -> Result<HttpResponse, DispatchError> {
match path.parse_opt_next()? {
None => index(request).await,
Some(handle) => ca(request, path, handle).await,
}
}
async fn index(
request: Request<'_>,
) -> Result<HttpResponse, DispatchError> {
match *request.method() {
Method::GET => index_get(request),
Method::POST => index_post(request).await,
_ => Ok(HttpResponse::method_not_allowed())
}
}
fn index_get(
request: Request<'_>,
) -> Result<HttpResponse, DispatchError> {
let (request, auth) = request.proceed_unchecked();
let server = request.empty()?;
Ok(HttpResponse::json(
&CertAuthList {
cas: {
server.krill().ca_handles()?.filter_map(|handle| {
auth.has_permission(
Permission::CaRead, Some(&handle)
).then_some(CertAuthSummary { handle })
}).collect()
}
}
))
}
async fn index_post(
request: Request<'_>,
) -> Result<HttpResponse, DispatchError> {
let (request, _) = request.proceed_permitted(
Permission::CaCreate, None
)?;
let (server, init) = request.read_json().await?;
server.krill().ca_init(init)?;
Ok(HttpResponse::ok())
}
pub async fn ca(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
request.check_permission(Permission::CaRead, Some(&ca))?;
match path.next() {
None => ca_index(request, ca).await,
Some("aspas") => aspas(request, path, ca).await,
Some("bgpsec") => bgpsec(request, path, ca).await,
Some("children") => children(request, path, ca).await,
Some("history") => history(request, path, ca),
Some("id") => id(request, path, ca),
Some("issues") => issues(request, path, ca),
Some("keys") => keys(request, path, ca),
Some("parents") => parents(request, path, ca).await,
Some("repo") => repo(request, path, ca).await,
Some("routes") => routes(request, path, ca).await,
Some("stats") => stats(request, path, ca),
Some("sync") => sync(request, path, ca),
_ => Ok(HttpResponse::not_found())
}
}
async fn ca_index(
request: Request<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_info(&ca)?
))
}
Method::DELETE => {
let (request, auth) = request.proceed_permitted(
Permission::CaDelete, Some(&ca)
)?;
let server = request.empty()?;
server.krill().ca_delete(&ca, auth.actor()).await?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
async fn aspas(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
None => aspas_index(request, ca).await,
Some("as") => aspas_as(request, path, ca).await,
_ => Ok(HttpResponse::not_found())
}
}
async fn aspas_index(
request: Request<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::AspasRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_aspas_definitions_show(&ca)?
))
}
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::AspasUpdate, Some(&ca)
)?;
let (server, updates) = request.read_json().await?;
server.krill().ca_aspas_definitions_update(
ca, updates, auth.actor(),
)?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
async fn aspas_as(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
let customer = path.parse_next()?;
path.check_exhausted()?;
match *request.method() {
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::AspasUpdate, Some(&ca)
)?;
let (server, update) = request.read_json().await?;
server.krill().ca_aspas_update_aspa(
ca, customer, update, auth.actor()
)?;
Ok(HttpResponse::ok())
}
Method::DELETE => {
let (request, auth) = request.proceed_permitted(
Permission::AspasUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().ca_aspas_definitions_update(
ca,
AspaDefinitionUpdates {
add_or_replace: Vec::new(),
remove: vec![customer]
},
auth.actor(),
)?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
async fn bgpsec(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::BgpsecRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_bgpsec_definitions_show(&ca)?
))
}
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::BgpsecUpdate, Some(&ca)
)?;
let (server, updates) = request.read_json().await?;
server.krill().ca_bgpsec_definitions_update(
ca, updates, auth.actor()
)?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
async fn children(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.parse_opt_next()? {
None => children_index(request, ca).await,
Some(child) => children_child(request, path, ca, child).await,
}
}
async fn children_index(
request: Request<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
request.check_post()?;
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let (server, child_req) = request.read_json().await?;
Ok(HttpResponse::json(
&server.krill().ca_add_child(&ca, child_req, auth.actor())?
))
}
async fn children_child(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
child: ChildHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
None => children_child_index(request, ca, child).await,
Some("contact") | Some("parent_response.json") => {
children_child_contact(request, path, ca, child)
}
Some("parent_response.xml") => {
children_child_contact_xml(request, path, ca, child)
}
Some("export") => children_child_export(request, path, ca, child),
Some("import") => {
children_child_import(request, path, ca, child).await
}
_ => Ok(HttpResponse::not_found())
}
}
async fn children_child_index(
request: Request<'_>,
ca: CaHandle,
child: ChildHandle,
) -> Result<HttpResponse, DispatchError> {
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_child_show(&ca, &child)?
))
}
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let (server, child_req) = request.read_json().await?;
server.krill().ca_child_update(
&ca, child, child_req, auth.actor()
)?;
Ok(HttpResponse::ok())
}
Method::DELETE => {
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().ca_child_remove(&ca, child, auth.actor())?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
fn children_child_contact(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
child: ChildHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_parent_response(&ca, child)?
))
}
fn children_child_contact_xml(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
child: ChildHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
let res = server.krill().ca_parent_response(&ca, child)?;
Ok(HttpResponse::xml(res.to_xml_vec()))
}
fn children_child_export(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
child: ChildHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_child_export(&ca, &child)?
))
}
async fn children_child_import(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
child: ChildHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_post()?;
let (request, auth) = request.proceed_permitted(
Permission::CaAdmin, Some(&ca)
)?;
let (server, import) = request.read_json::<ImportChild>().await?;
if import.name != child {
return Ok(HttpResponse::response_from_error(
Error::CaChildImportHandleMismatch {
path: child, body: import.name
}
))
}
server.krill().ca_child_import(&ca, import, auth.actor())?;
Ok(HttpResponse::ok())
}
fn history(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("commands") => history_commands(request, path, ca),
Some("details") => history_details(request, path, ca),
_ => Ok(HttpResponse::not_found())
}
}
fn history_commands(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
let mut path = path.strip_trailing_slash();
let rows_limit = Some(path.parse_opt_next()?.unwrap_or(100));
let offset = path.parse_opt_next()?.unwrap_or(0);
let after = path.parse_opt_next()?;
let before = path.parse_opt_next()?;
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_history(
&ca,
CommandHistoryCriteria {
before, after, offset, rows_limit,
.. Default::default()
}
)?
))
}
fn history_details(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
let version = path.parse_next()?;
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_command_details(&ca, version).map_err(|err| {
match err {
Error::AggregateStoreError(
AggregateStoreError::UnknownCommand(..)
) => {
HttpResponse::not_found()
},
err => {
HttpResponse::response_from_error(err)
}
}
})?
))
}
fn id(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
None => id_index(request, ca),
Some("child_request.json") => {
id_child_request_json(request, path, ca)
}
Some("child_request.xml") => id_child_request_xml(request, path, ca),
Some("publisher_request.json") => {
id_publisher_request_json(request, path, ca)
}
Some("publisher_request.xml") => {
id_publisher_request_xml(request, path, ca)
}
_ => Ok(HttpResponse::not_found())
}
}
fn id_index(
request: Request<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
request.check_post()?;
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().ca_update_id(ca, auth.actor())?;
Ok(HttpResponse::ok())
}
fn id_child_request_json(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_child_req(&ca)?
))
}
fn id_child_request_xml(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::xml(
server.krill().ca_child_req(&ca)?.to_xml_vec()
))
}
fn id_publisher_request_json(
request: Request,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_publisher_req(&ca)?
))
}
fn id_publisher_request_xml(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::xml(
server.krill().ca_publisher_req(&ca)?.to_xml_vec()
))
}
fn issues(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_issues(&ca)?
))
}
fn keys(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("roll_init") => keys_roll_init(request, path, ca),
Some("roll_activate") => keys_roll_activate(request, path, ca),
_ => Ok(HttpResponse::not_found())
}
}
fn keys_roll_init(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_post()?;
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().ca_keyroll_init(ca, auth.actor())?;
Ok(HttpResponse::ok())
}
fn keys_roll_activate(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_post()?;
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().ca_keyroll_activate(ca, auth.actor())?;
Ok(HttpResponse::ok())
}
async fn parents(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.parse_opt_next()? {
None => parents_index(request, ca).await,
Some(parent) => parents_parent(request, path, ca, parent).await,
}
}
async fn parents_index(
request: Request<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_status(&ca)?.into_parents()
))
}
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let (server, bytes) = request.read_bytes().await?;
let parent_req = extract_parent_ca_req(&ca, bytes, None)?;
server.krill().ca_parent_add_or_update(
ca, parent_req, auth.actor()
).await?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
async fn parents_parent(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
parent: ParentHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_my_parent_contact(&ca, &parent)?
))
}
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let (server, bytes) = request.read_bytes().await?;
let parent_req = extract_parent_ca_req(
&ca, bytes, Some(parent)
)?;
server.krill().ca_parent_add_or_update(
ca, parent_req, auth.actor()
).await?;
Ok(HttpResponse::ok())
}
Method::DELETE => {
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().ca_parent_remove(ca, parent, auth.actor()).await?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
fn extract_parent_ca_req(
ca: &CaHandle,
bytes: Bytes,
parent_override: Option<ParentHandle>,
) -> Result<ParentCaReq, Error> {
let bytes = bytes.trim_ascii_start();
if bytes.first().copied() == Some(b'<') {
let response = ParentResponse::parse(bytes).map_err(|err| {
Error::CaParentResponseInvalid(
ca.clone(),
err.to_string(),
)
})?;
let parent_name = parent_override.unwrap_or_else(|| {
response.parent_handle().clone()
});
Ok(ParentCaReq { handle: parent_name, response })
}
else {
let req: ParentCaReq = serde_json::from_slice(bytes).map_err(
Error::JsonError
)?;
if
let Some(parent_override) = parent_override
&& req.handle != parent_override
{
return Err(Error::Custom(format!(
"Used different parent names on path ({}) and \
submitted JSON ({}) for adding/updating a parent",
parent_override,
req.handle
)));
}
Ok(req)
}
}
async fn repo(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
None => repo_index(request, ca).await,
Some("status") => repo_status(request, path, ca),
_ => Ok(HttpResponse::not_found())
}
}
async fn repo_index(
request: Request<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_repo_details(&ca)?
))
}
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let (server, update) = request.read_bytes().await?;
let update = extract_repository_contact(&ca, update)?;
server.krill().ca_repo_update(ca, update, auth.actor()).await?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
pub fn extract_repository_contact(
ca: &CaHandle,
bytes: Bytes,
) -> Result<RepositoryContact, Error> {
let bytes = bytes.trim_ascii_start();
if bytes.first().copied() == Some(b'<') {
let response = RepositoryResponse::parse(bytes).map_err(|err| {
Error::CaRepoResponseInvalid(
ca.clone(),
err.to_string(),
)
})?;
RepositoryContact::try_from_response(response).map_err(|err| {
Error::CaRepoResponseInvalid(ca.clone(), err.to_string())
})
}
else {
let api_contact: ApiRepositoryContact = serde_json::from_slice(
bytes
).map_err(Error::JsonError)?;
RepositoryContact::try_from_response(api_contact.repository_response)
}
}
fn repo_status(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_status(&ca)?.into_repo()
))
}
async fn routes(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
None => routes_index(request, ca).await,
Some("try") => routes_try(request, path, ca).await,
Some("analysis") => routes_analysis(request, path, ca).await,
_ => Ok(HttpResponse::not_found())
}
}
async fn routes_index(
request: Request<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::RoutesRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_routes_show(&ca)?
))
}
Method::POST => {
let (request, auth) = request.proceed_permitted(
Permission::RoutesUpdate, Some(&ca)
)?;
let (server, updates) = request.read_json().await?;
server.krill().ca_routes_update(ca, updates, auth.actor())?;
Ok(HttpResponse::ok())
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
async fn routes_try(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_post()?;
let (request, auth) = request.proceed_permitted(
Permission::RoutesUpdate, Some(&ca)
)?;
let (server, mut updates)
= request.read_json::<RoaConfigurationUpdates>().await?;
let effect = server.krill().ca_routes_bgp_dry_run(
&ca, updates.clone()
)?;
if effect.contains_invalids() {
updates.set_explicit_max_length();
let resources = updates.affected_prefixes();
let suggestion = server.krill().ca_routes_bgp_suggest(
&ca, Some(resources)
)?;
Ok(HttpResponse::json(
&BgpAnalysisAdvice {
effect, suggestion,
}
))
}
else {
server.krill().ca_routes_update(ca, updates, auth.actor())?;
Ok(HttpResponse::ok())
}
}
async fn routes_analysis(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("full") => routes_analysis_full(request, path, ca),
Some("dryrun") => routes_analysis_dryrun(request, path, ca).await,
Some("suggest") => routes_analysis_suggest(request, path, ca).await,
_ => Ok(HttpResponse::not_found())
}
}
fn routes_analysis_full(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::RoutesAnalysis, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_routes_bgp_analysis(&ca)?
))
}
async fn routes_analysis_dryrun(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_post()?;
let (request, _) = request.proceed_permitted(
Permission::RoutesAnalysis, Some(&ca)
)?;
let (server, updates) = request.read_json().await?;
Ok(HttpResponse::json(
&server.krill().ca_routes_bgp_dry_run(&ca, updates)?
))
}
async fn routes_analysis_suggest(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
match *request.method() {
Method::GET => {
let (request, _) = request.proceed_permitted(
Permission::RoutesAnalysis, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_routes_bgp_suggest(&ca, None)?
))
}
Method::POST => {
let (request, _) = request.proceed_permitted(
Permission::RoutesAnalysis, Some(&ca)
)?;
let (server, resources) = request.read_json().await?;
Ok(HttpResponse::json(
&server.krill().ca_routes_bgp_suggest(
&ca, Some(resources)
)?
))
}
_ => Ok(HttpResponse::method_not_allowed())
}
}
fn stats(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("children") => stats_children(request, path, ca),
_ => Ok(HttpResponse::not_found())
}
}
fn stats_children(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("connections") => stats_children_connections(request, path, ca),
_ => Ok(HttpResponse::not_found())
}
}
fn stats_children_connections(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_get()?;
let (request, _) = request.proceed_permitted(
Permission::CaRead, Some(&ca)
)?;
let server = request.empty()?;
Ok(HttpResponse::json(
&server.krill().ca_stats_child_connections(&ca)?
))
}
fn sync(
request: Request<'_>,
mut path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
match path.next() {
Some("parents") => sync_parents(request, path, ca),
Some("repo") => sync_repo(request, path, ca),
_ => Ok(HttpResponse::not_found())
}
}
fn sync_parents(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_post()?;
let (request, _) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().cas_refresh_single(ca)?;
Ok(HttpResponse::ok())
}
fn sync_repo(
request: Request<'_>,
path: PathIter<'_>,
ca: CaHandle,
) -> Result<HttpResponse, DispatchError> {
path.check_exhausted()?;
request.check_post()?;
let (request, _) = request.proceed_permitted(
Permission::CaUpdate, Some(&ca)
)?;
let server = request.empty()?;
server.krill().cas_repo_sync_single(&ca)?;
Ok(HttpResponse::ok())
}