Skip to content

Commit

Permalink
API for showing exported prefixes
Browse files Browse the repository at this point in the history
- Fixes #6526
  • Loading branch information
rcgoodfellow committed Aug 21, 2024
1 parent 14b94f7 commit 6bd1659
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 20 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@ macaddr = { version = "1.0.1", features = ["serde_std"] }
maplit = "1.0.2"
mockall = "0.13"
newtype_derive = "0.1.6"
mg-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "73e63eaae3fe616bd7c48a20c69736d7e025836b" }
ddm-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "73e63eaae3fe616bd7c48a20c69736d7e025836b" }
mg-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42" }
ddm-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42" }
multimap = "0.10.0"
nexus-auth = { path = "nexus/auth" }
nexus-client = { path = "clients/nexus-client" }
Expand Down
10 changes: 10 additions & 0 deletions common/src/api/external/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub use dropshot::PaginationOrder;
pub use error::*;
use futures::stream::BoxStream;
use oxnet::IpNet;
use oxnet::Ipv4Net;
use parse_display::Display;
use parse_display::FromStr;
use rand::thread_rng;
Expand Down Expand Up @@ -2708,6 +2709,15 @@ pub struct BgpPeerStatus {
pub switch: SwitchLocation,
}

/// The current status of a BGP peer.
#[derive(
Clone, Debug, Deserialize, JsonSchema, Serialize, PartialEq, Default,
)]
pub struct BgpExported {
/// Exported routes indexed by peer address.
pub exports: HashMap<String, Vec<Ipv4Net>>,
}

/// Opaque object representing BGP message history for a given BGP peer. The
/// contents of this object are not yet stable.
#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down
73 changes: 71 additions & 2 deletions nexus/src/app/bgp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ use nexus_db_model::{BgpAnnounceSet, BgpAnnouncement, BgpConfig};
use nexus_db_queries::context::OpContext;
use omicron_common::api::external::http_pagination::PaginatedBy;
use omicron_common::api::external::{
self, BgpImportedRouteIpv4, BgpMessageHistory, BgpPeerStatus, CreateResult,
DeleteResult, ListResultVec, LookupResult, NameOrId, SwitchBgpHistory,
self, BgpExported, BgpImportedRouteIpv4, BgpMessageHistory, BgpPeerStatus,
CreateResult, DeleteResult, ListResultVec, LookupResult, NameOrId,
SwitchBgpHistory,
};
use std::net::IpAddr;

Expand Down Expand Up @@ -145,6 +146,74 @@ impl super::Nexus {
Ok(result)
}

pub async fn bgp_exported(
&self,
opctx: &OpContext,
) -> LookupResult<BgpExported> {
opctx.authorize(authz::Action::Read, &authz::FLEET).await?;
let mut result = BgpExported::default();
for (switch, client) in &self.mg_clients().await.map_err(|e| {
external::Error::internal_error(&format!(
"failed to get mg clients: {e}"
))
})? {
let router_info = match client.read_routers().await {
Ok(result) => result.into_inner(),
Err(e) => {
error!(
self.log,
"failed to get routers from {switch}: {e}"
);
continue;
}
};
for r in &router_info {
let asn = r.asn;

let exported = match client
.get_exported(&mg_admin_client::types::AsnSelector { asn })
.await
{
Ok(result) => result.into_inner(),
Err(e) => {
error!(
self.log,
"failed to get exports for asn {asn} from {switch}: {e}"
);
continue;
}
};
for (addr, exports) in exported {
let mut xps = Vec::new();
for ex in exports.iter() {
let net = match ex {
mg_admin_client::types::Prefix::V4(v4) => {
oxnet::Ipv4Net::new_unchecked(
v4.value, v4.length,
)
}
mg_admin_client::types::Prefix::V6(v6) => {
let v6 = oxnet::IpNet::V6(
oxnet::Ipv6Net::new_unchecked(
v6.value, v6.length,
),
);
warn!(
self.log,
"{v6}: ipv6 exports not supported yet"
);
continue;
}
};
xps.push(net);
}
result.exports.insert(addr.to_string(), xps);
}
}
}
Ok(result)
}

