Skip to content

Support multiple external IPs in blueprint zone type - #11236

Open
bnaecker wants to merge 8 commits into
mainfrom
ben/multiple-eips-in-blueprint-zone-types
Open

Support multiple external IPs in blueprint zone type#11236
bnaecker wants to merge 8 commits into
mainfrom
ben/multiple-eips-in-blueprint-zone-types

Conversation

@bnaecker

@bnaecker bnaecker commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator
  • Add support for multiple EIPs to the blueprint zone types for Nexus, External DNS, and Boundary NTP zones.
  • Add some newtypes and wrappers to support lists of these or up to 2 of them for the SNAT case of Boundary NTP.
  • Add a test that the full blueprint with multiple addresses round-trips through the database.
  • Planner still emits exactly one address in all these cases, this is only the structural change to support multiple addresses.
  • Update lockstep OpenAPI docs

@bnaecker
bnaecker force-pushed the ben/multiple-eips-in-blueprint-zone-types branch 3 times, most recently from 36eb2df to 3a6bc8d Compare September 7, 2026 02:46
- Add support for multiple EIPs to the blueprint zone types for Nexus,
  External DNS, and Boundary NTP zones.
- Add some newtypes and wrappers to support lists of these or up to 2 of
  them for the SNAT case of Boundary NTP.
- Add a test that the full blueprint with multiple addresses round-trips
  through the database.
- Planner still emits exactly one address in all these cases, this is
  only the structural change to support multiple addresses.
- Update lockstep OpenAPI docs
- Closes #9288
@bnaecker
bnaecker force-pushed the ben/multiple-eips-in-blueprint-zone-types branch from 3a6bc8d to 9c66fa5 Compare September 7, 2026 14:05
Comment thread nexus/types/src/deployment.rs Outdated
Comment thread nexus/types/src/deployment/zone_type.rs Outdated
Comment thread nexus/types/src/deployment/network_resources.rs Outdated
Comment thread nexus/types/src/deployment/network_resources.rs Outdated
Comment thread nexus/types/src/deployment/network_resources.rs Outdated
Comment thread nexus/types/src/deployment/zone_type.rs Outdated
Comment thread nexus/types/src/deployment/network_resources.rs Outdated
Comment thread nexus/types/src/deployment/network_resources.rs Outdated
Comment thread nexus/db-model/src/deployment.rs Outdated
Comment thread nexus/types/src/deployment/zone_type.rs Outdated
- Check uniqueness of external IP UUIDs too in container types
- Ensure entire set of IPs roundtrips to DB, not just the new one added
  later.
- Check any number of already-allocated EIPs for a zone when checking if
  it's already been allocated, rather than bailing if there is more than
  one.
- Clean up conversion between blueprint -> inventory types, and simplify
  proptests
- Misc comment cleanup, clarity, typos, etc, regenerate OpenAPI doc
- Fixup test catching bad reallocations of the same EIP by ID
- Support multiple IPs per zone in the `OmicronZoneNetworkResources`
  type. Loosen one of the internal maps from a three-key to two-key,
  enforcing only uniqueness of the IP and its ID, so that we can have
  multiple entries per zone. Add an explicit unit test for that.
Have the sled-agent populate all the private IP addresses an External
DNS zone needs in the sled-agent, to back all of its external IPs.
@bnaecker
bnaecker requested a review from jgallagher September 11, 2026 01:12

@jgallagher jgallagher left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all LGTM. I'm okay approving, but would like to give Dave a chance to look at this if time allows. I'm a little nervous I'm missing something that may bite us when we go to use this, but (a) I don't have anything specific to point to and (b) if we did miss anything I think we can probably fix it when we discover it.

With the changes on just this branch, could we add or extend any of the existing reconfigurator tests to exercise multiple IPs? Or do we need more changes to the planner get to that point?

Comment thread nexus/types/src/deployment/network_resources.rs Outdated
Comment thread sled-agent/src/services.rs Outdated
Comment thread nexus/types/src/deployment/zone_type.rs Outdated
@bnaecker

Copy link
Copy Markdown
Collaborator Author

