Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require both IPv4 and IPv6 blocks on VPC subnets #577

Closed
wants to merge 1 commit into from

Conversation

david-crespo
Copy link
Contributor

Leaving as a draft because I'm not sure whether we want to do this, but I wanted to see how it would look. @rmustacc's says here:

So IIRC we had some discussion around this earlier, I think when @teisenbe was working on the nexus/Omicron end. So hopefully what I'm about to say will agree with what I talked about then. The long term goal is to allow someone to have an entire VPC or an individual VPC subnet with only one of IPv4 or IPv6; however, to simplify the initial implementation we're requiring that both an IPv4 and IPv6 subnet be present at this time.

@teisenbe how does this comport with your memory of the conversation?

@bnaecker it looks like you originally wrote this comment, what do you remember?

// TODO-design: RFD 21 says that V4 subnets are currently required, and V6 are optional. If a
// V6 address is _not_ specified, one is created with a prefix that depends on the VPC and a
// unique subnet-specific portion of the prefix (40 and 16 bits for each, respectively).

ipv4_block: params.ipv4_block.map(Ipv4Net),
ipv6_block: params.ipv6_block.map(Ipv6Net),
ipv4_block: Some(Ipv4Net(params.ipv4_block)),
ipv6_block: Some(Ipv6Net(params.ipv6_block)),
Copy link
Contributor Author

@david-crespo david-crespo Jan 6, 2022

Choose a reason for hiding this comment

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

The fact that the IP blocks use Some but name and description do not suggests something is off here, though it may be that the former are correct and the latter are wrong.

It's a bit odd that name and description are optional on IdentityMetadataUpdateParams given that I thought we decided to go with the more strictly correct PUT scheme in which all fields are expected to be present in the request body. We probably just haven't updated all the code in accordance with that determination.

#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct IdentityMetadataUpdateParams {
pub name: Option<Name>,
pub description: Option<String>,
}

If name and description are made optional in the params, I would expect the fields to remain optional on the diesel changeset because we can use that internally to make queries that only update some fields but not others.

#[derive(AsChangeset)]
#[table_name = "vpc_subnet"]
pub struct VpcSubnetUpdate {
    pub name: Option<Name>,
    pub description: Option<String>,
    pub time_modified: DateTime<Utc>,
    pub ipv4_block: Option<Ipv4Net>,
    pub ipv6_block: Option<Ipv6Net>,
}

In that case the resolution to the above asymmetry will be to wrap name and description in Some:

name: Some(Name(params.identity.name)),
description: Some(params.identity.description),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Confirmed there's an issue for bringing our PUTs into line: #333

@bnaecker
Copy link
Collaborator

bnaecker commented Jan 6, 2022

My recollection is as that comment describes: that IPv4 was (at the time I wrote that) currently required, and IPv6 optional. But since the ultimate goal is that both should be optional, I made them Options. I understood that the requirement of IPv4 was to be enforced by the software at runtime, but the types in the API were optional to reflect that we'd ultimately relax that requirement without changing the API.

@david-crespo
Copy link
Contributor Author

Ok. After thinking about it a bit more, the long term solution is probably something like the below, and then in the DB model both remain optional like they are today. Unfortunately when converting from the DB model to the view, you have to assume at least one of IPv4 and IPv6 is there because we enforce that on the input side.

I confirmed that these get turned into the oneOf you'd expect in the OpenAPI spec. I'll close this and will either make an attempt at implementing the below or at least make an issue for it.

// params
pub enum VpcSubnetCreate {
    IPv4 {
        #[serde(flatten)]
        identity: IdentityMetadataCreateParams,
        ipv4_block: Ipv4Net,
    },
    IPv6 {
        #[serde(flatten)]
        identity: IdentityMetadataCreateParams,
        ipv6_block: Ipv6Net,
    },
    Ipv4Ipv6 {
        #[serde(flatten)]
        identity: IdentityMetadataCreateParams,
        ipv4_block: Ipv4Net,
        ipv6_block: Ipv6Net,
    },
}

