diff --git a/awx_collection/plugins/modules/tower_organization.py b/awx_collection/plugins/modules/tower_organization.py index e31ccc979e..4dedd6da70 100644 --- a/awx_collection/plugins/modules/tower_organization.py +++ b/awx_collection/plugins/modules/tower_organization.py @@ -103,7 +103,7 @@ def main(): # instance_group_names = module.params.get('instance_groups') state = module.params.get('state') - # Attempt to lookup the org the user specified + # Attempt to lookup the related items the user specified (these will fail the module if not found) # instance_group_objects = [] # for instance_name in instance_group_names: # instance_group_objects.append(module.resolve_name_to_id('instance_groups', instance_name)) diff --git a/awx_collection/plugins/modules/tower_settings.py b/awx_collection/plugins/modules/tower_settings.py index 8d0da8ed0d..aa5fb4972a 100644 --- a/awx_collection/plugins/modules/tower_settings.py +++ b/awx_collection/plugins/modules/tower_settings.py @@ -26,13 +26,18 @@ options: name: description: - Name of setting to modify - required: True + required: False type: str value: description: - Value to be modified for given setting. - required: True + required: False type: str + settings: + description: + - A data structure to be sent into the settings endpoint + required: False + type: dict extends_documentation_fragment: awx.awx.auth ''' @@ -56,51 +61,98 @@ EXAMPLES = ''' name: "AUTH_LDAP_BIND_PASSWORD" value: "Password" no_log: true + +- name: Set all the LDAP Auth Bind Params + tower_settings: + settings: + AUTH_LDAP_BIND_PASSWORD: "password" + AUTH_LDAP_USER_ATTR_MAP: + email: "mail" + first_name: "givenName" + last_name: "surname" + ... ''' -from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode - -try: - import tower_cli - import tower_cli.exceptions as exc - - from tower_cli.conf import settings -except ImportError: - pass - +from ..module_utils.tower_api import TowerModule +from json import loads +from json.decoder import JSONDecodeError +import re def main(): + # Any additional arguments that are not fields of the item can be added here argument_spec = dict( - name=dict(required=True), - value=dict(required=True), + name=dict(required=False), + value=dict(required=False), + settings=dict(required=False,type='dict'), ) + # Create a module for ourselves module = TowerModule( argument_spec=argument_spec, - supports_check_mode=False + supports_check_mode=True, + required_one_of=[['name','settings']], + mutually_exclusive=[['name','settings']], + required_if=[['name', 'present', ['value']]] ) - json_output = {} - + # Extract our parameters name = module.params.get('name') value = module.params.get('value') + new_settings = module.params.get('settings') - tower_auth = tower_auth_config(module) - with settings.runtime_values(**tower_auth): - tower_check_mode(module) + # If we were given a name/value pair we will just make settings out of that and proceed normally + if new_settings == None: + new_value = value try: - setting = tower_cli.get_resource('setting') - result = setting.modify(setting=name, value=value) + new_value = loads(value) + except JSONDecodeError as e: + # Attempt to deal with old tower_cli array types + if ',' in value: + new_value = re.split(",\s+", new_value) + + new_settings = { name: new_value } - json_output['id'] = result['id'] - json_output['value'] = result['value'] + # Load the existing settings + existing_settings = module.get_endpoint('settings/all')['json'] - except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: - module.fail_json(msg='Failed to modify the setting: {0}'.format(excinfo), changed=False) + # Begin a json response + json_response = { 'changed': False, 'old_values': {} } - json_output['changed'] = result['changed'] - module.exit_json(**json_output) + # Check any of the settings to see if anything needs to be updated + needs_update = False + for a_setting in new_settings: + if a_setting not in existing_settings or existing_settings[a_setting] != new_settings[a_setting]: + # At least one thing is different so we need to patch + needs_update = True + json_response['old_values'][ a_setting ] = existing_settings[a_setting] + # If nothing needs an update we can simply exit with the response (as not changed) + if not needs_update: + module.exit_json(**json_response) + + # Make the call to update the settings + response = module.patch_endpoint('settings/all', **{'data': new_settings}) + + if response['status_code'] == 200: + # Set the changed response to True + json_response['changed'] = True + + # To deal with the old style values we need to return 'value' in the response + new_values = {} + for a_setting in new_settings: + new_values[a_setting] = response['json'][a_setting] + + # If we were using a name we will just add a value of a string, otherwise we will return an array in values + if name != None: + json_response['value'] = new_values[name] + else: + json_response['values'] = new_values + + module.exit_json(**json_response) + elif 'json' in response and '__all__' in response['json']: + module.fail_json(msg=response['json']['__all__']) + else: + module.fail_json(**{'msg': "Unable to update settings, see response", 'response': response}) if __name__ == '__main__': main() diff --git a/awx_collection/plugins/modules/tower_team.py b/awx_collection/plugins/modules/tower_team.py index b5ba0a89a7..33a78275bc 100644 --- a/awx_collection/plugins/modules/tower_team.py +++ b/awx_collection/plugins/modules/tower_team.py @@ -80,7 +80,7 @@ def main(): organization = module.params.get('organization') state = module.params.get('state') - # Attempt to lookup the org the user specified + # Attempt to lookup the related items the user specified (these will fail the module if not found) org_id = module.resolve_name_to_id('organizations', organization) # Attempt to lookup team based on the provided name and org ID