gophercloud/utils

Auth: domain name and domain ID

Closed this issue · 6 comments

I just noticed that OS_DOMAIN_NAME and OS_DOMAIN_ID env variables are ignored in favor of OS_USER_DOMAIN_NAME and OS_USER_DOMAIN_ID:

https://github.com/gophercloud/utils/blob/3b35bcb43167f6d8080fa824c480f04b60311b51/openstack/clientconfig/requests.go#L579..L580

@jtopjian, is there a particular reason for this? Can we introduce a fallback to OS_DOMAIN_NAME and OS_DOMAIN_ID when OS_USER_DOMAIN_NAME and OS_USER_DOMAIN_ID are not set?

is there a particular reason for this?

I think so. Give me a day or so to remember why this is. You might also have some luck searching Terraform issues for things like OS_USER_DOMAIN_NAME.

If you take a look into the terraform provider code, you'll notice that OS_DOMAIN_NAME and OS_DOMAIN_ID are not used. Does it make sense to introduce the "default" feature, which was lost in legacy builtin terraform provider:
https://github.com/hashicorp/terraform/pull/9725/files#diff-9a2524cb455f54d1d76bbce99f06c37cR76

But for OS_USER_DOMAIN_NAME and OS_USER_DOMAIN_ID:

@@ -80,16 +101,24 @@ func Provider() terraform.ResourceProvider {
                        },
 
                        "user_domain_name": {
-                               Type:        schema.TypeString,
-                               Optional:    true,
-                               DefaultFunc: schema.EnvDefaultFunc("OS_USER_DOMAIN_NAME", ""),
+                               Type:     schema.TypeString,
+                               Optional: true,
+                               DefaultFunc: schema.MultiEnvDefaultFunc([]string{
+                                       "OS_USER_DOMAIN_NAME",
+                                       "OS_PROJECT_DOMAIN_NAME",
+                                       "OS_DOMAIN_NAME",
+                               }, ""),
                                Description: descriptions["user_domain_name"],
                        },
 
                        "user_domain_id": {
-                               Type:        schema.TypeString,
-                               Optional:    true,
-                               DefaultFunc: schema.EnvDefaultFunc("OS_USER_DOMAIN_ID", ""),
+                               Type:     schema.TypeString,
+                               Optional: true,
+                               DefaultFunc: schema.MultiEnvDefaultFunc([]string{
+                                       "OS_USER_DOMAIN_ID",
+                                       "OS_PROJECT_DOMAIN_ID",
+                                       "OS_DOMAIN_ID",
+                               }, ""),
                                Description: descriptions["user_domain_id"],
                        },

Or should we introduce similar logic inside this repo?

No, I'm quite positive what is currently in both repos is correct and there's a valid reason. I spent a number of months last year digging into all of it - I just need to look up that information.

So far, when I use an app, which is built on a pure gophercloud - regular OS_DOMAIN_NAME works. But terraform openstack provider, which uses gophercloud/utils, requires OS_USER_DOMAIN_NAME to be set.

After reviewing everything, I still believe everything is correct.

So far, when I use an app, which is built on a pure gophercloud - regular OS_DOMAIN_NAME works.

There was an old Gophercloud issue about this here (gophercloud/gophercloud#252) which goes into some details. There are also some linked issues that provide further details.

OpenStack authentication is not documented very well and there are a lot of apps which have implemented it incorrectly. Terraform used to be one of these apps, but I spent a lot of time digging into the Python SDK to figure out how everything should work.

Gophercloud can correctly use all the different OS_* auth things, but it's very low-level and can easily be misused. Apps should really use clientconfig for all authentication. clientconfig's goal is to have feature parity of the Python SDKs and work with standard openrc files downloaded from Horizon. If it doesn't, then it's a bug.

But clientconfig ultimately uses Gophercloud's core AuthOptions struct in the end, but again, it's easy to use AuthOptions wrong.

To outline what Terraform is doing:

  1. OS_DOMAIN_NAME and OS_DOMAIN_ID are supported here: https://github.com/terraform-providers/terraform-provider-openstack/blob/master/openstack/provider.go#L110-L122
  2. These get passed to clientconfig.AuthInfo here: https://github.com/terraform-providers/terraform-provider-openstack/blob/master/openstack/config.go#L110-L125
  3. They're then being set in correct order of precedence here: https://github.com/gophercloud/utils/blob/master/openstack/clientconfig/requests.go#L753-L792

Let me know if this helps clarify.

Thanks for the clarification. I misunderstood the setDomainIfNeeded purpose. Since we cannot use scope for application credential, then I have to add yet another if. And it should be like in #77