Skip to content

Commit 9031662

Browse files
authored
BlueprintBuilder: require caller to provide internal DNS subnet (#9250)
This is part of #9238: we'd like to pull `BlueprintResourceAllocator`'s weird construction out of `BlueprintBuilder`, and this removes _one_ use of it. When adding an internal DNS zone, the caller must now specify the `DnsSubet` instead of `BlueprintBuilder` choosing internally. To assist with this, adds `BlueprintBuilder::available_internal_dns_subnets()`, which returns an iterator of available subnets. I'm not sure this is the right interface; will leave a comment inline with some other ideas.
1 parent 97528cd commit 9031662

File tree

6 files changed

+69
-241
lines changed

6 files changed

+69
-241
lines changed

nexus/reconfigurator/planning/src/blueprint_builder/builder.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::blueprint_editor::EditedSled;
1111
use crate::blueprint_editor::ExternalNetworkingChoice;
1212
use crate::blueprint_editor::ExternalNetworkingError;
1313
use crate::blueprint_editor::ExternalSnatNetworkingChoice;
14-
use crate::blueprint_editor::NoAvailableDnsSubnets;
1514
use crate::blueprint_editor::SledEditError;
1615
use crate::blueprint_editor::SledEditor;
1716
use crate::mgs_updates::PendingHostPhase2Changes;
@@ -65,6 +64,7 @@ use nexus_types::inventory::Collection;
6564
use omicron_common::address::CLICKHOUSE_HTTP_PORT;
6665
use omicron_common::address::DNS_HTTP_PORT;
6766
use omicron_common::address::DNS_PORT;
67+
use omicron_common::address::DnsSubnet;
6868
use omicron_common::address::NTP_PORT;
6969
use omicron_common::address::ReservedRackSubnet;
7070
use omicron_common::api::external::Generation;
@@ -137,8 +137,10 @@ pub enum Error {
137137
},
138138
#[error("error constructing resource allocator")]
139139
AllocatorInput(#[from] BlueprintResourceAllocatorInputError),
140-
#[error("error allocating internal DNS subnet")]
141-
AllocateInternalDnsSubnet(#[from] NoAvailableDnsSubnets),
140+
#[error("no commissioned sleds - rack subnet is unknown")]
141+
RackSubnetUnknownNoSleds,
142+
#[error("no reserved subnets available for internal DNS")]
143+
NoAvailableDnsSubnets,
142144
#[error("error allocating external networking resources")]
143145
AllocateExternalNetworking(#[from] ExternalNetworkingError),
144146
#[error("zone is already up-to-date and should not be updated")]
@@ -693,6 +695,40 @@ impl<'a> BlueprintBuilder<'a> {
693695
self.new_blueprint_id
694696
}
695697

698+
pub fn available_internal_dns_subnets(
699+
&self,
700+
) -> Result<impl Iterator<Item = DnsSubnet>, Error> {
701+
// TODO-multirack We need the rack subnet to know what the reserved
702+
// internal DNS subnets are. Pick any sled; this isn't right in
703+
// multirack (either DNS will be on a wider subnet or we need to pick a
704+
// particular rack subnet here?).
705+
let any_sled_subnet = self
706+
.input
707+
.all_sled_resources(SledFilter::Commissioned)
708+
.map(|(_sled_id, resources)| resources.subnet)
709+
.next()
710+
.ok_or(Error::RackSubnetUnknownNoSleds)?;
711+
let rack_subnet = ReservedRackSubnet::from_subnet(any_sled_subnet);
712+
713+
// Compute the "in use" subnets; this includes all in-service internal
714+
// DNS zones _and_ any "expunged but not yet confirmed to be gone"
715+
// zones, so we use the somewhat unusual `could_be_running` filter
716+
// instead of the more typical `is_in_service`.
717+
let internal_dns_subnets_in_use = self
718+
.current_zones(BlueprintZoneDisposition::could_be_running)
719+
.filter_map(|(_sled_id, zone)| match &zone.zone_type {
720+
BlueprintZoneType::InternalDns(internal_dns) => {
721+
Some(DnsSubnet::from_addr(*internal_dns.dns_address.ip()))
722+
}
723+
_ => None,
724+
})
725+
.collect::<BTreeSet<_>>();
726+
727+
Ok(rack_subnet.get_dns_subnets().into_iter().filter(move |subnet| {
728+
!internal_dns_subnets_in_use.contains(&subnet)
729+
}))
730+
}
731+
696732
pub fn planning_input(&self) -> &PlanningInput {
697733
&self.input
698734
}
@@ -1381,12 +1417,9 @@ impl<'a> BlueprintBuilder<'a> {
13811417
&mut self,
13821418
sled_id: SledUuid,
13831419
image_source: BlueprintZoneImageSource,
1420+
dns_subnet: DnsSubnet,
13841421
) -> Result<(), Error> {
13851422
let gz_address_index = self.next_internal_dns_gz_address_index(sled_id);
1386-
let sled_subnet = self.sled_resources(sled_id)?.subnet;
1387-
let rack_subnet = ReservedRackSubnet::from_subnet(sled_subnet);
1388-
let dns_subnet =
1389-
self.resource_allocator()?.next_internal_dns_subnet(rack_subnet)?;
13901423
let address = dns_subnet.dns_address();
13911424
let zpool = self.sled_select_zpool(sled_id, ZoneKind::InternalDns)?;
13921425
let zone_type =

nexus/reconfigurator/planning/src/blueprint_editor.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ mod sled_editor;
1111

1212
pub use allocators::BlueprintResourceAllocatorInputError;
1313
pub use allocators::ExternalNetworkingError;
14-
pub use allocators::NoAvailableDnsSubnets;
1514
pub use sled_editor::DatasetsEditError;
1615
pub use sled_editor::DisksEditError;
1716
pub use sled_editor::MultipleDatasetsOfKind;

nexus/reconfigurator/planning/src/blueprint_editor/allocators.rs

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,16 @@ use std::net::IpAddr;
88

99
use super::SledEditor;
1010
use nexus_types::deployment::BlueprintZoneDisposition;
11-
use nexus_types::deployment::BlueprintZoneType;
12-
use nexus_types::deployment::blueprint_zone_type::InternalDns;
13-
use omicron_common::address::DnsSubnet;
1411
use omicron_common::address::IpRange;
15-
use omicron_common::address::ReservedRackSubnet;
1612

1713
mod external_networking;
18-
mod internal_dns;
1914

2015
pub use self::external_networking::ExternalNetworkingError;
21-
pub use self::internal_dns::NoAvailableDnsSubnets;
2216

2317
pub(crate) use self::external_networking::ExternalNetworkingChoice;
2418
pub(crate) use self::external_networking::ExternalSnatNetworkingChoice;
2519

2620
use self::external_networking::ExternalNetworkingAllocator;
27-
use self::internal_dns::InternalDnsSubnetAllocator;
2821

2922
#[derive(Debug, thiserror::Error)]
3023
pub enum BlueprintResourceAllocatorInputError {
@@ -35,7 +28,6 @@ pub enum BlueprintResourceAllocatorInputError {
3528
#[derive(Debug)]
3629
pub(crate) struct BlueprintResourceAllocator {
3730
external_networking: ExternalNetworkingAllocator,
38-
internal_dns: InternalDnsSubnetAllocator,
3931
}
4032

4133
impl BlueprintResourceAllocator {
@@ -46,26 +38,6 @@ impl BlueprintResourceAllocator {
4638
where
4739
I: Iterator<Item = &'a SledEditor> + Clone,
4840
{
49-
let internal_dns_subnets_in_use = all_sleds
50-
.clone()
51-
.flat_map(|editor| {
52-
editor
53-
// We use `could_be_running` here instead of `in_service` to
54-
// avoid reusing an internal DNS subnet from an
55-
// expunged-but-possibly-still-running zone.
56-
.zones(BlueprintZoneDisposition::could_be_running)
57-
.filter_map(|z| match z.zone_type {
58-
BlueprintZoneType::InternalDns(InternalDns {
59-
dns_address,
60-
..
61-
}) => Some(DnsSubnet::from_addr(*dns_address.ip())),
62-
_ => None,
63-
})
64-
})
65-
.collect();
66-
let internal_dns =
67-
InternalDnsSubnetAllocator::new(internal_dns_subnets_in_use);
68-
6941
let external_networking = ExternalNetworkingAllocator::new(
7042
all_sleds.clone().flat_map(|editor| {
7143
editor.zones(BlueprintZoneDisposition::is_in_service)
@@ -77,14 +49,7 @@ impl BlueprintResourceAllocator {
7749
)
7850
.map_err(BlueprintResourceAllocatorInputError::ExternalNetworking)?;
7951

80-
Ok(Self { external_networking, internal_dns })
81-
}
82-
83-
pub fn next_internal_dns_subnet(
84-
&mut self,
85-
rack_subnet: ReservedRackSubnet,
86-
) -> Result<DnsSubnet, NoAvailableDnsSubnets> {
87-
self.internal_dns.alloc(rack_subnet)
52+
Ok(Self { external_networking })
8853
}
8954

9055
pub(crate) fn next_external_ip_nexus(

nexus/reconfigurator/planning/src/blueprint_editor/allocators/internal_dns.rs

Lines changed: 0 additions & 195 deletions
This file was deleted.

nexus/reconfigurator/planning/src/example.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,8 @@ impl ExampleSystemBuilder {
598598
)
599599
.unwrap();
600600
}
601+
let mut internal_dns_subnets =
602+
builder.available_internal_dns_subnets().unwrap();
601603
for _ in 0..self
602604
.internal_dns_count
603605
.on(discretionary_ix, discretionary_sled_count)
@@ -610,6 +612,9 @@ impl ExampleSystemBuilder {
610612
.expect(
611613
"obtained InternalDNS image source",
612614
),
615+
internal_dns_subnets.next().expect(
616+
"sufficient available internal DNS subnets",
617+
),
613618
)
614619
.unwrap();
615620
}

0 commit comments

Comments
 (0)