Skip to content

Commit

Permalink
Update sled_add API based on discussion in #4607
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewjstone committed Dec 15, 2023
1 parent 7caa858 commit 395a7c8
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 15 deletions.
4 changes: 2 additions & 2 deletions nexus/db-queries/src/db/datastore/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ impl DataStore {
pub async fn find_hw_baseboard_id(
&self,
opctx: &OpContext,
baseboard_id: BaseboardId,
baseboard_id: &BaseboardId,
) -> Result<Uuid, Error> {
opctx.authorize(authz::Action::Read, &authz::INVENTORY).await?;
let conn = self.pool_connection_authorized(opctx).await?;
Expand Down Expand Up @@ -1442,7 +1442,7 @@ mod test {
part_number: "some-part".into(),
};
let err = datastore
.find_hw_baseboard_id(&opctx, baseboard_id)
.find_hw_baseboard_id(&opctx, &baseboard_id)
.await
.unwrap_err();
assert!(matches!(err, Error::ObjectNotFound { .. }));
Expand Down
53 changes: 49 additions & 4 deletions nexus/src/app/rack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use nexus_types::external_api::params::LinkConfig;
use nexus_types::external_api::params::LldpServiceConfig;
use nexus_types::external_api::params::RouteConfig;
use nexus_types::external_api::params::SwitchPortConfig;
use nexus_types::external_api::params::UninitializedSledId;
use nexus_types::external_api::params::{
AddressLotCreate, BgpPeerConfig, LoopbackAddressCreate, Route, SiloCreate,
SwitchPortSettingsCreate,
Expand All @@ -51,6 +52,7 @@ use omicron_common::api::external::ListResultVec;
use omicron_common::api::external::LookupResult;
use omicron_common::api::external::Name;
use omicron_common::api::external::NameOrId;
use omicron_common::api::external::ResourceType;
use omicron_common::api::internal::shared::ExternalPortDiscovery;
use sled_agent_client::types::AddSledRequest;
use sled_agent_client::types::EarlyNetworkConfigBody;
Expand Down Expand Up @@ -936,11 +938,13 @@ impl super::Nexus {
pub(crate) async fn sled_add(
&self,
opctx: &OpContext,
sled: Baseboard,
sled: UninitializedSledId,
) -> Result<(), Error> {
let baseboard_id = sled.clone().into();
let hw_baseboard_id =
self.db_datastore.find_hw_baseboard_id(opctx, baseboard_id).await?;
let hw_baseboard_id = self
.db_datastore
.find_hw_baseboard_id(opctx, &baseboard_id)
.await?;

let subnet = self.db_datastore.rack_subnet(opctx, self.rack_id).await?;
let rack_subnet =
Expand All @@ -955,11 +959,52 @@ impl super::Nexus {
)
.await?;

// Grab the SPs from the last collection
//
// This is necessary to get the revision_id for the given sled
//
// We set a limit of 200 here to give us some breathing room when
// querying for cabooses and RoT pages, each of which is "4 per SP/RoT",
// which in a single fully populated rack works out to (32 sleds + 2
// switches + 1 psc) * 4 = 140.
//
// This feels bad and probably needs more thought; see
// https://github.com/oxidecomputer/omicron/issues/4621 where this limit
// being too low bit us, and it will link to a more general followup
// issue.
let limit = NonZeroU32::new(200).unwrap();
let collection = self
.db_datastore
.inventory_get_latest_collection(opctx, limit)
.await?;

// If there isn't a collection, we don't know about the sled
let Some(collection) = collection else {
return Err(Error::ObjectNotFound {
type_name: ResourceType::Sled,
lookup_type:
omicron_common::api::external::LookupType::ByCompositeId(
format!("{sled:?}"),
),
});
};

// Find the revision
let Some(sp) = collection.sps.get(&baseboard_id) else {
return Err(Error::ObjectNotFound {
type_name: ResourceType::Sled,
lookup_type:
omicron_common::api::external::LookupType::ByCompositeId(
format!("{sled:?}"),
),
});
};

// Convert the baseboard as necessary
let baseboard = sled_agent_client::types::Baseboard::Gimlet {
identifier: sled.serial.clone(),
model: sled.part.clone(),
revision: sled.revision,
revision: sp.baseboard_revision.into(),
};

// Make the call to sled-agent
Expand Down
5 changes: 3 additions & 2 deletions nexus/src/external_api/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ use nexus_db_queries::{
authz::ApiResource, db::fixed_data::silo::INTERNAL_SILO_ID,
};
use nexus_types::external_api::{
params::ProjectSelector, shared::Baseboard, views::SiloQuotas,
params::{ProjectSelector, UninitializedSledId},
views::SiloQuotas,
};
use nexus_types::{
external_api::views::{SledInstance, Switch},
Expand Down Expand Up @@ -4601,7 +4602,7 @@ async fn sled_list_uninitialized(
}]
async fn sled_add(
rqctx: RequestContext<Arc<ServerContext>>,
sled: TypedBody<Baseboard>,
sled: TypedBody<UninitializedSledId>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
let apictx = rqctx.context();
let nexus = &apictx.nexus;
Expand Down
11 changes: 5 additions & 6 deletions nexus/tests/integration_tests/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use nexus_test_utils::SLED_AGENT_UUID;
use nexus_test_utils::SWITCH_UUID;
use nexus_types::external_api::params;
use nexus_types::external_api::shared;
use nexus_types::external_api::shared::Baseboard;
use nexus_types::external_api::shared::IpRange;
use nexus_types::external_api::shared::Ipv4Range;
use omicron_common::api::external::AddressLotKind;
Expand Down Expand Up @@ -64,11 +63,11 @@ lazy_static! {
pub static ref SLED_INSTANCES_URL: String =
format!("/v1/system/hardware/sleds/{}/instances", SLED_AGENT_UUID);

pub static ref DEMO_UNINITIALIZED_SLED: Baseboard = Baseboard {
serial: "demo-serial".to_string(),
part: "demo-part".to_string(),
revision: 6
};
pub static ref DEMO_UNINITIALIZED_SLED: params::UninitializedSledId =
params::UninitializedSledId {
serial: "demo-serial".to_string(),
part: "demo-part".to_string(),
};

// Global policy
pub static ref SYSTEM_POLICY_URL: &'static str = "/v1/system/policy";
Expand Down
17 changes: 17 additions & 0 deletions nexus/types/src/external_api/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ macro_rules! id_path_param {
};
}

/// The unique hardware ID for a sled
#[derive(
Clone,
Debug,
Serialize,
Deserialize,
JsonSchema,
PartialOrd,
Ord,
PartialEq,
Eq,
)]
pub struct UninitializedSledId {
pub serial: String,
pub part: String,
}

path_param!(ProjectPath, project, "project");
path_param!(InstancePath, instance, "instance");
path_param!(NetworkInterfacePath, interface, "network interface");
Expand Down
7 changes: 7 additions & 0 deletions nexus/types/src/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::sync::Arc;
use strum::EnumIter;
use uuid::Uuid;

use crate::external_api::params::UninitializedSledId;
use crate::external_api::shared::Baseboard;

/// Results of collecting hardware/software inventory from various Omicron
Expand Down Expand Up @@ -139,6 +140,12 @@ impl From<Baseboard> for BaseboardId {
}
}

impl From<UninitializedSledId> for BaseboardId {
fn from(value: UninitializedSledId) -> Self {
BaseboardId { part_number: value.part, serial_number: value.serial }
}
}

/// Caboose contents found during a collection
///
/// These are normalized in the database. Each distinct `Caboose` is assigned a
Expand Down
18 changes: 17 additions & 1 deletion openapi/nexus.json
Original file line number Diff line number Diff line change
Expand Up @@ -3770,7 +3770,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Baseboard"
"$ref": "#/components/schemas/UninitializedSledId"
}
}
},
Expand Down Expand Up @@ -14692,6 +14692,22 @@
"rack_id"
]
},
"UninitializedSledId": {
"description": "The unique hardware ID for a sled",
"type": "object",
"properties": {
"part": {
"type": "string"
},
"serial": {
"type": "string"
}
},
"required": [
"part",
"serial"
]
},
"UninitializedSledResultsPage": {
"description": "A single page of results",
"type": "object",
Expand Down

0 comments on commit 395a7c8

Please sign in to comment.