pub async fn bgp_message_history(
&self,
opctx: &OpContext,
Expand Down
31 changes: 28 additions & 3 deletions nexus/src/external_api/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use nexus_db_queries::db::lookup::ImageLookup;
use nexus_db_queries::db::lookup::ImageParentLookup;
use nexus_db_queries::db::model::Name;
use nexus_types::external_api::shared::{BfdStatus, ProbeInfo};
use omicron_common::api::external::http_pagination::data_page_params_for;
use omicron_common::api::external::http_pagination::marker_for_name;
use omicron_common::api::external::http_pagination::marker_for_name_or_id;
use omicron_common::api::external::http_pagination::name_or_id_pagination;
Expand All @@ -55,9 +56,11 @@ use omicron_common::api::external::http_pagination::ScanParams;
use omicron_common::api::external::AddressLot;
use omicron_common::api::external::AddressLotBlock;
use omicron_common::api::external::AddressLotCreateResponse;
use omicron_common::api::external::AggregateBgpMessageHistory;
use omicron_common::api::external::BgpAnnounceSet;
use omicron_common::api::external::BgpAnnouncement;
use omicron_common::api::external::BgpConfig;
use omicron_common::api::external::BgpExported;
use omicron_common::api::external::BgpImportedRouteIpv4;
use omicron_common::api::external::BgpPeerStatus;
use omicron_common::api::external::DataPageParams;
Expand All @@ -78,9 +81,6 @@ use omicron_common::api::external::TufRepoGetResponse;
use omicron_common::api::external::TufRepoInsertResponse;
use omicron_common::api::external::VpcFirewallRuleUpdateParams;
use omicron_common::api::external::VpcFirewallRules;
use omicron_common::api::external::{
http_pagination::data_page_params_for, AggregateBgpMessageHistory,
};
use omicron_common::bail_unless;
use omicron_uuid_kinds::GenericUuid;
use parse_display::Display;
Expand Down Expand Up @@ -277,6 +277,7 @@ pub(crate) fn external_api() -> NexusApiDescription {
api.register(networking_bgp_config_create)?;
api.register(networking_bgp_config_list)?;
api.register(networking_bgp_status)?;
api.register(networking_bgp_exported)?;
api.register(networking_bgp_imported_routes_ipv4)?;
api.register(networking_bgp_config_delete)?;
api.register(networking_bgp_announce_set_update)?;
Expand Down Expand Up @@ -3937,6 +3938,30 @@ async fn networking_bgp_status(
.await
}

//TODO pagination? the normal by-name/by-id stuff does not work here
/// Get BGP exported routes
#[endpoint {
method = GET,
path = "/v1/system/networking/bgp-exported",
tags = ["system/networking"],
}]
async fn networking_bgp_exported(
rqctx: RequestContext<ApiContext>,
) -> Result<HttpResponseOk<BgpExported>, HttpError> {
let apictx = rqctx.context();
let opctx = crate::context::op_context_for_external_api(&rqctx).await?;
let handler = async {
let nexus = &apictx.context.nexus;
let result = nexus.bgp_exported(&opctx).await?;
Ok(HttpResponseOk(result))
};
apictx
.context
.external_latencies
.instrument_dropshot_handler(&rqctx, handler)
.await
}

/// Get BGP router message history
#[endpoint {
method = GET,
Expand Down
11 changes: 11 additions & 0 deletions nexus/tests/integration_tests/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,8 @@ pub static DEMO_BGP_ANNOUNCE: Lazy<params::BgpAnnounceSetCreate> =
});
pub const DEMO_BGP_STATUS_URL: &'static str =
"/v1/system/networking/bgp-status";
pub const DEMO_BGP_EXPORTED_URL: &'static str =
"/v1/system/networking/bgp-exported";
pub const DEMO_BGP_ROUTES_IPV4_URL: &'static str =
"/v1/system/networking/bgp-routes-ipv4?asn=47";
pub const DEMO_BGP_MESSAGE_HISTORY_URL: &'static str =
Expand Down Expand Up @@ -2307,6 +2309,15 @@ pub static VERIFY_ENDPOINTS: Lazy<Vec<VerifyEndpoint>> = Lazy::new(|| {
],
},

VerifyEndpoint {
url: &DEMO_BGP_EXPORTED_URL,
visibility: Visibility::Public,
unprivileged_access: UnprivilegedAccess::None,
allowed_methods: vec![
AllowedMethod::GetNonexistent,
],
},

