Repository navigation
Add several features missing from OpenStack::MetaAPI - #28
Conversation
BUILDARGS built an OpenStack::Client::Auth from its arguments unconditionally and discarded everything else, so the 'auth' attribute -- declared required, and therefore apparently settable -- could not in fact be set. That shut out every authentication method OpenStack::Client::Auth does not implement. Keystone v3 application credentials are the case in hand: there is no username or password to hand over, so the only way to authenticate is to construct the auth object yourself, and that was the one thing there was no way to pass in. A lone hashref carrying a reference in 'auth' now goes straight through. Ordinary construction is new($endpoint, %args), whose first argument is a URL rather than a reference, so no existing caller matches this and none of them change behaviour. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Five things the API could not do, each needed to manage a server's whole life rather than only create and delete it. limits is the interesting one. Deciding whether another instance fits needs both the project's allowance and what it is already using, and /limits returns them together -- where /os-quota-sets gives only the allowance and leaves the caller to total up a server list to find the rest. server_action covers everything Nova models as an action on an existing server: snapshots, power state, rebuild. They are one POST to one path with a different single-key body, so they are one method. create_image is that, named, because snapshotting is the case people come looking for; it deliberately does not report the new image's id, since Nova returns it in a Location header and only puts it in the body from microversion 2.45, so neither is worth relying on. Ask Glance by name instead. flavors_detail exists because the flavor list is ids and names. Anything that has to choose a flavor by how much machine it is needs /flavors/detail. console_output is what a guest that never came up said before it gave up. There was no block storage service at all, so volumes could be neither made, found nor deleted. Its catalogue type is whatever the cloud still offers, newest first, rather than a name fixed here: 'volume' unadorned is not always present, and a current deployment may list only volumev3 and volumev2. Its two list routes are written out rather than declared in a Specs data block, because the spec package a service loads is named after its catalogue type -- so the same two routes would need one spec file per spelling of Cinder. Attaching a volume is Nova's endpoint rather than Cinder's, so attach_volume, detach_volume and server_volumes are on compute where they belong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
create_vm could build a server but not tell it anything, because user_data was
not among the fields it passed on. That is most of the point of creating one:
without it a new guest boots with no cloud-config, no users, no keys and no way
to be told what it is for, and the caller's only recourse was to bypass create_vm
and assemble the request itself -- losing the flavor and network lookups, the
wait for ACTIVE and the floating IP along with it.
Nova only accepts user_data base64 encoded, and callers have cloud-config
rather than base64, so it is encoded here. Making each caller remember is the
kind of detail that is discovered by a guest silently booting unconfigured.
availability_zone, metadata and block_device_mapping_v2 come along for the same
reason: each is an ordinary server-create field with no way to set it. They are
only sent when asked for, so a request that did not mention them is unchanged.
The security group was being sent as {name => $group->{id}}, which puts an id in
a field that means a name. Some clouds resolve either and some do not, so it
now sends the name and falls back to the id.
The test asserts on the request body rather than the response, which is what
required a way to see it: for a field the API encodes on the caller's behalf,
the encoding is the behaviour, and the canned response would exercise none of
it. Hence last_http_content in the test helper.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
images() died pointing at image_from_uid and image_from_name, and the warning behind that is real: listing a project's images unfiltered can take fifty requests. The cloud this was written against holds 632 of them. But some questions have no single-image answer, and "which snapshots does this guest have" is one -- Glance keeps them as ordinary images, so finding them means asking for the ones that match. With no filtered listing available, the only way to answer it was to not use this module. list_images passes %query to Glance, so the filtering happens there rather than in the caller: name, owner, visibility, status, or any image property. Nova stamps its snapshots with image_type and instance_uuid, which is what makes the question answerable in one request instead of 632 images' worth of pages. Pagination is not new work either; OpenStack::Client::all already follows the 'next' link, and had no way of being pointed at images. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
create_vm demanded network_for_floating_ip and always attached a floating IP, which made a whole shape of cloud impossible to build on. Not every deployment has a tenant network to escape from. Where the only network is external and shared -- which is how the cloud this was found on is arranged -- a server attached to it is given a routable address directly, and Nova reports that address as 'fixed'. There is no floating IP to allocate, no pool to allocate it from, and asking for one is an error rather than a formality. So the argument is optional now, and the floating IP is attached only when a network was named to take it from. A caller that named one is unaffected, and the existing failure for a network that does not exist still fails. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
9a027ab to
8ae7cc1
Compare
|
|
Koan-Bot
left a comment
There was a problem hiding this comment.
Warning
Important issues found.
- BUILDARGS auth-passthrough uses
ref, notblessed— a clouds.yaml hash silently becomes the auth object
|
note: #29 will fix CI |
The auth-passthrough guard checked ref $args[0]->{'auth'}, which is true
for any reference including a plain HASH. A clouds.yaml cloud entry is a
hashref whose own 'auth' key is an unblessed hash (auth_url, username,
password, ...), so it was accepted verbatim as the auth object: Moo stored
the unblessed hash and construction succeeded, deferring the failure to the
first delegated call, which died on an unblessed reference far from here.
Check blessed() instead so a config hash falls through and builds a real
OpenStack::Client::Auth, which dies legibly at construction. Add a test
covering the clouds.yaml-shaped hash.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed, thanks |
|
Issue #1 resolved. BUILDARGS now guards on |
Verified. |
PR Review — Add several features missing from OpenStack::MetaAPIA substantial, well-tested expansion of the API surface — fourteen new routes, a Cinder service class, base64 user_data, and an optional floating IP — with the previously blocking BUILDARGS guard now correctly fixed. Everything remaining is non-blocking.
✅ Resolved since last review (2)Previously-flagged issues verified fixed
🟢 Suggestions
1. list_images is still the only new route with no test, and returns a bare list
|
Koan-Bot
left a comment
There was a problem hiding this comment.
Tip
No blocking issues found — ready to merge.
Related PR (what I wrote this to serve):
Troglodyne-Internet-Widgets/trog-provisioner#121
That said I probably can use this within cPanel's QA testsuite or other CI workflows we have for those cases where terraform's openstack driver just doesn't have the functionality to get what you want done (as it generally only handles vm spawn/lifecyle, not things like image management, etc.)