Skip to content

Commit

Permalink
factor route management into dedicated saga phases
Browse files Browse the repository at this point in the history
  • Loading branch information
rcgoodfellow committed Jan 11, 2024
1 parent 2111398 commit 8c117dd
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 32 deletions.
91 changes: 60 additions & 31 deletions nexus/src/app/sagas/switch_port_settings_apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ declare_saga_actions! {
+ spa_ensure_switch_port_settings
- spa_undo_ensure_switch_port_settings
}
ENSURE_SWITCH_ROUTES -> "ensure_switch_routes" {
+ spa_ensure_switch_routes
- spa_undo_ensure_switch_routes
}
ENSURE_SWITCH_PORT_UPLINK -> "ensure_switch_port_uplink" {
+ spa_ensure_switch_port_uplink
- spa_undo_ensure_switch_port_uplink
Expand Down Expand Up @@ -178,9 +182,6 @@ async fn spa_ensure_switch_port_settings(
let dpd_client: Arc<dpd_client::Client> =
select_dendrite_client(&sagactx, &opctx, params.switch_port_id).await?;

let mg_client: Arc<mg_admin_client::Client> =
select_mg_client(&sagactx, &opctx, params.switch_port_id).await?;

let dpd_port_settings =
api_to_dpd_port_settings(&settings).map_err(|e| {
ActionError::action_failed(format!(
Expand Down Expand Up @@ -214,6 +215,21 @@ async fn spa_ensure_switch_port_settings(
_ => ActionError::action_failed(format!("dpd port settings apply {e}")),
})?;

Ok(())
}

async fn spa_ensure_switch_routes(
sagactx: NexusActionContext,
) -> Result<(), ActionError> {
let params = sagactx.saga_params::<Params>()?;
let opctx = crate::context::op_context_for_saga_action(
&sagactx,
&params.serialized_authn,
);

let settings = sagactx
.lookup::<SwitchPortSettingsCombinedResult>("switch_port_settings")?;

let mut rq = AddStaticRoute4Request {
routes: StaticRoute4List { list: Vec::new() },
};
Expand All @@ -230,13 +246,54 @@ async fn spa_ensure_switch_port_settings(
rq.routes.list.push(sr);
}

let mg_client: Arc<mg_admin_client::Client> =
select_mg_client(&sagactx, &opctx, params.switch_port_id).await?;

mg_client.inner.static_add_v4_route(&rq).await.map_err(|e| {
ActionError::action_failed(format!("mgd static route add {e}"))
})?;

Ok(())
}

async fn spa_undo_ensure_switch_routes(
sagactx: NexusActionContext,
) -> Result<(), Error> {
let params = sagactx.saga_params::<Params>()?;
let opctx = crate::context::op_context_for_saga_action(
&sagactx,
&params.serialized_authn,
);
let settings = sagactx
.lookup::<SwitchPortSettingsCombinedResult>("switch_port_settings")?;

let mut rq = DeleteStaticRoute4Request {
routes: StaticRoute4List { list: Vec::new() },
};

for r in settings.routes {
let nexthop = match r.gw.ip() {
IpAddr::V4(v4) => v4,
IpAddr::V6(_) => continue,
};
let prefix = match r.gw.ip() {
IpAddr::V4(v4) => Prefix4 { value: v4, length: r.gw.prefix() },
IpAddr::V6(_) => continue,
};
let sr = StaticRoute4 { nexthop, prefix };
rq.routes.list.push(sr);
}

let mg_client: Arc<mg_admin_client::Client> =
select_mg_client(&sagactx, &opctx, params.switch_port_id).await?;

mg_client.inner.static_remove_v4_route(&rq).await.map_err(|e| {
ActionError::action_failed(format!("mgd static route remove {e}"))
})?;

Ok(())
}

async fn spa_undo_ensure_switch_port_settings(
sagactx: NexusActionContext,
) -> Result<(), Error> {
Expand Down Expand Up @@ -300,34 +357,6 @@ async fn spa_undo_ensure_switch_port_settings(
.await
.map_err(|e| external::Error::internal_error(&e.to_string()))?;

// roll back the applied routes
let settings = sagactx
.lookup::<SwitchPortSettingsCombinedResult>("switch_port_settings")?;

let mut rq = DeleteStaticRoute4Request {
routes: StaticRoute4List { list: Vec::new() },
};

for r in settings.routes {
let nexthop = match r.gw.ip() {
IpAddr::V4(v4) => v4,
IpAddr::V6(_) => continue,
};
let prefix = match r.gw.ip() {
IpAddr::V4(v4) => Prefix4 { value: v4, length: r.gw.prefix() },
IpAddr::V6(_) => continue,
};
let sr = StaticRoute4 { nexthop, prefix };
rq.routes.list.push(sr);
}

let mg_client: Arc<mg_admin_client::Client> =
select_mg_client(&sagactx, &opctx, params.switch_port_id).await?;

mg_client.inner.static_remove_v4_route(&rq).await.map_err(|e| {
ActionError::action_failed(format!("mgd static route remove {e}"))
})?;

Ok(())
}

Expand Down
112 changes: 111 additions & 1 deletion nexus/src/app/sagas/switch_port_settings_clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ use crate::app::sagas::{
};
use anyhow::Error;
use dpd_client::types::PortId;
use mg_admin_client::types::DeleteNeighborRequest;
use mg_admin_client::types::{
AddStaticRoute4Request, DeleteNeighborRequest, DeleteStaticRoute4Request,
Prefix4, StaticRoute4, StaticRoute4List,
};
use nexus_db_model::NETWORK_KEY;
use nexus_db_queries::authn;
use nexus_db_queries::db::datastore::UpdatePrecondition;
use omicron_common::api::external::{self, NameOrId, SwitchLocation};
use serde::{Deserialize, Serialize};
use std::net::IpAddr;
use std::str::FromStr;
use std::sync::Arc;
use steno::ActionError;
Expand All @@ -43,6 +47,10 @@ declare_saga_actions! {
+ spa_clear_switch_port_settings
- spa_undo_clear_switch_port_settings
}
CLEAR_SWITCH_PORT_ROUTES -> "clear_switch_port_routes" {
+ spa_clear_switch_port_routes
- spa_undo_clear_switch_port_routes
}
CLEAR_SWITCH_PORT_UPLINK -> "clear_switch_port_uplink" {
+ spa_clear_switch_port_uplink
- spa_undo_clear_switch_port_uplink
Expand Down Expand Up @@ -351,6 +359,108 @@ async fn spa_undo_clear_switch_port_bgp_settings(
.await?)
}

async fn spa_clear_switch_port_routes(
sagactx: NexusActionContext,
) -> Result<(), ActionError> {
let osagactx = sagactx.user_data();
let params = sagactx.saga_params::<Params>()?;
let nexus = osagactx.nexus();
let opctx = crate::context::op_context_for_saga_action(
&sagactx,
&params.serialized_authn,
);

let orig_port_settings_id =
sagactx.lookup::<Option<Uuid>>("original_switch_port_settings_id")?;

let id = match orig_port_settings_id {
Some(id) => id,
None => return Ok(()),
};

let settings = nexus
.switch_port_settings_get(&opctx, &NameOrId::Id(id))
.await
.map_err(ActionError::action_failed)?;

let mut rq = DeleteStaticRoute4Request {
routes: StaticRoute4List { list: Vec::new() },
};

for r in settings.routes {
let nexthop = match r.gw.ip() {
IpAddr::V4(v4) => v4,
IpAddr::V6(_) => continue,
};
let prefix = match r.gw.ip() {
IpAddr::V4(v4) => Prefix4 { value: v4, length: r.gw.prefix() },
IpAddr::V6(_) => continue,
};
let sr = StaticRoute4 { nexthop, prefix };
rq.routes.list.push(sr);
}

let mg_client: Arc<mg_admin_client::Client> =
select_mg_client(&sagactx, &opctx, params.switch_port_id).await?;

mg_client.inner.static_remove_v4_route(&rq).await.map_err(|e| {
ActionError::action_failed(format!("mgd static route remove {e}"))
})?;

Ok(())
}

async fn spa_undo_clear_switch_port_routes(
sagactx: NexusActionContext,
) -> Result<(), Error> {
let osagactx = sagactx.user_data();
let params = sagactx.saga_params::<Params>()?;
let nexus = osagactx.nexus();
let opctx = crate::context::op_context_for_saga_action(
&sagactx,
&params.serialized_authn,
);

let orig_port_settings_id =
sagactx.lookup::<Option<Uuid>>("original_switch_port_settings_id")?;

let id = match orig_port_settings_id {
Some(id) => id,
None => return Ok(()),
};

let settings = nexus
.switch_port_settings_get(&opctx, &NameOrId::Id(id))
.await
.map_err(ActionError::action_failed)?;

let mut rq = AddStaticRoute4Request {
routes: StaticRoute4List { list: Vec::new() },
};

for r in settings.routes {
let nexthop = match r.gw.ip() {
IpAddr::V4(v4) => v4,
IpAddr::V6(_) => continue,
};
let prefix = match r.gw.ip() {
IpAddr::V4(v4) => Prefix4 { value: v4, length: r.gw.prefix() },
IpAddr::V6(_) => continue,
};
let sr = StaticRoute4 { nexthop, prefix };
rq.routes.list.push(sr);
}

let mg_client: Arc<mg_admin_client::Client> =
select_mg_client(&sagactx, &opctx, params.switch_port_id).await?;

mg_client.inner.static_add_v4_route(&rq).await.map_err(|e| {
ActionError::action_failed(format!("mgd static route remove {e}"))
})?;

Ok(())
}

async fn spa_clear_switch_port_bootstore_network_settings(
sagactx: NexusActionContext,
) -> Result<(), ActionError> {
Expand Down

0 comments on commit 8c117dd

Please sign in to comment.