VerifyEndpoint {
url: &DEMO_BGP_ROUTES_IPV4_URL,
visibility: Visibility::Public,
Expand Down
1 change: 1 addition & 0 deletions nexus/tests/output/nexus_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ networking_bgp_announce_set_update PUT /v1/system/networking/bgp-anno
networking_bgp_config_create POST /v1/system/networking/bgp
networking_bgp_config_delete DELETE /v1/system/networking/bgp
networking_bgp_config_list GET /v1/system/networking/bgp
networking_bgp_exported GET /v1/system/networking/bgp-exported
networking_bgp_imported_routes_ipv4 GET /v1/system/networking/bgp-routes-ipv4
networking_bgp_message_history GET /v1/system/networking/bgp-message-history
networking_bgp_status GET /v1/system/networking/bgp-status
Expand Down
46 changes: 46 additions & 0 deletions openapi/nexus.json
Original file line number Diff line number Diff line change
Expand Up @@ -6640,6 +6640,33 @@
}
}
},
"/v1/system/networking/bgp-exported": {
"get": {
"tags": [
"system/networking"
],
"summary": "Get BGP exported routes",
"operationId": "networking_bgp_exported",
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BgpExported"
}
}
}
},
"4XX": {
"$ref": "#/components/responses/Error"
},
"5XX": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/v1/system/networking/bgp-message-history": {
"get": {
"tags": [
Expand Down Expand Up @@ -10351,6 +10378,25 @@
"items"
]
},
"BgpExported": {
"description": "The current status of a BGP peer.",
"type": "object",
"properties": {
"exports": {
"description": "Exported routes indexed by peer address.",
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Ipv4Net"
}
}
}
},
"required": [
"exports"
]
},
"BgpImportedRouteIpv4": {
"description": "A route imported from a BGP peer.",
"type": "object",
Expand Down
12 changes: 6 additions & 6 deletions package-manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -628,10 +628,10 @@ source.repo = "maghemite"
# `tools/maghemite_openapi_version`. Failing to do so will cause a failure when
# building `ddm-admin-client` (which will instruct you to update
# `tools/maghemite_openapi_version`).
source.commit = "73e63eaae3fe616bd7c48a20c69736d7e025836b"
source.commit = "9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42"
# The SHA256 digest is automatically posted to:
# https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image/<commit>/mg-ddm-gz.sha256.txt
source.sha256 = "6b2b5b5fed0c8ea36d78138d8d9bb455e8768ae61e7443985ddea48535cfc2da"
source.sha256 = "c53a87b6c08323ea58c1604e3db24df061b9ee457e7d2b1dc6168abda4a686bc"
output.type = "tarball"

[package.mg-ddm]
Expand All @@ -644,10 +644,10 @@ source.repo = "maghemite"
# `tools/maghemite_openapi_version`. Failing to do so will cause a failure when
# building `ddm-admin-client` (which will instruct you to update
# `tools/maghemite_openapi_version`).
source.commit = "73e63eaae3fe616bd7c48a20c69736d7e025836b"
source.commit = "9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42"
# The SHA256 digest is automatically posted to:
# https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image/<commit>/mg-ddm.sha256.txt
source.sha256 = "725a5b1eeed5bc34ad5473cb54b8df4b3993f3ed3808cc50304696082e490a4a"
source.sha256 = "00b2433504cb4c984163c5cdfd455eee595858b125a29deadaa791628668e384"
output.type = "zone"
output.intermediate_only = true

Expand All @@ -659,10 +659,10 @@ source.repo = "maghemite"
# `tools/maghemite_openapi_version`. Failing to do so will cause a failure when
# building `ddm-admin-client` (which will instruct you to update
# `tools/maghemite_openapi_version`).
source.commit = "73e63eaae3fe616bd7c48a20c69736d7e025836b"
source.commit = "9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42"
# The SHA256 digest is automatically posted to:
# https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image/<commit>/mgd.sha256.txt
source.sha256 = "1f9833ce2d38bdb57099c3f7e7e9f2c414b17492fe0a3574e043b65756b78192"
source.sha256 = "67856e05347304523b03e7ddfbd7ec18e833b7bf291f39105d5d8c4c5c383392"
output.type = "zone"
output.intermediate_only = true

Expand Down
2 changes: 1 addition & 1 deletion tools/maghemite_ddm_openapi_version
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
COMMIT="73e63eaae3fe616bd7c48a20c69736d7e025836b"
COMMIT="9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42"
SHA2="007bfb717ccbc077c0250dee3121aeb0c5bb0d1c16795429a514fa4f8635a5ef"
4 changes: 2 additions & 2 deletions tools/maghemite_mg_openapi_version
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
COMMIT="73e63eaae3fe616bd7c48a20c69736d7e025836b"
SHA2="34536d8f55fc054d0b8114b5654b38c968099aafc7770562e04d405168f5be95"
COMMIT="9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42"
SHA2="5b327f213f8f341cf9072d428980f53757b2c6383f684ac80bbccfb1984ffe5f"
4 changes: 2 additions & 2 deletions tools/maghemite_mgd_checksums
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
CIDL_SHA256="1f9833ce2d38bdb57099c3f7e7e9f2c414b17492fe0a3574e043b65756b78192"
MGD_LINUX_SHA256="3c47a55af8daa4dc2cd7da5ecc3c5043cef5e6890b60d070a2e8672101cdbd30"
CIDL_SHA256="67856e05347304523b03e7ddfbd7ec18e833b7bf291f39105d5d8c4c5c383392"
MGD_LINUX_SHA256="6e37daa25ddb8310a4dd215db590bbd18999d55decf0f8a9baf7b919cf101c52"

0 comments on commit 6bd1659

Please sign in to comment.