-
Notifications
You must be signed in to change notification settings - Fork 45
Improve usability of switch port settings #7966
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
Improve usability of switch port settings #7966
Conversation
Switch port settings create params takes a hashmap of link name -> configuration value. However, we return a struct that has the configuration value and link name inside of a single type. We are updating this to be the same for create params and returned types. This change accomplishes two things: * The API is more consistent for users * The generated go client doesn't seem to work properly with the hash map style params. This change allows us to properly create settings using the go client.
@@ -2824,7 +2805,7 @@ pub struct SwitchPortRouteConfig { | |||
pub dst: oxnet::IpNet, | |||
|
|||
/// The route's gateway address. | |||
pub gw: oxnet::IpNet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why can this go from IpNet
to IpAddr
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was likely never supposed to be an IpNet
. The user provides an IpAddr
when they create the configuration:
omicron/nexus/types/src/external_api/params.rs
Line 1900 in abc98f2
pub gw: IpAddr, |
The DB stores singular ipv4 addresses as a full CIDR with /32, so that's probably how we ended up returning an IpNet
instead of an IpAddr
like what the user supplied.
@@ -2980,6 +2961,33 @@ pub struct SwitchPortAddressConfig { | |||
pub interface_name: String, | |||
} | |||
|
|||
/// An IP address configuration for a port settings object. | |||
#[derive(Clone, Debug, Deserialize, JsonSchema, Serialize, PartialEq)] | |||
pub struct SwitchPortAddressView { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see this matches up with SwitchPortSettingsView
, but we don't usually put View
on the end of these structs we call views. In this case I think SwitchPortAddress
might be ok, though it makes it sound like it's just the address. But either nothing or something more descriptive than View
would be an improvement.
SwitchPortSettingsView
can't be changed to SwitchPortSettings
because there is already a SwitchPortSettings
, and SwitchPortSettingsConfig
is ridiculous. What if instead of the settings
key, you took that #[serde(flatten)] identity
bit and stuck it directly in SwitchPortSettingsView
? Then you could rename the struct SwitchPortSettings
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Giving this a try now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the existing SwitchPortSettings
struct that wraps the IdentityMetadata
is what we return when we list the SwitchPortSettings
resource. I'm not sure on the original motivation for this, but the complete SwitchPortSettingsView
struct is quite large and requires a bit of work to populate, so maybe we didn't want to do that when listing the resource.
Would SwitchPortSettingsIdentity
make more sense for the wrapper struct? That would allow us to use SwitchPortSettings
for the "view" struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. That's a naming conundrum. I don't think we distinguish the full view from the list item anywhere else, so we are inventing the convention here. *Identity
feels natural because we have structs in the Rust code that are named like that, though we don't have any existing view schemas in the API ending with Identity
. I think your proposal is solid: the list endpoint would return ResultsPage<SwitchPortSettingsIdentity>
and the detail would be SwitchPortSettings
. An alternative pair of names could be SwitchPortSettings
and SwitchPortSettingsDetail
. But I think I like the first one better.
Yet another option would be to return the full thing for the list as well, but you weren't kidding about it being a lot, so we probably shouldn't do that.
@ahl what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated these type names to SwitchPortSettings
and SwitchPortSettingsIdentity
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, I think it looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I'm VERY happy to hear this! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Levon. Just a few questions about testing at this point.
}, | ||
)]), | ||
addresses: HashMap::new(), | ||
links: vec![], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update this test to assert full round trip consistency? We're just looking at the number of ports below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test should be ensuring full round trip consistency now
@@ -229,7 +227,7 @@ async fn test_port_settings_basic_crud(ctx: &ControlPlaneTestContext) { | |||
assert_eq!(&link0.link_name, "phy0"); | |||
assert_eq!(link0.mtu, 4700); | |||
|
|||
let lldp0 = &roundtrip.link_lldp[0]; | |||
let lldp0 = link0.lldp_link_config.clone().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to define (or derive) PartialEq
for these structures to make the round trip testing more concise and less error prone?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll look into this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Looks like this test was disabled back when we didn't have mgs in the test context. I re-enabled it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@internet-diglett maybe we can close out this one!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it!
nexus/db-model/src/schema.rs
Outdated
@@ -0,0 +1 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mistakenly added file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch
This PR aims to improve the usability of the switch port settings API by returning data of similar shape and content as what users provide when the create the switch port settings. Issues resolved: * Before this PR, you only need one call to create a complete switch port settings object, but you have to perform several lookups to get the complete switch port configuration. We were already returning the object ids of the nested objects, so it makes a lot of sense to just return the actual object (especially since the user supplied the entire object when they configured it) * The `HashMap<String_of_link_name, T>` pattern also did not give the expected behavior in our go client generation. Changing this to a `Vec<T_with_link_name_inside>` matches what the user provides during creation and also resolves this behavior. * Some of our `Vec<T>` fields can be empty but must be present. In the Go client, an empty array is omitted from the json object. We needed to add a `default` annotation to these fields so Serde handles this situation correctly. ## Related - oxidecomputer/oxide.go#278 - oxidecomputer/terraform-provider-oxide#426 Closes #5780
This PR aims to improve the usability of the switch port settings API by returning data of similar shape and content as what users provide when the create the switch port settings.
Issues resolved:
HashMap<String_of_link_name, T>
pattern also did not give the expected behavior in our go client generation. Changing this to aVec<T_with_link_name_inside>
matches what the user provides during creation and also resolves this behavior.Vec<T>
fields can be empty but must be present. In the Go client, an empty array is omitted from the json object. We needed to add adefault
annotation to these fields so Serde handles this situation correctly.Related
Closes #5780