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.
| pub dst: oxnet::IpNet, | ||
|
|
||
| /// The route's gateway address. | ||
| pub gw: oxnet::IpNet, |
There was a problem hiding this comment.
why can this go from IpNet to IpAddr?
There was a problem hiding this comment.
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
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.
|
|
||
| /// 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.
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.
Giving this a try now
There was a problem hiding this comment.
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.
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.
I've updated these type names to SwitchPortSettings and SwitchPortSettingsIdentity.
There was a problem hiding this comment.
Cool, I think it looks good.
I'm VERY happy to hear this! |
rcgoodfellow
left a comment
There was a problem hiding this comment.
Thanks Levon. Just a few questions about testing at this point.
| }, | ||
| )]), | ||
| addresses: HashMap::new(), | ||
| links: vec![], |
There was a problem hiding this comment.
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.
The test should be ensuring full round trip consistency now
| 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.
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.
I'll look into this
There was a problem hiding this comment.
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.
@internet-diglett maybe we can close out this one!?
There was a problem hiding this comment.
Looks like it!
| @@ -0,0 +1 @@ | |||
|
|
|||
There was a problem hiding this comment.
Mistakenly added file?
There was a problem hiding this comment.
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 adefaultannotation to these fields so Serde handles this situation correctly.Related
Closes #5780