{"action":"closed","issue":{"url":"https://api.github.com/repos/gophercloud/gophercloud/issues/252","repository_url":"https://api.github.com/repos/gophercloud/gophercloud","labels_url":"https://api.github.com/repos/gophercloud/gophercloud/issues/252/labels{/name}","comments_url":"https://api.github.com/repos/gophercloud/gophercloud/issues/252/comments","events_url":"https://api.github.com/repos/gophercloud/gophercloud/issues/252/events","html_url":"https://github.com/gophercloud/gophercloud/issues/252","id":207529913,"number":252,"title":"support for v3 auth is part broken, part incomplete","user":{"login":"majewsky","id":24696,"avatar_url":"https://avatars0.githubusercontent.com/u/24696?v=4","gravatar_id":"","url":"https://api.github.com/users/majewsky","html_url":"https://github.com/majewsky","followers_url":"https://api.github.com/users/majewsky/followers","following_url":"https://api.github.com/users/majewsky/following{/other_user}","gists_url":"https://api.github.com/users/majewsky/gists{/gist_id}","starred_url":"https://api.github.com/users/majewsky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/majewsky/subscriptions","organizations_url":"https://api.github.com/users/majewsky/orgs","repos_url":"https://api.github.com/users/majewsky/repos","events_url":"https://api.github.com/users/majewsky/events{/privacy}","received_events_url":"https://api.github.com/users/majewsky/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":18,"created_at":"2017-02-14T14:27:10Z","updated_at":"2018-04-24T03:06:38Z","closed_at":"2018-04-24T03:06:38Z","author_association":"CONTRIBUTOR","body":"Our corporate OpenStack installations support Identity v3 exclusively, and they use the whole feature set, down to users from one domain having roles in projects in different domains. When I look at [`func AuthOptionsFromEnv`](https://github.com/gophercloud/gophercloud/blob/50cdddf51c54e8df178af065055cbc5b3cf442e1/openstack/auth_env.go#L15), about half of the environment variables that I need are missing, and for some, the implementation in Gophercloud is wrong.\r\n\r\nI'll recap the terminology of the OpenStack Identity API here in case some readers are not familiar with it: In the v2 API, users are limited to *tenants*, and users can only do work in their respective tenant, so the sufficient auth options are:\r\n\r\n```go\r\nUserName   string // from $OS_USERNAME\r\nUserID     string // from $OS_USERID\r\nTenantName string // from $OS_TENANT_NAME\r\nTenantID   string // from $OS_TENANT_ID\r\n```\r\n\r\nThat's also what's in `type AuthOptions` (plus endpoint URL plus password). In the v3 API, users reside in *domains*, and tenants (now called *projects*) do so, too. A token can be scoped to a domain, to a project in a domain (not necessarily the user's domain), or to nothing. The sufficient auth options in this case are: [(reference)](https://github.com/openstack/python-openstackclient/blob/83cf09df28e200ba40f403504db3b11e623978fd/doc/source/man/openstack.rst#environment-variables)\r\n\r\n```go\r\nUserName          string // from $OS_USERNAME\r\nUserID            string // from $OS_USERID\r\nUserDomainName    string // from $OS_USER_DOMAIN_NAME\r\nUserDomainID      string // from $OS_USER_DOMAIN_ID\r\n//for domain scope:\r\nDomainName        string // from $OS_DOMAIN_NAME\r\nDomainID          string // from $OS_DOMAIN_ID\r\n//for project scope:\r\nProjectName       string // from $OS_PROJECT_NAME\r\nProjectID         string // from $OS_PROJECT_ID\r\nProjectDomainName string // from $OS_PROJECT_DOMAIN_NAME\r\nProjectDomainID   string // from $OS_PROJECT_DOMAIN_ID\r\n```\r\n\r\nNote how there is nearly no overlap with the v2 variable names. This is not reflected in `func AuthOptionsFromEnv` at all. It uses `OS_TENANT_{ID,NAME}` for the project scope, even though this is not consistent with the upstream `openstack` CLI tool. And even worse, it uses `OS_DOMAIN_{ID,NAME}` to identify the domain of the user (and *also* the domain to scope to, if no project is given). This is completely wrong, and breaks cross-domain scoping usecases, i.e. obtaining a token for one domain or a project within that domain, as a user who resides in a different domain.\r\n\r\n## Possible solutions\r\n\r\nThe main shortcoming is that [`type AuthOptions`](https://github.com/gophercloud/gophercloud/blob/50cdddf51c54e8df178af065055cbc5b3cf442e1/auth_options.go#L13) lacks a number of fields to express all the authentication scenarios that we need, and the fields `.Domain{Name,ID}` are confusingly named because they reflect `OS_USER_DOMAIN_{NAME,ID}` instead of `OS_DOMAIN_{NAME,ID}`.\r\n\r\n### Option 1a\r\n\r\nIf backwards compatibility were not a concern (I actually don't know if it is for you), here's what I would do:\r\n* Rename `.Domain{Name,ID}` to `.UserDomain{Name,ID}` as a clarification.\r\n* Move `.Tenant{Name,ID}` into a `type V2 struct`, so they would be referenced as `opts.V2.Tenant{Name,ID}`. These fields would thus be documented as being relevant for v2 auth only.\r\n* Add a `type V3 struct` containing `.{Domain,Project,ProjectDomain}{Name,ID}` fields that are only considered for v3 auth.\r\n\r\nThat way, if there is ever a v4 auth, we would not need to go through the same mess again. `type AuthOptions` would just gain a new field of type `type V4 struct` that has all the parameters that v4 auth cares about.\r\n\r\n### Option 1b\r\n\r\nAlternatively, replace the `type AuthOptions` by multiple types `AuthOptionsV2`, `AuthOptionsV3`, and so on, which all implement a shared interface (which would then be what `func AuthOptionsFromEnv` returns, for instance). This solution is not entirely backwards-compatible, since all the functions that take or return `type AuthOptions` would need to be adjusted to take/return the interface instead. Although, without actually having done it, it could probably be done so that at least a sizable number of consumers of this module would still compile. If `type AuthOptions` is left intact for backwards compatibility, deprecation warnings should be issued if it is used.\r\n\r\n### Option 2\r\n\r\nIf backwards compatibility is a major concern, here's an alternative proposal:\r\n* Reuse `.Tenant{Name,ID}` for the `OS_PROJECT_{NAME,ID}` in v3 auth. It will be confusing in the long term because the \"tenant\" term is being replaced by \"project\" across the OpenStack documentation and source code, but v2 tenants and v3 projects are technically equivalent, so it's still appropriate.\r\n* Add `.TenantDomain{Name,ID}` to mirror `OS_PROJECT_DOMAIN_{NAME,ID}`. (It should be called `.ProjectDomain{Name,ID}`, but if we're already misspelling \"project\" as \"tenant\", let's at least be consistent about it.)\r\n* Add `.ScopeDomain{Name,ID}` to mirror `OS_DOMAIN_{NAME,ID}`. The name `.Domain{Name,ID}` would be more appropriate, but it's already taken by `OS_USER_DOMAIN_{NAME,ID}`.\r\n\r\nYou see how ugly this gets... So, what's your choice? 😁 \r\n\r\nNote: I'm willing to do a pull request to try to rectify things, once a solution is chosen."}}
{"actor":{"display_login":"jtopjian"}}