Blame SOURCES/ansible-freeipa-0.1.8-Add-missing-attributes-to-ipasudorule_rhbz#1788168,1788035,1788024.patch

7d56d3
From dc0a5585fb036fbeba2200564e26c478465afeec Mon Sep 17 00:00:00 2001
7d56d3
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
7d56d3
Date: Tue, 31 Dec 2019 11:04:49 -0300
7d56d3
Subject: [PATCH] Add missing attributes to ipasudorule.
7d56d3
7d56d3
This patch adds the following attributes to ipasudorule:
7d56d3
7d56d3
    - order
7d56d3
    - sudooption
7d56d3
    - runasuser
7d56d3
    - runasgroup
7d56d3
7d56d3
It also fixes behavior of sudocmd assigned to the the sudorule, with the
7d56d3
adittion of the attributes:
7d56d3
7d56d3
    - allow_sudocmds
7d56d3
    - deny_sudocmds
7d56d3
    - allow_sudocmdgroups
7d56d3
    - deny_sudocmdgroups
7d56d3
7d56d3
README-sudorule and tests have been updated to comply with the changes.
7d56d3
---
7d56d3
 README-sudorule.md                            |  14 +-
7d56d3
 ...sure-sudorule-does-not-have-sudooption.yml |  14 +
7d56d3
 .../ensure-sudorule-has-sudooption.yml        |  13 +
7d56d3
 .../ensure-sudorule-is-present-with-order.yml |  12 +
7d56d3
 .../sudorule/ensure-sudorule-is-present.yml   |   2 +
7d56d3
 .../ensure-sudorule-runasuser-is-absent.yml   |  14 +
7d56d3
 .../ensure-sudorule-runasuser-is-present.yml  |  13 +
7d56d3
 .../ensure-sudorule-sudocmd-is-absent.yml     |   7 +-
7d56d3
 .../ensure-sudorule-sudocmd-is-present.yml    |   7 +-
7d56d3
 plugins/modules/ipasudorule.py                | 353 +++++++++++++-----
7d56d3
 tests/sudorule/test_sudorule.yml              | 204 +++++++---
7d56d3
 11 files changed, 504 insertions(+), 149 deletions(-)
7d56d3
 create mode 100644 playbooks/sudorule/ensure-sudorule-does-not-have-sudooption.yml
7d56d3
 create mode 100644 playbooks/sudorule/ensure-sudorule-has-sudooption.yml
7d56d3
 create mode 100644 playbooks/sudorule/ensure-sudorule-is-present-with-order.yml
7d56d3
 create mode 100644 playbooks/sudorule/ensure-sudorule-runasuser-is-absent.yml
7d56d3
 create mode 100644 playbooks/sudorule/ensure-sudorule-runasuser-is-present.yml
7d56d3
7d56d3
diff --git a/README-sudorule.md b/README-sudorule.md
7d56d3
index bb3498b..50c73ad 100644
7d56d3
--- a/README-sudorule.md
7d56d3
+++ b/README-sudorule.md
7d56d3
@@ -68,7 +68,7 @@ Example playbook to make sure sudocmds are present in Sudo Rule:
7d56d3
   - ipasudorule:
7d56d3
       ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
+      allow_sudocmd:
7d56d3
       - /sbin/ifconfig
7d56d3
       action: member
7d56d3
 ```
7d56d3
@@ -87,7 +87,7 @@ Example playbook to make sure sudocmds are not present in Sudo Rule:
7d56d3
   - ipasudorule:
7d56d3
       ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
+      allow_sudocmd:
7d56d3
       - /sbin/ifconfig
7d56d3
       action: member
7d56d3
       state: absent
7d56d3
@@ -130,8 +130,14 @@ Variable | Description | Required
7d56d3
 `hostgroup` | List of host group name strings assigned to this sudorule. | no
7d56d3
 `user` | List of user name strings assigned to this sudorule. | no
7d56d3
 `group` | List of user group name strings assigned to this sudorule. | no
7d56d3
-`cmd` | List of sudocmd name strings assigned to this sudorule. | no
7d56d3
-`cmdgroup` | List of sudocmd group name strings assigned wto this sudorule. | no
7d56d3
+`allow_sudocmd` | List of sudocmd name strings assigned to the allow group of this sudorule. | no
7d56d3
+`deny_sudocmd` | List of sudocmd name strings assigned to the deny group of this sudorule. | no
7d56d3
+`allow_sudocmdgroup` | List of sudocmd groups name strings assigned to the allow group of this sudorule. | no
7d56d3
+`deny_sudocmdgroup` | List of sudocmd groups name strings assigned to the deny group of this sudorule. | no
7d56d3
+`sudooption` \| `option` | List of options to the sudorule | no
7d56d3
+`order` | Integer to order the sudorule | no
7d56d3
+`runasuser` | List of users for Sudo to execute as. | no
7d56d3
+`runasgroup` | List of groups for Sudo to execute as. | no
7d56d3
 `action` | Work on sudorule or member level. It can be on of `member` or `sudorule` and defaults to `sudorule`. | no
7d56d3
 `state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | no
