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

Add oxide instance external-ip attach/detach #499

Merged
merged 1 commit into from
Jan 25, 2024
Merged

Add oxide instance external-ip attach/detach #499

merged 1 commit into from
Jan 25, 2024

Conversation

FelixMcFelix
Copy link
Contributor

@FelixMcFelix FelixMcFelix commented Jan 4, 2024

Relies on oxidecomputer/omicron#4694. This adds the autogenerated commands:

  • oxide floating-ip attach --floating-ip <floating-ip> --kind <kind> --parent <parent>
  • oxide floating-ip detach --floating-ip <floating-ip>
  • oxide instance external-ip attach-ephemeral --instance <instance>
  • oxide instance external-ip detach-ephemeral --instance <instance>

@ahl
Copy link
Collaborator

ahl commented Jan 4, 2024

It looks like we're adding oxide external-ip attach ephemeral and oxide external-ip attach floating. Sometimes a complex CLI is indicative of an overly complex API. Might we split the creation of external IPs into two distinct API operations? One for ephemeral and one for floating?

with regard to detach (for which the parameter is ExternalIpDelete which seems misnamed): I imagine a workflow is that I'd attach, list, detach. What info from list would I use for detach? I assumed it would just be the id of the external-ip, but... I guess we can't use that? What's the workflow you imagine?

Copy link
Collaborator

@ahl ahl left a comment

Choose a reason for hiding this comment

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

Not sure it works here, but search for "OxideOverride" and "OxideCli::command" for other ways in which we've augmented generated commands

cli/docs/cli.json Outdated Show resolved Hide resolved
@FelixMcFelix
Copy link
Contributor Author

Thanks for taking a look!

It looks like we're adding oxide external-ip attach ephemeral and oxide external-ip attach floating. Sometimes a complex CLI is indicative of an overly complex API. Might we split the creation of external IPs into two distinct API operations? One for ephemeral and one for floating?

I think we could do so, which give us some first-pass options:

  1. /v1/instances/{instance}/[ephemeral-ip, floating-ips]/[attach, detach]
  2. /v1/instances/{instance}/external-ips/attach-ephemeral, /detach-ephemeral, /attach-floating, /detach-floating
  3. Same as 2., but only adding a suffix for one class of IP (maybe ephemeral gets the suffix?).

with regard to detach (for which the parameter is ExternalIpDelete which seems misnamed): I imagine a workflow is that I'd attach, list, detach. What info from list would I use for detach? I assumed it would just be the id of the external-ip, but... I guess we can't use that? What's the workflow you imagine?

That's a good point. We do need to add more fields to views::ExternalIp to make this more useful -- without doing so, you need to bounce over to oxide floating-ips list and match on IP, which is Not Good. My understanding is that adding these extra fields shouldn't break console or existing SDK consumers?

Comment on lines 423 to 438
Err(ref e @ oxide::Error::InvalidResponsePayload(ref r)) if r.is_decode() => {
// This is a minor hack to account for the case where a double
// ephemeral detach returns null -- the operation was a success,
// for idempotency, but we no longer know what the actual IP object
// referenced is/would be.
let formatted = format!("{r}");
if formatted.contains("invalid type: null, expected struct ExternalIp") {
println!("success\n()")
} else {
println!("error\n{e:#?}")
}
}
Err(r) => {
println!("error\n{r:#?}")
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel like I'm overlooking a way on the omicron side to avoid having to do this -- the return type there is Option'd, but this is not reflected in the output OpenAPI spec.

Copy link
Contributor

Choose a reason for hiding this comment

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

You're missing something but it's not at all obvious. Top-level Option around a response does not work well. The good way to do this is to put it inside a non-optional struct:

struct MyResponseBody {
  key: Option<Value>
}

https://github.com/oxidecomputer/omicron/pull/4694/files#diff-7429b402f97c8a901b88c3599e8505de4afae78092b5f27e4542bc5818125f17R3779

Copy link
Collaborator

Choose a reason for hiding this comment

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

As noted in omicron, I think the answer is likely to respond with an error if the entity we're trying to detach is not found.

@FelixMcFelix FelixMcFelix marked this pull request as ready for review January 24, 2024 21:52
@@ -268,7 +268,7 @@ impl RunnableCmd for CmdInstanceFromImage {
.expect("valid disk name"),
size: self.size.clone(),
}])
.external_ips(vec![ExternalIpCreate::Ephemeral { pool_name: None }])
.external_ips(vec![ExternalIpCreate::Ephemeral { pool: None }])
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this now a required parameter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not a required parameter, this fixes a breaking field name change as we now take an Option<NameOrId>.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That makes so much more sense. Sorry for the dumb question. Going too fast!

@ahl ahl merged commit d7215da into main Jan 25, 2024
16 checks passed
@ahl ahl deleted the ip-attach branch January 25, 2024 05:52
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