mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-24 11:21:25 -07:00
keycloak_group: support keycloak subgroups (#5814)
* feat(module/keycloak_group): add support for ... ... handling subgroups * added changelog fragment and fixing sanity ... ... test issues * more sanity fixes * fix missing version and review issues * added missing licence header * fix docu * fix line beeing too long * replaced suboptimal string type prefixing ... ... with better subdict based approach * fix sanity issues * more sanity fixing * fixed more review issues * fix argument list too long * why is it failing? something wrong with the docu? * is it this line then? * undid group attribute removing, it does not ... ... belong into this PR * fix version_added for parents parameter --------- Co-authored-by: Mirko Wilhelmi <Mirko.Wilhelmi@sma.de>
This commit is contained in:
parent
1877ef1510
commit
7d3e6d1bb7
7 changed files with 796 additions and 9 deletions
|
@ -22,7 +22,7 @@ description:
|
|||
to your needs and a user having the expected roles.
|
||||
|
||||
- The names of module options are snake_cased versions of the camelCase ones found in the
|
||||
Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/8.0/rest-api/index.html).
|
||||
Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/20.0.2/rest-api/index.html).
|
||||
|
||||
- Attributes are multi-valued in the Keycloak API. All attributes are lists of individual values and will
|
||||
be returned that way by this module. You may pass single values for attributes when calling the module,
|
||||
|
@ -42,7 +42,9 @@ options:
|
|||
description:
|
||||
- State of the group.
|
||||
- On C(present), the group will be created if it does not yet exist, or updated with the parameters you provide.
|
||||
- On C(absent), the group will be removed if it exists.
|
||||
- >-
|
||||
On C(absent), the group will be removed if it exists. Be aware that absenting
|
||||
a group with subgroups will automatically delete all its subgroups too.
|
||||
default: 'present'
|
||||
type: str
|
||||
choices:
|
||||
|
@ -74,6 +76,38 @@ options:
|
|||
- A dict of key/value pairs to set as custom attributes for the group.
|
||||
- Values may be single values (e.g. a string) or a list of strings.
|
||||
|
||||
parents:
|
||||
version_added: "6.4.0"
|
||||
type: list
|
||||
description:
|
||||
- List of parent groups for the group to handle sorted top to bottom.
|
||||
- >-
|
||||
Set this to create a group as a subgroup of another group or groups (parents) or
|
||||
when accessing an existing subgroup by name.
|
||||
- >-
|
||||
Not necessary to set when accessing an existing subgroup by its C(ID) because in
|
||||
that case the group can be directly queried without necessarily knowing its parent(s).
|
||||
elements: dict
|
||||
suboptions:
|
||||
id:
|
||||
type: str
|
||||
description:
|
||||
- Identify parent by ID.
|
||||
- Needs less API calls than using I(name).
|
||||
- A deep parent chain can be started at any point when first given parent is given as ID.
|
||||
- Note that in principle both ID and name can be specified at the same time
|
||||
but current implementation only always use just one of them, with ID
|
||||
being preferred.
|
||||
name:
|
||||
type: str
|
||||
description:
|
||||
- Identify parent by name.
|
||||
- Needs more internal API calls than using I(id) to map names to ID's under the hood.
|
||||
- When giving a parent chain with only names it must be complete up to the top.
|
||||
- Note that in principle both ID and name can be specified at the same time
|
||||
but current implementation only always use just one of them, with ID
|
||||
being preferred.
|
||||
|
||||
notes:
|
||||
- Presently, the I(realmRoles), I(clientRoles) and I(access) attributes returned by the Keycloak API
|
||||
are read-only for groups. This limitation will be removed in a later version of this module.
|
||||
|
@ -97,6 +131,7 @@ EXAMPLES = '''
|
|||
auth_realm: master
|
||||
auth_username: USERNAME
|
||||
auth_password: PASSWORD
|
||||
register: result_new_kcgrp
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create a Keycloak group, authentication with token
|
||||
|
@ -162,6 +197,64 @@ EXAMPLES = '''
|
|||
- list
|
||||
- items
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create a Keycloak subgroup of a base group (using parent name)
|
||||
community.general.keycloak_group:
|
||||
name: my-new-kc-group-sub
|
||||
realm: MyCustomRealm
|
||||
state: present
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
auth_realm: master
|
||||
auth_username: USERNAME
|
||||
auth_password: PASSWORD
|
||||
parents:
|
||||
- name: my-new-kc-group
|
||||
register: result_new_kcgrp_sub
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create a Keycloak subgroup of a base group (using parent id)
|
||||
community.general.keycloak_group:
|
||||
name: my-new-kc-group-sub2
|
||||
realm: MyCustomRealm
|
||||
state: present
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
auth_realm: master
|
||||
auth_username: USERNAME
|
||||
auth_password: PASSWORD
|
||||
parents:
|
||||
- id: "{{ result_new_kcgrp.end_state.id }}"
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create a Keycloak subgroup of a subgroup (using parent names)
|
||||
community.general.keycloak_group:
|
||||
name: my-new-kc-group-sub-sub
|
||||
realm: MyCustomRealm
|
||||
state: present
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
auth_realm: master
|
||||
auth_username: USERNAME
|
||||
auth_password: PASSWORD
|
||||
parents:
|
||||
- name: my-new-kc-group
|
||||
- name: my-new-kc-group-sub
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Create a Keycloak subgroup of a subgroup (using direct parent id)
|
||||
community.general.keycloak_group:
|
||||
name: my-new-kc-group-sub-sub
|
||||
realm: MyCustomRealm
|
||||
state: present
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
auth_realm: master
|
||||
auth_username: USERNAME
|
||||
auth_password: PASSWORD
|
||||
parents:
|
||||
- id: "{{ result_new_kcgrp_sub.end_state.id }}"
|
||||
delegate_to: localhost
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
|
@ -240,6 +333,13 @@ def main():
|
|||
id=dict(type='str'),
|
||||
name=dict(type='str'),
|
||||
attributes=dict(type='dict'),
|
||||
parents=dict(
|
||||
type='list', elements='dict',
|
||||
options=dict(
|
||||
id=dict(type='str'),
|
||||
name=dict(type='str')
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
argument_spec.update(meta_args)
|
||||
|
@ -266,6 +366,8 @@ def main():
|
|||
name = module.params.get('name')
|
||||
attributes = module.params.get('attributes')
|
||||
|
||||
parents = module.params.get('parents')
|
||||
|
||||
# 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.
|
||||
|
@ -275,12 +377,12 @@ def main():
|
|||
|
||||
# Filter and map the parameters names that apply to the group
|
||||
group_params = [x for x in module.params
|
||||
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm'] and
|
||||
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'parents'] and
|
||||
module.params.get(x) is not None]
|
||||
|
||||
# See if it already exists in Keycloak
|
||||
if gid is None:
|
||||
before_group = kc.get_group_by_name(name, realm=realm)
|
||||
before_group = kc.get_group_by_name(name, realm=realm, parents=parents)
|
||||
else:
|
||||
before_group = kc.get_group_by_groupid(gid, realm=realm)
|
||||
|
||||
|
@ -323,9 +425,15 @@ def main():
|
|||
if module.check_mode:
|
||||
module.exit_json(**result)
|
||||
|
||||
# create it
|
||||
kc.create_group(desired_group, realm=realm)
|
||||
after_group = kc.get_group_by_name(name, realm)
|
||||
# create it ...
|
||||
if parents:
|
||||
# ... as subgroup of another parent group
|
||||
kc.create_subgroup(parents, desired_group, realm=realm)
|
||||
else:
|
||||
# ... as toplvl base group
|
||||
kc.create_group(desired_group, realm=realm)
|
||||
|
||||
after_group = kc.get_group_by_name(name, realm, parents=parents)
|
||||
|
||||
result['end_state'] = after_group
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue