diff --git a/common/src/address.rs b/common/src/address.rs index 8dee236c259..4a8b19d1f2f 100644 --- a/common/src/address.rs +++ b/common/src/address.rs @@ -9,6 +9,7 @@ use crate::api::external::{self, Error}; use crate::policy::INTERNAL_DNS_REDUNDANCY; +use daft::Diffable; use ipnetwork::Ipv6Network; use oxnet::{Ipv4Net, Ipv6Net}; use schemars::JsonSchema; @@ -273,12 +274,19 @@ pub const SLED_RESERVED_ADDRESSES: u16 = 32; Eq, PartialOrd, Ord, + Diffable, )] #[schemars(rename = "Ipv6Subnet")] pub struct Ipv6Subnet { net: Ipv6Net, } +impl std::fmt::Display for Ipv6Subnet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.net.fmt(f) + } +} + impl Ipv6Subnet { pub fn new(addr: Ipv6Addr) -> Self { // Create a network with the compile-time prefix length. @@ -302,6 +310,14 @@ impl From for Ipv6Subnet { } } +impl From> for Ipv6Network { + fn from(net: Ipv6Subnet) -> Self { + // Ipv6Subnet::new() asserts that `N` is a valid IPv6 prefix, so it's + // okay to unwrap here. + Self::new(net.net.prefix(), N).unwrap() + } +} + // We need a custom Deserialize to ensure that the subnet is what we expect. impl<'de, const N: u8> Deserialize<'de> for Ipv6Subnet { fn deserialize(deserializer: D) -> Result diff --git a/dev-tools/omdb/tests/successes.out b/dev-tools/omdb/tests/successes.out index 0d3c4203166..b6c37e6f52e 100644 --- a/dev-tools/omdb/tests/successes.out +++ b/dev-tools/omdb/tests/successes.out @@ -1552,7 +1552,10 @@ stdout: blueprint ............. parent: - sled: ..................... (active, config generation 2) + sled: ..................... + state::::::::::::: active + config generation: 2 + subnet:::::::::::: ::/64 host phase 2 contents: ------------------------ @@ -1591,7 +1594,10 @@ parent: - sled: ..................... (active, config generation 2) + sled: ..................... + state::::::::::::: active + config generation: 2 + subnet:::::::::::: ::/64 host phase 2 contents: ------------------------ @@ -1676,7 +1682,10 @@ stdout: blueprint ............. parent: - sled: ..................... (active, config generation 2) + sled: ..................... + state::::::::::::: active + config generation: 2 + subnet:::::::::::: ::/64 host phase 2 contents: ------------------------ @@ -1715,7 +1724,10 @@ parent: - sled: ..................... (active, config generation 2) + sled: ..................... + state::::::::::::: active + config generation: 2 + subnet:::::::::::: ::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-add-sled-no-disks-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-add-sled-no-disks-stdout index 19e1a7a3cf0..0e7584d3ea5 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-add-sled-no-disks-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-add-sled-no-disks-stdout @@ -57,7 +57,10 @@ planning report: blueprint 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21 - sled: 00320471-945d-413c-85e7-03e091a70b3c (active, config generation 1) + sled: 00320471-945d-413c-85e7-03e091a70b3c + state::::::::::::: active + config generation: 1 + subnet:::::::::::: fd00:1122:3344:104::/64 host phase 2 contents: ------------------------ @@ -86,7 +89,10 @@ parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 2) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -151,7 +157,10 @@ parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 2) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -213,7 +222,10 @@ parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 2) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout index a3028f9b689..847f19f00b7 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout @@ -82,7 +82,10 @@ zpools (10): blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 - sled: 2eb69596-f081-4e2d-9425-9994926e0832 (active, config generation 2) + sled: 2eb69596-f081-4e2d-9425-9994926e0832 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -196,7 +199,10 @@ parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 - sled: 32d8d836-4d8a-4e54-8fa9-f31d79c42646 (active, config generation 2) + sled: 32d8d836-4d8a-4e54-8fa9-f31d79c42646 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -307,7 +313,10 @@ parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 - sled: 89d02b1b-478c-401a-8e28-7a26f74fa41b (active, config generation 2) + sled: 89d02b1b-478c-401a-8e28-7a26f74fa41b + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -497,7 +506,10 @@ zpools (4): blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 - sled: 89d02b1b-478c-401a-8e28-7a26f74fa41b (active, config generation 2) + sled: 89d02b1b-478c-401a-8e28-7a26f74fa41b + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -1151,7 +1163,10 @@ T ENA ID PARENT blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 - sled: 2eb69596-f081-4e2d-9425-9994926e0832 (active, config generation 2) + sled: 2eb69596-f081-4e2d-9425-9994926e0832 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -1203,7 +1218,10 @@ parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 - sled: 32d8d836-4d8a-4e54-8fa9-f31d79c42646 (active, config generation 2) + sled: 32d8d836-4d8a-4e54-8fa9-f31d79c42646 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -1255,7 +1273,10 @@ parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 - sled: 89d02b1b-478c-401a-8e28-7a26f74fa41b (active, config generation 2) + sled: 89d02b1b-478c-401a-8e28-7a26f74fa41b + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-external-dns-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-external-dns-stdout index 5b6455a499e..567030c7ba4 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-external-dns-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-external-dns-stdout @@ -11,7 +11,10 @@ loaded example system with: blueprint 3f00b694-1b16-4aaa-8f78-e6b3a527b434 parent: 06c88262-f435-410e-ba98-101bed41ec27 - sled: 711ac7f8-d19e-4572-bdb9-e9b50f6e362a (active, config generation 2) + sled: 711ac7f8-d19e-4572-bdb9-e9b50f6e362a + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -125,7 +128,10 @@ parent: 06c88262-f435-410e-ba98-101bed41ec27 - sled: 9dc50690-f9bf-4520-bf80-051d0f465c2c (active, config generation 2) + sled: 9dc50690-f9bf-4520-bf80-051d0f465c2c + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -236,7 +242,10 @@ parent: 06c88262-f435-410e-ba98-101bed41ec27 - sled: a88790de-5962-4871-8686-61c1fd5b7094 (active, config generation 2) + sled: a88790de-5962-4871-8686-61c1fd5b7094 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -549,7 +558,10 @@ external DNS: blueprint 366b0b68-d80e-4bc1-abd3-dc69837847e0 parent: 3f00b694-1b16-4aaa-8f78-e6b3a527b434 - sled: 711ac7f8-d19e-4572-bdb9-e9b50f6e362a (active, config generation 3) + sled: 711ac7f8-d19e-4572-bdb9-e9b50f6e362a + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -663,7 +675,10 @@ parent: 3f00b694-1b16-4aaa-8f78-e6b3a527b434 - sled: 9dc50690-f9bf-4520-bf80-051d0f465c2c (active, config generation 2) + sled: 9dc50690-f9bf-4520-bf80-051d0f465c2c + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -774,7 +789,10 @@ parent: 3f00b694-1b16-4aaa-8f78-e6b3a527b434 - sled: a88790de-5962-4871-8686-61c1fd5b7094 (active, config generation 2) + sled: a88790de-5962-4871-8686-61c1fd5b7094 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -1112,7 +1130,10 @@ external DNS: blueprint 9c998c1d-1a7b-440a-ae0c-40f781dea6e2 parent: 366b0b68-d80e-4bc1-abd3-dc69837847e0 - sled: 711ac7f8-d19e-4572-bdb9-e9b50f6e362a (active, config generation 4) + sled: 711ac7f8-d19e-4572-bdb9-e9b50f6e362a + state::::::::::::: active + config generation: 4 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -1229,7 +1250,10 @@ parent: 366b0b68-d80e-4bc1-abd3-dc69837847e0 - sled: 9dc50690-f9bf-4520-bf80-051d0f465c2c (active, config generation 2) + sled: 9dc50690-f9bf-4520-bf80-051d0f465c2c + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -1340,7 +1364,10 @@ parent: 366b0b68-d80e-4bc1-abd3-dc69837847e0 - sled: a88790de-5962-4871-8686-61c1fd5b7094 (active, config generation 2) + sled: a88790de-5962-4871-8686-61c1fd5b7094 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-internal-dns-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-internal-dns-stdout index 52f5192d2cf..8d8f96928c4 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-internal-dns-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-newly-added-internal-dns-stdout @@ -9,7 +9,10 @@ loaded example system with: blueprint dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21 parent: 184f10b3-61cb-41ef-9b93-3489b2bac559 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 2) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -123,7 +126,10 @@ parent: 184f10b3-61cb-41ef-9b93-3489b2bac559 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 2) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -234,7 +240,10 @@ parent: 184f10b3-61cb-41ef-9b93-3489b2bac559 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 2) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-zones-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-zones-stdout index 1ad4c319a79..213417a4d10 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-zones-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-expunge-zones-stdout @@ -14,7 +14,10 @@ T ENA ID PARENT blueprint dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21 parent: 184f10b3-61cb-41ef-9b93-3489b2bac559 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 2) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -79,7 +82,10 @@ parent: 184f10b3-61cb-41ef-9b93-3489b2bac559 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 2) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -141,7 +147,10 @@ parent: 184f10b3-61cb-41ef-9b93-3489b2bac559 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 2) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-host-phase-2-source-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-host-phase-2-source-stdout index 612002675cb..45933052308 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-host-phase-2-source-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-host-phase-2-source-stdout @@ -353,7 +353,10 @@ external DNS: blueprint 58d5e830-0884-47d8-a7cd-b2b3751adeb4 parent: 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 4) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 4 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------------ @@ -856,7 +859,10 @@ external DNS: blueprint df06bb57-ad42-4431-9206-abff322896c7 parent: af934083-59b5-4bf6-8966-6fb5292c29e1 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 6) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 6 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout index 1033d599d0c..7c8f6ddf074 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout @@ -1218,7 +1218,10 @@ planning report: blueprint afb09faf-a586-4483-9289-04d4f1d8ba23 parent: c1a0d242-9160-40f4-96ae-61f8f40a0b1b - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 5) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 5 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -1269,7 +1272,10 @@ parent: c1a0d242-9160-40f4-96ae-61f8f40a0b1b - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 7) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 7 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -1317,7 +1323,10 @@ parent: c1a0d242-9160-40f4-96ae-61f8f40a0b1b - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 5) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 5 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -1548,7 +1557,10 @@ planning report: blueprint ce365dff-2cdb-4f35-a186-b15e20e1e700 parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 5) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 5 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -1599,7 +1611,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 7) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 7 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -1647,7 +1662,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 6) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 6 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -1914,7 +1932,10 @@ planning report: blueprint 12d602a6-5ab4-487a-b94e-eb30cdf30300 parent: 8f2d1f39-7c88-4701-aa43-56bf281b28c1 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 6) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 6 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -1965,7 +1986,10 @@ parent: 8f2d1f39-7c88-4701-aa43-56bf281b28c1 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 7) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 7 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -2013,7 +2037,10 @@ parent: 8f2d1f39-7c88-4701-aa43-56bf281b28c1 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 6) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 6 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-nexus-generation-autobump-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-nexus-generation-autobump-stdout index 0b75dfb0291..8cdec0d67bf 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-nexus-generation-autobump-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-nexus-generation-autobump-stdout @@ -1072,7 +1072,10 @@ empty planning report blueprint 58d5e830-0884-47d8-a7cd-b2b3751adeb4 parent: 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 3) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------------ @@ -1137,7 +1140,10 @@ parent: 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 3) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------------ @@ -1199,7 +1205,10 @@ parent: 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 3) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-set-mgs-updates-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-set-mgs-updates-stdout index 0f500bfd07d..dce677037c7 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-set-mgs-updates-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-set-mgs-updates-stdout @@ -11,7 +11,10 @@ loaded example system with: blueprint ad97e762-7bf1-45a6-a98f-60afb7e491c0 parent: 6ccc786b-17f1-4562-958f-5a7d9a5a15fd - sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 (active, config generation 2) + sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -76,7 +79,10 @@ parent: 6ccc786b-17f1-4562-958f-5a7d9a5a15fd - sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 (active, config generation 2) + sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -138,7 +144,10 @@ parent: 6ccc786b-17f1-4562-958f-5a7d9a5a15fd - sled: cc00b21a-5685-480a-ab5e-d2e29cf369df (active, config generation 2) + sled: cc00b21a-5685-480a-ab5e-d2e29cf369df + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -232,7 +241,10 @@ warn: no validation is done on the requested artifact hash or version blueprint cca24b71-09b5-4042-9185-b33e9f2ebba0 parent: ad97e762-7bf1-45a6-a98f-60afb7e491c0 - sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 (active, config generation 2) + sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -297,7 +309,10 @@ parent: ad97e762-7bf1-45a6-a98f-60afb7e491c0 - sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 (active, config generation 2) + sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -359,7 +374,10 @@ parent: ad97e762-7bf1-45a6-a98f-60afb7e491c0 - sled: cc00b21a-5685-480a-ab5e-d2e29cf369df (active, config generation 2) + sled: cc00b21a-5685-480a-ab5e-d2e29cf369df + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -535,7 +553,10 @@ warn: no validation is done on the requested artifact hash or version blueprint 5bf974f3-81f9-455b-b24e-3099f765664c parent: cca24b71-09b5-4042-9185-b33e9f2ebba0 - sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 (active, config generation 2) + sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -600,7 +621,10 @@ parent: cca24b71-09b5-4042-9185-b33e9f2ebba0 - sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 (active, config generation 2) + sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -662,7 +686,10 @@ parent: cca24b71-09b5-4042-9185-b33e9f2ebba0 - sled: cc00b21a-5685-480a-ab5e-d2e29cf369df (active, config generation 2) + sled: cc00b21a-5685-480a-ab5e-d2e29cf369df + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -841,7 +868,10 @@ warn: no validation is done on the requested artifact hash or version blueprint 1b837a27-3be1-4fcb-8499-a921c839e1d0 parent: 5bf974f3-81f9-455b-b24e-3099f765664c - sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 (active, config generation 2) + sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -906,7 +936,10 @@ parent: 5bf974f3-81f9-455b-b24e-3099f765664c - sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 (active, config generation 2) + sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -968,7 +1001,10 @@ parent: 5bf974f3-81f9-455b-b24e-3099f765664c - sled: cc00b21a-5685-480a-ab5e-d2e29cf369df (active, config generation 2) + sled: cc00b21a-5685-480a-ab5e-d2e29cf369df + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -1106,7 +1142,10 @@ blueprint 3682a71b-c6ca-4b7e-8f84-16df80c85960 created from blueprint 1b837a27-3 blueprint 3682a71b-c6ca-4b7e-8f84-16df80c85960 parent: 1b837a27-3be1-4fcb-8499-a921c839e1d0 - sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 (active, config generation 2) + sled: bb0ec23a-f97c-4b6a-a5bc-864b1ebc9236 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -1171,7 +1210,10 @@ parent: 1b837a27-3be1-4fcb-8499-a921c839e1d0 - sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 (active, config generation 2) + sled: bba6ea73-6c9c-4ab5-8bb4-1dd145071407 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -1233,7 +1275,10 @@ parent: 1b837a27-3be1-4fcb-8499-a921c839e1d0 - sled: cc00b21a-5685-480a-ab5e-d2e29cf369df (active, config generation 2) + sled: cc00b21a-5685-480a-ab5e-d2e29cf369df + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-set-remove-mupdate-override-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-set-remove-mupdate-override-stdout index 5f2ef7bbc74..38e000249d0 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-set-remove-mupdate-override-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-set-remove-mupdate-override-stdout @@ -49,7 +49,10 @@ blueprint 7f976e0d-d2a5-4eeb-9e82-c82bc2824aba created from latest blueprint (df blueprint 7f976e0d-d2a5-4eeb-9e82-c82bc2824aba parent: df06bb57-ad42-4431-9206-abff322896c7 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 2) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -100,7 +103,10 @@ parent: df06bb57-ad42-4431-9206-abff322896c7 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 2) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -148,7 +154,10 @@ parent: df06bb57-ad42-4431-9206-abff322896c7 - sled: 9a867dc9-d505-427f-9eff-cdb1d4d9bd73 (active, config generation 3) + sled: 9a867dc9-d505-427f-9eff-cdb1d4d9bd73 + state:::::::::::::::::::::::: active + config generation:::::::::::: 3 + subnet::::::::::::::::::::::: fd00:1122:3344:106::/64 will remove mupdate override: 00000000-0000-0000-0000-000000000000 host phase 2 contents: @@ -197,7 +206,10 @@ parent: df06bb57-ad42-4431-9206-abff322896c7 - sled: aff6c093-197d-42c5-ad80-9f10ba051a34 (active, config generation 3) + sled: aff6c093-197d-42c5-ad80-9f10ba051a34 + state:::::::::::::::::::::::: active + config generation:::::::::::: 3 + subnet::::::::::::::::::::::: fd00:1122:3344:104::/64 will remove mupdate override: 00000000-0000-0000-0000-000000000000 host phase 2 contents: @@ -236,7 +248,10 @@ parent: df06bb57-ad42-4431-9206-abff322896c7 - sled: b82ede02-399c-48c6-a1de-411df4fa49a7 (active, config generation 3) + sled: b82ede02-399c-48c6-a1de-411df4fa49a7 + state:::::::::::::::::::::::: active + config generation:::::::::::: 3 + subnet::::::::::::::::::::::: fd00:1122:3344:105::/64 will remove mupdate override: 00000000-0000-0000-0000-000000000000 host phase 2 contents: @@ -275,7 +290,10 @@ parent: df06bb57-ad42-4431-9206-abff322896c7 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 3) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state:::::::::::::::::::::::: active + config generation:::::::::::: 3 + subnet::::::::::::::::::::::: fd00:1122:3344:103::/64 will remove mupdate override: 00000000-0000-0000-0000-000000000000 host phase 2 contents: @@ -314,7 +332,10 @@ parent: df06bb57-ad42-4431-9206-abff322896c7 - sled: e96e226f-4ed9-4c01-91b9-69a9cd076c9e (active, config generation 3) + sled: e96e226f-4ed9-4c01-91b9-69a9cd076c9e + state:::::::::::::::::::::::: active + config generation:::::::::::: 3 + subnet::::::::::::::::::::::: fd00:1122:3344:107::/64 will remove mupdate override: 00000000-0000-0000-0000-000000000000 host phase 2 contents: @@ -695,7 +716,10 @@ blueprint ce365dff-2cdb-4f35-a186-b15e20e1e700 created from latest blueprint (af blueprint ce365dff-2cdb-4f35-a186-b15e20e1e700 parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: 00320471-945d-413c-85e7-03e091a70b3c (active, config generation 2) + sled: 00320471-945d-413c-85e7-03e091a70b3c + state:::::::::::::::::::::::: active + config generation:::::::::::: 2 + subnet::::::::::::::::::::::: fd00:1122:3344:108::/64 will remove mupdate override: ffffffff-ffff-ffff-ffff-ffffffffffff host phase 2 contents: @@ -725,7 +749,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 3) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state:::::::::::::::::::::::: active + config generation:::::::::::: 3 + subnet::::::::::::::::::::::: fd00:1122:3344:102::/64 will remove mupdate override: ffffffff-ffff-ffff-ffff-ffffffffffff host phase 2 contents: @@ -777,7 +804,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 2) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -825,7 +855,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: 9a867dc9-d505-427f-9eff-cdb1d4d9bd73 (active, config generation 4) + sled: 9a867dc9-d505-427f-9eff-cdb1d4d9bd73 + state:::::::::::::::::::::::: active + config generation:::::::::::: 4 + subnet::::::::::::::::::::::: fd00:1122:3344:106::/64 will remove mupdate override: 00000000-0000-0000-0000-000000000000 host phase 2 contents: @@ -874,7 +907,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: aff6c093-197d-42c5-ad80-9f10ba051a34 (active, config generation 3) + sled: aff6c093-197d-42c5-ad80-9f10ba051a34 + state:::::::::::::::::::::::: active + config generation:::::::::::: 3 + subnet::::::::::::::::::::::: fd00:1122:3344:104::/64 will remove mupdate override: 00000000-0000-0000-0000-000000000000 host phase 2 contents: @@ -913,7 +949,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: b82ede02-399c-48c6-a1de-411df4fa49a7 (active, config generation 4) + sled: b82ede02-399c-48c6-a1de-411df4fa49a7 + state:::::::::::::::::::::::: active + config generation:::::::::::: 4 + subnet::::::::::::::::::::::: fd00:1122:3344:105::/64 will remove mupdate override: ffffffff-ffff-ffff-ffff-ffffffffffff host phase 2 contents: @@ -952,7 +991,10 @@ parent: afb09faf-a586-4483-9289-04d4f1d8ba23 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 4) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 4 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-set-zone-images-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-set-zone-images-stdout index 388b338b306..86d9ef94924 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-set-zone-images-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-set-zone-images-stdout @@ -11,7 +11,10 @@ loaded example system with: blueprint 971eeb12-1830-4fa0-a699-98ea0164505c parent: 1b013011-2062-4b48-b544-a32b23bce83a - sled: 868d5b02-7792-4fc0-b6a9-654afcae9ea0 (active, config generation 2) + sled: 868d5b02-7792-4fc0-b6a9-654afcae9ea0 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -133,7 +136,10 @@ warn: no validation is done on the requested image source blueprint f714e6ea-e85a-4d7d-93c2-a018744fe176 parent: 9766ca20-38d4-4380-b005-e7c43c797e7c - sled: 868d5b02-7792-4fc0-b6a9-654afcae9ea0 (active, config generation 4) + sled: 868d5b02-7792-4fc0-b6a9-654afcae9ea0 + state::::::::::::: active + config generation: 4 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -371,7 +377,10 @@ warn: no validation is done on the requested image source blueprint d9c572a1-a68c-4945-b1ec-5389bd588fe9 parent: bb128f06-a2e1-44c1-8874-4f789d0ff896 - sled: 868d5b02-7792-4fc0-b6a9-654afcae9ea0 (active, config generation 6) + sled: 868d5b02-7792-4fc0-b6a9-654afcae9ea0 + state::::::::::::: active + config generation: 6 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout index 801845e6a3b..66ce6ecbbeb 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout @@ -9050,7 +9050,10 @@ external DNS: blueprint 008e1541-3d9d-4a50-a877-eed4a3cf86ab parent: 05685571-d61f-4754-a2b2-604ea8c45dff - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 18) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 18 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------------ @@ -9127,7 +9130,10 @@ parent: 05685571-d61f-4754-a2b2-604ea8c45dff - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 19) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 19 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------------ @@ -9203,7 +9209,10 @@ parent: 05685571-d61f-4754-a2b2-604ea8c45dff - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 17) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 17 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------------ diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-unsafe-zone-mgs-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-unsafe-zone-mgs-stdout index 7492024e0bc..691209d2742 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-unsafe-zone-mgs-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-unsafe-zone-mgs-stdout @@ -1079,7 +1079,10 @@ d81c6a84-79b8-4958-ae41-ea46c9b19763 serial2 3 fd00:1122:3344:103::/64 blueprint 58d5e830-0884-47d8-a7cd-b2b3751adeb4 parent: 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 - sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 3) + sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -1144,7 +1147,10 @@ parent: 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 - sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 3) + sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -1206,7 +1212,10 @@ parent: 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1 - sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 3) + sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ diff --git a/nexus/db-model/src/deployment.rs b/nexus/db-model/src/deployment.rs index 37b1a1de795..02c6d3b5404 100644 --- a/nexus/db-model/src/deployment.rs +++ b/nexus/db-model/src/deployment.rs @@ -58,6 +58,8 @@ use nexus_types::deployment::{ OmicronZoneExternalSnatIp, }; use nexus_types::inventory::BaseboardId; +use omicron_common::address::Ipv6Subnet; +use omicron_common::address::SLED_PREFIX; use omicron_common::api::internal::shared::NetworkInterface; use omicron_common::disk::DiskIdentity; use omicron_common::zpool_name::ZpoolName; @@ -217,9 +219,24 @@ pub struct BpSledMetadata { pub remove_mupdate_override: Option>, pub host_phase_2_desired_slot_a: Option, pub host_phase_2_desired_slot_b: Option, + /// Public only for easy of writing queries; consumers should prefer the + /// `subnet()` method. + pub subnet: IpNetwork, } impl BpSledMetadata { + pub fn subnet(&self) -> anyhow::Result> { + let subnet = match self.subnet { + IpNetwork::V4(subnet) => bail!( + "invalid subnet for sled {}: {subnet} (should be Ipv6)", + self.sled_id + ), + IpNetwork::V6(subnet) => subnet, + }; + + Ok(subnet.into()) + } + pub fn host_phase_2( &self, slot_a_artifact_version: Option, diff --git a/nexus/db-model/src/schema_versions.rs b/nexus/db-model/src/schema_versions.rs index 1ee9a2a936a..691c8a5ecd6 100644 --- a/nexus/db-model/src/schema_versions.rs +++ b/nexus/db-model/src/schema_versions.rs @@ -16,7 +16,7 @@ use std::{collections::BTreeMap, sync::LazyLock}; /// /// This must be updated when you change the database schema. Refer to /// schema/crdb/README.adoc in the root of this repository for details. -pub const SCHEMA_VERSION: Version = Version::new(209, 0, 0); +pub const SCHEMA_VERSION: Version = Version::new(210, 0, 0); /// List of all past database schema versions, in *reverse* order /// @@ -28,6 +28,7 @@ static KNOWN_VERSIONS: LazyLock> = LazyLock::new(|| { // | leaving the first copy as an example for the next person. // v // KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"), + KnownVersion::new(210, "blueprint-sled-config-subnet"), KnownVersion::new(209, "multicast-group-support"), KnownVersion::new(208, "disable-tuf-repo-pruner"), KnownVersion::new(207, "disk-types"), diff --git a/nexus/db-queries/src/db/datastore/deployment.rs b/nexus/db-queries/src/db/datastore/deployment.rs index ffb44a69c7a..3b5f406cd86 100644 --- a/nexus/db-queries/src/db/datastore/deployment.rs +++ b/nexus/db-queries/src/db/datastore/deployment.rs @@ -41,6 +41,7 @@ use diesel::sql_types; use diesel::sql_types::Nullable; use futures::FutureExt; use iddqd::IdOrdMap; +use ipnetwork::Ipv6Network; use nexus_db_errors::ErrorHandler; use nexus_db_errors::OptionalError; use nexus_db_errors::TransactionError; @@ -262,6 +263,7 @@ impl DataStore { .slot_b .artifact_hash() .map(ArtifactHash), + subnet: Ipv6Network::from(sled.subnet).into(), }) .collect::>(); @@ -793,8 +795,14 @@ impl DataStore { paginator = p.found_batch(&batch, &|(s, _, _)| s.sled_id); for (s, slot_a_version, slot_b_version) in batch { + let subnet = s.subnet().map_err(|e| { + Error::internal_error( + &InlineErrorChain::new(&*e).to_string(), + ) + })?; let config = BlueprintSledConfig { state: s.sled_state.into(), + subnet, sled_agent_generation: *s.sled_agent_generation, disks: IdOrdMap::new(), datasets: IdOrdMap::new(), diff --git a/nexus/db-schema/src/schema.rs b/nexus/db-schema/src/schema.rs index 3f8576b0d14..29cca5f5daa 100644 --- a/nexus/db-schema/src/schema.rs +++ b/nexus/db-schema/src/schema.rs @@ -2044,6 +2044,8 @@ table! { host_phase_2_desired_slot_a -> Nullable, host_phase_2_desired_slot_b -> Nullable, + + subnet -> Inet, } } diff --git a/nexus/reconfigurator/execution/src/database.rs b/nexus/reconfigurator/execution/src/database.rs index 075ecb7af33..5a3b691de81 100644 --- a/nexus/reconfigurator/execution/src/database.rs +++ b/nexus/reconfigurator/execution/src/database.rs @@ -79,12 +79,14 @@ mod test { use nexus_types::deployment::BlueprintZoneImageSource; use nexus_types::deployment::BlueprintZoneType; use nexus_types::deployment::CockroachDbPreserveDowngrade; + use nexus_types::deployment::OmicronZoneExternalFloatingIp; use nexus_types::deployment::OximeterReadMode; use nexus_types::deployment::PendingMgsUpdates; use nexus_types::deployment::blueprint_zone_type; use nexus_types::external_api::views::SledState; use nexus_types::inventory::NetworkInterface; use nexus_types::inventory::NetworkInterfaceKind; + use omicron_common::address::Ipv6Subnet; use omicron_common::api::external::Error; use omicron_common::api::external::Generation; use omicron_common::api::external::MacAddr; @@ -98,6 +100,8 @@ mod test { use omicron_uuid_kinds::SledUuid; use omicron_uuid_kinds::ZpoolUuid; use std::collections::BTreeMap; + use std::net::IpAddr; + use std::net::Ipv6Addr; fn create_test_blueprint( top_level_nexus_generation: Generation, @@ -112,38 +116,45 @@ mod test { let zones: IdOrdMap = nexus_zones .into_iter() - .map(|(zone_id, disposition, nexus_generation)| BlueprintZoneConfig { - disposition, - id: zone_id, - filesystem_pool: ZpoolName::new_external(ZpoolUuid::new_v4()), - zone_type: BlueprintZoneType::Nexus(blueprint_zone_type::Nexus { - internal_address: "[::1]:0".parse().unwrap(), - lockstep_port: 0, - external_dns_servers: Vec::new(), - external_ip: nexus_types::deployment::OmicronZoneExternalFloatingIp { - id: ExternalIpUuid::new_v4(), - ip: std::net::IpAddr::V6(std::net::Ipv6Addr::LOCALHOST), - }, - external_tls: true, - nic: NetworkInterface { - id: uuid::Uuid::new_v4(), - kind: NetworkInterfaceKind::Service { - id: zone_id.into_untyped_uuid(), + .map(|(zone_id, disposition, nexus_generation)| { + BlueprintZoneConfig { + disposition, + id: zone_id, + filesystem_pool: ZpoolName::new_external( + ZpoolUuid::new_v4(), + ), + zone_type: BlueprintZoneType::Nexus( + blueprint_zone_type::Nexus { + internal_address: "[::1]:0".parse().unwrap(), + lockstep_port: 0, + external_dns_servers: Vec::new(), + external_ip: OmicronZoneExternalFloatingIp { + id: ExternalIpUuid::new_v4(), + ip: IpAddr::V6(Ipv6Addr::LOCALHOST), + }, + external_tls: true, + nic: NetworkInterface { + id: uuid::Uuid::new_v4(), + kind: NetworkInterfaceKind::Service { + id: zone_id.into_untyped_uuid(), + }, + name: "test-nic".parse().unwrap(), + ip: "192.168.1.1".parse().unwrap(), + mac: MacAddr::random_system(), + subnet: ipnetwork::IpNetwork::V4( + "192.168.1.0/24".parse().unwrap(), + ) + .into(), + vni: Vni::try_from(100).unwrap(), + primary: true, + slot: 0, + transit_ips: Vec::new(), + }, + nexus_generation, }, - name: "test-nic".parse().unwrap(), - ip: "192.168.1.1".parse().unwrap(), - mac: MacAddr::random_system(), - subnet: ipnetwork::IpNetwork::V4( - "192.168.1.0/24".parse().unwrap() - ).into(), - vni: Vni::try_from(100).unwrap(), - primary: true, - slot: 0, - transit_ips: Vec::new(), - }, - nexus_generation, - }), - image_source: BlueprintZoneImageSource::InstallDataset, + ), + image_source: BlueprintZoneImageSource::InstallDataset, + } }) .collect(); @@ -152,6 +163,7 @@ mod test { sled_id, BlueprintSledConfig { state: SledState::Active, + subnet: Ipv6Subnet::new(Ipv6Addr::LOCALHOST), sled_agent_generation: Generation::new(), zones, disks: IdOrdMap::new(), diff --git a/nexus/reconfigurator/execution/src/dns.rs b/nexus/reconfigurator/execution/src/dns.rs index fb932f75792..45813489d7f 100644 --- a/nexus/reconfigurator/execution/src/dns.rs +++ b/nexus/reconfigurator/execution/src/dns.rs @@ -706,6 +706,7 @@ mod test { sa.sled_id, BlueprintSledConfig { state: SledState::Active, + subnet: Ipv6Subnet::new(*sa.sled_agent_address.ip()), sled_agent_generation: ledgered_sled_config.generation, disks: IdOrdMap::new(), datasets: IdOrdMap::new(), diff --git a/nexus/reconfigurator/execution/src/omicron_sled_config.rs b/nexus/reconfigurator/execution/src/omicron_sled_config.rs index 1d09b8708af..5a3758976d9 100644 --- a/nexus/reconfigurator/execution/src/omicron_sled_config.rs +++ b/nexus/reconfigurator/execution/src/omicron_sled_config.rs @@ -97,6 +97,7 @@ mod tests { use nexus_types::external_api::views::SledPolicy; use nexus_types::external_api::views::SledProvisionPolicy; use nexus_types::external_api::views::SledState; + use omicron_common::address::Ipv6Subnet; use omicron_common::address::REPO_DEPOT_PORT; use omicron_common::api::external::Generation; use omicron_common::api::internal::shared::DatasetKind; @@ -109,6 +110,7 @@ mod tests { use omicron_uuid_kinds::OmicronZoneUuid; use omicron_uuid_kinds::PhysicalDiskUuid; use omicron_uuid_kinds::ZpoolUuid; + use std::net::Ipv6Addr; use std::net::SocketAddr; type ControlPlaneTestContext = @@ -259,6 +261,7 @@ mod tests { let sled_config = BlueprintSledConfig { state: SledState::Active, + subnet: Ipv6Subnet::new(Ipv6Addr::LOCALHOST), sled_agent_generation: sim_sled_agent_config_generation.next(), disks, datasets, diff --git a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs index ca9c8c67480..35023d421fb 100644 --- a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs +++ b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs @@ -580,31 +580,10 @@ impl<'a> BlueprintBuilder<'a> { // Convert our parent blueprint's sled configs into `SledEditor`s. let mut sled_editors = BTreeMap::new(); for (sled_id, sled_cfg) in &parent_blueprint.sleds { - let state = sled_cfg.state; - - let editor = match state { - SledState::Active => { - let details = input - .sled_lookup(SledFilter::Commissioned, *sled_id) - .with_context(|| { - format!( - "failed to find sled details for \ - active sled in parent blueprint {sled_id}" - ) - })?; - SledEditor::for_existing_active( - details.resources.subnet, - sled_cfg.clone(), - ) - } - SledState::Decommissioned => { - SledEditor::for_existing_decommissioned(sled_cfg.clone()) - } - } - .with_context(|| { - format!("failed to construct SledEditor for sled {sled_id}") - })?; - + let editor = SledEditor::for_existing(sled_cfg.clone()) + .with_context(|| { + format!("failed to construct SledEditor for sled {sled_id}") + })?; sled_editors.insert(*sled_id, editor); } diff --git a/nexus/reconfigurator/planning/src/blueprint_editor/sled_editor.rs b/nexus/reconfigurator/planning/src/blueprint_editor/sled_editor.rs index a88f59b6315..e0a75b1b367 100644 --- a/nexus/reconfigurator/planning/src/blueprint_editor/sled_editor.rs +++ b/nexus/reconfigurator/planning/src/blueprint_editor/sled_editor.rs @@ -159,33 +159,18 @@ enum InnerSledEditor { } impl SledEditor { - pub fn for_existing_active( - subnet: Ipv6Subnet, + pub fn for_existing( config: BlueprintSledConfig, ) -> Result { - assert_eq!( - config.state, - SledState::Active, - "for_existing_active called on non-active sled" - ); - let inner = ActiveSledEditor::new(subnet, config)?; - Ok(Self(InnerSledEditor::Active(inner))) - } - - pub fn for_existing_decommissioned( - config: BlueprintSledConfig, - ) -> Result { - assert_eq!( - config.state, - SledState::Decommissioned, - "for_existing_decommissioned called on non-decommissioned sled" - ); - let inner = EditedSled { - config, - edit_counts: SledEditCounts::zeroes(), - scalar_edits: EditedSledScalarEdits::zeroes(), + let inner = match config.state { + SledState::Active => { + InnerSledEditor::Active(ActiveSledEditor::new(config)?) + } + SledState::Decommissioned => { + InnerSledEditor::Decommissioned(EditedSled::new(config)) + } }; - Ok(Self(InnerSledEditor::Decommissioned(inner))) + Ok(Self(inner)) } pub fn for_new_active(subnet: Ipv6Subnet) -> Self { @@ -504,11 +489,18 @@ pub(crate) struct EditedSled { pub scalar_edits: EditedSledScalarEdits, } +impl EditedSled { + fn new(config: BlueprintSledConfig) -> Self { + Self { + config, + edit_counts: SledEditCounts::zeroes(), + scalar_edits: EditedSledScalarEdits::zeroes(), + } + } +} + impl ActiveSledEditor { - pub fn new( - subnet: Ipv6Subnet, - config: BlueprintSledConfig, - ) -> Result { + pub fn new(config: BlueprintSledConfig) -> Result { let zones = ZonesEditor::new(config.sled_agent_generation, config.zones); @@ -521,7 +513,8 @@ impl ActiveSledEditor { Ok(Self { underlay_ip_allocator: SledUnderlayIpAllocator::new( - subnet, zone_ips, + config.subnet, + zone_ips, ), incoming_sled_agent_generation: config.sled_agent_generation, zones, @@ -585,6 +578,7 @@ impl ActiveSledEditor { EditedSled { config: BlueprintSledConfig { state: SledState::Active, + subnet: self.underlay_ip_allocator.subnet(), sled_agent_generation, disks, datasets, diff --git a/nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt b/nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt index cd6ce50710c..585009ab08c 100644 --- a/nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt +++ b/nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt @@ -1,7 +1,10 @@ blueprint 4a0b8410-b14f-41e7-85e7-3c0fe7050ccc parent: e35b2fdd-354d-48d9-acb5-703b2c269a54 - sled: 0dbf1e39-e265-4071-a8df-6d1225b46694 (active, config generation 2) + sled: 0dbf1e39-e265-4071-a8df-6d1225b46694 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:105::/64 host phase 2 contents: ------------------------ @@ -120,7 +123,10 @@ parent: e35b2fdd-354d-48d9-acb5-703b2c269a54 - sled: 15cf73a6-445b-4d36-9232-5ed364019bc6 (active, config generation 2) + sled: 15cf73a6-445b-4d36-9232-5ed364019bc6 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:104::/64 host phase 2 contents: ------------------------ @@ -234,7 +240,10 @@ parent: e35b2fdd-354d-48d9-acb5-703b2c269a54 - sled: 50e6c1c0-43b2-4abc-9041-41165597f639 (active, config generation 2) + sled: 50e6c1c0-43b2-4abc-9041-41165597f639 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -345,7 +354,10 @@ parent: e35b2fdd-354d-48d9-acb5-703b2c269a54 - sled: 969ff976-df34-402c-a362-53db03a6b97f (active, config generation 2) + sled: 969ff976-df34-402c-a362-53db03a6b97f + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -456,7 +468,10 @@ parent: e35b2fdd-354d-48d9-acb5-703b2c269a54 - sled: ec5c0b37-b651-4c45-ac1c-24541ef9c44b (active, config generation 2) + sled: ec5c0b37-b651-4c45-ac1c-24541ef9c44b + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ diff --git a/nexus/reconfigurator/planning/tests/output/planner_decommissions_sleds_bp2.txt b/nexus/reconfigurator/planning/tests/output/planner_decommissions_sleds_bp2.txt index 09c4543f386..869c520946d 100644 --- a/nexus/reconfigurator/planning/tests/output/planner_decommissions_sleds_bp2.txt +++ b/nexus/reconfigurator/planning/tests/output/planner_decommissions_sleds_bp2.txt @@ -1,7 +1,10 @@ blueprint 1ac2d88f-27dd-4506-8585-6b2be832528e parent: 516e80a3-b362-4fac-bd3c-4559717120dd - sled: a1b477db-b629-48eb-911d-1ccdafca75b9 (decommissioned, config generation 3) + sled: a1b477db-b629-48eb-911d-1ccdafca75b9 + state::::::::::::: decommissioned + config generation: 3 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -112,7 +115,10 @@ parent: 516e80a3-b362-4fac-bd3c-4559717120dd - sled: d67ce8f0-a691-4010-b414-420d82e80527 (active, config generation 3) + sled: d67ce8f0-a691-4010-b414-420d82e80527 + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ @@ -224,7 +230,10 @@ parent: 516e80a3-b362-4fac-bd3c-4559717120dd - sled: fefcf4cf-f7e7-46b3-b629-058526ce440e (active, config generation 3) + sled: fefcf4cf-f7e7-46b3-b629-058526ce440e + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ diff --git a/nexus/reconfigurator/planning/tests/output/planner_nonprovisionable_bp2.txt b/nexus/reconfigurator/planning/tests/output/planner_nonprovisionable_bp2.txt index e4e0d1907ce..96db5496f0c 100644 --- a/nexus/reconfigurator/planning/tests/output/planner_nonprovisionable_bp2.txt +++ b/nexus/reconfigurator/planning/tests/output/planner_nonprovisionable_bp2.txt @@ -1,7 +1,10 @@ blueprint 9f71f5d3-a272-4382-9154-6ea2e171a6c6 parent: 4d4e6c38-cd95-4c4e-8f45-6af4d686964b - sled: 2d1cb4f2-cf44-40fc-b118-85036eb732a9 (active, config generation 2) + sled: 2d1cb4f2-cf44-40fc-b118-85036eb732a9 + state::::::::::::: active + config generation: 2 + subnet:::::::::::: fd00:1122:3344:105::/64 host phase 2 contents: ------------------------ @@ -112,7 +115,10 @@ parent: 4d4e6c38-cd95-4c4e-8f45-6af4d686964b - sled: 48d95fef-bc9f-4f50-9a53-1e075836291d (decommissioned, config generation 3) + sled: 48d95fef-bc9f-4f50-9a53-1e075836291d + state::::::::::::: decommissioned + config generation: 3 + subnet:::::::::::: fd00:1122:3344:103::/64 host phase 2 contents: ------------------------ @@ -220,7 +226,10 @@ parent: 4d4e6c38-cd95-4c4e-8f45-6af4d686964b - sled: 68d24ac5-f341-49ea-a92a-0381b52ab387 (decommissioned, config generation 2) + sled: 68d24ac5-f341-49ea-a92a-0381b52ab387 + state::::::::::::: decommissioned + config generation: 2 + subnet:::::::::::: fd00:1122:3344:102::/64 host phase 2 contents: ------------------------ @@ -328,7 +337,10 @@ parent: 4d4e6c38-cd95-4c4e-8f45-6af4d686964b - sled: 75bc286f-2b4b-482c-9431-59272af529da (active, config generation 3) + sled: 75bc286f-2b4b-482c-9431-59272af529da + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:104::/64 host phase 2 contents: ------------------------ @@ -437,7 +449,10 @@ parent: 4d4e6c38-cd95-4c4e-8f45-6af4d686964b - sled: affab35f-600a-4109-8ea0-34a067a4e0bc (active, config generation 3) + sled: affab35f-600a-4109-8ea0-34a067a4e0bc + state::::::::::::: active + config generation: 3 + subnet:::::::::::: fd00:1122:3344:101::/64 host phase 2 contents: ------------------------ diff --git a/nexus/src/app/background/tasks/blueprint_execution.rs b/nexus/src/app/background/tasks/blueprint_execution.rs index 53a86896c82..0e3d7b64dab 100644 --- a/nexus/src/app/background/tasks/blueprint_execution.rs +++ b/nexus/src/app/background/tasks/blueprint_execution.rs @@ -250,17 +250,18 @@ mod test { blueprint_zone_type, }; use nexus_types::external_api::views::SledState; + use omicron_common::address::Ipv6Subnet; use omicron_common::api::external; use omicron_common::api::external::Generation; use omicron_common::zpool_name::ZpoolName; use omicron_uuid_kinds::BlueprintUuid; - use omicron_uuid_kinds::OmicronZoneUuid; use omicron_uuid_kinds::PhysicalDiskUuid; use omicron_uuid_kinds::SledUuid; use omicron_uuid_kinds::ZpoolUuid; use serde_json::json; use std::collections::BTreeMap; + use std::net::Ipv6Addr; use std::net::SocketAddr; use std::sync::Arc; use tokio::sync::watch; @@ -285,6 +286,7 @@ mod test { sled_id, BlueprintSledConfig { state: SledState::Active, + subnet: Ipv6Subnet::new(Ipv6Addr::LOCALHOST), sled_agent_generation: Generation::new().next(), disks: IdOrdMap::new(), datasets: IdOrdMap::new(), diff --git a/nexus/test-utils/src/lib.rs b/nexus/test-utils/src/lib.rs index 2b801ba6694..da63e103731 100644 --- a/nexus/test-utils/src/lib.rs +++ b/nexus/test-utils/src/lib.rs @@ -66,6 +66,7 @@ use nexus_types::deployment::blueprint_zone_type; use nexus_types::external_api::views::SledState; use nexus_types::internal_api::params::DnsConfigParams; use omicron_common::address::DNS_OPTE_IPV4_SUBNET; +use omicron_common::address::Ipv6Subnet; use omicron_common::address::NEXUS_OPTE_IPV4_SUBNET; use omicron_common::address::NTP_OPTE_IPV4_SUBNET; use omicron_common::address::NTP_PORT; @@ -1708,6 +1709,7 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { sled_id, BlueprintSledConfig { state: SledState::Active, + subnet: Ipv6Subnet::new(Ipv6Addr::LOCALHOST), sled_agent_generation, disks, datasets, diff --git a/nexus/tests/integration_tests/schema.rs b/nexus/tests/integration_tests/schema.rs index 11cc874287a..9c00a3b8e32 100644 --- a/nexus/tests/integration_tests/schema.rs +++ b/nexus/tests/integration_tests/schema.rs @@ -3476,6 +3476,122 @@ fn after_207_0_0<'a>(ctx: &'a MigrationContext<'a>) -> BoxFuture<'a, ()> { }) } +mod migration_210 { + use super::*; + use omicron_common::address::Ipv6Subnet; + use omicron_common::address::SLED_PREFIX; + use pretty_assertions::assert_eq; + use std::collections::BTreeSet; + + // randomly-generated IDs + const SLED_ID_1: &str = "48e1d10b-3ec8-4abd-95e2-5f37f79da546"; + const SLED_ID_2: &str = "2144219e-d989-4929-b0b3-db895f51b7b5"; + const SLED_ID_3: &str = "d2de378b-c788-4940-9a11-60ac4e633f0c"; + + // randomly-generated IPs + const SLED_IP_1: &str = "445c:212f:f2bc:f202:2b90:5b0e:2d6c:585e"; + const SLED_IP_2: &str = "05fb:7e45:22b1:8dfb:9a06:0dbf:22ab:3eb4"; + const SLED_IP_3: &str = "92a6:42c8:0cf2:7556:5ace:5bab:26e4:4dd1"; + + async fn before_impl(ctx: &MigrationContext<'_>) { + ctx.client + .batch_execute(&format!( + " + INSERT INTO omicron.public.sled ( + id, time_created, time_modified, rcgen, rack_id, is_scrimlet, + serial_number, part_number, revision, usable_hardware_threads, + usable_physical_ram, reservoir_size, ip, port, last_used_address, + sled_policy, sled_state, repo_depot_port, cpu_family + ) + VALUES + ('{SLED_ID_1}', now(), now(), 1, gen_random_uuid(), false, + 'migration-210-serial1', 'part1', 1, 64, 12345678, 123456, + '{SLED_IP_1}', 12345, '{SLED_IP_1}', 'in_service', 'active', + 12346, 'unknown'), + ('{SLED_ID_2}', now(), now(), 1, gen_random_uuid(), false, + 'migration-210-serial2', 'part1', 1, 64, 12345678, 123456, + '{SLED_IP_2}', 12345, '{SLED_IP_2}', 'no_provision', 'active', + 12346, 'unknown'), + ('{SLED_ID_3}', now(), now(), 1, gen_random_uuid(), false, + 'migration-210-serial3', 'part1', 1, 64, 12345678, 123456, + '{SLED_IP_3}', 12345, '{SLED_IP_3}', 'expunged', 'decommissioned', + 12346, 'unknown'); + + INSERT INTO omicron.public.bp_sled_metadata ( + blueprint_id, sled_id, sled_state, sled_agent_generation, + remove_mupdate_override, host_phase_2_desired_slot_a, + host_phase_2_desired_slot_b + ) + VALUES + (gen_random_uuid(), '{SLED_ID_1}', 'active', 1, NULL, NULL, NULL), + (gen_random_uuid(), '{SLED_ID_2}', 'active', 1, NULL, NULL, NULL), + (gen_random_uuid(), '{SLED_ID_3}', 'decommissioned', 1, + NULL, NULL, NULL); + " + )) + .await + .expect("inserted pre-migration data"); + } + + async fn after_impl(ctx: &MigrationContext<'_>) { + let sled_id_1: Uuid = SLED_ID_1.parse().unwrap(); + let sled_id_2: Uuid = SLED_ID_2.parse().unwrap(); + let sled_id_3: Uuid = SLED_ID_3.parse().unwrap(); + + let expected = [ + ( + sled_id_1, + Ipv6Subnet::::new(SLED_IP_1.parse().unwrap()) + .to_string(), + ), + ( + sled_id_2, + Ipv6Subnet::::new(SLED_IP_2.parse().unwrap()) + .to_string(), + ), + ( + sled_id_3, + Ipv6Subnet::::new(SLED_IP_3.parse().unwrap()) + .to_string(), + ), + ] + .into_iter() + .collect::>(); + + let rows = ctx + .client + .query( + " + SELECT sled_id, subnet::text + FROM omicron.public.bp_sled_metadata + WHERE sled_id IN ($1, $2, $3) + ", + &[&sled_id_1, &sled_id_2, &sled_id_3], + ) + .await + .expect("queried post-migration data"); + let got = rows + .into_iter() + .map(|row| { + (row.get::<_, Uuid>("sled_id"), row.get::<_, String>("subnet")) + }) + .collect::>(); + assert_eq!(expected, got); + } + + pub(super) fn before<'a>( + ctx: &'a MigrationContext<'a>, + ) -> BoxFuture<'a, ()> { + Box::pin(before_impl(ctx)) + } + + pub(super) fn after<'a>( + ctx: &'a MigrationContext<'a>, + ) -> BoxFuture<'a, ()> { + Box::pin(after_impl(ctx)) + } +} + // Lazily initializes all migration checks. The combination of Rust function // pointers and async makes defining a static table fairly painful, so we're // using lazy initialization instead. @@ -3586,6 +3702,12 @@ fn get_migration_checks() -> BTreeMap { Version::new(207, 0, 0), DataMigrationFns::new().before(before_207_0_0).after(after_207_0_0), ); + map.insert( + Version::new(210, 0, 0), + DataMigrationFns::new() + .before(migration_210::before) + .after(migration_210::after), + ); map } diff --git a/nexus/types/src/deployment.rs b/nexus/types/src/deployment.rs index 01272eeb750..2cee0ca6e26 100644 --- a/nexus/types/src/deployment.rs +++ b/nexus/types/src/deployment.rs @@ -34,6 +34,8 @@ use nexus_sled_agent_shared::inventory::OmicronSledConfig; use nexus_sled_agent_shared::inventory::OmicronZoneConfig; use nexus_sled_agent_shared::inventory::OmicronZoneImageSource; use nexus_sled_agent_shared::inventory::ZoneKind; +use omicron_common::address::Ipv6Subnet; +use omicron_common::address::SLED_PREFIX; use omicron_common::api::external::ByteCount; use omicron_common::api::external::Generation; use omicron_common::api::external::TufArtifactMeta; @@ -814,6 +816,7 @@ impl fmt::Display for BlueprintDisplay<'_> { for (sled_id, config) in sleds { let BlueprintSledConfig { state, + subnet, sled_agent_generation, disks, datasets, @@ -822,14 +825,13 @@ impl fmt::Display for BlueprintDisplay<'_> { host_phase_2, } = config; - // Report the sled state - writeln!( - f, - "\n sled: {sled_id} ({state}, config generation \ - {sled_agent_generation})", - )?; - + // Report toplevel sled info + writeln!(f, "\n sled: {sled_id}")?; let mut rows = Vec::new(); + rows.push((STATE, state.to_string())); + rows.push((CONFIG_GENERATION, sled_agent_generation.to_string())); + rows.push((SUBNET, subnet.to_string())); + if let Some(id) = remove_mupdate_override { rows.push((WILL_REMOVE_MUPDATE_OVERRIDE, id.to_string())); } @@ -926,6 +928,7 @@ impl fmt::Display for BlueprintDisplay<'_> { )] pub struct BlueprintSledConfig { pub state: SledState, + pub subnet: Ipv6Subnet, /// Generation number used when this type is converted into an /// `OmicronSledConfig` for use by sled-agent. diff --git a/nexus/types/src/deployment/blueprint_display.rs b/nexus/types/src/deployment/blueprint_display.rs index dec9ce3e699..bfa51da9fcb 100644 --- a/nexus/types/src/deployment/blueprint_display.rs +++ b/nexus/types/src/deployment/blueprint_display.rs @@ -53,6 +53,9 @@ pub mod constants { "(not present in collection)"; pub const INVALID_VALUE_PARENS: &str = "(invalid value)"; pub const GENERATION: &str = "generation"; + pub const STATE: &str = "state"; + pub const CONFIG_GENERATION: &str = "config generation"; + pub const SUBNET: &str = "subnet"; } use constants::*; use std::fmt::Display; diff --git a/openapi/nexus-lockstep.json b/openapi/nexus-lockstep.json index ce07eeaac5a..3ea4798c36d 100644 --- a/openapi/nexus-lockstep.json +++ b/openapi/nexus-lockstep.json @@ -2389,6 +2389,9 @@ "state": { "$ref": "#/components/schemas/SledState" }, + "subnet": { + "$ref": "#/components/schemas/Ipv6Subnet" + }, "zones": { "title": "IdOrdMap", "x-rust-type": { @@ -2414,6 +2417,7 @@ "host_phase_2", "sled_agent_generation", "state", + "subnet", "zones" ] }, @@ -5338,6 +5342,18 @@ "last" ] }, + "Ipv6Subnet": { + "description": "Wraps an [`Ipv6Net`] with a compile-time prefix length.", + "type": "object", + "properties": { + "net": { + "$ref": "#/components/schemas/Ipv6Net" + } + }, + "required": [ + "net" + ] + }, "KeeperId": { "description": "A unique ID for a ClickHouse Keeper", "type": "integer", diff --git a/schema/crdb/blueprint-sled-config-subnet/up1.sql b/schema/crdb/blueprint-sled-config-subnet/up1.sql new file mode 100644 index 00000000000..0d619ea8eea --- /dev/null +++ b/schema/crdb/blueprint-sled-config-subnet/up1.sql @@ -0,0 +1,2 @@ +ALTER TABLE omicron.public.bp_sled_metadata + ADD COLUMN IF NOT EXISTS subnet INET; diff --git a/schema/crdb/blueprint-sled-config-subnet/up2.sql b/schema/crdb/blueprint-sled-config-subnet/up2.sql new file mode 100644 index 00000000000..3d33f7b2619 --- /dev/null +++ b/schema/crdb/blueprint-sled-config-subnet/up2.sql @@ -0,0 +1,8 @@ +SET LOCAL disallow_full_table_scans = off; + +UPDATE omicron.public.bp_sled_metadata as bp + SET subnet = ( + SELECT set_masklen(netmask('::/64') & ip, 64) + FROM omicron.public.sled AS s + WHERE bp.sled_id = s.id + ); diff --git a/schema/crdb/blueprint-sled-config-subnet/up3.sql b/schema/crdb/blueprint-sled-config-subnet/up3.sql new file mode 100644 index 00000000000..3747d8d38cf --- /dev/null +++ b/schema/crdb/blueprint-sled-config-subnet/up3.sql @@ -0,0 +1,2 @@ +ALTER TABLE omicron.public.bp_sled_metadata + ALTER COLUMN subnet SET NOT NULL; diff --git a/schema/crdb/dbinit.sql b/schema/crdb/dbinit.sql index 9ce28021a5f..2dd10ed5973 100644 --- a/schema/crdb/dbinit.sql +++ b/schema/crdb/dbinit.sql @@ -4791,6 +4791,9 @@ CREATE TABLE IF NOT EXISTS omicron.public.bp_sled_metadata ( host_phase_2_desired_slot_a STRING(64), host_phase_2_desired_slot_b STRING(64), + -- the sled's /64 subnet on the underlay address + subnet INET NOT NULL, + PRIMARY KEY (blueprint_id, sled_id) ); @@ -7378,7 +7381,7 @@ INSERT INTO omicron.public.db_metadata ( version, target_version ) VALUES - (TRUE, NOW(), NOW(), '209.0.0', NULL) + (TRUE, NOW(), NOW(), '210.0.0', NULL) ON CONFLICT DO NOTHING; COMMIT; diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index 34c43da981d..869c967ed18 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -171,6 +171,7 @@ impl SledConfig { pub(crate) struct PlannedSledDescription { pub(crate) underlay_address: SocketAddrV6, pub(crate) sled_id: SledUuid, + pub(crate) subnet: Ipv6Subnet, pub(crate) config: SledConfig, } @@ -812,6 +813,7 @@ impl Plan { .map(|sled_info| PlannedSledDescription { underlay_address: sled_info.sled_address, sled_id: sled_info.sled_id, + subnet: sled_info.subnet, config: sled_info.request, }) .collect(); @@ -910,6 +912,7 @@ impl Plan { sled_description.sled_id, BlueprintSledConfig { state: SledState::Active, + subnet: sled_description.subnet, sled_agent_generation: sled_agent_config_generation, disks: sled_config.disks.clone(), datasets, diff --git a/sled-agent/src/sim/server.rs b/sled-agent/src/sim/server.rs index df511660761..a00f2f38202 100644 --- a/sled-agent/src/sim/server.rs +++ b/sled-agent/src/sim/server.rs @@ -40,8 +40,8 @@ use nexus_types::deployment::{ }; use nexus_types::inventory::NetworkInterfaceKind; use omicron_common::FileKv; -use omicron_common::address::DNS_OPTE_IPV4_SUBNET; use omicron_common::address::NEXUS_OPTE_IPV4_SUBNET; +use omicron_common::address::{DNS_OPTE_IPV4_SUBNET, Ipv6Subnet}; use omicron_common::api::external::Generation; use omicron_common::api::external::MacAddr; use omicron_common::api::external::Vni; @@ -590,6 +590,7 @@ pub async fn run_standalone_server( all_sleds.insert_overwrite(PlannedSledDescription { underlay_address, sled_id: config.id, + subnet: Ipv6Subnet::new(*underlay_address.ip()), config: SledConfig { disks: omicron_physical_disks_config .disks