def main(): """ Module execution :return: """ argument_spec = keycloak_argument_spec() meta_args = dict( state=dict(type='str', default='present', choices=['present', 'absent']), name=dict(type='str', required=True), description=dict(type='str'), realm=dict(type='str', default='master'), client_id=dict(type='str'), attributes=dict(type='dict'), ) argument_spec.update(meta_args) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_one_of=([[ 'token', 'auth_realm', 'auth_username', 'auth_password' ]]), required_together=([['auth_realm', 'auth_username', 'auth_password']])) result = dict(changed=False, msg='', diff={}, proposed={}, existing={}, end_state={}) # Obtain access token, initialize API try: connection_header = get_token(module.params) except KeycloakError as e: module.fail_json(msg=str(e)) kc = KeycloakAPI(module, connection_header) realm = module.params.get('realm') clientid = module.params.get('client_id') name = module.params.get('name') state = module.params.get('state') # attributes in Keycloak have their values returned as lists # via the API. attributes is a dict, so we'll transparently convert # the values to lists. if module.params.get('attributes') is not None: for key, val in module.params['attributes'].items(): module.params['attributes'][key] = [ val ] if not isinstance(val, list) else val # convert module parameters to client representation parameters (if they belong in there) role_params = [ x for x in module.params if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'client_id', 'composites'] and module.params.get(x) is not None ] # does the role already exist? if clientid is None: before_role = kc.get_realm_role(name, realm) else: before_role = kc.get_client_role(name, clientid, realm) if before_role is None: before_role = dict() # build a changeset changeset = dict() for param in role_params: new_param_value = module.params.get(param) old_value = before_role[param] if param in before_role else None if new_param_value != old_value: changeset[camel(param)] = new_param_value # prepare the new role updated_role = before_role.copy() updated_role.update(changeset) result['proposed'] = changeset result['existing'] = before_role # if before_role is none, the role doesn't exist. if before_role == dict(): if state == 'absent': # nothing to do. if module._diff: result['diff'] = dict(before='', after='') result['changed'] = False result['end_state'] = dict() result['msg'] = 'Role does not exist; doing nothing.' module.exit_json(**result) # for 'present', create a new role. result['changed'] = True if name is None: module.fail_json( msg='name must be specified when creating a new role') if module._diff: result['diff'] = dict(before='', after=updated_role) if module.check_mode: module.exit_json(**result) # do it for real! if clientid is None: kc.create_realm_role(updated_role, realm) after_role = kc.get_realm_role(name, realm) else: kc.create_client_role(updated_role, clientid, realm) after_role = kc.get_client_role(name, clientid, realm) result['end_state'] = after_role result['msg'] = 'Role {name} has been created'.format(name=name) module.exit_json(**result) else: if state == 'present': # no changes if updated_role == before_role: result['changed'] = False result['end_state'] = updated_role result['msg'] = "No changes required to role {name}.".format( name=name) module.exit_json(**result) # update the existing role result['changed'] = True if module._diff: result['diff'] = dict(before=before_role, after=updated_role) if module.check_mode: module.exit_json(**result) # do the update if clientid is None: kc.update_realm_role(updated_role, realm) after_role = kc.get_realm_role(name, realm) else: kc.update_client_role(updated_role, clientid, realm) after_role = kc.get_client_role(name, clientid, realm) result['end_state'] = after_role result['msg'] = "Role {name} has been updated".format(name=name) module.exit_json(**result) elif state == 'absent': result['changed'] = True if module._diff: result['diff'] = dict(before=before_role, after='') if module.check_mode: module.exit_json(**result) # delete for real if clientid is None: kc.delete_realm_role(name, realm) else: kc.delete_client_role(name, clientid, realm) result['end_state'] = dict() result['msg'] = "Role {name} has been deleted".format(name=name) module.exit_json(**result) module.exit_json(**result)
def main(): """ Module execution :return: """ argument_spec = keycloak_argument_spec() meta_args = dict( state=dict(type='str', default='present', choices=['present', 'absent']), name=dict(type='str', required=True), description=dict(type='str'), realm=dict(type='str', default='master'), client_id=dict(type='str'), attributes=dict(type='dict'), ) argument_spec.update(meta_args) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_one_of=([[ 'token', 'auth_realm', 'auth_username', 'auth_password' ]]), required_together=([['auth_realm', 'auth_username', 'auth_password']])) result = dict(changed=False, msg='', diff={}, proposed={}, existing={}, end_state={}) # Obtain access token, initialize API try: connection_header = get_token(module.params) except KeycloakError as e: module.fail_json(msg=str(e)) kc = KeycloakAPI(module, connection_header) realm = module.params.get('realm') clientid = module.params.get('client_id') name = module.params.get('name') state = module.params.get('state') # attributes in Keycloak have their values returned as lists # via the API. attributes is a dict, so we'll transparently convert # the values to lists. if module.params.get('attributes') is not None: for key, val in module.params['attributes'].items(): module.params['attributes'][key] = [ val ] if not isinstance(val, list) else val # Filter and map the parameters names that apply to the role role_params = [ x for x in module.params if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'client_id', 'composites'] and module.params.get(x) is not None ] # See if it already exists in Keycloak if clientid is None: before_role = kc.get_realm_role(name, realm) else: before_role = kc.get_client_role(name, clientid, realm) if before_role is None: before_role = {} # Build a proposed changeset from parameters given to this module changeset = {} for param in role_params: new_param_value = module.params.get(param) old_value = before_role[param] if param in before_role else None if new_param_value != old_value: changeset[camel(param)] = new_param_value # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) desired_role = before_role.copy() desired_role.update(changeset) result['proposed'] = changeset result['existing'] = before_role # Cater for when it doesn't exist (an empty dict) if not before_role: if state == 'absent': # Do nothing and exit if module._diff: result['diff'] = dict(before='', after='') result['changed'] = False result['end_state'] = {} result['msg'] = 'Role does not exist, doing nothing.' module.exit_json(**result) # Process a creation result['changed'] = True if name is None: module.fail_json( msg='name must be specified when creating a new role') if module._diff: result['diff'] = dict(before='', after=desired_role) if module.check_mode: module.exit_json(**result) # create it if clientid is None: kc.create_realm_role(desired_role, realm) after_role = kc.get_realm_role(name, realm) else: kc.create_client_role(desired_role, clientid, realm) after_role = kc.get_client_role(name, clientid, realm) result['end_state'] = after_role result['msg'] = 'Role {name} has been created'.format(name=name) module.exit_json(**result) else: if state == 'present': # Process an update # no changes if desired_role == before_role: result['changed'] = False result['end_state'] = desired_role result['msg'] = "No changes required to role {name}.".format( name=name) module.exit_json(**result) # doing an update result['changed'] = True if module._diff: result['diff'] = dict(before=before_role, after=desired_role) if module.check_mode: module.exit_json(**result) # do the update if clientid is None: kc.update_realm_role(desired_role, realm) after_role = kc.get_realm_role(name, realm) else: kc.update_client_role(desired_role, clientid, realm) after_role = kc.get_client_role(name, clientid, realm) result['end_state'] = after_role result['msg'] = "Role {name} has been updated".format(name=name) module.exit_json(**result) else: # Process a deletion (because state was not 'present') result['changed'] = True if module._diff: result['diff'] = dict(before=before_role, after='') if module.check_mode: module.exit_json(**result) # delete it if clientid is None: kc.delete_realm_role(name, realm) else: kc.delete_client_role(name, clientid, realm) result['end_state'] = {} result['msg'] = "Role {name} has been deleted".format(name=name) module.exit_json(**result)