[bgp-config] add networking_bgp_config_update endpoint#10566
[bgp-config] add networking_bgp_config_update endpoint#10566nicolaskagami wants to merge 5 commits into
networking_bgp_config_update endpoint#10566Conversation
73050fb to
9ca6ecf
Compare
9ca6ecf to
b78fcef
Compare
networking_bgp_config_update endpointnetworking_bgp_config_update endpoint
|
(This is my first PR as an Oxide employee, so I'm still learning the ropes) This was made drawing from Levon's old PR and the neighboring I also didn't attempt to remove the Lastly, I wrote a little unit test mostly because it simply pains me not to do it. It was great because I found a (rather innocuous) bug on |
jgallagher
left a comment
There was a problem hiding this comment.
LGTM, just a few small nits and a docs phrasing question.
| let lookup_err = |e, not_found_err, msg| { | ||
| error!(opctx.log, "{msg}"; "error" => ?e); |
There was a problem hiding this comment.
Couple minor nits: (1) I don't think we're super consistent with this, but error! seems like too high of a log level for the NotFound case and probably even the internal_error case. Could we make this a warn! instead? (2) We should use the InlineErrorChain adapter instead of ?e so we know we get any underlying causes (docs on this):
| let lookup_err = |e, not_found_err, msg| { | |
| error!(opctx.log, "{msg}"; "error" => ?e); | |
| let lookup_err = |e: diesel::result::Error, not_found_err, msg| { | |
| warn!(opctx.log, "{msg}"; InlineErrorChain::new(&e)); |
(I think both of these also apply to the other error! logs added below)
There was a problem hiding this comment.
I agree 100% but I didn't want to stray away from the current standard we had for the other bgp_config methods (e.g. bgp_config_create). Would it be alright if I tackle those as well but on a follow-up PR?
| .map_err(|e| lookup_err(e, not_found_err, msg))?; | ||
|
|
||
| // Resolve bgp_announce_set_id if an update was requested | ||
| let new_bgp_announce_set_id = match &update.bgp_announce_set_id { |
There was a problem hiding this comment.
Instead of accessing the fields of update, can we destructure it like this:
let networking::BgpConfigUpdate {
identity: update_identity,
bgp_announce_set_id: update_bgp_announce_set_id,
max_paths: update_max_paths,
} = update;and then refer to those bound fields here and on lines 314-327? This way if someone adds a new field to BgpConfigUpdate, they get a compilation error here and are forced to update it, instead of (potentially) forgetting to, and then we silently fail to update some fields.
| bgp_config_dsl::description.eq(new_description), | ||
| bgp_config_dsl::bgp_announce_set_id | ||
| .eq(new_bgp_announce_set_id), | ||
| bgp_config_dsl::max_paths.eq(i16::from(new_max_paths)), |
There was a problem hiding this comment.
End result is the same, but it's clearer to use our unsigned integer adapters here:
| bgp_config_dsl::max_paths.eq(i16::from(new_max_paths)), | |
| bgp_config_dsl::max_paths.eq(SqlU8(new_max_paths)), |
| "system/networking" | ||
| ], | ||
| "summary": "Update BGP configuration", | ||
| "description": "Update the mutable fields of an existing BGP configuration. The `asn` field is intentionally not updatable; changing the autonomous system number requires creating a new BGP configuration object, since many things are keyed off the ASN.", |
There was a problem hiding this comment.
This may be leaking out more information than is relevant for a caller of this endpoint; I wonder if we could get away with just
Update the mutable fields of an existing BGP configuration.
or you think people might assume they can change the ASN here, we could maybe shorten this slightly:
Update the mutable fields of an existing BGP configuration. The
asnfield is not updatable; to change the autonomous system number, create a new BGP configuration object.
@ahl might have wordsmithing suggestions?
There was a problem hiding this comment.
I liked your second suggestion better:
Update the mutable fields of an existing BGP configuration. The asn field is not updatable; to change the autonomous system number, create a new BGP configuration object.
| "system/networking" | ||
| ], | ||
| "summary": "Update BGP configuration", | ||
| "description": "Update the mutable fields of an existing BGP configuration. The `asn` field is intentionally not updatable; changing the autonomous system number requires creating a new BGP configuration object, since many things are keyed off the ASN.", |
| ] | ||
| }, | ||
| "BgpConfigUpdate": { | ||
| "description": "Parameters for updating a BGP configuration.\n\nThe `asn` field is intentionally not updatable; changing the autonomous system number requires creating a new BGP configuration object, since many things are keyed off the ASN.", |
There was a problem hiding this comment.
This feels redundant with the description above; how about
| "description": "Parameters for updating a BGP configuration.\n\nThe `asn` field is intentionally not updatable; changing the autonomous system number requires creating a new BGP configuration object, since many things are keyed off the ASN.", | |
| "description": "New values when updating a BGP configuration.", |
In particular I think it's important to specify that it's all the new values--leaving a field unpopulated effectively deletes it. In some cases we've use the Nullable newtype wrapper to force users to specify values
There was a problem hiding this comment.
Actually, those are not the update semantics we're following here (!). More specifically, the current implementation keeps the old values for unpopulated fields in the update object.
I tried to closely follow Levon's reference implementation and we do have a few optional update fields being updated with PUT (where a case could be made for PATCH). Example:
omicron/nexus/types/versions/src/initial/silo.rs
Lines 219 to 239 in 9fc857e
In the case of BgpConfig as well, the fields in the database representation are not optional, so for now they can at least be consistent in this interpretation. However, I'm unsure (and uneasy) about this strategy in the long run, where we might want to add Nullable fields and have to change update semantics.
Can you point me to some discussion/documentation on this?
Adds a
networking_bgp_config_updateendpoint with the following updatable fields:vrfisn't added because it's to be removed.asnisn't included because it may be used as an id internally.closes #10066