// view
pub enum VpcSubnet {
    IPv4 {
        #[serde(flatten)]
        identity: IdentityMetadata,
        vpc_id: Uuid,
        ipv4_block: Ipv4Net,
    },
    IPv6 {
        #[serde(flatten)]
        identity: IdentityMetadata,
        vpc_id: Uuid,
        ipv6_block: Ipv6Net,
    },
    Ipv4Ipv6 {
        #[serde(flatten)]
        identity: IdentityMetadata,
        vpc_id: Uuid,
        ipv4_block: Ipv4Net,
        ipv6_block: Ipv6Net,
    },
}

@david-crespo david-crespo deleted the require-ipv4-ipv6 branch January 6, 2022 20:21
leftwo pushed a commit that referenced this pull request Jan 10, 2024
Propolis changes since the last update:
Gripe when using non-raw block device
Update zerocopy dependency
nvme: Wire up GetFeatures command
Make Viona more robust in the face of errors
bump softnpu (#577)
Modernize 16550 UART

Crucible changes since the last update:
Don't check ROP if the scrub is done (#1093)
Allow crutest cli to be quiet on generic test (#1070)
Offload write encryption (#1066)
Simplify handling of BlockReq at program exit (#1085)
Update Rust crate byte-unit to v5 (#1054)
Remove unused fields in match statements, downstairs edition (#1084)
Remove unused fields in match statements and consolidate (#1083)
Add logger to Guest (#1082)
Drive hash / decrypt tests from Upstairs::apply
Wait to reconnect if auto_promote is false
Change guest work id from u64 -> GuestWorkId
remove BlockOp::Commit (#1072)
Various clippy fixes (#1071)
Don't panic if tasks are destroyed out of order
Update Rust crate reedline to 0.27.1 (#1074)
Update Rust crate async-trait to 0.1.75 (#1073)
Buffer should destructure to Vec when single-referenced
Don't fail to make unencrypted regions (#1067)
Fix shadowing in downstairs (#1063)
Single-task refactoring (#1058)
Update Rust crate tokio to 1.35 (#1052)
Update Rust crate openapiv3 to 2.0.0 (#1050)
Update Rust crate libc to 0.2.151 (#1049)
Update Rust crate rusqlite to 0.30 (#1035)
leftwo added a commit that referenced this pull request Jan 11, 2024
Propolis changes since the last update:
Gripe when using non-raw block device
Update zerocopy dependency
nvme: Wire up GetFeatures command
Make Viona more robust in the face of errors
bump softnpu (#577)
Modernize 16550 UART

Crucible changes since the last update:
Don't check ROP if the scrub is done (#1093)
Allow crutest cli to be quiet on generic test (#1070)
Offload write encryption (#1066)
Simplify handling of BlockReq at program exit (#1085)
Update Rust crate byte-unit to v5 (#1054)
Remove unused fields in match statements, downstairs edition (#1084)
Remove unused fields in match statements and consolidate (#1083)
Add logger to Guest (#1082)
Drive hash / decrypt tests from Upstairs::apply
Wait to reconnect if auto_promote is false
Change guest work id from u64 -> GuestWorkId
remove BlockOp::Commit (#1072)
Various clippy fixes (#1071)
Don't panic if tasks are destroyed out of order
Update Rust crate reedline to 0.27.1 (#1074)
Update Rust crate async-trait to 0.1.75 (#1073)
Buffer should destructure to Vec when single-referenced
Don't fail to make unencrypted regions (#1067)
Fix shadowing in downstairs (#1063)
Single-task refactoring (#1058)
Update Rust crate tokio to 1.35 (#1052)
Update Rust crate openapiv3 to 2.0.0 (#1050)
Update Rust crate libc to 0.2.151 (#1049)
Update Rust crate rusqlite to 0.30 (#1035)

---------

Co-authored-by: Alan Hanson <[email protected]>
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.

2 participants