Cherry pick Tower credential fixes to stable-2.4 (#36807)
* Fix credentials for Tower API V2 (cherry picked from commit640749d54f
) * tower cred: implement credential /api/v1/ kind compatability (cherry picked from commit9cb4b70e27
) * tower cred: filter user name lookup by the proper key (cherry picked from commitcd6855275e
) * tower cred: update kind options in documentation (cherry picked from commit8a41233202
) * tower cred: support credential kind/type for /api/v1/ and /api/v2/ (#36662) older versions of Tower (3.1) don't have a concept of CredentialTypes (this was introduced in Tower 3.2). This change detects older versions of pre-3.2 tower-cli that *only* support the deprecated `kind` attribute. (cherry picked from commit641f8b4ef6
) * Add CHANGELOG entry for Ansible Tower module credential fix * properly detect the absence of credential_type in older tower-cli (#36908) (cherry picked from commita82043939b
) * Do not import HAS_TOWER_CLI since it does not exist in stable-2.4 * properly pass /api/v1/ credential fields for older Towers (#36917) (cherry picked from commit0e7106b106
)
This commit is contained in:
parent
0d57282a1a
commit
47eccd366b
2 changed files with 116 additions and 45 deletions
|
@ -90,6 +90,10 @@ Ansible Changes By Release
|
|||
https://github.com/ansible/ansible/pull/36124
|
||||
* fix debug output
|
||||
https://github.com/ansible/ansible/pull/36307
|
||||
* Fix credentials for Ansible Tower modules to work with v1 and v2 of the API
|
||||
(https://github.com/ansible/ansible/pull/36587)
|
||||
(https://github.com/ansible/ansible/pull/36662)
|
||||
|
||||
|
||||
<a id="2.4.3"></a>
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ options:
|
|||
description:
|
||||
- Type of credential being added.
|
||||
required: True
|
||||
choices: ["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", "cloudforms", "gce", "azure", "azure_rm", "openstack"]
|
||||
choices: ["ssh", "vault", "net", "scm", "aws", "vmware", "satellite6", "cloudforms", "gce", "azure_rm", "openstack", "rhv", "insights", "tower"]
|
||||
host:
|
||||
description:
|
||||
- Host for this credential.
|
||||
|
@ -190,56 +190,89 @@ EXAMPLES = '''
|
|||
tower_config_file: "~/tower_cli.cfg"
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode
|
||||
|
||||
try:
|
||||
import os
|
||||
import tower_cli
|
||||
import tower_cli.utils.exceptions as exc
|
||||
|
||||
from tower_cli.conf import settings
|
||||
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
|
||||
|
||||
HAS_TOWER_CLI = True
|
||||
except ImportError:
|
||||
HAS_TOWER_CLI = False
|
||||
|
||||
|
||||
KIND_CHOICES = {
|
||||
'ssh': 'Machine',
|
||||
'vault': 'Ansible Vault',
|
||||
'net': 'Network',
|
||||
'scm': 'Source Control',
|
||||
'aws': 'Amazon Web Services',
|
||||
'vmware': 'VMware vCenter',
|
||||
'satellite6': 'Red Hat Satellite 6',
|
||||
'cloudforms': 'Red Hat CloudForms',
|
||||
'gce': 'Google Compute Engine',
|
||||
'azure_rm': 'Microsoft Azure Resource Manager',
|
||||
'openstack': 'OpenStack',
|
||||
'rhv': 'Red Hat Virtualization',
|
||||
'insights': 'Insights',
|
||||
'tower': 'Ansible Tower',
|
||||
}
|
||||
|
||||
|
||||
def credential_type_for_v1_kind(params, module):
|
||||
credential_type_res = tower_cli.get_resource('credential_type')
|
||||
kind = params.pop('kind')
|
||||
arguments = {'managed_by_tower': True}
|
||||
if kind == 'ssh':
|
||||
if params.get('vault_password'):
|
||||
arguments['kind'] = 'vault'
|
||||
else:
|
||||
arguments['kind'] = 'ssh'
|
||||
elif kind in ('net', 'scm', 'insights', 'vault'):
|
||||
arguments['kind'] = kind
|
||||
elif kind in KIND_CHOICES:
|
||||
arguments.update(dict(
|
||||
kind='cloud',
|
||||
name=KIND_CHOICES[kind]
|
||||
))
|
||||
return credential_type_res.get(**arguments)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
name=dict(required=True),
|
||||
user=dict(),
|
||||
team=dict(),
|
||||
kind=dict(required=True,
|
||||
choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6",
|
||||
"cloudforms", "gce", "azure", "azure_rm", "openstack"]),
|
||||
host=dict(),
|
||||
username=dict(),
|
||||
password=dict(no_log=True),
|
||||
ssh_key_data=dict(no_log=True),
|
||||
ssh_key_unlock=dict(no_log=True),
|
||||
authorize=dict(type='bool', default=False),
|
||||
authorize_password=dict(no_log=True),
|
||||
client=dict(),
|
||||
secret=dict(),
|
||||
tenant=dict(),
|
||||
subscription=dict(),
|
||||
domain=dict(),
|
||||
become_method=dict(),
|
||||
become_username=dict(),
|
||||
become_password=dict(no_log=True),
|
||||
vault_password=dict(no_log=True),
|
||||
description=dict(),
|
||||
organization=dict(required=True),
|
||||
project=dict(),
|
||||
tower_host=dict(),
|
||||
tower_username=dict(),
|
||||
tower_password=dict(no_log=True),
|
||||
tower_verify_ssl=dict(type='bool', default=True),
|
||||
tower_config_file=dict(type='path'),
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
argument_spec = tower_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
name=dict(required=True),
|
||||
user=dict(),
|
||||
team=dict(),
|
||||
kind=dict(required=True,
|
||||
choices=KIND_CHOICES.keys()),
|
||||
host=dict(),
|
||||
username=dict(),
|
||||
password=dict(no_log=True),
|
||||
ssh_key_data=dict(no_log=True, type='path'),
|
||||
ssh_key_unlock=dict(no_log=True),
|
||||
authorize=dict(type='bool', default=False),
|
||||
authorize_password=dict(no_log=True),
|
||||
client=dict(),
|
||||
secret=dict(),
|
||||
tenant=dict(),
|
||||
subscription=dict(),
|
||||
domain=dict(),
|
||||
become_method=dict(),
|
||||
become_username=dict(),
|
||||
become_password=dict(no_log=True),
|
||||
vault_password=dict(no_log=True),
|
||||
description=dict(),
|
||||
organization=dict(required=True),
|
||||
project=dict(),
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
))
|
||||
|
||||
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
|
||||
|
||||
if not HAS_TOWER_CLI:
|
||||
module.fail_json(msg='ansible-tower-cli required for this module')
|
||||
|
@ -255,23 +288,57 @@ def main():
|
|||
tower_check_mode(module)
|
||||
credential = tower_cli.get_resource('credential')
|
||||
try:
|
||||
params = module.params.copy()
|
||||
params = {}
|
||||
params['create_on_missing'] = True
|
||||
params['name'] = name
|
||||
|
||||
if organization:
|
||||
org_res = tower_cli.get_resource('organization')
|
||||
org = org_res.get(name=organization)
|
||||
params['organization'] = org['id']
|
||||
|
||||
if params['ssh_key_data']:
|
||||
filename = params['ssh_key_data']
|
||||
filename = os.path.expanduser(filename)
|
||||
try:
|
||||
tower_cli.get_resource('credential_type')
|
||||
except (ImportError, AttributeError):
|
||||
# /api/v1/ backwards compat
|
||||
# older versions of tower-cli don't *have* a credential_type
|
||||
# resource
|
||||
params['kind'] = module.params['kind']
|
||||
else:
|
||||
credential_type = credential_type_for_v1_kind(module.params, module)
|
||||
params['credential_type'] = credential_type['id']
|
||||
|
||||
if module.params.get('description'):
|
||||
params['description'] = module.params.get('description')
|
||||
|
||||
if module.params.get('user'):
|
||||
user_res = tower_cli.get_resource('user')
|
||||
user = user_res.get(username=module.params.get('user'))
|
||||
params['user'] = user['id']
|
||||
|
||||
if module.params.get('team'):
|
||||
team_res = tower_cli.get_resource('team')
|
||||
team = team_res.get(name=module.params.get('team'))
|
||||
params['team'] = team['id']
|
||||
|
||||
if module.params.get('ssh_key_data'):
|
||||
filename = module.params.get('ssh_key_data')
|
||||
if not os.path.exists(filename):
|
||||
module.fail_json(msg='file not found: %s' % filename)
|
||||
if os.path.isdir(filename):
|
||||
module.fail_json(msg='attempted to read contents of directory: %s' % filename)
|
||||
with open(filename, 'rb') as f:
|
||||
params['ssh_key_data'] = f.read()
|
||||
module.params['ssh_key_data'] = f.read()
|
||||
|
||||
for key in ('authorize', 'authorize_password', 'client', 'secret',
|
||||
'tenant', 'subscription', 'domain', 'become_method',
|
||||
'become_username', 'become_password', 'vault_password',
|
||||
'project', 'host', 'username', 'password',
|
||||
'ssh_key_data', 'ssh_key_unlock'):
|
||||
if 'kind' in params:
|
||||
params[key] = module.params.get(key)
|
||||
elif module.params.get(key):
|
||||
params.setdefault('inputs', {})[key] = module.params.get(key)
|
||||
|
||||
if state == 'present':
|
||||
result = credential.modify(**params)
|
||||
|
|
Loading…
Reference in a new issue