diff --git a/Cargo.lock b/Cargo.lock index eba31ceca4..3060a8fae7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -692,9 +692,9 @@ dependencies = [ name = "bootstrap-agent-client" version = "0.1.0" dependencies = [ - "ipnetwork", "omicron-common", "omicron-workspace-hack", + "oxnet", "progenitor", "regress", "reqwest", @@ -4490,7 +4490,6 @@ version = "0.1.0" dependencies = [ "chrono", "futures", - "ipnetwork", "nexus-types", "omicron-common", "omicron-passwords", @@ -4803,7 +4802,6 @@ dependencies = [ "indexmap 2.2.6", "internal-dns", "ipnet", - "ipnetwork", "maplit", "nexus-config", "nexus-inventory", @@ -8716,7 +8714,6 @@ dependencies = [ "anyhow", "async-trait", "chrono", - "ipnetwork", "omicron-common", "omicron-uuid-kinds", "omicron-workspace-hack", @@ -10991,7 +10988,6 @@ version = "0.1.0" dependencies = [ "anyhow", "gateway-client", - "ipnetwork", "maplit", "omicron-common", "omicron-workspace-hack", @@ -11064,7 +11060,6 @@ dependencies = [ "installinator-artifactd", "installinator-common", "internal-dns", - "ipnetwork", "itertools 0.12.1", "maplit", "omicron-certificates", @@ -11076,6 +11071,7 @@ dependencies = [ "once_cell", "openapi-lint", "openapiv3", + "oxnet", "rand 0.8.5", "reqwest", "schemars", @@ -11110,7 +11106,6 @@ version = "0.1.0" dependencies = [ "chrono", "installinator-common", - "ipnetwork", "omicron-common", "omicron-workspace-hack", "progenitor", diff --git a/clients/bootstrap-agent-client/Cargo.toml b/clients/bootstrap-agent-client/Cargo.toml index 272abdedae..0b1d2fab4b 100644 --- a/clients/bootstrap-agent-client/Cargo.toml +++ b/clients/bootstrap-agent-client/Cargo.toml @@ -10,7 +10,6 @@ workspace = true [dependencies] omicron-common.workspace = true progenitor.workspace = true -ipnetwork.workspace = true regress.workspace = true reqwest = { workspace = true, features = [ "json", "rustls-tls", "stream" ] } schemars.workspace = true @@ -20,3 +19,4 @@ sled-hardware-types.workspace = true slog.workspace = true uuid.workspace = true omicron-workspace-hack.workspace = true +oxnet.workspace = true diff --git a/clients/bootstrap-agent-client/src/lib.rs b/clients/bootstrap-agent-client/src/lib.rs index be309cc3e2..b29f4e69f4 100644 --- a/clients/bootstrap-agent-client/src/lib.rs +++ b/clients/bootstrap-agent-client/src/lib.rs @@ -18,16 +18,12 @@ progenitor::generate_api!( slog::debug!(log, "client response"; "result" => ?result); }), derives = [schemars::JsonSchema], + crates = { + "oxnet" = "0.1.0", + }, replace = { - ImportExportPolicy = omicron_common::api::external::ImportExportPolicy, - Ipv4Network = ipnetwork::Ipv4Network, - Ipv6Network = ipnetwork::Ipv6Network, - IpNetwork = ipnetwork::IpNetwork, - IpNet = omicron_common::api::external::IpNet, - Ipv4Net = omicron_common::api::external::Ipv4Net, - Ipv6Net = omicron_common::api::external::Ipv6Net, - IpAllowList = omicron_common::api::external::IpAllowList, AllowedSourceIps = omicron_common::api::external::AllowedSourceIps, + ImportExportPolicy = omicron_common::api::external::ImportExportPolicy, } ); diff --git a/clients/gateway-client/src/lib.rs b/clients/gateway-client/src/lib.rs index 7dbc50eea2..6e932577a7 100644 --- a/clients/gateway-client/src/lib.rs +++ b/clients/gateway-client/src/lib.rs @@ -50,15 +50,15 @@ progenitor::generate_api!( }), derives = [schemars::JsonSchema], patch = { - SpIdentifier = { derives = [Copy, PartialEq, Hash, Eq, Serialize, Deserialize] }, - SpIgnition = { derives = [PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - SpIgnitionSystemType = { derives = [Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - SpState = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - RotState = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - RotImageDetails = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - RotSlot = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - ImageVersion = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - HostPhase2RecoveryImageId = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, + HostPhase2RecoveryImageId = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + ImageVersion = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + RotImageDetails = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + RotSlot = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + RotState = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + SpIdentifier = { derives = [Copy, PartialEq, Hash, Eq] }, + SpIgnition = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + SpIgnitionSystemType = { derives = [Copy, PartialEq, Eq, PartialOrd, Ord] }, + SpState = { derives = [PartialEq, Eq, PartialOrd, Ord] }, }, ); diff --git a/clients/installinator-artifact-client/src/lib.rs b/clients/installinator-artifact-client/src/lib.rs index de3072a34a..96806c2cab 100644 --- a/clients/installinator-artifact-client/src/lib.rs +++ b/clients/installinator-artifact-client/src/lib.rs @@ -19,13 +19,13 @@ progenitor::generate_api!( }), derives = [schemars::JsonSchema], replace = { + Duration = std::time::Duration, EventReportForInstallinatorSpec = installinator_common::EventReport, - StepEventForInstallinatorSpec = installinator_common::StepEvent, + M2Slot = installinator_common::M2Slot, + ProgressEventForGenericSpec = installinator_common::ProgressEvent, ProgressEventForInstallinatorSpec = installinator_common::ProgressEvent, StepEventForGenericSpec = installinator_common::StepEvent, - ProgressEventForGenericSpec = installinator_common::ProgressEvent, - M2Slot = installinator_common::M2Slot, - Duration = std::time::Duration, + StepEventForInstallinatorSpec = installinator_common::StepEvent, } ); diff --git a/clients/nexus-client/Cargo.toml b/clients/nexus-client/Cargo.toml index b4e299da67..1b64fa24d1 100644 --- a/clients/nexus-client/Cargo.toml +++ b/clients/nexus-client/Cargo.toml @@ -10,7 +10,6 @@ workspace = true [dependencies] chrono.workspace = true futures.workspace = true -ipnetwork.workspace = true nexus-types.workspace = true omicron-common.workspace = true omicron-passwords.workspace = true diff --git a/clients/nexus-client/src/lib.rs b/clients/nexus-client/src/lib.rs index bcdd3971c0..6546af8673 100644 --- a/clients/nexus-client/src/lib.rs +++ b/clients/nexus-client/src/lib.rs @@ -21,6 +21,9 @@ progenitor::generate_api!( post_hook = (|log: &slog::Logger, result: &Result<_, _>| { slog::debug!(log, "client response"; "result" => ?result); }), + crates = { + "oxnet" = "0.1.0", + }, replace = { // It's kind of unfortunate to pull in such a complex and unstable type // as "blueprint" this way, but we have really useful functionality @@ -28,14 +31,11 @@ progenitor::generate_api!( Blueprint = nexus_types::deployment::Blueprint, Generation = omicron_common::api::external::Generation, ImportExportPolicy = omicron_common::api::external::ImportExportPolicy, - Ipv4Network = ipnetwork::Ipv4Network, - Ipv6Network = ipnetwork::Ipv6Network, - IpNetwork = ipnetwork::IpNetwork, MacAddr = omicron_common::api::external::MacAddr, Name = omicron_common::api::external::Name, - NewPasswordHash = omicron_passwords::NewPasswordHash, NetworkInterface = omicron_common::api::internal::shared::NetworkInterface, NetworkInterfaceKind = omicron_common::api::internal::shared::NetworkInterfaceKind, + NewPasswordHash = omicron_passwords::NewPasswordHash, TypedUuidForCollectionKind = omicron_uuid_kinds::CollectionUuid, TypedUuidForDownstairsKind = omicron_uuid_kinds::TypedUuid, TypedUuidForSledKind = omicron_uuid_kinds::TypedUuid, @@ -419,50 +419,16 @@ impl TryFrom } } -impl TryFrom<&oxnet::Ipv4Net> for types::Ipv4Net { - type Error = String; - - fn try_from(net: &oxnet::Ipv4Net) -> Result { - types::Ipv4Net::try_from(net.to_string()).map_err(|e| e.to_string()) - } -} - -impl TryFrom<&oxnet::Ipv6Net> for types::Ipv6Net { - type Error = String; - - fn try_from(net: &oxnet::Ipv6Net) -> Result { - types::Ipv6Net::try_from(net.to_string()).map_err(|e| e.to_string()) - } -} - -impl TryFrom<&oxnet::IpNet> for types::IpNet { - type Error = String; - - fn try_from(net: &oxnet::IpNet) -> Result { - use oxnet::IpNet; - match net { - IpNet::V4(v4) => types::Ipv4Net::try_from(v4).map(types::IpNet::V4), - IpNet::V6(v6) => types::Ipv6Net::try_from(v6).map(types::IpNet::V6), - } - } -} - -impl TryFrom<&omicron_common::api::external::AllowedSourceIps> +impl From<&omicron_common::api::external::AllowedSourceIps> for types::AllowedSourceIps { - type Error = String; - - fn try_from( - ips: &omicron_common::api::external::AllowedSourceIps, - ) -> Result { + fn from(ips: &omicron_common::api::external::AllowedSourceIps) -> Self { use omicron_common::api::external::AllowedSourceIps; match ips { - AllowedSourceIps::Any => Ok(types::AllowedSourceIps::Any), - AllowedSourceIps::List(list) => list - .iter() - .map(TryInto::try_into) - .collect::, _>>() - .map(types::AllowedSourceIps::List), + AllowedSourceIps::Any => types::AllowedSourceIps::Any, + AllowedSourceIps::List(list) => { + types::AllowedSourceIps::List(list.iter().cloned().collect()) + } } } } diff --git a/clients/sled-agent-client/Cargo.toml b/clients/sled-agent-client/Cargo.toml index caca3c8c73..11cc5adfd7 100644 --- a/clients/sled-agent-client/Cargo.toml +++ b/clients/sled-agent-client/Cargo.toml @@ -12,15 +12,14 @@ anyhow.workspace = true async-trait.workspace = true chrono.workspace = true omicron-common.workspace = true +omicron-uuid-kinds.workspace = true +omicron-workspace-hack.workspace = true +oxnet.workspace = true progenitor.workspace = true -ipnetwork.workspace = true regress.workspace = true reqwest = { workspace = true, features = [ "json", "rustls-tls", "stream" ] } schemars.workspace = true serde.workspace = true +serde_json.workspace = true slog.workspace = true uuid.workspace = true -omicron-workspace-hack.workspace = true -omicron-uuid-kinds.workspace = true -oxnet.workspace = true -serde_json.workspace = true diff --git a/clients/sled-agent-client/src/lib.rs b/clients/sled-agent-client/src/lib.rs index 24bb2a6df8..300e3713ea 100644 --- a/clients/sled-agent-client/src/lib.rs +++ b/clients/sled-agent-client/src/lib.rs @@ -16,7 +16,7 @@ use uuid::Uuid; progenitor::generate_api!( spec = "../../openapi/sled-agent.json", - derives = [ schemars::JsonSchema, PartialEq ], + derives = [schemars::JsonSchema, PartialEq], inner_type = slog::Logger, pre_hook = (|log: &slog::Logger, request: &reqwest::Request| { slog::debug!(log, "client request"; @@ -29,33 +29,31 @@ progenitor::generate_api!( slog::debug!(log, "client response"; "result" => ?result); }), patch = { - BfdPeerConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, - BgpConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, - BgpPeerConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, - PortConfigV1 = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, - RouteConfig = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, - IpNet = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, - VirtualNetworkInterfaceHost = { derives = [PartialEq, Eq, Hash, Serialize, Deserialize] }, - OmicronPhysicalDiskConfig = { derives = [Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord] }, + BfdPeerConfig = { derives = [Eq, Hash] }, + BgpConfig = { derives = [Eq, Hash] }, + BgpPeerConfig = { derives = [Eq, Hash] }, + OmicronPhysicalDiskConfig = { derives = [Eq, Hash, PartialOrd, Ord] }, + PortConfigV1 = { derives = [Eq, Hash] }, + RouteConfig = { derives = [Eq, Hash] }, + VirtualNetworkInterfaceHost = { derives = [Eq, Hash] }, + }, + crates = { + "oxnet" = "0.1.0", }, - //TODO trade the manual transformations later in this file for the - // replace directives below? replace = { ByteCount = omicron_common::api::external::ByteCount, DiskIdentity = omicron_common::disk::DiskIdentity, Generation = omicron_common::api::external::Generation, + ImportExportPolicy = omicron_common::api::external::ImportExportPolicy, MacAddr = omicron_common::api::external::MacAddr, Name = omicron_common::api::external::Name, - SwitchLocation = omicron_common::api::external::SwitchLocation, - ImportExportPolicy = omicron_common::api::external::ImportExportPolicy, - Ipv6Network = ipnetwork::Ipv6Network, - IpNetwork = ipnetwork::IpNetwork, + NetworkInterface = omicron_common::api::internal::shared::NetworkInterface, PortFec = omicron_common::api::internal::shared::PortFec, PortSpeed = omicron_common::api::internal::shared::PortSpeed, SourceNatConfig = omicron_common::api::internal::shared::SourceNatConfig, - Vni = omicron_common::api::external::Vni, - NetworkInterface = omicron_common::api::internal::shared::NetworkInterface, + SwitchLocation = omicron_common::api::external::SwitchLocation, TypedUuidForZpoolKind = omicron_uuid_kinds::ZpoolUuid, + Vni = omicron_common::api::external::Vni, ZpoolKind = omicron_common::zpool_name::ZpoolKind, ZpoolName = omicron_common::zpool_name::ZpoolName, } @@ -413,111 +411,6 @@ impl From for omicron_common::api::external::DiskState { } } -impl From for types::Ipv4Net { - fn from(n: oxnet::Ipv4Net) -> Self { - Self::try_from(n.to_string()).unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for types::Ipv6Net { - fn from(n: oxnet::Ipv6Net) -> Self { - Self::try_from(n.to_string()).unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for types::IpNet { - fn from(s: oxnet::IpNet) -> Self { - match s { - oxnet::IpNet::V4(v4) => Self::V4(v4.into()), - oxnet::IpNet::V6(v6) => Self::V6(v6.into()), - } - } -} - -impl From for types::Ipv4Net { - fn from(n: ipnetwork::Ipv4Network) -> Self { - Self::try_from(n.to_string()).unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for types::Ipv4Network { - fn from(n: ipnetwork::Ipv4Network) -> Self { - Self::try_from(n.to_string()).unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for oxnet::Ipv4Net { - fn from(n: types::Ipv4Net) -> Self { - n.parse().unwrap() - } -} - -impl From for types::Ipv4Network { - fn from(n: oxnet::Ipv4Net) -> Self { - Self::try_from(n.to_string()).unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for types::Ipv6Net { - fn from(n: ipnetwork::Ipv6Network) -> Self { - Self::try_from(n.to_string()).unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for ipnetwork::Ipv6Network { - fn from(n: types::Ipv6Net) -> Self { - n.parse().unwrap() - } -} - -impl From for types::IpNet { - fn from(n: ipnetwork::IpNetwork) -> Self { - use ipnetwork::IpNetwork; - match n { - IpNetwork::V4(v4) => Self::V4(v4.into()), - IpNetwork::V6(v6) => Self::V6(v6.into()), - } - } -} - -impl From for ipnetwork::IpNetwork { - fn from(n: types::IpNet) -> Self { - match n { - types::IpNet::V4(v4) => ipnetwork::IpNetwork::V4(v4.into()), - types::IpNet::V6(v6) => ipnetwork::IpNetwork::V6(v6.into()), - } - } -} - -impl From for ipnetwork::Ipv4Network { - fn from(n: types::Ipv4Net) -> Self { - n.parse().unwrap() - } -} - -impl From for types::Ipv4Net { - fn from(n: std::net::Ipv4Addr) -> Self { - Self::try_from(format!("{n}/32")) - .unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for types::Ipv6Net { - fn from(n: std::net::Ipv6Addr) -> Self { - Self::try_from(format!("{n}/128")) - .unwrap_or_else(|e| panic!("{}: {}", n, e)) - } -} - -impl From for types::IpNet { - fn from(s: std::net::IpAddr) -> Self { - match s { - IpAddr::V4(v4) => Self::V4(v4.into()), - IpAddr::V6(v6) => Self::V6(v6.into()), - } - } -} - impl From for types::L4PortRange { fn from(s: omicron_common::api::external::L4PortRange) -> Self { Self::try_from(s.to_string()).unwrap_or_else(|e| panic!("{}: {}", s, e)) @@ -578,7 +471,7 @@ impl From fn from(s: omicron_common::api::internal::nexus::HostIdentifier) -> Self { use omicron_common::api::internal::nexus::HostIdentifier::*; match s { - Ip(net) => Self::Ip(net.into()), + Ip(net) => Self::Ip(net), Vpc(vni) => Self::Vpc(vni), } } diff --git a/clients/wicketd-client/Cargo.toml b/clients/wicketd-client/Cargo.toml index 364cb5ec86..8e50964e59 100644 --- a/clients/wicketd-client/Cargo.toml +++ b/clients/wicketd-client/Cargo.toml @@ -10,8 +10,8 @@ workspace = true [dependencies] chrono.workspace = true installinator-common.workspace = true -ipnetwork.workspace = true omicron-common.workspace = true +omicron-workspace-hack.workspace = true progenitor.workspace = true regress.workspace = true reqwest = { workspace = true, features = ["rustls-tls", "stream"] } @@ -23,4 +23,3 @@ slog.workspace = true update-engine.workspace = true uuid.workspace = true wicket-common.workspace = true -omicron-workspace-hack.workspace = true diff --git a/clients/wicketd-client/src/lib.rs b/clients/wicketd-client/src/lib.rs index 4248c3719f..8edb797b20 100644 --- a/clients/wicketd-client/src/lib.rs +++ b/clients/wicketd-client/src/lib.rs @@ -18,32 +18,28 @@ progenitor::generate_api!( slog::debug!(log, "client response"; "result" => ?result); }), derives = [schemars::JsonSchema], - patch = - { - SpComponentCaboose = { derives = [PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - SpIdentifier = { derives = [Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - SpState = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize] }, - SpComponentInfo= { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - SpIgnition= { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - SpIgnitionSystemType= { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - SpInventory = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - RackV1Inventory = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - RotState = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - RotImageDetails = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - RotInventory = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - RotSlot = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - ImageVersion = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize]}, - StartUpdateOptions = { derives = [ Serialize, Deserialize, Default ]}, - Baseboard = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, - RackInitId = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, - RackResetId = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, - RackOperationStatus = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, - RackNetworkConfigV1 = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, - UplinkConfig = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, - CurrentRssUserConfigInsensitive = { derives = [ PartialEq, Serialize, Deserialize ] }, - CurrentRssUserConfigSensitive = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, - CurrentRssUserConfig = { derives = [ PartialEq, Serialize, Deserialize ] }, - GetLocationResponse = { derives = [ PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize ] }, + patch = { + CurrentRssUserConfig = { derives = [PartialEq] }, + CurrentRssUserConfigSensitive = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + GetLocationResponse = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + ImageVersion = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + RackInitId = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + RackNetworkConfigV1 = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + RackOperationStatus = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + RackResetId = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + RackV1Inventory = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + RotImageDetails = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + RotInventory = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + RotSlot = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + RotState = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + SpComponentCaboose = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + SpComponentInfo = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + SpIgnition = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + SpIgnitionSystemType= { derives = [PartialEq, Eq, PartialOrd, Ord]}, + SpInventory = { derives = [PartialEq, Eq, PartialOrd, Ord]}, + SpState = { derives = [PartialEq, Eq, PartialOrd, Ord] }, + StartUpdateOptions = { derives = [Default]}, + UplinkConfig = { derives = [PartialEq, Eq, PartialOrd, Ord] }, }, replace = { AllowedSourceIps = omicron_common::api::internal::shared::AllowedSourceIps, @@ -61,10 +57,8 @@ progenitor::generate_api!( Duration = std::time::Duration, EventReportForWicketdEngineSpec = wicket_common::update_events::EventReport, GetBgpAuthKeyInfoResponse = wicket_common::rack_setup::GetBgpAuthKeyInfoResponse, - IpNetwork = ipnetwork::IpNetwork, + ImportExportPolicy = omicron_common::api::internal::shared::ImportExportPolicy, IpRange = omicron_common::address::IpRange, - Ipv4Network = ipnetwork::Ipv4Network, - Ipv6Network = ipnetwork::Ipv6Network, Ipv4Range = omicron_common::address::Ipv4Range, Ipv6Range = omicron_common::address::Ipv6Range, M2Slot = installinator_common::M2Slot, @@ -86,7 +80,6 @@ progenitor::generate_api!( UserSpecifiedImportExportPolicy = wicket_common::rack_setup::UserSpecifiedImportExportPolicy, UserSpecifiedPortConfig = wicket_common::rack_setup::UserSpecifiedPortConfig, UserSpecifiedRackNetworkConfig = wicket_common::rack_setup::UserSpecifiedRackNetworkConfig, - ImportExportPolicy = omicron_common::api::internal::shared::ImportExportPolicy, } ); diff --git a/common/src/address.rs b/common/src/address.rs index b7476d6ff4..eddfb996c4 100644 --- a/common/src/address.rs +++ b/common/src/address.rs @@ -248,24 +248,16 @@ impl DnsSubnet { /// Returns the DNS server address within the subnet. /// /// This is the first address within the subnet. - pub fn dns_address(&self) -> Ipv6Net { - Ipv6Net::new( - self.subnet.net().nth(DNS_ADDRESS_INDEX as u128).unwrap(), - SLED_PREFIX, - ) - .unwrap() + pub fn dns_address(&self) -> Ipv6Addr { + self.subnet.net().nth(DNS_ADDRESS_INDEX as u128).unwrap() } /// Returns the address which the Global Zone should create /// to be able to contact the DNS server. /// /// This is the second address within the subnet. - pub fn gz_address(&self) -> Ipv6Net { - Ipv6Net::new( - self.subnet.net().nth(GZ_ADDRESS_INDEX as u128).unwrap(), - SLED_PREFIX, - ) - .unwrap() + pub fn gz_address(&self) -> Ipv6Addr { + self.subnet.net().nth(GZ_ADDRESS_INDEX as u128).unwrap() } } @@ -304,7 +296,7 @@ pub fn get_internal_dns_server_addresses(addr: Ipv6Addr) -> Vec { &reserved_rack_subnet.get_dns_subnets()[0..DNS_REDUNDANCY]; dns_subnets .iter() - .map(|dns_subnet| IpAddr::from(dns_subnet.dns_address().addr())) + .map(|dns_subnet| IpAddr::from(dns_subnet.dns_address())) .collect() } @@ -686,11 +678,11 @@ mod test { // The DNS address and GZ address should be only differing by one. assert_eq!( - "fd00:1122:3344:0001::1/64".parse::().unwrap(), + "fd00:1122:3344:0001::1".parse::().unwrap(), dns_subnets[0].dns_address(), ); assert_eq!( - "fd00:1122:3344:0001::2/64".parse::().unwrap(), + "fd00:1122:3344:0001::2".parse::().unwrap(), dns_subnets[0].gz_address(), ); } diff --git a/common/src/api/internal/shared.rs b/common/src/api/internal/shared.rs index b0d3232eed..9e3e1a71f5 100644 --- a/common/src/api/internal/shared.rs +++ b/common/src/api/internal/shared.rs @@ -8,8 +8,7 @@ use crate::{ address::NUM_SOURCE_NAT_PORTS, api::external::{self, BfdMode, ImportExportPolicy, Name}, }; -use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network}; -use oxnet::IpNet; +use oxnet::{IpNet, Ipv4Net, Ipv6Net}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::{ @@ -160,7 +159,7 @@ pub type RackNetworkConfig = RackNetworkConfigV1; /// Initial network configuration #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] pub struct RackNetworkConfigV1 { - pub rack_subnet: Ipv6Network, + pub rack_subnet: Ipv6Net, // TODO: #3591 Consider making infra-ip ranges implicit for uplinks /// First ip address to be used for configuring network infrastructure pub infra_ip_first: Ipv4Addr, @@ -180,7 +179,7 @@ pub struct BgpConfig { /// The autonomous system number for the BGP configuration. pub asn: u32, /// The set of prefixes for the BGP router to originate. - pub originate: Vec, + pub originate: Vec, /// Shaper to apply to outgoing messages. #[serde(default)] @@ -292,7 +291,7 @@ pub struct BfdPeerConfig { #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct RouteConfig { /// The destination of the route. - pub destination: IpNetwork, + pub destination: IpNet, /// The nexthop/gateway address. pub nexthop: IpAddr, /// The VLAN id associated with this route. @@ -305,7 +304,7 @@ pub struct PortConfigV1 { /// The set of routes associated with this port. pub routes: Vec, /// This port's addresses. - pub addresses: Vec, + pub addresses: Vec, /// Switch the port belongs to. pub switch: SwitchLocation, /// Nmae of the port this config applies to. @@ -356,7 +355,7 @@ pub struct UplinkConfig { pub uplink_port_fec: PortFec, /// IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport /// (must be in infra_ip pool) - pub uplink_cidr: Ipv4Network, + pub uplink_cidr: Ipv4Net, /// VLAN id to use for uplink pub uplink_vid: Option, } @@ -374,7 +373,7 @@ pub struct HostPortConfig { /// IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport /// (must be in infra_ip pool) - pub addrs: Vec, + pub addrs: Vec, } impl From for HostPortConfig { diff --git a/internal-dns/src/resolver.rs b/internal-dns/src/resolver.rs index 670b4b420c..cf5def01c5 100644 --- a/internal-dns/src/resolver.rs +++ b/internal-dns/src/resolver.rs @@ -118,7 +118,7 @@ impl Resolver { .get_dns_subnets() .into_iter() .map(|dns_subnet| { - let ip_addr = IpAddr::V6(dns_subnet.dns_address().addr()); + let ip_addr = IpAddr::V6(dns_subnet.dns_address()); SocketAddr::new(ip_addr, DNS_PORT) }) .collect() diff --git a/nexus/reconfigurator/planning/Cargo.toml b/nexus/reconfigurator/planning/Cargo.toml index 7bbc9aa36b..989ad6aa32 100644 --- a/nexus/reconfigurator/planning/Cargo.toml +++ b/nexus/reconfigurator/planning/Cargo.toml @@ -14,7 +14,6 @@ gateway-client.workspace = true indexmap.workspace = true internal-dns.workspace = true ipnet.workspace = true -ipnetwork.workspace = true nexus-config.workspace = true nexus-inventory.workspace = true nexus-types.workspace = true diff --git a/nexus/src/app/background/sync_switch_configuration.rs b/nexus/src/app/background/sync_switch_configuration.rs index 7efe9ef92b..54fc5b8be0 100644 --- a/nexus/src/app/background/sync_switch_configuration.rs +++ b/nexus/src/app/background/sync_switch_configuration.rs @@ -11,6 +11,7 @@ use crate::app::{ }, map_switch_zone_addrs, }; +use oxnet::Ipv4Net; use slog::o; use internal_dns::resolver::Resolver; @@ -50,8 +51,8 @@ use omicron_common::{ use serde_json::json; use sled_agent_client::types::{ BgpConfig as SledBgpConfig, BgpPeerConfig as SledBgpPeerConfig, - EarlyNetworkConfig, EarlyNetworkConfigBody, HostPortConfig, Ipv4Network, - PortConfigV1, RackNetworkConfigV1, RouteConfig as SledRouteConfig, + EarlyNetworkConfig, EarlyNetworkConfigBody, HostPortConfig, PortConfigV1, + RackNetworkConfigV1, RouteConfig as SledRouteConfig, }; use std::{ collections::{hash_map::Entry, HashMap, HashSet}, @@ -868,7 +869,7 @@ impl BackgroundTask for SwitchPortSettingsManager { // build the desired bootstore config from the records we've fetched let subnet = match rack.rack_subnet { - Some(IpNetwork::V6(subnet)) => subnet, + Some(IpNetwork::V6(subnet)) => subnet.into(), Some(IpNetwork::V4(_)) => { error!(log, "rack subnet must be ipv6"; "rack" => ?rack); continue; @@ -881,14 +882,13 @@ impl BackgroundTask for SwitchPortSettingsManager { // TODO: is this correct? Do we place the BgpConfig for both switches in a single Vec to send to the bootstore? let mut bgp: Vec = switch_bgp_config.iter().map(|(_location, (_id, config))| { - let announcements: Vec = bgp_announce_prefixes + let announcements = bgp_announce_prefixes .get(&config.bgp_announce_set_id) .expect("bgp config is present but announce set is not populated") .iter() .map(|prefix| { - ipnetwork::Ipv4Network::new(prefix.value, prefix.length) - .expect("Prefix4 and Ipv4Network's value types have diverged") - .into() + Ipv4Net::new(prefix.value, prefix.length) + .expect("Prefix4 and Ipv4Net's value types have diverged") }).collect(); SledBgpConfig { @@ -923,7 +923,7 @@ impl BackgroundTask for SwitchPortSettingsManager { }; let mut port_config = PortConfigV1 { - addresses: info.addresses.iter().map(|a| a.address).collect(), + addresses: info.addresses.iter().map(|a| a.address.into()).collect(), autoneg: info .links .get(0) //TODO breakout support @@ -962,7 +962,7 @@ impl BackgroundTask for SwitchPortSettingsManager { .routes .iter() .map(|r| SledRouteConfig { - destination: r.dst, + destination: r.dst.into(), nexthop: r.gw.ip(), vlan_id: r.vid.map(|x| x.0), }) @@ -1401,7 +1401,7 @@ fn uplinks( }; let config = HostPortConfig { port: port.port_name.clone(), - addrs: config.addresses.iter().map(|a| a.address).collect(), + addrs: config.addresses.iter().map(|a| a.address.into()).collect(), }; match uplinks.entry(*location) { diff --git a/nexus/src/app/rack.rs b/nexus/src/app/rack.rs index 1327558dd4..da97c77c04 100644 --- a/nexus/src/app/rack.rs +++ b/nexus/src/app/rack.rs @@ -63,6 +63,7 @@ use omicron_common::api::external::ResourceType; use omicron_common::api::internal::shared::ExternalPortDiscovery; use omicron_uuid_kinds::GenericUuid; use omicron_uuid_kinds::SledUuid; +use oxnet::IpNet; use sled_agent_client::types::AddSledRequest; use sled_agent_client::types::StartSledAgentRequest; use sled_agent_client::types::StartSledAgentRequestBody; @@ -286,7 +287,8 @@ impl super::Nexus { // The `rack` row is created with the rack ID we know when Nexus starts, // but we didn't know the rack subnet until now. Set it. let mut rack = self.rack_lookup(opctx, &self.rack_id).await?; - rack.rack_subnet = Some(rack_network_config.rack_subnet.into()); + rack.rack_subnet = + Some(IpNet::from(rack_network_config.rack_subnet).into()); self.datastore().update_rack_subnet(opctx, &rack).await?; // TODO - https://github.com/oxidecomputer/omicron/pull/3359 @@ -427,8 +429,8 @@ impl super::Nexus { .originate .iter() .map(|o| AddressLotBlockCreate { - first_address: o.network().into(), - last_address: o.broadcast().into(), + first_address: o.first_addr().into(), + last_address: o.last_addr().into(), }) .collect(), }, @@ -460,13 +462,13 @@ impl super::Nexus { announcement: bgp_config .originate .iter() - .map(|x| BgpAnnouncementCreate { + .map(|ipv4_net| BgpAnnouncementCreate { address_lot_block: NameOrId::Name( format!("as{}", bgp_config.asn) .parse() .unwrap(), ), - network: IpNetwork::from(*x).into(), + network: (*ipv4_net).into(), }) .collect(), }, @@ -552,7 +554,7 @@ impl super::Nexus { .iter() .map(|a| Address { address_lot: NameOrId::Name(address_lot_name.clone()), - address: (*a).into(), + address: (*a), }) .collect(); @@ -563,11 +565,7 @@ impl super::Nexus { let routes: Vec = uplink_config .routes .iter() - .map(|r| Route { - dst: r.destination.into(), - gw: r.nexthop, - vid: None, - }) + .map(|r| Route { dst: r.destination, gw: r.nexthop, vid: None }) .collect(); port_settings_params @@ -660,7 +658,8 @@ impl super::Nexus { .rack_set_initialized( opctx, RackInit { - rack_subnet: rack_network_config.rack_subnet.into(), + rack_subnet: IpNet::from(rack_network_config.rack_subnet) + .into(), rack_id, blueprint, physical_disks, @@ -852,8 +851,7 @@ impl super::Nexus { rack_subnet, allocation.subnet_octet.try_into().unwrap(), ) - .net() - .into(), + .net(), }, }, }, diff --git a/openapi/bootstrap-agent.json b/openapi/bootstrap-agent.json index ddfc1e91f8..b09f34ea9e 100644 --- a/openapi/bootstrap-agent.json +++ b/openapi/bootstrap-agent.json @@ -334,7 +334,7 @@ "description": "The set of prefixes for the BGP router to originate.", "type": "array", "items": { - "$ref": "#/components/schemas/Ipv4Network" + "$ref": "#/components/schemas/Ipv4Net" } }, "shaper": { @@ -644,27 +644,6 @@ } ] }, - "IpNetwork": { - "x-rust-type": "ipnetwork::IpNetwork", - "oneOf": [ - { - "title": "v4", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv4Network" - } - ] - }, - { - "title": "v6", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv6Network" - } - ] - } - ] - }, "IpRange": { "oneOf": [ { @@ -697,11 +676,6 @@ "type": "string", "pattern": "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$" }, - "Ipv4Network": { - "x-rust-type": "ipnetwork::Ipv4Network", - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/(3[0-2]|[0-2]?[0-9])$" - }, "Ipv4Range": { "description": "A non-decreasing IPv4 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -732,11 +706,6 @@ "type": "string", "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$" }, - "Ipv6Network": { - "x-rust-type": "ipnetwork::Ipv6Network", - "type": "string", - "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\")[/](12[0-8]|1[0-1][0-9]|[0-9]?[0-9])$" - }, "Ipv6Range": { "description": "A non-decreasing IPv6 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -775,7 +744,7 @@ "description": "This port's addresses.", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } }, "autoneg": { @@ -1002,7 +971,7 @@ } }, "rack_subnet": { - "$ref": "#/components/schemas/Ipv6Network" + "$ref": "#/components/schemas/Ipv6Net" } }, "required": [ @@ -1211,7 +1180,7 @@ "description": "The destination of the route.", "allOf": [ { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } ] }, diff --git a/openapi/nexus-internal.json b/openapi/nexus-internal.json index f9ca60b360..828378eaba 100644 --- a/openapi/nexus-internal.json +++ b/openapi/nexus-internal.json @@ -1573,7 +1573,7 @@ "description": "The set of prefixes for the BGP router to originate.", "type": "array", "items": { - "$ref": "#/components/schemas/Ipv4Network" + "$ref": "#/components/schemas/Ipv4Net" } }, "shaper": { @@ -3287,27 +3287,6 @@ } ] }, - "IpNetwork": { - "x-rust-type": "ipnetwork::IpNetwork", - "oneOf": [ - { - "title": "v4", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv4Network" - } - ] - }, - { - "title": "v6", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv6Network" - } - ] - } - ] - }, "IpRange": { "oneOf": [ { @@ -3387,11 +3366,6 @@ "type": "string", "pattern": "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$" }, - "Ipv4Network": { - "x-rust-type": "ipnetwork::Ipv4Network", - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/(3[0-2]|[0-2]?[0-9])$" - }, "Ipv4Range": { "description": "A non-decreasing IPv4 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -3422,11 +3396,6 @@ "type": "string", "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$" }, - "Ipv6Network": { - "x-rust-type": "ipnetwork::Ipv6Network", - "type": "string", - "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\")[/](12[0-8]|1[0-1][0-9]|[0-9]?[0-9])$" - }, "Ipv6Range": { "description": "A non-decreasing IPv6 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -3837,7 +3806,7 @@ "description": "This port's addresses.", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } }, "autoneg": { @@ -4226,7 +4195,7 @@ } }, "rack_subnet": { - "$ref": "#/components/schemas/Ipv6Network" + "$ref": "#/components/schemas/Ipv6Net" } }, "required": [ @@ -4351,7 +4320,7 @@ "description": "The destination of the route.", "allOf": [ { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } ] }, diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index 763a67910f..b975f16484 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -1475,7 +1475,7 @@ "description": "The set of prefixes for the BGP router to originate.", "type": "array", "items": { - "$ref": "#/components/schemas/Ipv4Network" + "$ref": "#/components/schemas/Ipv4Net" } }, "shaper": { @@ -2710,7 +2710,7 @@ "description": "IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport (must be in infra_ip pool)", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } }, "port": { @@ -3412,27 +3412,6 @@ } ] }, - "IpNetwork": { - "x-rust-type": "ipnetwork::IpNetwork", - "oneOf": [ - { - "title": "v4", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv4Network" - } - ] - }, - { - "title": "v6", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv6Network" - } - ] - } - ] - }, "Ipv4Net": { "example": "192.168.1.0/24", "title": "An IPv4 subnet", @@ -3445,11 +3424,6 @@ "type": "string", "pattern": "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$" }, - "Ipv4Network": { - "x-rust-type": "ipnetwork::Ipv4Network", - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/(3[0-2]|[0-2]?[0-9])$" - }, "Ipv6Net": { "example": "fd12:3456::/64", "title": "An IPv6 subnet", @@ -3462,11 +3436,6 @@ "type": "string", "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$" }, - "Ipv6Network": { - "x-rust-type": "ipnetwork::Ipv6Network", - "type": "string", - "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\")[/](12[0-8]|1[0-1][0-9]|[0-9]?[0-9])$" - }, "Ipv6Subnet": { "description": "Wraps an [`Ipv6Net`] with a compile-time prefix length.", "type": "object", @@ -4087,7 +4056,7 @@ "description": "This port's addresses.", "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } }, "autoneg": { @@ -4237,7 +4206,7 @@ } }, "rack_subnet": { - "$ref": "#/components/schemas/Ipv6Network" + "$ref": "#/components/schemas/Ipv6Net" } }, "required": [ @@ -4255,7 +4224,7 @@ "description": "The destination of the route.", "allOf": [ { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } ] }, diff --git a/openapi/wicketd.json b/openapi/wicketd.json index 762fbfade0..fd8e49b6e3 100644 --- a/openapi/wicketd.json +++ b/openapi/wicketd.json @@ -1055,7 +1055,7 @@ "description": "The set of prefixes for the BGP router to originate.", "type": "array", "items": { - "$ref": "#/components/schemas/Ipv4Network" + "$ref": "#/components/schemas/Ipv4Net" } }, "shaper": { @@ -1690,27 +1690,6 @@ } ] }, - "IpNetwork": { - "x-rust-type": "ipnetwork::IpNetwork", - "oneOf": [ - { - "title": "v4", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv4Network" - } - ] - }, - { - "title": "v6", - "allOf": [ - { - "$ref": "#/components/schemas/Ipv6Network" - } - ] - } - ] - }, "IpRange": { "oneOf": [ { @@ -1743,11 +1722,6 @@ "type": "string", "pattern": "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$" }, - "Ipv4Network": { - "x-rust-type": "ipnetwork::Ipv4Network", - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/(3[0-2]|[0-2]?[0-9])$" - }, "Ipv4Range": { "description": "A non-decreasing IPv4 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -1778,11 +1752,6 @@ "type": "string", "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$" }, - "Ipv6Network": { - "x-rust-type": "ipnetwork::Ipv6Network", - "type": "string", - "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\")[/](12[0-8]|1[0-1][0-9]|[0-9]?[0-9])$" - }, "Ipv6Range": { "description": "A non-decreasing IPv6 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -2752,7 +2721,7 @@ "description": "The destination of the route.", "allOf": [ { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } ] }, @@ -5060,7 +5029,7 @@ "addresses": { "type": "array", "items": { - "$ref": "#/components/schemas/IpNetwork" + "$ref": "#/components/schemas/IpNet" } }, "autoneg": { diff --git a/schema/rss-sled-plan.json b/schema/rss-sled-plan.json index 204dddff99..5971235634 100644 --- a/schema/rss-sled-plan.json +++ b/schema/rss-sled-plan.json @@ -204,7 +204,7 @@ "description": "The set of prefixes for the BGP router to originate.", "type": "array", "items": { - "$ref": "#/definitions/Ipv4Network" + "$ref": "#/definitions/Ipv4Net" } }, "shaper": { @@ -500,27 +500,6 @@ "version": "0.1.0" } }, - "IpNetwork": { - "oneOf": [ - { - "title": "v4", - "allOf": [ - { - "$ref": "#/definitions/Ipv4Network" - } - ] - }, - { - "title": "v6", - "allOf": [ - { - "$ref": "#/definitions/Ipv6Network" - } - ] - } - ], - "x-rust-type": "ipnetwork::IpNetwork" - }, "IpRange": { "oneOf": [ { @@ -555,11 +534,6 @@ "version": "0.1.0" } }, - "Ipv4Network": { - "type": "string", - "pattern": "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/(3[0-2]|[0-2]?[0-9])$", - "x-rust-type": "ipnetwork::Ipv4Network" - }, "Ipv4Range": { "description": "A non-decreasing IPv4 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -592,11 +566,6 @@ "version": "0.1.0" } }, - "Ipv6Network": { - "type": "string", - "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\")[/](12[0-8]|1[0-1][0-9]|[0-9]?[0-9])$", - "x-rust-type": "ipnetwork::Ipv6Network" - }, "Ipv6Range": { "description": "A non-decreasing IPv6 address range, inclusive of both ends.\n\nThe first address must be less than or equal to the last address.", "type": "object", @@ -656,7 +625,7 @@ "description": "This port's addresses.", "type": "array", "items": { - "$ref": "#/definitions/IpNetwork" + "$ref": "#/definitions/IpNet" } }, "autoneg": { @@ -879,7 +848,7 @@ } }, "rack_subnet": { - "$ref": "#/definitions/Ipv6Network" + "$ref": "#/definitions/Ipv6Net" } } }, @@ -914,7 +883,7 @@ "description": "The destination of the route.", "allOf": [ { - "$ref": "#/definitions/IpNetwork" + "$ref": "#/definitions/IpNet" } ] }, diff --git a/sled-agent/src/bootstrap/early_networking.rs b/sled-agent/src/bootstrap/early_networking.rs index 8727a01eae..bd12bb745a 100644 --- a/sled-agent/src/bootstrap/early_networking.rs +++ b/sled-agent/src/bootstrap/early_networking.rs @@ -14,7 +14,6 @@ use futures::future; use gateway_client::Client as MgsClient; use internal_dns::resolver::{ResolveError, Resolver as DnsResolver}; use internal_dns::ServiceName; -use ipnetwork::Ipv6Network; use mg_admin_client::types::{ AddStaticRoute4Request, ApplyRequest, BfdPeerConfig, BgpPeerConfig, CheckerSource, ImportExportPolicy as MgImportExportPolicy, Prefix, Prefix4, @@ -34,7 +33,7 @@ use omicron_common::backoff::{ }; use omicron_common::OMICRON_DPD_TAG; use omicron_ddm_admin_client::DdmError; -use oxnet::IpNet; +use oxnet::{IpNet, Ipv6Net}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use slog::Logger; @@ -579,7 +578,7 @@ impl<'a> EarlyNetworkSetup<'a> { originate: config .originate .iter() - .map(|x| Prefix4 { length: x.prefix(), value: x.ip() }) + .map(|x| Prefix4 { length: x.width(), value: x.addr() }) .collect(), }) .await @@ -601,9 +600,9 @@ impl<'a> EarlyNetworkSetup<'a> { IpAddr::V4(v4) => v4, IpAddr::V6(_) => continue, }; - let prefix = match r.destination.ip() { + let prefix = match r.destination.addr() { IpAddr::V4(v4) => { - Prefix4 { value: v4, length: r.destination.prefix() } + Prefix4 { value: v4, length: r.destination.width() } } IpAddr::V6(_) => continue, }; @@ -658,7 +657,7 @@ impl<'a> EarlyNetworkSetup<'a> { // TODO We're discarding the `uplink_cidr.prefix()` here and only using // the IP address; at some point we probably need to give the full CIDR // to dendrite? - addrs.push(a.ip()); + addrs.push(a.addr()); } let link_settings = LinkSettings { @@ -886,7 +885,7 @@ impl RackNetworkConfigV0 { v0: RackNetworkConfigV0, ) -> RackNetworkConfigV1 { RackNetworkConfigV1 { - rack_subnet: Ipv6Network::new(rack_subnet, 56).unwrap(), + rack_subnet: Ipv6Net::new(rack_subnet, 56).unwrap(), infra_ip_first: v0.infra_ip_first, infra_ip_last: v0.infra_ip_last, ports: v0 @@ -973,7 +972,7 @@ mod tests { body: EarlyNetworkConfigBody { ntp_servers: v0.ntp_servers.clone(), rack_network_config: Some(RackNetworkConfigV1 { - rack_subnet: Ipv6Network::new(v0.rack_subnet, 56).unwrap(), + rack_subnet: Ipv6Net::new(v0.rack_subnet, 56).unwrap(), infra_ip_first: v0_rack_network_config.infra_ip_first, infra_ip_last: v0_rack_network_config.infra_ip_last, ports: vec![PortConfigV1 { diff --git a/sled-agent/src/bootstrap/params.rs b/sled-agent/src/bootstrap/params.rs index cc5c0648d6..e458900c53 100644 --- a/sled-agent/src/bootstrap/params.rs +++ b/sled-agent/src/bootstrap/params.rs @@ -384,6 +384,7 @@ mod tests { use super::*; use camino::Utf8PathBuf; + use oxnet::Ipv6Net; #[test] fn parse_rack_initialization() { @@ -505,7 +506,7 @@ mod tests { user_password_hash: "$argon2id$v=19$m=98304,t=13,p=1$RUlWc0ZxaHo0WFdrN0N6ZQ$S8p52j85GPvMhR/ek3GL0el/oProgTwWpHJZ8lsQQoY".parse().unwrap(), }, rack_network_config: RackNetworkConfig { - rack_subnet: Ipv6Addr::LOCALHOST.into(), + rack_subnet: Ipv6Net::host_net(Ipv6Addr::LOCALHOST), infra_ip_first: Ipv4Addr::LOCALHOST, infra_ip_last: Ipv4Addr::LOCALHOST, ports: Vec::new(), diff --git a/sled-agent/src/rack_setup/config.rs b/sled-agent/src/rack_setup/config.rs index 9fe62d3582..e52ed14304 100644 --- a/sled-agent/src/rack_setup/config.rs +++ b/sled-agent/src/rack_setup/config.rs @@ -70,13 +70,15 @@ impl SetupServiceConfig { } pub fn az_subnet(&self) -> Ipv6Subnet { - Ipv6Subnet::::new(self.rack_network_config.rack_subnet.ip()) + Ipv6Subnet::::new( + self.rack_network_config.rack_subnet.addr(), + ) } /// Returns the subnet for our rack. pub fn rack_subnet(&self) -> Ipv6Subnet { Ipv6Subnet::::new( - self.rack_network_config.rack_subnet.ip(), + self.rack_network_config.rack_subnet.addr(), ) } @@ -96,6 +98,7 @@ mod test { use omicron_common::address::IpRange; use omicron_common::api::internal::shared::AllowedSourceIps; use omicron_common::api::internal::shared::RackNetworkConfig; + use oxnet::Ipv6Net; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; #[test] @@ -123,7 +126,11 @@ mod test { .unwrap(), }, rack_network_config: RackNetworkConfig { - rack_subnet: "fd00:1122:3344:0100::".parse().unwrap(), + rack_subnet: Ipv6Net::new( + "fd00:1122:3344:0100::".parse().unwrap(), + RACK_PREFIX, + ) + .unwrap(), infra_ip_first: Ipv4Addr::LOCALHOST, infra_ip_last: Ipv4Addr::LOCALHOST, ports: Vec::new(), diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index a763d61923..b48e4f18b8 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -384,11 +384,11 @@ impl Plan { &reserved_rack_subnet.get_dns_subnets()[0..DNS_REDUNDANCY]; let rack_dns_servers = dns_subnets .into_iter() - .map(|dns_subnet| dns_subnet.dns_address().addr().into()) + .map(|dns_subnet| dns_subnet.dns_address().into()) .collect::>(); for i in 0..dns_subnets.len() { let dns_subnet = &dns_subnets[i]; - let ip = dns_subnet.dns_address().addr(); + let ip = dns_subnet.dns_address(); let sled = { let which_sled = sled_allocator.next().ok_or(PlanError::NotEnoughSleds)?; @@ -419,7 +419,7 @@ impl Plan { }, http_address, dns_address, - gz_address: dns_subnet.gz_address().addr(), + gz_address: dns_subnet.gz_address(), gz_address_index: i.try_into().expect("Giant indices?"), }, }); @@ -1156,6 +1156,7 @@ mod tests { use omicron_common::address::IpRange; use omicron_common::api::internal::shared::AllowedSourceIps; use omicron_common::api::internal::shared::RackNetworkConfig; + use oxnet::Ipv6Net; const EXPECTED_RESERVED_ADDRESSES: u16 = 2; const EXPECTED_USABLE_ADDRESSES: u16 = @@ -1251,7 +1252,7 @@ mod tests { user_password_hash: "$argon2id$v=19$m=98304,t=13,p=1$RUlWc0ZxaHo0WFdrN0N6ZQ$S8p52j85GPvMhR/ek3GL0el/oProgTwWpHJZ8lsQQoY".parse().unwrap(), }, rack_network_config: RackNetworkConfig { - rack_subnet: Ipv6Addr::LOCALHOST.into(), + rack_subnet: Ipv6Net::host_net(Ipv6Addr::LOCALHOST), infra_ip_first: Ipv4Addr::LOCALHOST, infra_ip_last: Ipv4Addr::LOCALHOST, ports: Vec::new(), diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index c39ccffacd..1d8b3e7ad3 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -752,7 +752,7 @@ impl ServiceInner { vlan_id: r.vlan_id, }) .collect(), - addresses: config.addresses.clone(), + addresses: config.addresses.iter().cloned().map(Into::into).collect(), switch: config.switch.into(), uplink_port_speed: config.uplink_port_speed.into(), uplink_port_fec: config.uplink_port_fec.into(), @@ -788,7 +788,7 @@ impl ServiceInner { .iter() .map(|config| NexusTypes::BgpConfig { asn: config.asn, - originate: config.originate.clone(), + originate: config.originate.iter().cloned().map(Into::into).collect(), shaper: config.shaper.clone(), checker: config.checker.clone(), }) diff --git a/sled-agent/src/sim/server.rs b/sled-agent/src/sim/server.rs index e3ce4ad4e4..ae7f40f5f3 100644 --- a/sled-agent/src/sim/server.rs +++ b/sled-agent/src/sim/server.rs @@ -36,6 +36,7 @@ use omicron_common::FileKv; use omicron_uuid_kinds::GenericUuid; use omicron_uuid_kinds::SledUuid; use omicron_uuid_kinds::ZpoolUuid; +use oxnet::Ipv6Net; use slog::{info, Drain, Logger}; use std::collections::BTreeMap; use std::collections::HashMap; @@ -527,7 +528,7 @@ pub async fn run_standalone_server( HashMap::new(), ), rack_network_config: NexusTypes::RackNetworkConfigV1 { - rack_subnet: Ipv6Addr::LOCALHOST.into(), + rack_subnet: Ipv6Net::host_net(Ipv6Addr::LOCALHOST), infra_ip_first: Ipv4Addr::LOCALHOST, infra_ip_last: Ipv4Addr::LOCALHOST, ports: Vec::new(), diff --git a/sled-agent/src/sim/sled_agent.rs b/sled-agent/src/sim/sled_agent.rs index d9308bf769..742639350a 100644 --- a/sled-agent/src/sim/sled_agent.rs +++ b/sled-agent/src/sim/sled_agent.rs @@ -27,7 +27,6 @@ use anyhow::Context; use dropshot::{HttpError, HttpServer}; use futures::lock::Mutex; use illumos_utils::opte::params::VirtualNetworkInterfaceHost; -use ipnetwork::Ipv6Network; use omicron_common::api::external::{ ByteCount, DiskState, Error, Generation, ResourceType, }; @@ -40,6 +39,7 @@ use omicron_common::api::internal::nexus::{ use omicron_common::api::internal::shared::RackNetworkConfig; use omicron_common::disk::DiskIdentity; use omicron_uuid_kinds::ZpoolUuid; +use oxnet::Ipv6Net; use propolis_client::{ types::VolumeConstructionRequest, Client as PropolisClient, }; @@ -154,7 +154,7 @@ impl SledAgent { body: EarlyNetworkConfigBody { ntp_servers: Vec::new(), rack_network_config: Some(RackNetworkConfig { - rack_subnet: Ipv6Network::new(Ipv6Addr::UNSPECIFIED, 56) + rack_subnet: Ipv6Net::new(Ipv6Addr::UNSPECIFIED, 56) .unwrap(), infra_ip_first: Ipv4Addr::UNSPECIFIED, infra_ip_last: Ipv4Addr::UNSPECIFIED, diff --git a/wicket-common/Cargo.toml b/wicket-common/Cargo.toml index 685514f399..9a82b3d8bd 100644 --- a/wicket-common/Cargo.toml +++ b/wicket-common/Cargo.toml @@ -9,12 +9,12 @@ workspace = true [dependencies] anyhow.workspace = true +gateway-client.workspace = true +maplit.workspace = true omicron-common.workspace = true +omicron-workspace-hack.workspace = true owo-colors.workspace = true oxnet.workspace = true -gateway-client.workspace = true -ipnetwork.workspace = true -maplit.workspace = true schemars.workspace = true serde.workspace = true serde_json.workspace = true @@ -22,7 +22,6 @@ sha2.workspace = true sled-hardware-types.workspace = true thiserror.workspace = true update-engine.workspace = true -omicron-workspace-hack.workspace = true [dev-dependencies] toml.workspace = true diff --git a/wicket-common/src/rack_setup.rs b/wicket-common/src/rack_setup.rs index 9221153398..ba88c258a5 100644 --- a/wicket-common/src/rack_setup.rs +++ b/wicket-common/src/rack_setup.rs @@ -6,7 +6,6 @@ pub use gateway_client::types::SpIdentifier as GatewaySpIdentifier; pub use gateway_client::types::SpType as GatewaySpType; -use ipnetwork::IpNetwork; use omicron_common::address; use omicron_common::api::external::ImportExportPolicy; use omicron_common::api::external::Name; @@ -182,7 +181,7 @@ impl UserSpecifiedRackNetworkConfig { #[serde(deny_unknown_fields)] pub struct UserSpecifiedPortConfig { pub routes: Vec, - pub addresses: Vec, + pub addresses: Vec, pub uplink_port_speed: PortSpeed, pub uplink_port_fec: PortFec, pub autoneg: bool, diff --git a/wicketd/Cargo.toml b/wicketd/Cargo.toml index fe0fa27e15..bfd8a4cf45 100644 --- a/wicketd/Cargo.toml +++ b/wicketd/Cargo.toml @@ -13,8 +13,8 @@ async-trait.workspace = true base64.workspace = true buf-list.workspace = true bytes.workspace = true -camino.workspace = true camino-tempfile.workspace = true +camino.workspace = true clap.workspace = true debug-ignore.workspace = true display-error-chain.workspace = true @@ -25,28 +25,28 @@ flume.workspace = true futures.workspace = true gateway-messages.workspace = true hex.workspace = true -hubtools.workspace = true http.workspace = true +hubtools.workspace = true hyper.workspace = true illumos-utils.workspace = true -ipnetwork.workspace = true internal-dns.workspace = true itertools.workspace = true once_cell.workspace = true +oxnet.workspace = true reqwest.workspace = true schemars.workspace = true serde.workspace = true -sha2.workspace = true serde_json.workspace = true -slog.workspace = true +sha2.workspace = true slog-dtrace.workspace = true +slog.workspace = true thiserror.workspace = true tokio = { workspace = true, features = [ "full" ] } tokio-stream.workspace = true tokio-util.workspace = true +toml.workspace = true tough.workspace = true trust-dns-resolver.workspace = true -toml.workspace = true uuid.workspace = true bootstrap-agent-client.workspace = true diff --git a/wicketd/src/preflight_check/uplink.rs b/wicketd/src/preflight_check/uplink.rs index f17580a1de..3a70823b5b 100644 --- a/wicketd/src/preflight_check/uplink.rs +++ b/wicketd/src/preflight_check/uplink.rs @@ -16,12 +16,12 @@ use dpd_client::ClientState as DpdClientState; use either::Either; use illumos_utils::zone::SVCCFG; use illumos_utils::PFEXEC; -use ipnetwork::IpNetwork; use omicron_common::address::DENDRITE_PORT; use omicron_common::api::internal::shared::PortFec as OmicronPortFec; use omicron_common::api::internal::shared::PortSpeed as OmicronPortSpeed; use omicron_common::api::internal::shared::SwitchLocation; use omicron_common::OMICRON_DPD_TAG; +use oxnet::IpNet; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; @@ -760,7 +760,7 @@ fn build_port_settings( let mut port_settings = PortSettings { links: HashMap::new() }; - let addrs = uplink.addresses.iter().map(|a| a.ip()).collect(); + let addrs = uplink.addresses.iter().map(|a| a.addr()).collect(); port_settings.links.insert( link_id.to_string(), @@ -777,7 +777,7 @@ fn build_port_settings( ); for r in &uplink.routes { - if let (IpNetwork::V4(_dst), IpAddr::V4(_nexthop)) = + if let (IpNet::V4(_dst), IpAddr::V4(_nexthop)) = (r.destination, r.nexthop) { // TODO: do we need to create config for mgd? @@ -895,7 +895,7 @@ pub(crate) enum UplinkPreflightTerminalError { #[error( "failed to remove host OS route {destination} -> {nexthop}: {err}" )] - RemoveHostRoute { err: String, destination: IpNetwork, nexthop: IpAddr }, + RemoveHostRoute { err: String, destination: IpNet, nexthop: IpAddr }, #[error("failed to remove uplink SMF property {property:?}: {err}")] RemoveSmfProperty { property: String, err: String }, #[error("failed to refresh uplink service config: {0}")] diff --git a/wicketd/src/rss_config.rs b/wicketd/src/rss_config.rs index c90f672500..77e107a129 100644 --- a/wicketd/src/rss_config.rs +++ b/wicketd/src/rss_config.rs @@ -631,8 +631,8 @@ fn validate_rack_network_config( for (_, _, port_config) in config.iter_uplinks() { for addr in &port_config.addresses { // ... and check that it contains `uplink_ip`. - if addr.ip() < infra_ip_range.first - || addr.ip() > infra_ip_range.last + if addr.addr() < infra_ip_range.first + || addr.addr() > infra_ip_range.last { bail!( "`uplink_cidr`'s IP address must be in the range defined by \ @@ -652,7 +652,7 @@ fn validate_rack_network_config( // TODO Add more client side checks on `rack_network_config` contents? Ok(bootstrap_agent_client::types::RackNetworkConfigV1 { - rack_subnet: RACK_SUBNET.net().into(), + rack_subnet: RACK_SUBNET.net(), infra_ip_first: config.infra_ip_first, infra_ip_last: config.infra_ip_last, ports: config @@ -704,7 +704,7 @@ fn build_port_config( vlan_id: r.vlan_id, }) .collect(), - addresses: config.addresses.clone(), + addresses: config.addresses.iter().cloned().map(Into::into).collect(), bgp_peers: config .bgp_peers .iter()