From 92d6dddd492773e088ffa4a5f75dbe273ed6bace Mon Sep 17 00:00:00 2001 From: Felix Grzelka Date: Mon, 8 Jun 2026 13:21:27 +0000 Subject: [PATCH] rename to role_owner_client_id --- .../identity/keycloak/keycloak.py | 74 +++++++++---------- .../keycloak/keycloak_clientsecret.py | 2 +- plugins/modules/keycloak_client.py | 4 +- plugins/modules/keycloak_client_rolescope.py | 66 ++++++++--------- .../keycloak_client_scope_rolemappings.py | 2 +- 5 files changed, 74 insertions(+), 74 deletions(-) diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index a4b7c1d..7360397 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -701,7 +701,7 @@ class KeycloakAPI: except Exception as e: self.fail_request(e, msg=f"Could not obtain list of clients for realm {realm}: {e}") - def get_client_by_clientid(self, client_id, realm: str = "master"): + def get_client_by_client_id(self, client_id, realm: str = "master"): """Get client representation by clientId :param client_id: The clientId to be queried :param realm: realm from which to obtain the client representation @@ -744,7 +744,7 @@ class KeycloakAPI: :param realm: client template from this realm :return: id of client (usually a UUID) """ - result = self.get_client_by_clientid(client_id, realm) + result = self.get_client_by_client_id(client_id, realm) if isinstance(result, dict) and "id" in result: return result["id"] else: @@ -2020,7 +2020,7 @@ class KeycloakAPI: composite_url = "" try: if clientid is not None: - client = self.get_client_by_clientid(client_id=clientid, realm=realm) + client = self.get_client_by_client_id(client_id=clientid, realm=realm) cid = client["id"] composite_url = URL_CLIENT_ROLE_COMPOSITES.format( url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"], safe="") @@ -2038,7 +2038,7 @@ class KeycloakAPI: composite_url = "" try: if clientid is not None: - client = self.get_client_by_clientid(client_id=clientid, realm=realm) + client = self.get_client_by_client_id(client_id=clientid, realm=realm) cid = client["id"] composite_url = URL_CLIENT_ROLE_COMPOSITES.format( url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"], safe="") @@ -2057,7 +2057,7 @@ class KeycloakAPI: composite_url = "" try: if clientid is not None: - client = self.get_client_by_clientid(client_id=clientid, realm=realm) + client = self.get_client_by_client_id(client_id=clientid, realm=realm) cid = client["id"] composite_url = URL_CLIENT_ROLE_COMPOSITES.format( url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"], safe="") @@ -3305,71 +3305,71 @@ class KeycloakAPI: msg=f"Could not fetch client roles from client {client_id} for client scope {client_scope_id} in realm {realm}: {e}", ) - def get_client_role_scope_from_client(self, clientid, client_scope_id, realm: str = "master"): + def get_client_role_scope_from_client(self, target_client_id, role_owner_client_id, realm: str = "master"): """Fetch the roles associated with the client's scope for a specific client on the Keycloak server. - :param clientid: ID of the client from which to obtain the associated roles. - :param client_scope_id: ID of the client who owns the roles. + :param target_client_id: ID of the client from which to obtain the associated roles. + :param role_owner_client_id: ID of the client who owns the roles. :param realm: Realm from which to obtain the scope. :return: The client scope of roles from specified client. """ client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format( - url=self.baseurl, realm=realm, id=clientid, scopeid=client_scope_id + url=self.baseurl, realm=realm, id=target_client_id, scopeid=role_owner_client_id ) try: return self._request_and_deserialize(client_role_scope_url, method="GET") except Exception as e: - self.fail_request(e, msg=f"Could not fetch roles scope for client {clientid} in realm {realm}: {e}") + self.fail_request(e, msg=f"Could not fetch roles scope for client {target_client_id} in realm {realm}: {e}") - def update_client_role_scope_from_client(self, payload, clientid, client_scope_id, realm: str = "master"): + def update_client_role_scope_from_client(self, roles, target_client_id, role_owner_client_id, realm: str = "master"): """Update and fetch the roles associated with the client's scope on the Keycloak server. - :param payload: List of roles to be added to the scope. - :param clientid: ID of the client to update scope. - :param client_scope_id: ID of the client who owns the roles. + :param roles: List of roles to be added to the scope. + :param target_client_id: ID of the client to update scope. + :param role_owner_client_id: ID of the client who owns the roles. :param realm: Realm from which to obtain the clients. :return: The client scope of roles from specified client. """ client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format( - url=self.baseurl, realm=realm, id=clientid, scopeid=client_scope_id + url=self.baseurl, realm=realm, id=target_client_id, scopeid=role_owner_client_id ) try: - self._request(client_role_scope_url, method="POST", data=json.dumps(payload)) + self._request(client_role_scope_url, method="POST", data=json.dumps(roles)) except Exception as e: - self.fail_request(e, msg=f"Could not update roles scope for client {clientid} in realm {realm}: {e}") + self.fail_request(e, msg=f"Could not update roles scope for client {target_client_id} in realm {realm}: {e}") - return self.get_client_role_scope_from_client(clientid, client_scope_id, realm) + return self.get_client_role_scope_from_client(target_client_id, role_owner_client_id, realm) - def delete_client_role_scope_from_client(self, payload, clientid, client_scope_id, realm: str = "master"): - """Delete the roles contains in the payload from the client's scope on the Keycloak server. - :param payload: List of roles to be deleted. - :param clientid: ID of the client to delete roles from scope. - :param client_scope_id: ID of the client who owns the roles. + def delete_client_role_scope_from_client(self, roles, target_client_id, role_owner_client_id, realm: str = "master"): + """Delete the roles contained in the payload from the client's scope on the Keycloak server. + :param roles: List of roles to be deleted. + :param target_client_id: ID of the client to delete roles from scope. + :param role_owner_client_id: ID of the client who owns the roles. :param realm: Realm from which to obtain the clients. :return: The client scope of roles from specified client. """ client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format( - url=self.baseurl, realm=realm, id=clientid, scopeid=client_scope_id + url=self.baseurl, realm=realm, id=target_client_id, scopeid=role_owner_client_id ) try: - self._request(client_role_scope_url, method="DELETE", data=json.dumps(payload)) + self._request(client_role_scope_url, method="DELETE", data=json.dumps(roles)) except Exception as e: - self.fail_request(e, msg=f"Could not delete roles scope for client {clientid} in realm {realm}: {e}") + self.fail_request(e, msg=f"Could not delete roles from scope for client {target_client_id} in realm {realm}: {e}") - return self.get_client_role_scope_from_client(clientid, client_scope_id, realm) + return self.get_client_role_scope_from_client(target_client_id, role_owner_client_id, realm) def update_client_scope_scope_mappings_client( - self, payload: list[dict], client_scope_id: str, client_id: str, realm: str = "master" + self, payload: list[dict], client_scope_id: str, role_owner_client_id: str, realm: str = "master" ): """Update and fetch the client roles (scope-mappings) associated with the client scope on the Keycloak server. :param payload: List of client roles to be added to the scope. :param client_scope_id: ID of the client scope to update scope-mappings. - :param clientid: ID of the client from which to obtain the associated roles. + :param role_owner_client_id: ID of the client from which to obtain the associated roles. :param realm: Realm from which to obtain the client. :return: The client scope client scope-mappings. """ client_role_scope_url = URL_CLIENT_SCOPE_SCOPE_MAPPINGS_CLIENT.format( - url=self.baseurl, realm=realm, id=client_scope_id, client=client_id + url=self.baseurl, realm=realm, id=client_scope_id, client=role_owner_client_id ) try: self._request(client_role_scope_url, method="POST", data=json.dumps(payload)) @@ -3377,10 +3377,10 @@ class KeycloakAPI: except Exception as e: self.fail_request( e, - msg=f"Could not update scope mappings for client scope {client_id}.{client_scope_id} in realm {realm}: {e}", + msg=f"Could not update scope mappings for client scope {role_owner_client_id}.{client_scope_id} in realm {realm}: {e}", ) - return self.get_client_scope_scope_mappings_client(client_scope_id, client_id, realm) + return self.get_client_scope_scope_mappings_client(client_scope_id, role_owner_client_id, realm) def update_client_scope_scope_mappings_realm(self, payload: list[dict], client_scope_id: str, realm: str = "master"): """Update and fetch the realm roles (scope-mappings) associated with the client scope on the Keycloak server. @@ -3403,17 +3403,17 @@ class KeycloakAPI: return self.get_client_scope_scope_mappings_realm(client_scope_id, realm) def delete_client_scope_scope_mappings_client( - self, payload: list[dict], client_scope_id: str, client_id: str, realm: str = "master" + self, roles: list[dict], client_scope_id: str, role_owner_client_id: str, realm: str = "master" ): """Delete the client roles (scope_mappings) contained in the payload from the client scope on the Keycloak server. :param payload: List of roles to be deleted. :param client_scope_id: ID of the client scope to delete roles from scope-mappings. - :param clientid: ID of the client who owns the roles. + :param role_owner_client_id: ID of the client who owns the roles. :param realm: Realm from which to obtain the client. :return: The client scope client scope-mappings. """ client_role_scope_url = URL_CLIENT_SCOPE_SCOPE_MAPPINGS_CLIENT.format( - url=self.baseurl, realm=realm, id=client_scope_id, client=client_id + url=self.baseurl, realm=realm, id=client_scope_id, client=role_owner_client_id ) try: self._request(client_role_scope_url, method="DELETE", data=json.dumps(payload)) @@ -3421,10 +3421,10 @@ class KeycloakAPI: except Exception as e: self.fail_request( e, - msg=f"Could not delete scope mappings for client scope {client_id}.{client_scope_id} in realm {realm}: {e}", + msg=f"Could not delete scope mappings for client scope {role_owner_client_id}.{client_scope_id} in realm {realm}: {e}", ) - return self.get_client_scope_scope_mappings_client(client_scope_id, client_id, realm) + return self.get_client_scope_scope_mappings_client(client_scope_id, role_owner_client_id, realm) def delete_client_scope_scope_mappings_realm(self, payload: list[dict], client_scope_id: str, realm: str = "master"): """Delete the realm roles (scope_mappings) contained in the payload from the client scope on the Keycloak server. diff --git a/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py b/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py index ffa5974..54fa277 100644 --- a/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py +++ b/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py @@ -66,7 +66,7 @@ def keycloak_clientsecret_module_resolve_params(module: AnsibleModule, kc: Keycl # less lookup. if id is None: # Due to the required_one_of spec, client_id is guaranteed to not be None - client = kc.get_client_by_clientid(client_id, realm=realm) + client = kc.get_client_by_client_id(client_id, realm=realm) if client is None: module.fail_json(msg=f"Client does not exist {client_id}") diff --git a/plugins/modules/keycloak_client.py b/plugins/modules/keycloak_client.py index 0407a13..e6f0f9e 100644 --- a/plugins/modules/keycloak_client.py +++ b/plugins/modules/keycloak_client.py @@ -1346,7 +1346,7 @@ def main(): # See if it already exists in Keycloak if cid is None: - before_client = kc.get_client_by_clientid(module.params.get("client_id"), realm=realm) + before_client = kc.get_client_by_client_idd(module.params.get("client_id"), realm=realm) if before_client is not None: cid = before_client["id"] else: @@ -1440,7 +1440,7 @@ def main(): # create it kc.create_client(desired_client, realm=realm) - after_client = kc.get_client_by_clientid(desired_client["clientId"], realm=realm) + after_client = kc.get_client_by_client_id(desired_client["clientId"], realm=realm) result["end_state"] = sanitize_cr(after_client) diff --git a/plugins/modules/keycloak_client_rolescope.py b/plugins/modules/keycloak_client_rolescope.py index 2ea710a..df16e29 100644 --- a/plugins/modules/keycloak_client_rolescope.py +++ b/plugins/modules/keycloak_client_rolescope.py @@ -19,7 +19,7 @@ description: to the REST API using OpenID Connect; the user connecting and the client being used must have the requisite access rights. In a default Keycloak installation, admin-cli and an admin user would work, as would a separate client definition with the scope tailored to your needs and a user having the expected roles. - - Client O(client_id) must have O(middleware_automation.keycloak.keycloak_client#module:full_scope_allowed) set to V(false). + - Client O(target_client_id) must have O(middleware_automation.keycloak.keycloak_client#module:full_scope_allowed) set to V(false). - Attributes are multi-valued in the Keycloak API. All attributes are lists of individual values and are returned that way by this module. You may pass single values for attributes when calling the module, and this is translated into a list suitable for the API. @@ -50,12 +50,12 @@ options: - The Keycloak realm under which clients resides. default: 'master' - client_id: + target_client_id: type: str required: true description: - Roles provided in O(role_names) while be added to this client scope. - client_scope_id: + role_owner_client_id: type: str description: - If the O(role_names) are client role, the client ID under which it resides. @@ -66,8 +66,8 @@ options: elements: str description: - Names of roles to manipulate. - - If O(client_scope_id) is present, all roles must be under this client. - - If O(client_scope_id) is absent, all roles must be under the realm. + - If O(role_owner_client_id) is present, all roles must be under this client. + - If O(role_owner_client_id) is absent, all roles must be under the realm. extends_documentation_fragment: - middleware_automation.keycloak.keycloak - middleware_automation.keycloak.actiongroup_keycloak @@ -85,8 +85,8 @@ EXAMPLES = r""" auth_username: USERNAME auth_password: PASSWORD realm: MyCustomRealm - client_id: frontend-client-public - client_scope_id: backend-client-private + target_client_id: frontend-client-public + role_owner_client_id: backend-client-private role_names: - backend-role-admin - backend-role-user @@ -98,8 +98,8 @@ EXAMPLES = r""" auth_username: USERNAME auth_password: PASSWORD realm: MyCustomRealm - client_id: frontend-client-public - client_scope_id: backend-client-private + target_client_id: frontend-client-public + role_owner_client_id: backend-client-private role_names: - backend-role-admin state: absent @@ -111,7 +111,7 @@ EXAMPLES = r""" auth_username: USERNAME auth_password: PASSWORD realm: MyCustomRealm - client_id: frontend-client-public + target_client_id: frontend-client-public role_names: - realm-role-admin - realm-role-user @@ -167,8 +167,8 @@ def main(): argument_spec = keycloak_argument_spec() meta_args = dict( - client_id=dict(type="str", required=True), - client_scope_id=dict(type="str"), + target_client_id=dict(type="str", required=True), + role_owner_client_id=dict(type="str"), realm=dict(type="str", default="master"), role_names=dict(type="list", elements="str", required=True), state=dict(type="str", default="present", choices=["present", "absent"]), @@ -189,8 +189,8 @@ def main(): kc = KeycloakAPI(module, connection_header) realm = module.params.get("realm") - clientid = module.params.get("client_id") - client_scope_id = module.params.get("client_scope_id") + target_client_id = module.params.get("target_client_id") + role_owner_client_id = module.params.get("role_owner_client_id") role_names = module.params.get("role_names") state = module.params.get("state") @@ -198,23 +198,23 @@ def main(): if not objRealm: module.fail_json(msg=f"Failed to retrive realm '{realm}'") - objClient = kc.get_client_by_clientid(clientid, realm) + objClient = kc.get_client_by_target_client_id(target_client_id, realm) if not objClient: - module.fail_json(msg=f"Failed to retrive client '{realm}.{clientid}'") + module.fail_json(msg=f"Failed to retrive client '{realm}.{target_client_id}'") if objClient["fullScopeAllowed"] and state == "present": - module.fail_json(msg=f"FullScopeAllowed is active for Client '{realm}.{clientid}'") + module.fail_json(msg=f"FullScopeAllowed is active for Client '{realm}.{target_client_id}'") - if client_scope_id: - objClientScope = kc.get_client_by_clientid(client_scope_id, realm) - if not objClientScope: - module.fail_json(msg=f"Failed to retrive client '{realm}.{client_scope_id}'") - before_role_mapping = kc.get_client_role_scope_from_client(objClient["id"], objClientScope["id"], realm) + if role_owner_client_id: + role_owner_client = kc.get_client_by_client_id(role_owner_client_id, realm) + if not role_owner_client: + module.fail_json(msg=f"Failed to retrive client '{realm}.{role_owner_client_id}'") + before_role_mapping = kc.get_client_role_scope_from_client(objClient["id"], role_owner_client["id"], realm) else: before_role_mapping = kc.get_client_role_scope_from_realm(objClient["id"], realm) - if client_scope_id: + if role_owner_client_id: # retrive all role from client_scope - client_scope_roles_by_name = kc.get_client_roles_by_id(objClientScope["id"], realm) + client_scope_roles_by_name = kc.get_client_roles_by_id(role_owner_client["id"], realm) else: # retrive all role from realm client_scope_roles_by_name = kc.get_realm_roles(realm) @@ -228,8 +228,8 @@ def main(): # update desired for role_name in role_names: if role_name not in client_scope_roles_by_name: - if client_scope_id: - module.fail_json(msg=f"Failed to retrive role '{realm}.{client_scope_id}.{role_name}'") + if role_owner_client_id: + module.fail_json(msg=f"Failed to retrive role '{realm}.{role_owner_client_id}.{role_name}'") else: module.fail_json(msg=f"Failed to retrive role '{realm}.{role_name}'") if role_name not in role_mapping_by_name: @@ -253,33 +253,33 @@ def main(): if not result["changed"]: # no changes result["end_state"] = before_role_mapping - result["msg"] = f"No changes required for client role scope {clientid}." + result["msg"] = f"No changes required for client role scope {target_client_id}." elif state == "present": # doing update if module.check_mode: result["end_state"] = desired_role_mapping - elif client_scope_id: + elif role_owner_client_id: result["end_state"] = kc.update_client_role_scope_from_client( - role_mapping_to_manipulate, objClient["id"], objClientScope["id"], realm + role_mapping_to_manipulate, objClient["id"], role_owner_client["id"], realm ) else: result["end_state"] = kc.update_client_role_scope_from_realm( role_mapping_to_manipulate, objClient["id"], realm ) - result["msg"] = f"Client role scope for {clientid} has been updated" + result["msg"] = f"Client role scope for {target_client_id} has been updated" else: # doing delete if module.check_mode: result["end_state"] = desired_role_mapping - elif client_scope_id: + elif role_owner_client_id: result["end_state"] = kc.delete_client_role_scope_from_client( - role_mapping_to_manipulate, objClient["id"], objClientScope["id"], realm + role_mapping_to_manipulate, objClient["id"], role_owner_client["id"], realm ) else: result["end_state"] = kc.delete_client_role_scope_from_realm( role_mapping_to_manipulate, objClient["id"], realm ) - result["msg"] = f"Client role scope for {clientid} has been deleted" + result["msg"] = f"Client role scope for {target_client_id} has been deleted" module.exit_json(**result) diff --git a/plugins/modules/keycloak_client_scope_rolemappings.py b/plugins/modules/keycloak_client_scope_rolemappings.py index a503336..bd8e6fb 100644 --- a/plugins/modules/keycloak_client_scope_rolemappings.py +++ b/plugins/modules/keycloak_client_scope_rolemappings.py @@ -200,7 +200,7 @@ def main(): if client_id: # add client role - client_object = kc.get_client_by_clientid(client_id, realm) + client_object = kc.get_client_by_client_id(client_id, realm) if not client_object: module.fail_json(msg=f"Failed to retrieve client '{realm}.{client_id}'") if client_object["fullScopeAllowed"] and state == "present":