With the changes on just this branch, could we add or extend any of the existing reconfigurator tests to exercise multiple IPs? Or do we need more changes to the planner get to that point?

I think we need to change the planner. I have the next branch in my chain lined up, in which for_new_nexus() returns multiple IPs for a Nexus zone. I think that's the minimum required to test things at the planner, but I'd rather keep that separate given this is already too big.

@bnaecker

Copy link
Copy Markdown
Collaborator Author

I'm on the fence, leaning toward I don't think a newtype just for the vec would be worth it here. OTOH this method is already returning a tuple - maybe we could return a struct instead, something like

I like this idea. It's not much more work than this, and will be a good bit safer. I'll take it for a spin.

Comment thread sled-agent/src/services.rs
"dns_address",
"astring",
private_dns_address,
private_dns_addresses,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reasoning out loud:

I can't think of a way for this to go wrong (that's not pretty out-of-bounds, like a backwards MUPdate), but it does make me nervous. I don't have any suggestions though!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my conclusion. You could only have multiple addresses here if Nexus has been updated to include this PR, which is after 11207. So all the zones have to be updated first, and in that case, even if they're the old zone image that supports 1 IP and the sled-agent supports multiple, the actual zone configuration can only have one IP in the plan.

I agree that we should figure out how to minimize these inter-zone dependencies. I think Nexus does a pretty good job in this regard, since it has a configuration file we deserialize into a defined Rust type. Using these CLI arguments, especially through SMF properties, feels pretty fraught to me.

Comment thread sled-agent/src/services.rs
Comment thread nexus/types/src/deployment/network_resources.rs Outdated
Comment thread nexus/types/src/deployment/network_resources.rs Outdated
}
}

impl std::cmp::Ord for OmicronZoneExternalFloatingIps {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does seem kind of weird to define an ordering between two sets of things. I'd be inclined to remove it but I guess it depends on what consumer needs it.

Comment thread nexus/types/src/deployment/network_resources.rs Outdated
@bnaecker

Copy link
Copy Markdown
Collaborator Author

It does seem kind of weird to define an ordering between two sets of things. I'd be inclined to remove it but I guess it depends on what consumer needs it.

The parent container blueprint_zone_type::Nexus is Ord, so we need it on this type. It's also required on a whole chain of parent types, e.g., BlueprintZoneType the enum and BlueprintZoneConfig. I think this is all basically because we want to stuff many of these types into IdOrdMaps, such as the field BlueprintSledConfig.zones.

I agree it's a bit odd. I also think we need it if we want to (1) internally use an IdOrdMap in this type itself, and (2) continue to use IdOrdMaps in anything transitively containing this.

- Use richer type for returning a zone's external networking data,
  update callers
- Drop unnecessary Cow
- Comment cleanup
@bnaecker

Copy link
Copy Markdown
Collaborator Author

Thanks @davepacheco and @jgallagher. I think I've addressed everything except for the implementation of Ord. I think it's required, but I could be missing something. LMK if y'all have more thoughts!

@davepacheco

Copy link
Copy Markdown
Collaborator

It does seem kind of weird to define an ordering between two sets of things. I'd be inclined to remove it but I guess it depends on what consumer needs it.

The parent container blueprint_zone_type::Nexus is Ord, so we need it on this type. It's also required on a whole chain of parent types, e.g., BlueprintZoneType the enum and BlueprintZoneConfig. I think this is all basically because we want to stuff many of these types into IdOrdMaps, such as the field BlueprintSledConfig.zones.

I agree it's a bit odd. I also think we need it if we want to (1) internally use an IdOrdMap in this type itself, and (2) continue to use IdOrdMaps in anything transitively containing this.

For IdOrdMap, you only need the entries to impl IdOrdItem, which only requires that the key is Ord. If the key is the zone id, that's easy for BlueprintZoneConfig without the whole type being Ord. I wonder if we could get away with that instead of impl'ing Ord all the way down. This is outside the scope of this PR, for sure.

@bnaecker

Copy link
Copy Markdown
Collaborator Author

Thanks @davepacheco, that makes sense. I can make a follow-up issue, if that's helpful? And LMK if you have other thoughts on the PR at this point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants