Skip to content

Appcred auth support - #300

Open
simonepelosi wants to merge 5 commits into
canonical:masterfrom
simonepelosi:appcred-auth-support
Open

simonepelosi wants to merge 5 commits into
canonical:masterfrom
simonepelosi:appcred-auth-support

Conversation

@simonepelosi

Copy link
Copy Markdown

No description provided.

OpenStack backend only ever authenticated with a plain Keystone v3
username/password (identity.AuthUserPassV3), reading account/key as
User/Secrets and scoping every request to the project in location.
An OpenStack application credential is not a username/password pair
and Keystone rejects an explicit project scope alongside one (it is
already scoped at creation time), so there was no way to use one
here.

Add a backend auth-type field (openstack only). The existing
password flow is unchanged and remains the default
(auth-type unset or 'password'). auth-type: application-credential
authenticates with account/key as the credential's ID/secret via the
new identity.AuthApplicationCredentialV3 mode (goose fork, see
go.mod), and never sets a project scope.

Also fixes authenticate() silently discarding the Keystone auth
error: 'if err := authClient.Authenticate(); err != nil { err = ... }'
shadowed the outer err and returned nil regardless, so a bad
credential only ever surfaced later, confusingly, as a failure of
whatever OpenStack call happened to trigger goose's lazy
re-authentication (e.g. 'cannot retrieve flavors list: ... 401')
instead of as an authentication failure.
Exercise the full authenticate() path - version discovery, the real
Keystone v3 request/response wire format, and goose's service-catalog
region validation - against a fake Keystone that only accepts
application-credential auth, instead of only unit-testing the
Credentials/AuthMode construction in isolation.

This caught a real bug in the goose fork (client.NewClient() was
posting the auth request to the wrong Keystone endpoint for the new
auth mode), which the identity-package-level tests alone did not
catch.
The goose fork was rebased onto the current upstream v5 branch (21
commits ahead of the previously pinned 2023-04-21 commit) so the
application-credential PR has a clean, mergeable base. One of those
commits changed neutron.Client.ListSecurityGroupsV2 to take a
ListSecurityGroupsV2Query (optional tag filtering), breaking this
call site. Pass an empty query, preserving the previous
list-everything behavior.
go.mod pointed the goose replace directive at a local filesystem
path (../goose), which only resolves on a machine with that sibling
checkout. CI (and any other clone) has no such directory, so every
build/test failed immediately with 'replacement directory ../goose
does not exist' (confirmed: PR canonical#300 run
https://github.com/canonical/spread/actions/runs/37593813048).

Point the replace at the pushed fork on GitHub, pinned to a specific
commit via its resolved pseudo-version, so it fetches through the Go
module proxy like any other dependency.
Update termExp in toTerms to recognize known architectures
(amd64v3, ppc64el, riscv64, amd64, arm64, armhf, armel, s390x, i386)
as atomic terms before splitting letters and numbers.

Previously, amd64 was tokenized into "amd" and "64", which matched
"amd64v3" ("amd", "64", "v", "3") as a subsequence. When both amd64
and newer amd64v3 images were present, amd64v3 was selected by mistake.

By matching architecture names atomically, searching for amd64 will
not match amd64v3.
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.

1 participant