20260718 新增查询服务 VRP 检索接口

This commit is contained in:
2026-07-20 10:04:43 +08:00
parent e80fba44c3
commit 6d9eedd680
5 changed files with 532 additions and 3 deletions

View File

@@ -8,6 +8,7 @@ use std::sync::{Arc, Mutex};
use rpki::blob_store::ExternalRepoBytesDb;
use rpki::query::report_stream::{ObjectFilter, ObjectScope};
use rpki::query::vrp::VrpLookup;
use rpki::query_db::{
ChainEdgeRecord, ExportJobRecord, ObjectInstanceRecord, ObjectUriIndexRecord, QueryDb,
QueryDbError, ValidationExplainRecord,
@@ -598,6 +599,22 @@ fn route_request(
Some(run_id),
)
}
["runs", raw_run_id, "vrps", "lookup"] => {
let run_id = resolve_run(db, raw_run_id)?;
let lookup = vrp_lookup_from_query(&query)?;
let asn = query
.get("asn")
.map(|value| {
value.parse::<u32>().map_err(|_| {
ApiError::new(400, format!("invalid ASN query parameter: {value}"))
})
})
.transpose()?;
page_response(
db.lookup_vrps(&run_id, &lookup, asn, limit(&query), cursor(&query))?,
Some(run_id),
)
}
["runs", raw_run_id, "repos"] => {
let run_id = resolve_run(db, raw_run_id)?;
page_response(
@@ -2136,6 +2153,27 @@ fn object_filter_from_query(query: &BTreeMap<String, String>) -> Result<ObjectFi
Ok(filter)
}
fn vrp_lookup_from_query(query: &BTreeMap<String, String>) -> Result<VrpLookup, ApiError> {
let ip = query.get("ip");
let prefix = query.get("prefix");
match (ip, prefix) {
(Some(_), Some(_)) => Err(ApiError::new(
400,
"ip and prefix query parameters are mutually exclusive",
)),
(None, None) => Err(ApiError::new(
400,
"one of ip or prefix query parameters is required",
)),
(Some(value), None) => {
VrpLookup::parse_ip(value).map_err(|error| ApiError::new(400, error))
}
(None, Some(value)) => {
VrpLookup::parse_prefix(value).map_err(|error| ApiError::new(400, error))
}
}
}
fn cursor(query: &BTreeMap<String, String>) -> Option<&str> {
query.get("cursor").map(String::as_str)
}
@@ -2481,6 +2519,28 @@ mod tests {
.as_u64(),
Some(1)
);
let vrp_ip = test_route_request(
&db,
Some(&repo_bytes),
"/api/v1/runs/latest/vrps/lookup?ip=2001:da8::1",
)
.expect("VRP IP lookup");
assert_eq!(vrp_ip["data"][0]["asn"].as_u64(), Some(4538));
assert_eq!(vrp_ip["meta"]["runId"].as_str(), Some("run_0001"));
let vrp_prefix = test_route_request(
&db,
Some(&repo_bytes),
"/api/v1/runs/latest/vrps/lookup?prefix=2001%3Ada8%3A%3A%2F32&asn=4538",
)
.expect("VRP prefix lookup");
assert_eq!(vrp_prefix["data"].as_array().unwrap().len(), 1);
let invalid = test_route_request(
&db,
Some(&repo_bytes),
"/api/v1/runs/latest/vrps/lookup?ip=192.0.2.1&prefix=192.0.2.0%2F24",
)
.expect_err("conflicting VRP lookup parameters");
assert_eq!(invalid.status, 400);
for target in [
"/api/v1/runs/latest/repos",