From 68f775842dea9dd41e7316ca216e3c5e73cc28c6 Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Wed, 29 Dec 2021 11:16:55 -0300
Subject: [PATCH] iparole: Add state 'renamed'.

All ansible-freeipa modules which allow object renaming should support
'state: renamed'.

This patch adds suport for the missing state, and fixes cases where a
user could try to rename the object and set its members, which would
fail depending on the operation order.

Fix #566
---
 plugins/modules/iparole.py | 30 +++++++++++++++++++++++-------
 tests/role/test_role.yml   |  4 +++-
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/plugins/modules/iparole.py b/plugins/modules/iparole.py
index dc5b6922..75500d3c 100644
--- a/plugins/modules/iparole.py
+++ b/plugins/modules/iparole.py
@@ -72,7 +72,7 @@ options:
     required: false
   state:
     description: The state to ensure.
-    choices: ["present", "absent"]
+    choices: ["present", "absent", "renamed"]
     default: present
     required: true
 """
@@ -145,9 +145,22 @@ def check_parameters(module):
 
     invalid = []
 
+    if state == "renamed":
+        if action == "member":
+            module.fail_json(
+                msg="Invalid action 'member' with state 'renamed'.")
+        invalid = [
+            "description",
+            "user", "group",
+            "host", "hostgroup",
+            "service",
+            "privilege",
+        ]
+
     if state == "present":
+        invalid = ["rename"]
         if action == "member":
-            invalid.extend(['description', 'rename'])
+            invalid.extend(['description'])
 
     if state == "absent":
         invalid.extend(['description', 'rename'])
@@ -335,17 +348,20 @@ def role_commands_for_name(module, state, action, name):
     """Define commands for the Role module."""
     commands = []
 
-    rename = module.params_get("rename")
-
     res_find = find_role(module, name)
 
+    if state == "renamed":
+        args = gen_args(module)
+        if res_find is None:
+            module.fail_json(msg="No role '%s'" % name)
+        else:
+            commands.append([name, 'role_mod', args])
+
     if state == "present":
         args = gen_args(module)
 
         if action == "role":
             if res_find is None:
-                if rename is not None:
-                    module.fail_json(msg="Cannot `rename` inexistent role.")
                 commands.append([name, 'role_add', args])
                 res_find = {}
             else:
@@ -391,7 +407,7 @@ def create_module():
             action=dict(type="str", default="role",
                         choices=["role", "member"]),
             state=dict(type="str", default="present",
-                       choices=["present", "absent"]),
+                       choices=["present", "absent", "renamed"]),
         ),
         supports_check_mode=True,
         mutually_exclusive=[],
diff --git a/tests/role/test_role.yml b/tests/role/test_role.yml
index 6f9ba90d..5c4f81b9 100644
--- a/tests/role/test_role.yml
+++ b/tests/role/test_role.yml
@@ -36,6 +36,7 @@
       ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: renamerole
       rename: testrole
+      state: renamed
     register: result
     failed_when: not result.changed or result.failed
 
@@ -47,8 +48,9 @@
       ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: renamerole
       rename: testrole
+      state: renamed
     register: result
-    failed_when: result.changed
+    failed_when: result.changed or (not result.failed and "No role 'renamerole'" not in result.msg)
 
   - name: Ensure role has member has privileges.
     iparole:
-- 
GitLab