7d56d3
 
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-does-not-have-sudooption.yml b/playbooks/sudorule/ensure-sudorule-does-not-have-sudooption.yml
7d56d3
new file mode 100644
7d56d3
index 0000000..1307044
7d56d3
--- /dev/null
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-does-not-have-sudooption.yml
7d56d3
@@ -0,0 +1,14 @@
7d56d3
+---
7d56d3
+- name: Tests
7d56d3
+  hosts: ipaserver
7d56d3
+  become: true
7d56d3
+  gather_facts: false
7d56d3
+
7d56d3
+  tasks:
7d56d3
+  # Ensure sudooption is absent in sudorule
7d56d3
+  - ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      sudooption: "!root"
7d56d3
+      action: member
7d56d3
+      state: absent
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-has-sudooption.yml b/playbooks/sudorule/ensure-sudorule-has-sudooption.yml
7d56d3
new file mode 100644
7d56d3
index 0000000..1f32b9a
7d56d3
--- /dev/null
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-has-sudooption.yml
7d56d3
@@ -0,0 +1,13 @@
7d56d3
+---
7d56d3
+- name: Tests
7d56d3
+  hosts: ipaserver
7d56d3
+  become: true
7d56d3
+  gather_facts: false
7d56d3
+
7d56d3
+  tasks:
7d56d3
+  # Ensure sudooption is present in sudorule
7d56d3
+  - ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      sudooption: "!root"
7d56d3
+      action: member
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-is-present-with-order.yml b/playbooks/sudorule/ensure-sudorule-is-present-with-order.yml
7d56d3
new file mode 100644
7d56d3
index 0000000..9a3c2b2
7d56d3
--- /dev/null
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-is-present-with-order.yml
7d56d3
@@ -0,0 +1,12 @@
7d56d3
+---
7d56d3
+- name: Tests
7d56d3
+  hosts: ipaserver
7d56d3
+  become: true
7d56d3
+  gather_facts: false
7d56d3
+
7d56d3
+  tasks:
7d56d3
+  # Ensure sudorule is present with the given order.
7d56d3
+  - ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      order: 2
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-is-present.yml b/playbooks/sudorule/ensure-sudorule-is-present.yml
7d56d3
index 5b8f32b..89041af 100644
7d56d3
--- a/playbooks/sudorule/ensure-sudorule-is-present.yml
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-is-present.yml
7d56d3
@@ -9,4 +9,6 @@
7d56d3
       ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       description: A test sudo rule.
7d56d3
+      allow_sudocmd: /bin/ls
7d56d3
+      deny_sudocmd: /bin/vim
7d56d3
       state: present
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-runasuser-is-absent.yml b/playbooks/sudorule/ensure-sudorule-runasuser-is-absent.yml
7d56d3
new file mode 100644
7d56d3
index 0000000..56612f1
7d56d3
--- /dev/null
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-runasuser-is-absent.yml
7d56d3
@@ -0,0 +1,14 @@
7d56d3
+---
7d56d3
+- name: Tests
7d56d3
+  hosts: ipaserver
7d56d3
+  become: true
7d56d3
+  gather_facts: false
7d56d3
+
7d56d3
+  tasks:
7d56d3
+  # Ensure sudorule is present with the given order.
7d56d3
+  - ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      runasuser: admin
7d56d3
+      action: member
7d56d3
+      state: absent
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-runasuser-is-present.yml b/playbooks/sudorule/ensure-sudorule-runasuser-is-present.yml
7d56d3
new file mode 100644
7d56d3
index 0000000..8af49b9
7d56d3
--- /dev/null
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-runasuser-is-present.yml
7d56d3
@@ -0,0 +1,13 @@
7d56d3
+---
7d56d3
+- name: Tests
7d56d3
+  hosts: ipaserver
7d56d3
+  become: true
7d56d3
+  gather_facts: false
7d56d3
+
7d56d3
+  tasks:
7d56d3
+  # Ensure sudorule is present with the given order.
7d56d3
+  - ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      runasuser: admin
7d56d3
+      action: member
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-sudocmd-is-absent.yml b/playbooks/sudorule/ensure-sudorule-sudocmd-is-absent.yml
7d56d3
index 942d0b5..328242a 100644
7d56d3
--- a/playbooks/sudorule/ensure-sudorule-sudocmd-is-absent.yml
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-sudocmd-is-absent.yml
7d56d3
@@ -8,8 +8,13 @@
7d56d3
   - ipasudorule:
7d56d3
       ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
+      allow_sudocmd:
7d56d3
       - /sbin/ifconfig
7d56d3
+      deny_sudocmd:
7d56d3
       - /usr/bin/vim
7d56d3
+      allow_sudocmdgroup:
7d56d3
+      - devops
7d56d3
+      deny_sudocmdgroup:
7d56d3
+      - users
7d56d3
       action: member
7d56d3
       state: absent
7d56d3
diff --git a/playbooks/sudorule/ensure-sudorule-sudocmd-is-present.yml b/playbooks/sudorule/ensure-sudorule-sudocmd-is-present.yml
7d56d3
index 61fcbb0..55acd61 100644
7d56d3
--- a/playbooks/sudorule/ensure-sudorule-sudocmd-is-present.yml
7d56d3
+++ b/playbooks/sudorule/ensure-sudorule-sudocmd-is-present.yml
7d56d3
@@ -8,7 +8,12 @@
7d56d3
   - ipasudorule:
7d56d3
       ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
+      allow_sudocmd:
7d56d3
       - /sbin/ifconfig
7d56d3
+      deny_sudocmd:
7d56d3
       - /usr/bin/vim
7d56d3
+      allow_sudocmdgroup:
7d56d3
+      - devops
7d56d3
+      deny_sudocmdgroup:
7d56d3
+      - users
7d56d3
       action: member
7d56d3
diff --git a/plugins/modules/ipasudorule.py b/plugins/modules/ipasudorule.py
7d56d3
index c21f247..285a946 100644
7d56d3
--- a/plugins/modules/ipasudorule.py
7d56d3
+++ b/plugins/modules/ipasudorule.py
7d56d3
@@ -79,18 +79,43 @@
7d56d3
     description: Host category the sudo rule applies to.
7d56d3
     required: false
7d56d3
     choices: ["all"]
7d56d3
-  cmd:
7d56d3
-    description: List of sudocmds assigned to this sudorule.
7d56d3
+  allow_sudocmd:
7d56d3
+    description: List of allowed sudocmds assigned to this sudorule.
7d56d3
     required: false
