Skip to content

Commit 5671cd5

Browse files
authored
add API endpoint for BGP announce set modification (#6024)
1 parent c9f1ddd commit 5671cd5

16 files changed

+190
-40
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ macaddr = { version = "1.0.1", features = ["serde_std"] }
333333
maplit = "1.0.2"
334334
mockall = "0.12"
335335
newtype_derive = "0.1.6"
336-
mg-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "6e0a232fd0b443c19f61f94bf02b7695505aa8e3" }
337-
ddm-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "6e0a232fd0b443c19f61f94bf02b7695505aa8e3" }
336+
mg-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "d1686c86f92ead77e07ddc6024837dee4a401d6d" }
337+
ddm-admin-client = { git = "https://github.com/oxidecomputer/maghemite", rev = "d1686c86f92ead77e07ddc6024837dee4a401d6d" }
338338
multimap = "0.10.0"
339339
nexus-auth = { path = "nexus/auth" }
340340
nexus-client = { path = "clients/nexus-client" }

nexus/db-queries/src/db/datastore/bgp.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,78 @@ impl DataStore {
314314
})
315315
}
316316

317+
pub async fn bgp_update_announce_set(
318+
&self,
319+
opctx: &OpContext,
320+
announce: &params::BgpAnnounceSetCreate,
321+
) -> CreateResult<(BgpAnnounceSet, Vec<BgpAnnouncement>)> {
322+
use db::schema::bgp_announce_set::dsl as announce_set_dsl;
323+
use db::schema::bgp_announcement::dsl as bgp_announcement_dsl;
324+
325+
let conn = self.pool_connection_authorized(opctx).await?;
326+
327+
self.transaction_retry_wrapper("bgp_update_announce_set")
328+
.transaction(&conn, |conn| async move {
329+
let bas: BgpAnnounceSet = announce.clone().into();
330+
331+
// ensure the announce set exists
332+
let found_as: Option<BgpAnnounceSet> =
333+
announce_set_dsl::bgp_announce_set
334+
.filter(
335+
announce_set_dsl::name
336+
.eq(Name::from(bas.name().clone())),
337+
)
338+
.filter(announce_set_dsl::time_deleted.is_null())
339+
.select(BgpAnnounceSet::as_select())
340+
.limit(1)
341+
.first_async(&conn)
342+
.await
343+
.ok();
344+
345+
let db_as = match found_as {
346+
Some(v) => v,
347+
None => {
348+
diesel::insert_into(announce_set_dsl::bgp_announce_set)
349+
.values(bas.clone())
350+
.returning(BgpAnnounceSet::as_returning())
351+
.get_result_async::<BgpAnnounceSet>(&conn)
352+
.await?
353+
}
354+
};
355+
356+
// clear existing announcements
357+
diesel::delete(bgp_announcement_dsl::bgp_announcement)
358+
.filter(
359+
bgp_announcement_dsl::announce_set_id.eq(db_as.id()),
360+
)
361+
.execute_async(&conn)
362+
.await?;
363+
364+
// repopulate announcements
365+
let mut db_annoucements = Vec::new();
366+
for a in &announce.announcement {
367+
let an = BgpAnnouncement {
368+
announce_set_id: db_as.id(),
369+
address_lot_block_id: bas.identity.id,
370+
network: a.network.into(),
371+
};
372+
let db_an = diesel::insert_into(
373+
bgp_announcement_dsl::bgp_announcement,
374+
)
375+
.values(an.clone())
376+
.returning(BgpAnnouncement::as_returning())
377+
.get_result_async::<BgpAnnouncement>(&conn)
378+
.await?;
379+
380+
db_annoucements.push(db_an);
381+
}
382+
383+
Ok((db_as, db_annoucements))
384+
})
385+
.await
386+
.map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))
387+
}
388+
317389
pub async fn bgp_create_announce_set(
318390
&self,
319391
opctx: &OpContext,

nexus/db-queries/src/db/datastore/switch_port.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,7 @@ impl DataStore {
336336
}
337337
}
338338
else {
339-
public_error_from_diesel(
340-
e,
341-
ErrorHandler::Conflict(
342-
ResourceType::SwitchPortSettings,
343-
params.identity.name.as_str(),
344-
),
345-
)
339+
public_error_from_diesel(e, ErrorHandler::Server)
346340
}
347341
})
348342
}
@@ -1451,6 +1445,36 @@ async fn do_switch_port_settings_delete(
14511445
.execute_async(conn)
14521446
.await?;
14531447

1448+
// delete allowed exports
1449+
use db::schema::switch_port_settings_bgp_peer_config_allow_export as allow_export;
1450+
use db::schema::switch_port_settings_bgp_peer_config_allow_export::dsl as allow_export_dsl;
1451+
diesel::delete(
1452+
allow_export_dsl::switch_port_settings_bgp_peer_config_allow_export,
1453+
)
1454+
.filter(allow_export::port_settings_id.eq(id))
1455+
.execute_async(conn)
1456+
.await?;
1457+
1458+
// delete allowed imports
1459+
use db::schema::switch_port_settings_bgp_peer_config_allow_import as allow_import;
1460+
use db::schema::switch_port_settings_bgp_peer_config_allow_import::dsl as allow_import_dsl;
1461+
diesel::delete(
1462+
allow_import_dsl::switch_port_settings_bgp_peer_config_allow_import,
1463+
)
1464+
.filter(allow_import::port_settings_id.eq(id))
1465+
.execute_async(conn)
1466+
.await?;
1467+
1468+
// delete communities
1469+
use db::schema::switch_port_settings_bgp_peer_config_communities as bgp_communities;
1470+
use db::schema::switch_port_settings_bgp_peer_config_communities::dsl as bgp_communities_dsl;
1471+
diesel::delete(
1472+
bgp_communities_dsl::switch_port_settings_bgp_peer_config_communities,
1473+
)
1474+
.filter(bgp_communities::port_settings_id.eq(id))
1475+
.execute_async(conn)
1476+
.await?;
1477+
14541478
// delete address configs
14551479
use db::schema::switch_port_settings_address_config::{
14561480
self as address_config, dsl as address_config_dsl,

nexus/src/app/bgp.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,18 @@ impl super::Nexus {
5353
Ok(result)
5454
}
5555

56-
pub async fn bgp_create_announce_set(
56+
pub async fn bgp_update_announce_set(
5757
&self,
5858
opctx: &OpContext,
5959
announce: &params::BgpAnnounceSetCreate,
6060
) -> CreateResult<(BgpAnnounceSet, Vec<BgpAnnouncement>)> {
6161
opctx.authorize(authz::Action::Modify, &authz::FLEET).await?;
6262
let result =
63-
self.db_datastore.bgp_create_announce_set(opctx, announce).await?;
63+
self.db_datastore.bgp_update_announce_set(opctx, announce).await?;
64+
65+
// eagerly propagate changes via rpw
66+
self.background_tasks
67+
.activate(&self.background_tasks.task_switch_port_settings_manager);
6468
Ok(result)
6569
}
6670

nexus/src/app/switch_port.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ impl super::Nexus {
4343
)
4444
.await
4545
{
46-
Ok(id) => self.switch_port_settings_update(opctx, id, params).await,
46+
Ok(id) => {
47+
info!(self.log, "updating port settings {id}");
48+
self.switch_port_settings_update(opctx, id, params).await
49+
}
4750
Err(_) => {
51+
info!(self.log, "creating new switch port settings");
4852
self.switch_port_settings_create(opctx, params, None).await
4953
}
5054
}

nexus/src/external_api/http_entrypoints.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ pub(crate) fn external_api() -> NexusApiDescription {
278278
api.register(networking_bgp_status)?;
279279
api.register(networking_bgp_imported_routes_ipv4)?;
280280
api.register(networking_bgp_config_delete)?;
281-
api.register(networking_bgp_announce_set_create)?;
281+
api.register(networking_bgp_announce_set_update)?;
282282
api.register(networking_bgp_announce_set_list)?;
283283
api.register(networking_bgp_announce_set_delete)?;
284284
api.register(networking_bgp_message_history)?;
@@ -4059,13 +4059,16 @@ async fn networking_bgp_config_delete(
40594059
.await
40604060
}
40614061

4062-
/// Create new BGP announce set
4062+
/// Update BGP announce set
4063+
///
4064+
/// If the announce set exists, this endpoint replaces the existing announce
4065+
/// set with the one specified.
40634066
#[endpoint {
4064-
method = POST,
4067+
method = PUT,
40654068
path = "/v1/system/networking/bgp-announce",
40664069
tags = ["system/networking"],
40674070
}]
4068-
async fn networking_bgp_announce_set_create(
4071+
async fn networking_bgp_announce_set_update(
40694072
rqctx: RequestContext<ApiContext>,
40704073
config: TypedBody<params::BgpAnnounceSetCreate>,
40714074
) -> Result<HttpResponseCreated<BgpAnnounceSet>, HttpError> {
@@ -4074,7 +4077,7 @@ async fn networking_bgp_announce_set_create(
40744077
let nexus = &apictx.context.nexus;
40754078
let config = config.into_inner();
40764079
let opctx = crate::context::op_context_for_external_api(&rqctx).await?;
4077-
let result = nexus.bgp_create_announce_set(&opctx, &config).await?;
4080+
let result = nexus.bgp_update_announce_set(&opctx, &config).await?;
40784081
Ok(HttpResponseCreated::<BgpAnnounceSet>(result.0.into()))
40794082
};
40804083
apictx

nexus/tests/integration_tests/endpoints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2307,7 +2307,7 @@ pub static VERIFY_ENDPOINTS: Lazy<Vec<VerifyEndpoint>> = Lazy::new(|| {
23072307
visibility: Visibility::Public,
23082308
unprivileged_access: UnprivilegedAccess::None,
23092309
allowed_methods: vec![
2310-
AllowedMethod::Post(
2310+
AllowedMethod::Put(
23112311
serde_json::to_value(&*DEMO_BGP_ANNOUNCE).unwrap(),
23122312
),
23132313
AllowedMethod::GetNonexistent,

nexus/tests/output/nexus_tags.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ networking_allow_list_view GET /v1/system/networking/allow-li
179179
networking_bfd_disable POST /v1/system/networking/bfd-disable
180180
networking_bfd_enable POST /v1/system/networking/bfd-enable
181181
networking_bfd_status GET /v1/system/networking/bfd-status
182-
networking_bgp_announce_set_create POST /v1/system/networking/bgp-announce
183182
networking_bgp_announce_set_delete DELETE /v1/system/networking/bgp-announce
184183
networking_bgp_announce_set_list GET /v1/system/networking/bgp-announce
184+
networking_bgp_announce_set_update PUT /v1/system/networking/bgp-announce
185185
networking_bgp_config_create POST /v1/system/networking/bgp
186186
networking_bgp_config_delete DELETE /v1/system/networking/bgp
187187
networking_bgp_config_list GET /v1/system/networking/bgp

openapi/nexus.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6630,12 +6630,13 @@
66306630
}
66316631
}
66326632
},
6633-
"post": {
6633+
"put": {
66346634
"tags": [
66356635
"system/networking"
66366636
],
6637-
"summary": "Create new BGP announce set",
6638-
"operationId": "networking_bgp_announce_set_create",
6637+
"summary": "Update BGP announce set",
6638+
"description": "If the announce set exists, this endpoint replaces the existing announce set with the one specified.",
6639+
"operationId": "networking_bgp_announce_set_update",
66396640
"requestBody": {
66406641
"content": {
66416642
"application/json": {

package-manifest.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -563,10 +563,10 @@ source.repo = "maghemite"
563563
# `tools/maghemite_openapi_version`. Failing to do so will cause a failure when
564564
# building `ddm-admin-client` (which will instruct you to update
565565
# `tools/maghemite_openapi_version`).
566-
source.commit = "6e0a232fd0b443c19f61f94bf02b7695505aa8e3"
566+
source.commit = "d1686c86f92ead77e07ddc6024837dee4a401d6d"
567567
# The SHA256 digest is automatically posted to:
568568
# https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image/<commit>/mg-ddm-gz.sha256.txt
569-
source.sha256 = "01b63e4b2b9537b223a417b9283cefb998ae8a3180108b7fbd7710adcf49bbf0"
569+
source.sha256 = "280bd6e5c30d8f1076bac9b8dbbdbc45379e76259aa6319da257192fcbf64a54"
570570
output.type = "tarball"
571571

572572
[package.mg-ddm]
@@ -579,10 +579,10 @@ source.repo = "maghemite"
579579
# `tools/maghemite_openapi_version`. Failing to do so will cause a failure when
580580
# building `ddm-admin-client` (which will instruct you to update
581581
# `tools/maghemite_openapi_version`).
582-
source.commit = "6e0a232fd0b443c19f61f94bf02b7695505aa8e3"
582+
source.commit = "d1686c86f92ead77e07ddc6024837dee4a401d6d"
583583
# The SHA256 digest is automatically posted to:
584584
# https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image/<commit>/mg-ddm.sha256.txt
585-
source.sha256 = "29ac6f5f61795795a2b1026606ac43d48435f1d685d2db2ab097aaaa9c5d6e6c"
585+
source.sha256 = "f15f8bb0e13b1a9372c895775dae96b68ff1cc5e395e6bad4389c2a97957354e"
586586
output.type = "zone"
587587
output.intermediate_only = true
588588

@@ -594,10 +594,10 @@ source.repo = "maghemite"
594594
# `tools/maghemite_openapi_version`. Failing to do so will cause a failure when
595595
# building `ddm-admin-client` (which will instruct you to update
596596
# `tools/maghemite_openapi_version`).
597-
source.commit = "6e0a232fd0b443c19f61f94bf02b7695505aa8e3"
597+
source.commit = "d1686c86f92ead77e07ddc6024837dee4a401d6d"
598598
# The SHA256 digest is automatically posted to:
599599
# https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image/<commit>/mgd.sha256.txt
600-
source.sha256 = "49f5224ea5f5078c11d71098fea29db9aafe9575876825f4e0216d9c64361f55"
600+
source.sha256 = "b0223e0aad4c22bf980da17084caf6704d0428bad1b3e5daf54e7d415ce82d3e"
601601
output.type = "zone"
602602
output.intermediate_only = true
603603

tools/maghemite_ddm_openapi_version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
COMMIT="6e0a232fd0b443c19f61f94bf02b7695505aa8e3"
1+
COMMIT="d1686c86f92ead77e07ddc6024837dee4a401d6d"
22
SHA2="007bfb717ccbc077c0250dee3121aeb0c5bb0d1c16795429a514fa4f8635a5ef"

tools/maghemite_mg_openapi_version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
COMMIT="6e0a232fd0b443c19f61f94bf02b7695505aa8e3"
1+
COMMIT="d1686c86f92ead77e07ddc6024837dee4a401d6d"
22
SHA2="e4b42ab9daad90f0c561a830b62a9d17e294b4d0da0a6d44b4030929b0c37b7e"

tools/maghemite_mgd_checksums

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
CIDL_SHA256="49f5224ea5f5078c11d71098fea29db9aafe9575876825f4e0216d9c64361f55"
2-
MGD_LINUX_SHA256="48aa39bb2d68a81be5ad49986d9ebd3cbad64eee0bd6b4556c91b089760265ec"
1+
CIDL_SHA256="b0223e0aad4c22bf980da17084caf6704d0428bad1b3e5daf54e7d415ce82d3e"
2+
MGD_LINUX_SHA256="776f18e9e7fc905d5a2f33d1a1bdd8863ed988bb2965a222217ec06790a3f452"

0 commit comments

Comments
 (0)