예제 #1
0
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)
예제 #2
0
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)