7d56d3
     type: list
7d56d3
-  cmdgroup:
7d56d3
-    description: List of sudocmd groups assigned to this sudorule.
7d56d3
+  allow_sudocmdgroup:
7d56d3
+    description: List of allowed sudocmd groups assigned to this sudorule.
7d56d3
+    required: false
7d56d3
+    type: list
7d56d3
+  deny_sudocmd:
7d56d3
+    description: List of denied sudocmds assigned to this sudorule.
7d56d3
+    required: false
7d56d3
+    type: list
7d56d3
+  deny_sudocmdgroup:
7d56d3
+    description: List of denied sudocmd groups assigned to this sudorule.
7d56d3
     required: false
7d56d3
     type: list
7d56d3
   cmdcategory:
7d56d3
-    description: Cammand category the sudo rule applies to
7d56d3
+    description: Command category the sudo rule applies to
7d56d3
     required: false
7d56d3
     choices: ["all"]
7d56d3
+  order:
7d56d3
+    description: Order to apply this rule.
7d56d3
+    required: false
7d56d3
+    type: int
7d56d3
+  sudooption:
7d56d3
+    description:
7d56d3
+    required: false
7d56d3
+    type: list
7d56d3
+    aliases: ["options"]
7d56d3
+  runasuser:
7d56d3
+    description: List of users for Sudo to execute as.
7d56d3
+    required: false
7d56d3
+    type: list
7d56d3
+  runasgroup:
7d56d3
+    description: List of groups for Sudo to execute as.
7d56d3
+    required: false
7d56d3
+    type: list
7d56d3
   action:
7d56d3
     description: Work on sudorule or member level
7d56d3
     default: sudorule
7d56d3
@@ -111,13 +136,13 @@
7d56d3
 
7d56d3
 # Ensure sudocmd is present in Sudo Rule
7d56d3
 - ipasudorule:
7d56d3
-  ipaadmin_password: pass1234
7d56d3
-  name: testrule1
7d56d3
-  cmd:
7d56d3
-  - /sbin/ifconfig
7d56d3
-  - /usr/bin/vim
7d56d3
-  action: member
7d56d3
-  state: absent
7d56d3
+    ipaadmin_password: pass1234
7d56d3
+    name: testrule1
7d56d3
+    allow_sudocmd:
7d56d3
+      - /sbin/ifconfig
7d56d3
+      - /usr/bin/vim
7d56d3
+    action: member
7d56d3
+    state: absent
7d56d3
 
7d56d3
 # Ensure host server is present in Sudo Rule
7d56d3
 - ipasudorule:
7d56d3
@@ -160,7 +185,7 @@
7d56d3
 from ansible.module_utils.basic import AnsibleModule
7d56d3
 from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
7d56d3
     temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
7d56d3
-    module_params_get
7d56d3
+    module_params_get, gen_add_del_lists
7d56d3
 
7d56d3
 
7d56d3
 def find_sudorule(module, name):
7d56d3
@@ -180,14 +205,26 @@ def find_sudorule(module, name):
7d56d3
         return None
7d56d3
 
7d56d3
 
7d56d3
-def gen_args(ansible_module):
7d56d3
-    arglist = ['description', 'usercategory', 'hostcategory', 'cmdcategory',
7d56d3
-               'runasusercategory', 'runasgroupcategory', 'nomembers']
7d56d3
+def gen_args(description, usercat, hostcat, cmdcat, runasusercat,
7d56d3
+             runasgroupcat, order, nomembers):
7d56d3
     _args = {}
7d56d3
-    for arg in arglist:
7d56d3
-        value = module_params_get(ansible_module, arg)
7d56d3
-        if value is not None:
7d56d3
-            _args[arg] = value
7d56d3
+
7d56d3
+    if description is not None:
7d56d3
+        _args['description'] = description
7d56d3
+    if usercat is not None:
7d56d3
+        _args['usercategory'] = usercat
7d56d3
+    if hostcat is not None:
7d56d3
+        _args['hostcategory'] = hostcat
7d56d3
+    if cmdcat is not None:
7d56d3
+        _args['cmdcategory'] = cmdcat
7d56d3
+    if runasusercat is not None:
7d56d3
+        _args['ipasudorunasusercategory'] = runasusercat
7d56d3
+    if runasgroupcat is not None:
7d56d3
+        _args['ipasudorunasgroupcategory'] = runasgroupcat
7d56d3
+    if order is not None:
7d56d3
+        _args['sudoorder'] = order
7d56d3
+    if nomembers is not None:
7d56d3
+        _args['nomembers'] = nomembers
7d56d3
 
7d56d3
     return _args
7d56d3
 
7d56d3
@@ -212,13 +249,21 @@ def main():
7d56d3
             hostgroup=dict(required=False, type='list', default=None),
7d56d3
             user=dict(required=False, type='list', default=None),
7d56d3
             group=dict(required=False, type='list', default=None),
7d56d3
-            cmd=dict(required=False, type="list", default=None),
7d56d3
+            allow_sudocmd=dict(required=False, type="list", default=None),
7d56d3
+            deny_sudocmd=dict(required=False, type="list", default=None),
7d56d3
+            allow_sudocmdgroup=dict(required=False, type="list", default=None),
7d56d3
+            deny_sudocmdgroup=dict(required=False, type="list", default=None),
7d56d3
             cmdcategory=dict(required=False, type="str", default=None,
7d56d3
                              choices=["all"]),
7d56d3
             runasusercategory=dict(required=False, type="str", default=None,
7d56d3
                                    choices=["all"]),
7d56d3
             runasgroupcategory=dict(required=False, type="str", default=None,
7d56d3
                                     choices=["all"]),
