Repository: ansible/ansible

Issue:
os_keystone_domain fails to work with identity v3 API when cloud options is not presented
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
* `modules/cloud/openstack/os_keystone_domain.py`
* `module_utils/openstack.py`

And I believe most OpenStack modules which need to call domain API are affected too.

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.3.1.0
  config file = /root/.ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Nov 20 2015, 02:00:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

Content of `ansible.cfg` file
```
[defaults]
retry_files_enabled = False
```
##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
* Control Machine: `CentOS Linux release 7.2.1511 (Core)`
* Managed Machines:  `CentOS Linux release 7.3.1611 (Core)`

##### SUMMARY
<!--- Explain the problem briefly -->
Most of time, the information of managed OpenStack clouds is presented by the  [`cloud`](https://github.com/ansible/ansible/blob/v2.3.1.0-1/lib/ansible/module_utils/openstack.py#L76) options which is driven by `os-client-config`.  This option will be used by [`shade`](https://github.com/openstack-infra/shade). 
The `cloud` option is not needed when [`auth`](https://github.com/ansible/ansible/blob/v2.3.1.0-1/lib/ansible/module_utils/openstack.py#L78) is provided.  In that case, `os-client-config` will provides a default `cloud` option based on the `auth` option.  The default `cloud` option will use identity 2.0 and there is no way to inject identity version in the `auth` option at the moment. 

When identity v2.0 is indicated, [`shade`](https://github.com/openstack-infra/shade/blob/master/shade/_tasks.py#L177) will use 2.0 keystone client who knows nothing about the domain. 


##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
`playbook.yml`
```yaml
- hosts: all
  vars_files:
    - vars/main.yml

  tasks:
    - name: create domain for jdomain
      os_keystone_domain:
        name: jdomain
        state: present
        region_name: RegionOne
        auth: "{{ keystone_admin_auth }}"
        endpoint_type: admin
      delegate_to: localhost
      run_once: yes
```

`vars/main.yml`
```
---
keystone_admin_auth:
  auth_url: http://{{ keystone_host }}:35357
  username: admin
  password: "{{ keystone_admin_token }}"
  project_name: admin
  project_domain_name: Default
  user_domain_name: Default
```
It should be noted that it still fails even the `auth_url` is changed to `http://{{ keystone_host }}:35357/v3` or `http://{{ keystone_host }}:35357/v3/`.

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
The new domain was created.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
The task failed to create a new domain.
<!--- Paste verbatim command output between quotes below -->
```
fatal: [keystone01 -> localhost]: FAILED! => {"changed": false, "failed": true, "msg": "Failed to list domains (Inner Exception: Unknown Attribute: domains)"}
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/module_utils/openstack.py b/lib/ansible/module_utils/openstack.py
--- a/lib/ansible/module_utils/openstack.py
+++ b/lib/ansible/module_utils/openstack.py
@@ -90,6 +90,9 @@ def openstack_full_argument_spec(**kwargs):
         api_timeout=dict(default=None, type='int'),
         endpoint_type=dict(
             default='public', choices=['public', 'internal', 'admin']
+        ),
+        identity_api_version=dict(
+            default=None, choices=['2.0', '3']
         )
     )
     spec.update(kwargs)
diff --git a/lib/ansible/utils/module_docs_fragments/openstack.py b/lib/ansible/utils/module_docs_fragments/openstack.py
--- a/lib/ansible/utils/module_docs_fragments/openstack.py
+++ b/lib/ansible/utils/module_docs_fragments/openstack.py
@@ -93,6 +93,12 @@ class ModuleDocFragment(object):
     choices: [public, internal, admin]
     required: false
     default: public
+  identity_api_version:
+    description:
+        - The identity API version
+    choices: [2.0, 3]
+    required: false
+    default: None
 requirements:
   - python >= 2.7
   - shade


Test patch: