Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions wicketd/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::MgsHandle;
use crate::bgp_auth_keys::BgpAuthKeyError;
use crate::bgp_auth_keys::BgpAuthKeys;
use crate::bootstrap_addrs::BootstrapPeersFromDdm;
use crate::http_helpers::http_error_with_message;
use crate::multirack_config::CurrentMultirackJoinConfig;
use crate::preflight_check::PreflightCheckerHandler;
use crate::rss_config::CurrentRssConfig;
Expand All @@ -22,6 +23,7 @@ use iddqd::IdOrdMap;
use internal_dns_resolver::Resolver;
use sled_hardware_types::Baseboard;
use slog::info;
use slog_error_chain::InlineErrorChain;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::mem;
Expand Down Expand Up @@ -329,10 +331,12 @@ impl ServerContext {
}
}

pub(crate) async fn local_switch_id(&self) -> Option<SpIdentifier> {
pub(crate) async fn local_switch_id(
&self,
) -> Result<SpIdentifier, LocalSwitchIdError> {
// Do we already have it cached from a previous invocation?
if let Some(&switch_id) = self.local_switch_id.get() {
return Some(switch_id);
return Ok(switch_id);
}

// We don't have a cached switch ID; try to fetch it from MGS. We
Expand All @@ -352,16 +356,33 @@ impl ServerContext {
self.transceiver_handle.set_local_switch_id(switch_id);
}

Some(switch_id)
Ok(switch_id)
}
Err(err) => {
slog::warn!(
self.log,
"Failed to fetch local switch ID from MGS";
"err" => #%err,
);
None
Err(LocalSwitchIdError::from(err))
}
}
}
}

/// An error returned when the local switch ID cannot be fetched from MGS.
#[derive(Debug, thiserror::Error)]
#[error("failed to fetch local switch ID from MGS")]
pub(crate) struct LocalSwitchIdError(
#[from] gateway_client::Error<gateway_client::types::Error>,
);

impl LocalSwitchIdError {
pub(crate) fn to_http_error(&self) -> HttpError {
http_error_with_message(
dropshot::ErrorStatusCode::SERVICE_UNAVAILABLE,
Some("UnknownSwitchSlot".to_string()),
format!("{} (is MGS running?)", InlineErrorChain::new(self)),
)
}
}
16 changes: 8 additions & 8 deletions wicketd/src/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,10 @@ impl WicketdApi for WicketdApiImpl {
let rqctx = rqctx.context();
let inventory = mgs_inventory_or_unavail(&rqctx.mgs_handle).await?;

let switch_id = rqctx.local_switch_id().await;
// We don't error out in get_location on the local switch ID not being
// available, so discard the error here (it's already logged in
// local_switch_id).
let switch_id = rqctx.local_switch_id().await.ok();
let sled_baseboard = rqctx.baseboard.clone();

let mut switch_baseboard = None;
Expand Down Expand Up @@ -592,7 +595,7 @@ impl WicketdApi for WicketdApiImpl {
let options = body.into_inner();

let our_switch_slot = match rqctx.local_switch_id().await {
Some(SpIdentifier { slot, typ: SpType::Switch }) => match slot {
Ok(SpIdentifier { slot, typ: SpType::Switch }) => match slot {
0 => SwitchSlot::Switch0,
1 => SwitchSlot::Switch1,
_ => {
Expand All @@ -601,16 +604,13 @@ impl WicketdApi for WicketdApiImpl {
)));
}
},
Some(other) => {
Ok(other) => {
return Err(HttpError::for_internal_error(format!(
"unexpected switch SP identifier {other:?}"
)));
}
None => {
return Err(HttpError::for_unavail(
Some("UnknownSwitchSlot".to_string()),
"local switch slot not yet determined".to_string(),
));
Err(err) => {
return Err(err.to_http_error());
}
};

Expand Down
2 changes: 1 addition & 1 deletion wicketd/src/http_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ pub(crate) fn ba_lockstep_error_to_http(
///
/// This avoids using methods on `HttpError`, many of which don't expose the
/// full message to clients for security reasons.
fn http_error_with_message(
pub(crate) fn http_error_with_message(
status_code: dropshot::ErrorStatusCode,
error_code: Option<String>,
message: String,
Expand Down
Loading