7d56d3
+            runasuser=dict(required=False, type="list", default=None),
7d56d3
+            runasgroup=dict(required=False, type="list", default=None),
7d56d3
+            order=dict(type="int", required=False, aliases=['sudoorder']),
7d56d3
+            sudooption=dict(required=False, type='list', default=None,
7d56d3
+                            aliases=["options"]),
7d56d3
             action=dict(type="str", default="sudorule",
7d56d3
                         choices=["member", "sudorule"]),
7d56d3
             # state
7d56d3
@@ -256,8 +301,16 @@ def main():
7d56d3
     hostgroup = module_params_get(ansible_module, "hostgroup")
7d56d3
     user = module_params_get(ansible_module, "user")
7d56d3
     group = module_params_get(ansible_module, "group")
7d56d3
-    cmd = module_params_get(ansible_module, 'cmd')
7d56d3
-    cmdgroup = module_params_get(ansible_module, 'cmdgroup')
7d56d3
+    allow_sudocmd = module_params_get(ansible_module, 'allow_sudocmd')
7d56d3
+    allow_sudocmdgroup = module_params_get(ansible_module,
7d56d3
+                                           'allow_sudocmdgroup')
7d56d3
+    deny_sudocmd = module_params_get(ansible_module, 'deny_sudocmd')
7d56d3
+    deny_sudocmdgroup = module_params_get(ansible_module,
7d56d3
+                                          'deny_sudocmdgroup')
7d56d3
+    sudooption = module_params_get(ansible_module, "sudooption")
7d56d3
+    order = module_params_get(ansible_module, "order")
7d56d3
+    runasuser = module_params_get(ansible_module, "runasuser")
7d56d3
+    runasgroup = module_params_get(ansible_module, "runasgroup")
7d56d3
     action = module_params_get(ansible_module, "action")
7d56d3
 
7d56d3
     # state
7d56d3
@@ -272,28 +325,30 @@ def main():
7d56d3
         if action == "member":
7d56d3
             invalid = ["description", "usercategory", "hostcategory",
7d56d3
                        "cmdcategory", "runasusercategory",
7d56d3
-                       "runasgroupcategory", "nomembers"]
7d56d3
+                       "runasgroupcategory", "order", "nomembers"]
7d56d3
 
7d56d3
-            for x in invalid:
7d56d3
-                if x in vars() and vars()[x] is not None:
7d56d3
+            for arg in invalid:
7d56d3
+                if arg in vars() and vars()[arg] is not None:
7d56d3
                     ansible_module.fail_json(
7d56d3
                         msg="Argument '%s' can not be used with action "
7d56d3
-                        "'%s'" % (x, action))
7d56d3
+                        "'%s'" % (arg, action))
7d56d3
 
7d56d3
     elif state == "absent":
7d56d3
         if len(names) < 1:
7d56d3
             ansible_module.fail_json(msg="No name given.")
7d56d3
         invalid = ["description", "usercategory", "hostcategory",
7d56d3
                    "cmdcategory", "runasusercategory",
7d56d3
-                   "runasgroupcategory", "nomembers"]
7d56d3
+                   "runasgroupcategory", "nomembers", "order"]
7d56d3
         if action == "sudorule":
7d56d3
             invalid.extend(["host", "hostgroup", "user", "group",
7d56d3
-                            "cmd", "cmdgroup"])
7d56d3
-        for x in invalid:
7d56d3
-            if vars()[x] is not None:
7d56d3
+                            "runasuser", "runasgroup", "allow_sudocmd",
7d56d3
+                            "allow_sudocmdgroup", "deny_sudocmd",
7d56d3
+                            "deny_sudocmdgroup", "sudooption"])
7d56d3
+        for arg in invalid:
7d56d3
+            if vars()[arg] is not None:
7d56d3
                 ansible_module.fail_json(
7d56d3
                     msg="Argument '%s' can not be used with state '%s'" %
7d56d3
-                    (x, state))
7d56d3
+                    (arg, state))
7d56d3
 
7d56d3
     elif state in ["enabled", "disabled"]:
7d56d3
         if len(names) < 1:
7d56d3
@@ -305,12 +360,14 @@ def main():
7d56d3
         invalid = ["description", "usercategory", "hostcategory",
7d56d3
                    "cmdcategory", "runasusercategory", "runasgroupcategory",
7d56d3
                    "nomembers", "nomembers", "host", "hostgroup",
7d56d3
-                   "user", "group", "cmd", "cmdgroup"]
7d56d3
-        for x in invalid:
7d56d3
-            if vars()[x] is not None:
7d56d3
+                   "user", "group", "allow_sudocmd", "allow_sudocmdgroup",
7d56d3
+                   "deny_sudocmd", "deny_sudocmdgroup", "runasuser",
7d56d3
+                   "runasgroup", "order", "sudooption"]
7d56d3
+        for arg in invalid:
7d56d3
+            if vars()[arg] is not None:
7d56d3
                 ansible_module.fail_json(
7d56d3
                     msg="Argument '%s' can not be used with state '%s'" %
7d56d3
-                    (x, state))
7d56d3
+                    (arg, state))
7d56d3
     else:
7d56d3
         ansible_module.fail_json(msg="Invalid state '%s'" % state)
7d56d3
 
7d56d3
@@ -335,7 +392,9 @@ def main():
7d56d3
             # Create command
7d56d3
             if state == "present":
7d56d3
                 # Generate args
7d56d3
-                args = gen_args(ansible_module)
7d56d3
+                args = gen_args(description, usercategory, hostcategory,
7d56d3
+                                cmdcategory, runasusercategory,
7d56d3
+                                runasgroupcategory, order, nomembers)
7d56d3
                 if action == "sudorule":
7d56d3
                     # Found the sudorule
7d56d3
                     if res_find is not None:
7d56d3
@@ -351,44 +410,42 @@ def main():
7d56d3
                         res_find = {}
7d56d3
 
7d56d3
                     # Generate addition and removal lists
7d56d3
-                    host_add = list(
7d56d3
-                        set(host or []) -
7d56d3
-                        set(res_find.get("member_host", [])))
7d56d3
-                    host_del = list(
7d56d3
-                        set(res_find.get("member_host", [])) -
7d56d3
-                        set(host or []))
7d56d3
-                    hostgroup_add = list(
7d56d3
-                        set(hostgroup or []) -
7d56d3
-                        set(res_find.get("member_hostgroup", [])))
7d56d3
-                    hostgroup_del = list(
7d56d3
-                        set(res_find.get("member_hostgroup", [])) -
7d56d3
-                        set(hostgroup or []))
7d56d3
-
7d56d3
-                    user_add = list(
7d56d3
-                        set(user or []) -
7d56d3
-                        set(res_find.get("member_user", [])))
7d56d3
-                    user_del = list(
7d56d3
-                        set(res_find.get("member_user", [])) -
7d56d3
-                        set(user or []))
7d56d3
-                    group_add = list(
7d56d3
-                        set(group or []) -
7d56d3
-                        set(res_find.get("member_group", [])))
7d56d3
-                    group_del = list(
7d56d3
-                        set(res_find.get("member_group", [])) -
7d56d3
-                        set(group or []))
7d56d3
-
7d56d3
-                    cmd_add = list(
7d56d3
-                        set(cmd or []) -
7d56d3
-                        set(res_find.get("member_cmd", [])))
7d56d3
-                    cmd_del = list(
7d56d3
-                        set(res_find.get("member_cmd", [])) -
7d56d3
-                        set(cmd or []))
7d56d3
-                    cmdgroup_add = list(
7d56d3
-                        set(cmdgroup or []) -
7d56d3
-                        set(res_find.get("member_cmdgroup", [])))
7d56d3
-                    cmdgroup_del = list(
7d56d3
-                        set(res_find.get("member_cmdgroup", [])) -
7d56d3
-                        set(cmdgroup or []))
7d56d3
+                    host_add, host_del = gen_add_del_lists(
7d56d3
+                        host, res_find.get('member_host', []))
7d56d3
+
7d56d3
+                    hostgroup_add, hostgroup_del = gen_add_del_lists(
7d56d3
+                        hostgroup, res_find.get('member_hostgroup', []))
7d56d3
+
7d56d3
+                    user_add, user_del = gen_add_del_lists(
7d56d3
+                        user, res_find.get('member_user', []))
7d56d3
+
7d56d3
+                    group_add, group_del = gen_add_del_lists(
7d56d3
+                        group, res_find.get('member_group', []))
7d56d3
+
7d56d3
+                    allow_cmd_add, allow_cmd_del = gen_add_del_lists(
7d56d3
+                        allow_sudocmd,
7d56d3
+                        res_find.get('memberallowcmd_sudocmd', []))
7d56d3
+
7d56d3
+                    allow_cmdgroup_add, allow_cmdgroup_del = gen_add_del_lists(
7d56d3
+                        allow_sudocmdgroup,
7d56d3
+                        res_find.get('memberallowcmd_sudocmdgroup', []))
7d56d3
+
7d56d3
+                    deny_cmd_add, deny_cmd_del = gen_add_del_lists(
7d56d3
+                        deny_sudocmd,
7d56d3
+                        res_find.get('memberdenycmd_sudocmd', []))
7d56d3
+
7d56d3
+                    deny_cmdgroup_add, deny_cmdgroup_del = gen_add_del_lists(
7d56d3
+                        deny_sudocmdgroup,
7d56d3
+                        res_find.get('memberdenycmd_sudocmdgroup', []))
7d56d3
+
7d56d3
+                    sudooption_add, sudooption_del = gen_add_del_lists(
7d56d3
+                        sudooption, res_find.get('ipasudoopt', []))
7d56d3
+
7d56d3
+                    runasuser_add, runasuser_del = gen_add_del_lists(
7d56d3
+                        runasuser, res_find.get('ipasudorunas_user', []))
7d56d3
+
7d56d3
+                    runasgroup_add, runasgroup_del = gen_add_del_lists(
7d56d3
+                        runasgroup, res_find.get('ipasudorunas_group', []))
7d56d3
 
7d56d3
                     # Add hosts and hostgroups
7d56d3
                     if len(host_add) > 0 or len(hostgroup_add) > 0:
7d56d3
@@ -420,20 +477,59 @@ def main():
7d56d3
                                              "group": group_del,
7d56d3
                                          }])
7d56d3
 
7d56d3
-                    # Add commands
7d56d3
-                    if len(cmd_add) > 0 or len(cmdgroup_add) > 0:
7d56d3
+                    # Add commands allowed
7d56d3
+                    if len(allow_cmd_add) > 0 or len(allow_cmdgroup_add) > 0:
7d56d3
                         commands.append([name, "sudorule_add_allow_command",
7d56d3
-                                         {
7d56d3
-                                             "sudocmd": cmd_add,
7d56d3
-                                             "sudocmdgroup": cmdgroup_add,
7d56d3
-                                         }])
7d56d3
-
7d56d3
-                    if len(cmd_del) > 0 or len(cmdgroup_del) > 0:
7d56d3
+                                         {"sudocmd": allow_cmd_add,
7d56d3
+                                          "sudocmdgroup": allow_cmdgroup_add,
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    if len(allow_cmd_del) > 0 or len(allow_cmdgroup_del) > 0:
7d56d3
+                        commands.append([name, "sudorule_remove_allow_command",
7d56d3
+                                         {"sudocmd": allow_cmd_del,
7d56d3
+                                          "sudocmdgroup": allow_cmdgroup_del
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    # Add commands denied
7d56d3
+                    if len(deny_cmd_add) > 0 or len(deny_cmdgroup_add) > 0:
7d56d3
                         commands.append([name, "sudorule_add_deny_command",
7d56d3
-                                         {
7d56d3
-                                             "sudocmd": cmd_del,
7d56d3
-                                             "sudocmdgroup": cmdgroup_del
7d56d3
-                                         }])
7d56d3
+                                         {"sudocmd": deny_cmd_add,
7d56d3
+                                          "sudocmdgroup": deny_cmdgroup_add,
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    if len(deny_cmd_del) > 0 or len(deny_cmdgroup_del) > 0:
7d56d3
+                        commands.append([name, "sudorule_remove_deny_command",
7d56d3
+                                         {"sudocmd": deny_cmd_del,
7d56d3
+                                          "sudocmdgroup": deny_cmdgroup_del
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    # Add RunAS Users
7d56d3
+                    if len(runasuser_add) > 0:
7d56d3
+                        commands.append([name, "sudorule_add_runasuser",
7d56d3
+                                         {"user": runasuser_add}])
7d56d3
+                    # Remove RunAS Users
7d56d3
+                    if len(runasuser_del) > 0:
7d56d3
+                        commands.append([name, "sudorule_remove_runasuser",
7d56d3
+                                         {"user": runasuser_del}])
7d56d3
+
7d56d3
+                    # Add RunAS Groups
7d56d3
+                    if len(runasgroup_add) > 0:
7d56d3
+                        commands.append([name, "sudorule_add_runasgroup",
7d56d3
+                                         {"group": runasgroup_add}])
7d56d3
+                    # Remove RunAS Groups
7d56d3
+                    if len(runasgroup_del) > 0:
7d56d3
+                        commands.append([name, "sudorule_remove_runasgroup",
7d56d3
+                                         {"group": runasgroup_del}])
7d56d3
+
7d56d3
+                    # Add sudo options
7d56d3
+                    for sudoopt in sudooption_add:
7d56d3
+                        commands.append([name, "sudorule_add_option",
7d56d3
+                                         {"ipasudoopt": sudoopt}])
7d56d3
+
7d56d3
+                    # Remove sudo options
7d56d3
+                    for sudoopt in sudooption_del:
7d56d3
+                        commands.append([name, "sudorule_remove_option",
7d56d3
+                                         {"ipasudoopt": sudoopt}])
7d56d3
 
7d56d3
                 elif action == "member":
7d56d3
                     if res_find is None:
7d56d3
@@ -456,11 +552,38 @@ def main():
7d56d3
                                          }])
7d56d3
 
7d56d3
                     # Add commands
7d56d3
-                    if cmd is not None:
7d56d3
+                    if allow_sudocmd is not None \
7d56d3
+                       or allow_sudocmdgroup is not None:
7d56d3
                         commands.append([name, "sudorule_add_allow_command",
7d56d3
-                                         {
7d56d3
-                                             "sudocmd": cmd,
7d56d3
-                                         }])
7d56d3
+                                         {"sudocmd": allow_sudocmd,
7d56d3
+                                          "sudocmdgroup": allow_sudocmdgroup,
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    # Add commands
7d56d3
+                    if deny_sudocmd is not None \
7d56d3
+                       or deny_sudocmdgroup is not None:
7d56d3
+                        commands.append([name, "sudorule_add_deny_command",
7d56d3
+                                         {"sudocmd": deny_sudocmd,
7d56d3
+                                          "sudocmdgroup": deny_sudocmdgroup,
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    # Add RunAS Users
7d56d3
+                    if runasuser is not None:
7d56d3
+                        commands.append([name, "sudorule_add_runasuser",
7d56d3
+                                         {"user": runasuser}])
7d56d3
+
7d56d3
+                    # Add RunAS Groups
7d56d3
+                    if runasgroup is not None:
7d56d3
+                        commands.append([name, "sudorule_add_runasgroup",
7d56d3
+                                         {"group": runasgroup}])
7d56d3
+
7d56d3
+                    # Add options
7d56d3
+                    if sudooption is not None:
7d56d3
+                        existing_opts = res_find.get('ipasudoopt', [])
7d56d3
+                        for sudoopt in sudooption:
7d56d3
+                            if sudoopt not in existing_opts:
7d56d3
+                                commands.append([name, "sudorule_add_option",
7d56d3
+                                                 {"ipasudoopt": sudoopt}])
7d56d3
 
7d56d3
             elif state == "absent":
7d56d3
                 if action == "sudorule":
7d56d3
@@ -487,12 +610,40 @@ def main():
7d56d3
                                              "group": group,
7d56d3
                                          }])
7d56d3
 
7d56d3
-                    # Remove commands
7d56d3
-                    if cmd is not None:
7d56d3
-                        commands.append([name, "sudorule_add_deny_command",
7d56d3
-                                         {
7d56d3
-                                             "sudocmd": cmd,
7d56d3
-                                         }])
7d56d3
+                    # Remove allow commands
7d56d3
+                    if allow_sudocmd is not None \
7d56d3
+                       or allow_sudocmdgroup is not None:
7d56d3
+                        commands.append([name, "sudorule_remove_allow_command",
7d56d3
+                                         {"sudocmd": allow_sudocmd,
7d56d3
+                                          "sudocmdgroup": allow_sudocmdgroup
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    # Remove deny commands
7d56d3
+                    if deny_sudocmd is not None \
7d56d3
+                       or deny_sudocmdgroup is not None:
7d56d3
+                        commands.append([name, "sudorule_remove_deny_command",
7d56d3
+                                         {"sudocmd": deny_sudocmd,
7d56d3
+                                          "sudocmdgroup": deny_sudocmdgroup
7d56d3
+                                          }])
7d56d3
+
7d56d3
+                    # Remove RunAS Users
7d56d3
+                    if runasuser is not None:
7d56d3
+                        commands.append([name, "sudorule_remove_runasuser",
7d56d3
+                                         {"user": runasuser}])
7d56d3
+
7d56d3
+                    # Remove RunAS Groups
7d56d3
+                    if runasgroup is not None:
7d56d3
+                        commands.append([name, "sudorule_remove_runasgroup",
7d56d3
+                                         {"group": runasgroup}])
7d56d3
+
7d56d3
+                    # Remove options
7d56d3
+                    if sudooption is not None:
7d56d3
+                        existing_opts = res_find.get('ipasudoopt', [])
7d56d3
+                        for sudoopt in sudooption:
7d56d3
+                            if sudoopt in existing_opts:
7d56d3
+                                commands.append([name,
7d56d3
+                                                 "sudorule_remove_option",
7d56d3
+                                                 {"ipasudoopt": sudoopt}])
7d56d3
 
7d56d3
             elif state == "enabled":
7d56d3
                 if res_find is None:
7d56d3
@@ -530,9 +681,9 @@ def main():
7d56d3
                         changed = True
7d56d3
                 else:
7d56d3
                     changed = True
7d56d3
-            except Exception as e:
7d56d3
+            except Exception as ex:
7d56d3
                 ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
7d56d3
-                                                             str(e)))
7d56d3
+                                                             str(ex)))
7d56d3
             # Get all errors
7d56d3
             # All "already a member" and "not a member" failures in the
7d56d3
             # result are ignored. All others are reported.
7d56d3
@@ -549,8 +700,8 @@ def main():
7d56d3
         if len(errors) > 0:
7d56d3
             ansible_module.fail_json(msg=", ".join(errors))
7d56d3
 
7d56d3
-    except Exception as e:
7d56d3
-        ansible_module.fail_json(msg=str(e))
7d56d3
+    except Exception as ex:
7d56d3
+        ansible_module.fail_json(msg=str(ex))
7d56d3
 
7d56d3
     finally:
7d56d3
         temp_kdestroy(ccache_dir, ccache_name)
7d56d3
diff --git a/tests/sudorule/test_sudorule.yml b/tests/sudorule/test_sudorule.yml
7d56d3
index 88ed90a..25090bb 100644
7d56d3
--- a/tests/sudorule/test_sudorule.yml
7d56d3
+++ b/tests/sudorule/test_sudorule.yml
7d56d3
@@ -16,15 +16,22 @@
7d56d3
 
7d56d3
   - name: Ensure some sudocmds are available
7d56d3
     ipasudocmd:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name:
7d56d3
           - /sbin/ifconfig
7d56d3
           - /usr/bin/vim
7d56d3
       state: present
7d56d3
 
7d56d3
+  - name: Ensure sudocmdgroup is available
7d56d3
+    ipasudocmdgroup:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: test_sudorule
7d56d3
+      sudocmd: /usr/bin/vim
7d56d3
+      state: present
7d56d3
+
7d56d3
   - name: Ensure sudorules are absent
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name:
7d56d3
       - testrule1
7d56d3
       - allusers
7d56d3
@@ -34,21 +41,21 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is present
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
     register: result
7d56d3
     failed_when: not result.changed
7d56d3
 
7d56d3
   - name: Ensure sudorule is present again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
     register: result
7d56d3
     failed_when: result.changed
7d56d3
 
7d56d3
   - name: Ensure sudorule is present, runAsUserCategory.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       runAsUserCategory: all
7d56d3
     register: result
7d56d3
@@ -56,7 +63,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is present, with usercategory 'all'
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allusers
7d56d3
       usercategory: all
7d56d3
     register: result
7d56d3
@@ -64,7 +71,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is present, with usercategory 'all', again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allusers
7d56d3
       usercategory: all
7d56d3
     register: result
7d56d3
@@ -72,7 +79,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is present, with hostategory 'all'
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allhosts
7d56d3
       hostcategory: all
7d56d3
     register: result
7d56d3
@@ -80,7 +87,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is present, with hostategory 'all', again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allhosts
7d56d3
       hostcategory: all
7d56d3
     register: result
7d56d3
@@ -88,13 +95,13 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is disabled
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       state: disabled
7d56d3
 
7d56d3
   - name: Ensure sudorule is disabled, again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       state: disabled
7d56d3
     register: result
7d56d3
@@ -102,7 +109,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is enabled
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       state: enabled
7d56d3
     register: result
7d56d3
@@ -110,37 +117,77 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is enabled, again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       state: enabled
7d56d3
     register: result
7d56d3
     failed_when: result.changed
7d56d3
 
7d56d3
-  - name: Ensure sudorule is present and some sudocmd are a member of it.
7d56d3
+  - name: Ensure sudorule is present and some sudocmd are allowed.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
+      allow_sudocmd:
7d56d3
       - /sbin/ifconfig
7d56d3
-      - /usr/bin/vim
7d56d3
       action: member
7d56d3
     register: result
7d56d3
     failed_when: not result.changed
7d56d3
 
7d56d3
-  - name: Ensure sudorule is present and some sudocmd are a member of it, again.
7d56d3
+  - name: Ensure sudorule is present and some sudocmd are allowed, again.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
+      allow_sudocmd:
7d56d3
       - /sbin/ifconfig
7d56d3
+      action: member
7d56d3
+    register: result
7d56d3
+    failed_when: result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present and some sudocmd are denyed.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      deny_sudocmd:
7d56d3
+      - /usr/bin/vim
7d56d3
+      action: member
7d56d3
+    register: result
7d56d3
+    failed_when: not result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present and some sudocmd are denyed, again.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      deny_sudocmd:
7d56d3
       - /usr/bin/vim
7d56d3
       action: member
7d56d3
     register: result
7d56d3
     failed_when: result.changed
7d56d3
 
7d56d3
+  - name: Ensure sudorule is present and, sudocmds are absent.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      allow_sudocmd: /sbin/ifconfig
7d56d3
+      deny_sudocmd: /usr/bin/vim
7d56d3
+      action: member
7d56d3
+      state: absent
7d56d3
+    register: result
7d56d3
+    failed_when: not result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present and, sudocmds are absent, again.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      allow_sudocmd: /sbin/ifconfig
7d56d3
+      deny_sudocmd: /usr/bin/vim
7d56d3
+      action: member
7d56d3
+      state: absent
7d56d3
+    register: result
7d56d3
+    failed_when: result.changed
7d56d3
+
7d56d3
   - name: Ensure sudorule is present with cmdcategory 'all'.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allcommands
7d56d3
       cmdcategory: all
7d56d3
     register: result
7d56d3
@@ -148,7 +195,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is present with cmdcategory 'all', again.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allcommands
7d56d3
       cmdcategory: all
7d56d3
     register: result
7d56d3
@@ -156,7 +203,7 @@
7d56d3
 
7d56d3
   - name: Ensure host "{{ groups.ipaserver[0] }}" is present in sudorule.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       host: "{{ groups.ipaserver[0] }}"
7d56d3
       action: member
7d56d3
@@ -165,7 +212,7 @@
7d56d3
 
7d56d3
   - name: Ensure host "{{ groups.ipaserver[0] }}" is present in sudorule, again.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       host: "{{ groups.ipaserver[0] }}"
7d56d3
       action: member
7d56d3
@@ -190,25 +237,77 @@
7d56d3
     register: result
7d56d3
     failed_when: result.changed
7d56d3
 
7d56d3
-  - name: Ensure sudorule sudocmds are absent
7d56d3
+  - name: Ensure sudorule is present, with an allow_sudocmdgroup.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
-      - /sbin/ifconfig
7d56d3
-      - /usr/bin/vim
7d56d3
+      allow_sudocmdgroup: test_sudorule
7d56d3
+      state: present
7d56d3
+    register: result
7d56d3
+    failed_when: not result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present, with an allow_sudocmdgroup, again.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      allow_sudocmdgroup: test_sudorule
7d56d3
+      state: present
7d56d3
+    register: result
7d56d3
+    failed_when: result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present, but allow_sudocmdgroup is absent.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      allow_sudocmdgroup: test_sudorule
7d56d3
       action: member
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
     failed_when: not result.changed
7d56d3
 
7d56d3
-  - name: Ensure sudorule sudocmds are absent, again
7d56d3
+  - name: Ensure sudorule is present, but allow_sudocmdgroup is absent.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
-      cmd:
7d56d3
-      - /sbin/ifconfig
7d56d3
-      - /usr/bin/vim
7d56d3
+      allow_sudocmdgroup: test_sudorule
7d56d3
+      action: member
7d56d3
+      state: absent
7d56d3
+    register: result
7d56d3
+    failed_when: result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present, with an deny_sudocmdgroup.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      deny_sudocmdgroup: test_sudorule
7d56d3
+      state: present
7d56d3
+    register: result
7d56d3
+    failed_when: not result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present, with an deny_sudocmdgroup, again.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      deny_sudocmdgroup: test_sudorule
7d56d3
+      state: present
7d56d3
+    register: result
7d56d3
+    failed_when: result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present, but deny_sudocmdgroup is absent.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      deny_sudocmdgroup: test_sudorule
7d56d3
+      action: member
7d56d3
+      state: absent
7d56d3
+    register: result
7d56d3
+    failed_when: not result.changed
7d56d3
+
7d56d3
+  - name: Ensure sudorule is present, but deny_sudocmdgroup is absent, again.
7d56d3
+    ipasudorule:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: testrule1
7d56d3
+      deny_sudocmdgroup: test_sudorule
7d56d3
       action: member
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -216,7 +315,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is absent
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -224,7 +323,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule is absent, again.
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: testrule1
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -232,7 +331,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule allhosts is absent
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allhosts
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -240,7 +339,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule allhosts is absent, again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allhosts
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -248,7 +347,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule allusers is absent
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allusers
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -256,7 +355,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule allusers is absent, again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allusers
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -264,7 +363,7 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule allcommands is absent
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allcommands
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
@@ -272,8 +371,29 @@
7d56d3
 
7d56d3
   - name: Ensure sudorule allcommands is absent, again
7d56d3
     ipasudorule:
7d56d3
-      ipaadmin_password: pass1234
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
       name: allcommands
7d56d3
       state: absent
7d56d3
     register: result
7d56d3
     failed_when: result.changed
7d56d3
+
7d56d3
+  # cleanup
7d56d3
+  - name : Ensure sudocmdgroup is absent
7d56d3
+    ipasudocmdgroup:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: test_sudorule
7d56d3
+      state: absent
7d56d3
+
7d56d3
+  - name: Ensure hostgroup is absent.
7d56d3
+    ipahostgroup:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name: cluster
7d56d3
+      state: absent
7d56d3
+
7d56d3
+  - name: Ensure sudocmds are absent
7d56d3
+    ipasudocmd:
7d56d3
+      ipaadmin_password: MyPassword123
7d56d3
+      name:
7d56d3
+      - /sbin/ifconfig
7d56d3
+      - /usr/bin/vim
7d56d3
+      state: absent