Blame SOURCES/ansible-freeipa-0.1.12-Fix-forwardzone-issues_rhbz#1843826,1843828,1843829,1843830,1843831.patch

01db47
From f0f933b4630bce810475a519e295828013d301d6 Mon Sep 17 00:00:00 2001
01db47
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
01db47
Date: Wed, 10 Jun 2020 20:40:45 -0300
01db47
Subject: [PATCH] Changed admin password on tests to match other modules.
01db47
01db47
Use of the same password on all module tests ease test automation,
01db47
and this change ensure that dnsforwardzone use the same password as
01db47
other modules.
01db47
---
01db47
 tests/dnsforwardzone/test_dnsforwardzone.yml | 42 ++++++++++----------
01db47
 1 file changed, 21 insertions(+), 21 deletions(-)
01db47
01db47
diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
index 1a45e826..ac08a48f 100644
01db47
--- a/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
@@ -7,13 +7,13 @@
01db47
   tasks:
01db47
   - name: ensure forwardzone example.com is absent - prep
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: absent
01db47
 
01db47
   - name: ensure forwardzone example.com is created
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -25,7 +25,7 @@
01db47
 
01db47
   - name: ensure forwardzone example.com is present again
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -37,7 +37,7 @@
01db47
 
01db47
   - name: ensure forwardzone example.com has two forwarders
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -50,7 +50,7 @@
01db47
 
01db47
   - name: ensure forwardzone example.com has one forwarder again
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       forwarders:
01db47
         - 8.8.8.8
01db47
@@ -62,7 +62,7 @@
01db47
 
01db47
   - name: skip_overlap_check can only be set on creation so change nothing
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       forwarders:
01db47
         - 8.8.8.8
01db47
@@ -74,7 +74,7 @@
01db47
 
01db47
   - name: change all the things at once
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -87,13 +87,13 @@
01db47
 
01db47
   - name: ensure forwardzone example.com is absent for next testset
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: absent
01db47
 
01db47
   - name: ensure forwardzone example.com is created with minimal args
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       skip_overlap_check: true
01db47
@@ -104,7 +104,7 @@
01db47
 
01db47
   - name: add a forwarder to any existing ones
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -115,7 +115,7 @@
01db47
 
01db47
   - name: check the list of forwarders is what we expect
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -127,7 +127,7 @@
01db47
 
01db47
   - name: remove a single forwarder
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: absent
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -138,7 +138,7 @@
01db47
 
01db47
   - name: check the list of forwarders is what we expect now
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -149,13 +149,13 @@
01db47
 
01db47
   - name: ensure forwardzone example.com is absent again
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: absent
01db47
 
01db47
   - name: try to create a new forwarder with action=member
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -167,13 +167,13 @@
01db47
 
01db47
   - name: ensure forwardzone example.com is absent - tidy up
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: absent
01db47
 
01db47
   - name: try to create a new forwarder is disabled state
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: disabled
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -184,7 +184,7 @@
01db47
 
01db47
   - name: enable the forwarder
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: enabled
01db47
     register: result
01db47
@@ -192,7 +192,7 @@
01db47
 
01db47
   - name: disable the forwarder again
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: disabled
01db47
       action: member
01db47
@@ -201,7 +201,7 @@
01db47
 
01db47
   - name: ensure it stays disabled
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: disabled
01db47
     register: result
01db47
@@ -209,6 +209,6 @@
01db47
 
01db47
   - name: ensure forwardzone example.com is absent - tidy up
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: absent
01db47
From f8ebca760dbaaf38c7b74b0c855b05d26e9cb812 Mon Sep 17 00:00:00 2001
01db47
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
01db47
Date: Wed, 10 Jun 2020 22:14:27 -0300
01db47
Subject: [PATCH] Allow processing of multiple names for deleting
01db47
 dnsforwardzones.
01db47
01db47
---
01db47
 plugins/modules/ipadnsforwardzone.py | 189 ++++++++++++++-------------
01db47
 1 file changed, 98 insertions(+), 91 deletions(-)
01db47
01db47
diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py
01db47
index 90bd3876..b28f28db 100644
01db47
--- a/plugins/modules/ipadnsforwardzone.py
01db47
+++ b/plugins/modules/ipadnsforwardzone.py
01db47
@@ -134,7 +134,7 @@ def main():
01db47
             # general
01db47
             ipaadmin_principal=dict(type="str", default="admin"),
01db47
             ipaadmin_password=dict(type="str", required=False, no_log=True),
01db47
-            name=dict(type="str", aliases=["cn"], default=None,
01db47
+            name=dict(type="list", aliases=["cn"], default=None,
01db47
                       required=True),
01db47
             forwarders=dict(type='list', aliases=["idnsforwarders"],
01db47
                             required=False),
01db47
@@ -158,7 +158,7 @@ def main():
01db47
                                            "ipaadmin_principal")
01db47
     ipaadmin_password = module_params_get(ansible_module,
01db47
                                           "ipaadmin_password")
01db47
-    name = module_params_get(ansible_module, "name")
01db47
+    names = module_params_get(ansible_module, "name")
01db47
     action = module_params_get(ansible_module, "action")
01db47
     forwarders = module_params_get(ansible_module, "forwarders")
01db47
     forwardpolicy = module_params_get(ansible_module, "forwardpolicy")
01db47
@@ -166,6 +166,12 @@ def main():
01db47
                                            "skip_overlap_check")
01db47
     state = module_params_get(ansible_module, "state")
01db47
 
01db47
+    if state == 'present' and len(names) != 1:
01db47
+        ansible_module.fail_json(
01db47
+            msg="Only one dnsforwardzone can be added at a time.")
01db47
+    if state == 'absent' and len(names) < 1:
01db47
+        ansible_module.fail_json(msg="No name given.")
01db47
+
01db47
     # absent stae means delete if the action is NOT member but update if it is
01db47
     # if action is member then update an exisiting resource
01db47
     # and if action is not member then create a resource
01db47
@@ -207,101 +213,102 @@ def main():
01db47
                                                  ipaadmin_password)
01db47
         api_connect()
01db47
 
01db47
-        # Make sure forwardzone exists
01db47
-        existing_resource = find_dnsforwardzone(ansible_module, name)
01db47
-
01db47
-        if existing_resource is None and operation == "update":
01db47
-            # does not exist and is updating
01db47
-            # trying to update something that doesn't exist, so error
01db47
-            ansible_module.fail_json(msg="""dnsforwardzone '%s' is not
01db47
-                                                     valid""" % (name))
01db47
-        elif existing_resource is None and operation == "del":
01db47
-            # does not exists and should be absent
01db47
-            # set command
01db47
-            command = None
01db47
-            # enabled or disabled?
01db47
-            is_enabled = "IGNORE"
01db47
-        elif existing_resource is not None and operation == "del":
01db47
-            # exists but should be absent
01db47
-            # set command
01db47
-            command = "dnsforwardzone_del"
01db47
-            # enabled or disabled?
01db47
-            is_enabled = "IGNORE"
01db47
-        elif forwarders is None:
01db47
-            # forwarders are not defined its not a delete, update state?
01db47
-            # set command
01db47
-            command = None
01db47
-            # enabled or disabled?
01db47
-            if existing_resource is not None:
01db47
-                is_enabled = existing_resource["idnszoneactive"][0]
01db47
-            else:
01db47
-                is_enabled = "IGNORE"
01db47
-        elif existing_resource is not None and operation == "update":
01db47
-            # exists and is updating
01db47
-            # calculate the new forwarders and mod
01db47
-            # determine args
01db47
-            if state != "absent":
01db47
-                forwarders = list(set(existing_resource["idnsforwarders"]
01db47
-                                      + forwarders))
01db47
-            else:
01db47
-                forwarders = list(set(existing_resource["idnsforwarders"])
01db47
-                                  - set(forwarders))
01db47
-            args = gen_args(forwarders, forwardpolicy,
01db47
-                            skip_overlap_check)
01db47
-            if skip_overlap_check is not None:
01db47
-                del args['skip_overlap_check']
01db47
-
01db47
-            # command
01db47
-            if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
-                command = "dnsforwardzone_mod"
01db47
-            else:
01db47
+        for name in names:
01db47
+            # Make sure forwardzone exists
01db47
+            existing_resource = find_dnsforwardzone(ansible_module, name)
01db47
+
01db47
+            if existing_resource is None and operation == "update":
01db47
+                # does not exist and is updating
01db47
+                # trying to update something that doesn't exist, so error
01db47
+                ansible_module.fail_json(msg="""dnsforwardzone '%s' is not
01db47
+                                                         valid""" % (name))
01db47
+            elif existing_resource is None and operation == "del":
01db47
+                # does not exists and should be absent
01db47
+                # set command
01db47
                 command = None
01db47
-
01db47
-            # enabled or disabled?
01db47
-            is_enabled = existing_resource["idnszoneactive"][0]
01db47
-
01db47
-        elif existing_resource is None and operation == "add":
01db47
-            # does not exist but should be present
01db47
-            # determine args
01db47
-            args = gen_args(forwarders, forwardpolicy,
01db47
-                            skip_overlap_check)
01db47
-            # set command
01db47
-            command = "dnsforwardzone_add"
01db47
-            # enabled or disabled?
01db47
-            is_enabled = "TRUE"
01db47
-
01db47
-        elif existing_resource is not None and operation == "add":
01db47
-            # exists and should be present, has it changed?
01db47
-            # determine args
01db47
-            args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
01db47
-            if skip_overlap_check is not None:
01db47
-                del args['skip_overlap_check']
01db47
-
01db47
-            # set command
01db47
-            if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
-                command = "dnsforwardzone_mod"
01db47
-            else:
01db47
+                # enabled or disabled?
01db47
+                is_enabled = "IGNORE"
01db47
+            elif existing_resource is not None and operation == "del":
01db47
+                # exists but should be absent
01db47
+                # set command
01db47
+                command = "dnsforwardzone_del"
01db47
+                # enabled or disabled?
01db47
+                is_enabled = "IGNORE"
01db47
+            elif forwarders is None:
01db47
+                # forwarders are not defined its not a delete, update state?
01db47
+                # set command
01db47
                 command = None
01db47
+                # enabled or disabled?
01db47
+                if existing_resource is not None:
01db47
+                    is_enabled = existing_resource["idnszoneactive"][0]
01db47
+                else:
01db47
+                    is_enabled = "IGNORE"
01db47
+            elif existing_resource is not None and operation == "update":
01db47
+                # exists and is updating
01db47
+                # calculate the new forwarders and mod
01db47
+                # determine args
01db47
+                if state != "absent":
01db47
+                    forwarders = list(set(existing_resource["idnsforwarders"]
01db47
+                                          + forwarders))
01db47
+                else:
01db47
+                    forwarders = list(set(existing_resource["idnsforwarders"])
01db47
+                                      - set(forwarders))
01db47
+                args = gen_args(forwarders, forwardpolicy,
01db47
+                                skip_overlap_check)
01db47
+                if skip_overlap_check is not None:
01db47
+                    del args['skip_overlap_check']
01db47
+
01db47
+                # command
01db47
+                if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
+                    command = "dnsforwardzone_mod"
01db47
+                else:
01db47
+                    command = None
01db47
+
01db47
+                # enabled or disabled?
01db47
+                is_enabled = existing_resource["idnszoneactive"][0]
01db47
 
01db47
-            # enabled or disabled?
01db47
-            is_enabled = existing_resource["idnszoneactive"][0]
01db47
-
01db47
-        # if command is set then run it with the args
01db47
-        if command is not None:
01db47
-            api_command(ansible_module, command, name, args)
01db47
-            changed = True
01db47
+            elif existing_resource is None and operation == "add":
01db47
+                # does not exist but should be present
01db47
+                # determine args
01db47
+                args = gen_args(forwarders, forwardpolicy,
01db47
+                                skip_overlap_check)
01db47
+                # set command
01db47
+                command = "dnsforwardzone_add"
01db47
+                # enabled or disabled?
01db47
+                is_enabled = "TRUE"
01db47
+
01db47
+            elif existing_resource is not None and operation == "add":
01db47
+                # exists and should be present, has it changed?
01db47
+                # determine args
01db47
+                args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
01db47
+                if skip_overlap_check is not None:
01db47
+                    del args['skip_overlap_check']
01db47
+
01db47
+                # set command
01db47
+                if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
+                    command = "dnsforwardzone_mod"
01db47
+                else:
01db47
+                    command = None
01db47
+
01db47
+                # enabled or disabled?
01db47
+                is_enabled = existing_resource["idnszoneactive"][0]
01db47
 
01db47
-        # does the enabled state match what we want (if we care)
01db47
-        if is_enabled != "IGNORE":
01db47
-            if wants_enable and is_enabled != "TRUE":
01db47
-                api_command(ansible_module, "dnsforwardzone_enable",
01db47
-                            name, {})
01db47
-                changed = True
01db47
-            elif not wants_enable and is_enabled != "FALSE":
01db47
-                api_command(ansible_module, "dnsforwardzone_disable",
01db47
-                            name, {})
01db47
+            # if command is set then run it with the args
01db47
+            if command is not None:
01db47
+                api_command(ansible_module, command, name, args)
01db47
                 changed = True
01db47
 
01db47
+            # does the enabled state match what we want (if we care)
01db47
+            if is_enabled != "IGNORE":
01db47
+                if wants_enable and is_enabled != "TRUE":
01db47
+                    api_command(ansible_module, "dnsforwardzone_enable",
01db47
+                                name, {})
01db47
+                    changed = True
01db47
+                elif not wants_enable and is_enabled != "FALSE":
01db47
+                    api_command(ansible_module, "dnsforwardzone_disable",
01db47
+                                name, {})
01db47
+                    changed = True
01db47
+
01db47
     except Exception as e:
01db47
         ansible_module.fail_json(msg=str(e))
01db47
 
01db47
From 3f785bc0e9fe1ab3ad874ce4f26e6897189db8aa Mon Sep 17 00:00:00 2001
01db47
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
01db47
Date: Wed, 10 Jun 2020 22:20:20 -0300
01db47
Subject: [PATCH] Fix error message when adding dnsforwardzone without
01db47
 forwarders.
01db47
01db47
---
01db47
 plugins/modules/ipadnsforwardzone.py         |  5 +++++
01db47
 tests/dnsforwardzone/test_dnsforwardzone.yml | 13 +++++++++++--
01db47
 2 files changed, 16 insertions(+), 2 deletions(-)
01db47
01db47
diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py
01db47
index b28f28db..3968e6a1 100644
01db47
--- a/plugins/modules/ipadnsforwardzone.py
01db47
+++ b/plugins/modules/ipadnsforwardzone.py
01db47
@@ -217,6 +217,11 @@ def main():
01db47
             # Make sure forwardzone exists
01db47
             existing_resource = find_dnsforwardzone(ansible_module, name)
01db47
 
01db47
+            # validate parameters
01db47
+            if state == 'present':
01db47
+                if existing_resource is None and not forwarders:
01db47
+                    ansible_module.fail_json(msg='No forwarders specified.')
01db47
+
01db47
             if existing_resource is None and operation == "update":
01db47
                 # does not exist and is updating
01db47
                 # trying to update something that doesn't exist, so error
01db47
diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
index ac08a48f..d94db9e5 100644
01db47
--- a/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
@@ -5,10 +5,12 @@
01db47
   gather_facts: false
01db47
 
01db47
   tasks:
01db47
-  - name: ensure forwardzone example.com is absent - prep
01db47
+  - name: ensure test forwardzones are absent - prep
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
-      name: example.com
01db47
+      name:
01db47
+      - example.com
01db47
+      - newfailzone.com
01db47
       state: absent
01db47
 
01db47
   - name: ensure forwardzone example.com is created
01db47
@@ -207,6 +209,13 @@
01db47
     register: result
01db47
     failed_when: result.changed
01db47
 
01db47
+  - name: Ensure forwardzone is not added without forwarders, with correct message.
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: newfailzone.com
01db47
+    register: result
01db47
+    failed_when: not result.failed or "No forwarders specified" not in result.msg
01db47
+
01db47
   - name: ensure forwardzone example.com is absent - tidy up
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
From 1d223c2b63634abe86f7702a64dd83c4fbc272ce Mon Sep 17 00:00:00 2001
01db47
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
01db47
Date: Mon, 15 Jun 2020 16:14:25 -0300
01db47
Subject: [PATCH] Add support for attributes `ip_address` and `port` to
01db47
 `forwarders`.
01db47
01db47
This patch modify the was forwarders are configured, using two attributes,
01db47
`ip_address` and `port`, instead of IPA API internal string representation
01db47
of `IP port PORT`.
01db47
---
01db47
 README-dnsforwardzone.md                     |  6 ++-
01db47
 plugins/modules/ipadnsforwardzone.py         | 37 ++++++++++++++---
01db47
 tests/dnsforwardzone/test_dnsforwardzone.yml | 43 ++++++++++++--------
01db47
 3 files changed, 62 insertions(+), 24 deletions(-)
01db47
01db47
diff --git a/README-dnsforwardzone.md b/README-dnsforwardzone.md
01db47
index 81919295..15b2b574 100644
01db47
--- a/README-dnsforwardzone.md
01db47
+++ b/README-dnsforwardzone.md
01db47
@@ -99,8 +99,10 @@ Variable | Description | Required
01db47
 `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
01db47
 `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
01db47
 `name` \| `cn` | Zone name (FQDN). | yes if `state` == `present`
01db47
-`forwarders` \| `idnsforwarders` |  Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`) | no
01db47
-`forwardpolicy` \| `idnsforwardpolicy` | Per-zone conditional forwarding policy. Set to "none" to disable forwarding to global forwarder for this zone. In that case, conditional zone forwarders are disregarded. | no
01db47
+`forwarders` \| `idnsforwarders` |  Per-zone forwarders. A custom port can be specified for each forwarder. Options | no
01db47
+  | `ip_address`: The forwarder IP address. | yes
01db47
+  | `port`: The forwarder IP port. | no
01db47
+`forwardpolicy` \| `idnsforwardpolicy` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`. Set to "none" to disable forwarding to global forwarder for this zone. In that case, conditional zone forwarders are disregarded. | no
01db47
 `skip_overlap_check` | Force DNS zone creation even if it will overlap with an existing zone. Defaults to False. | no
01db47
 `action` | Work on group or member level. It can be on of `member` or `dnsforwardzone` and defaults to `dnsforwardzone`. | no
01db47
 `state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | yes
01db47
diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py
01db47
index 3968e6a1..8e5c3464 100644
01db47
--- a/plugins/modules/ipadnsforwardzone.py
01db47
+++ b/plugins/modules/ipadnsforwardzone.py
01db47
@@ -54,9 +54,16 @@
01db47
   forwarders:
01db47
     description:
01db47
     - List of the DNS servers to forward to
01db47
-    required: true
01db47
-    type: list
01db47
     aliases: ["idnsforwarders"]
01db47
+    options:
01db47
+      ip_address:
01db47
+        description: Forwarder IP address (either IPv4 or IPv6).
01db47
+        required: false
01db47
+        type: string
01db47
+      port:
01db47
+        description: Forwarder port.
01db47
+        required: false
01db47
+        type: int
01db47
   forwardpolicy:
01db47
     description: Per-zone conditional forwarding policy
01db47
     required: false
01db47
@@ -128,6 +135,20 @@ def gen_args(forwarders, forwardpolicy, skip_overlap_check):
01db47
     return _args
01db47
 
01db47
 
01db47
+def forwarder_list(forwarders):
01db47
+    """Convert the forwarder dict into a list compatible with IPA API."""
01db47
+    if forwarders is None:
01db47
+        return None
01db47
+    fwd_list = []
01db47
+    for forwarder in forwarders:
01db47
+        if forwarder.get('port', None) is not None:
01db47
+            formatter = "{ip_address} port {port}"
01db47
+        else:
01db47
+            formatter = "{ip_address}"
01db47
+        fwd_list.append(formatter.format(**forwarder))
01db47
+    return fwd_list
01db47
+
01db47
+
01db47
 def main():
01db47
     ansible_module = AnsibleModule(
01db47
         argument_spec=dict(
01db47
@@ -136,8 +157,13 @@ def main():
01db47
             ipaadmin_password=dict(type="str", required=False, no_log=True),
01db47
             name=dict(type="list", aliases=["cn"], default=None,
01db47
                       required=True),
01db47
-            forwarders=dict(type='list', aliases=["idnsforwarders"],
01db47
-                            required=False),
01db47
+            forwarders=dict(type="list", default=None, required=False,
01db47
+                            aliases=["idnsforwarders"], elements='dict',
01db47
+                            options=dict(
01db47
+                                 ip_address=dict(type='str', required=True),
01db47
+                                 port=dict(type='int', required=False,
01db47
+                                           default=None),
01db47
+                            )),
01db47
             forwardpolicy=dict(type='str', aliases=["idnsforwardpolicy"],
01db47
                                required=False,
01db47
                                choices=['only', 'first', 'none']),
01db47
@@ -160,7 +186,8 @@ def main():
01db47
                                           "ipaadmin_password")
01db47
     names = module_params_get(ansible_module, "name")
01db47
     action = module_params_get(ansible_module, "action")
01db47
-    forwarders = module_params_get(ansible_module, "forwarders")
01db47
+    forwarders = forwarder_list(
01db47
+        module_params_get(ansible_module, "forwarders"))
01db47
     forwardpolicy = module_params_get(ansible_module, "forwardpolicy")
01db47
     skip_overlap_check = module_params_get(ansible_module,
01db47
                                            "skip_overlap_check")
01db47
diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
index d94db9e5..468cd4ce 100644
01db47
--- a/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
@@ -5,7 +5,7 @@
01db47
   gather_facts: false
01db47
 
01db47
   tasks:
01db47
-  - name: ensure test forwardzones are absent - prep
01db47
+  - name: ensure test forwardzones are absent
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name:
01db47
@@ -19,7 +19,7 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
+        - ip_address: 8.8.8.8
01db47
       forwardpolicy: first
01db47
       skip_overlap_check: true
01db47
     register: result
01db47
@@ -31,7 +31,7 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
+        - ip_address: 8.8.8.8
01db47
       forwardpolicy: first
01db47
       skip_overlap_check: true
01db47
     register: result
01db47
@@ -43,19 +43,22 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
-        - 4.4.4.4
01db47
+        - ip_address: 8.8.8.8
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
       forwardpolicy: first
01db47
       skip_overlap_check: true
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
+  - pause:
01db47
+
01db47
   - name: ensure forwardzone example.com has one forwarder again
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
+        - ip_address: 8.8.8.8
01db47
       forwardpolicy: first
01db47
       skip_overlap_check: true
01db47
       state: present
01db47
@@ -67,7 +70,7 @@
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
+        - ip_address: 8.8.8.8
01db47
       forwardpolicy: first
01db47
       skip_overlap_check: false
01db47
       state: present
01db47
@@ -80,8 +83,9 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
-        - 4.4.4.4
01db47
+        - ip_address: 8.8.8.8
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
       forwardpolicy: only
01db47
       skip_overlap_check: false
01db47
     register: result
01db47
@@ -100,7 +104,7 @@
01db47
       name: example.com
01db47
       skip_overlap_check: true
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
+        - ip_address: 8.8.8.8
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
@@ -110,7 +114,8 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 4.4.4.4
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
       action: member
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
@@ -121,8 +126,9 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 4.4.4.4
01db47
-        - 8.8.8.8
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
+        - ip_address: 8.8.8.8
01db47
       action: member
01db47
     register: result
01db47
     failed_when: result.changed
01db47
@@ -133,7 +139,7 @@
01db47
       state: absent
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 8.8.8.8
01db47
+        - ip_address: 8.8.8.8
01db47
       action: member
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
@@ -144,7 +150,8 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 4.4.4.4
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
       action: member
01db47
     register: result
01db47
     failed_when: result.changed
01db47
@@ -161,7 +168,8 @@
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 4.4.4.4
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
       action: member
01db47
       skip_overlap_check: true
01db47
     register: result
01db47
@@ -179,7 +187,8 @@
01db47
       state: disabled
01db47
       name: example.com
01db47
       forwarders:
01db47
-        - 4.4.4.4
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
       skip_overlap_check: true
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
From bf864469a1da81c6b23e9726562b21408764ac8f Mon Sep 17 00:00:00 2001
01db47
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
01db47
Date: Mon, 15 Jun 2020 20:42:23 -0300
01db47
Subject: [PATCH] Add support for attribute `permission` on dnsforwardzone
01db47
 module.
01db47
01db47
Adds missing attribute `permission to dnsforwardzone module, that
01db47
enable setting `manageby` for the DNS Forwar Zone.
01db47
---
01db47
 README-dnsforwardzone.md                     |   1 +
01db47
 plugins/modules/ipadnsforwardzone.py         |  71 ++++++++----
01db47
 tests/dnsforwardzone/test_dnsforwardzone.yml | 110 +++++++++++++++----
01db47
 3 files changed, 136 insertions(+), 46 deletions(-)
01db47
01db47
diff --git a/README-dnsforwardzone.md b/README-dnsforwardzone.md
01db47
index 15b2b574..175e6f8b 100644
01db47
--- a/README-dnsforwardzone.md
01db47
+++ b/README-dnsforwardzone.md
01db47
@@ -104,6 +104,7 @@ Variable | Description | Required
01db47
   | `port`: The forwarder IP port. | no
01db47
 `forwardpolicy` \| `idnsforwardpolicy` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`. Set to "none" to disable forwarding to global forwarder for this zone. In that case, conditional zone forwarders are disregarded. | no
01db47
 `skip_overlap_check` | Force DNS zone creation even if it will overlap with an existing zone. Defaults to False. | no
01db47
+`permission` | Allow DNS Forward Zone to be managed. (bool) | no
01db47
 `action` | Work on group or member level. It can be on of `member` or `dnsforwardzone` and defaults to `dnsforwardzone`. | no
01db47
 `state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | yes
01db47
 
01db47
diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py
01db47
index 8e5c3464..a729197b 100644
01db47
--- a/plugins/modules/ipadnsforwardzone.py
01db47
+++ b/plugins/modules/ipadnsforwardzone.py
01db47
@@ -75,6 +75,11 @@
01db47
     - Force DNS zone creation even if it will overlap with an existing zone.
01db47
     required: false
01db47
     default: false
01db47
+  permission:
01db47
+    description:
01db47
+    - Allow DNS Forward Zone to be managed.
01db47
+    required: false
01db47
+    type: bool
01db47
 '''
01db47
 
01db47
 EXAMPLES = '''
01db47
@@ -168,6 +173,8 @@ def main():
01db47
                                required=False,
01db47
                                choices=['only', 'first', 'none']),
01db47
             skip_overlap_check=dict(type='bool', required=False),
01db47
+            permission=dict(type='bool', required=False,
01db47
+                            aliases=['managedby']),
01db47
             action=dict(type="str", default="dnsforwardzone",
01db47
                         choices=["member", "dnsforwardzone"]),
01db47
             # state
01db47
@@ -191,6 +198,7 @@ def main():
01db47
     forwardpolicy = module_params_get(ansible_module, "forwardpolicy")
01db47
     skip_overlap_check = module_params_get(ansible_module,
01db47
                                            "skip_overlap_check")
01db47
+    permission = module_params_get(ansible_module, "permission")
01db47
     state = module_params_get(ansible_module, "state")
01db47
 
01db47
     if state == 'present' and len(names) != 1:
01db47
@@ -215,7 +223,9 @@ def main():
01db47
         wants_enable = True
01db47
 
01db47
     if operation == "del":
01db47
-        invalid = ["forwarders", "forwardpolicy", "skip_overlap_check"]
01db47
+        invalid = [
01db47
+            "forwarders", "forwardpolicy", "skip_overlap_check", "permission"
01db47
+        ]
01db47
         for x in invalid:
01db47
             if vars()[x] is not None:
01db47
                 ansible_module.fail_json(
01db47
@@ -241,6 +251,9 @@ def main():
01db47
         api_connect()
01db47
 
01db47
         for name in names:
01db47
+            commands = []
01db47
+            command = None
01db47
+
01db47
             # Make sure forwardzone exists
01db47
             existing_resource = find_dnsforwardzone(ansible_module, name)
01db47
 
01db47
@@ -249,6 +262,18 @@ def main():
01db47
                 if existing_resource is None and not forwarders:
01db47
                     ansible_module.fail_json(msg='No forwarders specified.')
01db47
 
01db47
+            if existing_resource is not None:
01db47
+                if state != "absent":
01db47
+                    if forwarders:
01db47
+                        forwarders = list(
01db47
+                            set(existing_resource["idnsforwarders"]
01db47
+                                + forwarders))
01db47
+                else:
01db47
+                    if forwarders:
01db47
+                        forwarders = list(
01db47
+                            set(existing_resource["idnsforwarders"])
01db47
+                            - set(forwarders))
01db47
+
01db47
             if existing_resource is None and operation == "update":
01db47
                 # does not exist and is updating
01db47
                 # trying to update something that doesn't exist, so error
01db47
@@ -256,20 +281,17 @@ def main():
01db47
                                                          valid""" % (name))
01db47
             elif existing_resource is None and operation == "del":
01db47
                 # does not exists and should be absent
01db47
-                # set command
01db47
-                command = None
01db47
                 # enabled or disabled?
01db47
                 is_enabled = "IGNORE"
01db47
             elif existing_resource is not None and operation == "del":
01db47
                 # exists but should be absent
01db47
                 # set command
01db47
                 command = "dnsforwardzone_del"
01db47
+                args = {}
01db47
                 # enabled or disabled?
01db47
                 is_enabled = "IGNORE"
01db47
             elif forwarders is None:
01db47
                 # forwarders are not defined its not a delete, update state?
01db47
-                # set command
01db47
-                command = None
01db47
                 # enabled or disabled?
01db47
                 if existing_resource is not None:
01db47
                     is_enabled = existing_resource["idnszoneactive"][0]
01db47
@@ -278,23 +300,13 @@ def main():
01db47
             elif existing_resource is not None and operation == "update":
01db47
                 # exists and is updating
01db47
                 # calculate the new forwarders and mod
01db47
-                # determine args
01db47
-                if state != "absent":
01db47
-                    forwarders = list(set(existing_resource["idnsforwarders"]
01db47
-                                          + forwarders))
01db47
-                else:
01db47
-                    forwarders = list(set(existing_resource["idnsforwarders"])
01db47
-                                      - set(forwarders))
01db47
-                args = gen_args(forwarders, forwardpolicy,
01db47
-                                skip_overlap_check)
01db47
-                if skip_overlap_check is not None:
01db47
+                args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
01db47
+                if "skip_overlap_check" in args:
01db47
                     del args['skip_overlap_check']
01db47
 
01db47
                 # command
01db47
                 if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
                     command = "dnsforwardzone_mod"
01db47
-                else:
01db47
-                    command = None
01db47
 
01db47
                 # enabled or disabled?
01db47
                 is_enabled = existing_resource["idnszoneactive"][0]
01db47
@@ -313,21 +325,36 @@ def main():
01db47
                 # exists and should be present, has it changed?
01db47
                 # determine args
01db47
                 args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
01db47
-                if skip_overlap_check is not None:
01db47
+                if 'skip_overlap_check' in args:
01db47
                     del args['skip_overlap_check']
01db47
 
01db47
                 # set command
01db47
                 if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
                     command = "dnsforwardzone_mod"
01db47
-                else:
01db47
-                    command = None
01db47
 
01db47
                 # enabled or disabled?
01db47
                 is_enabled = existing_resource["idnszoneactive"][0]
01db47
 
01db47
-            # if command is set then run it with the args
01db47
+            # if command is set...
01db47
             if command is not None:
01db47
-                api_command(ansible_module, command, name, args)
01db47
+                commands.append([name, command, args])
01db47
+
01db47
+            if permission is not None:
01db47
+                if existing_resource is None:
01db47
+                    managedby = None
01db47
+                else:
01db47
+                    managedby = existing_resource.get('managedby', None)
01db47
+                if permission and managedby is None:
01db47
+                    commands.append(
01db47
+                        [name, 'dnsforwardzone_add_permission', {}]
01db47
+                    )
01db47
+                elif not permission and managedby is not None:
01db47
+                    commands.append(
01db47
+                        [name, 'dnsforwardzone_remove_permission', {}]
01db47
+                    )
01db47
+
01db47
+            for name, command, args in commands:
01db47
+                result = api_command(ansible_module, command, name, args)
01db47
                 changed = True
01db47
 
01db47
             # does the enabled state match what we want (if we care)
01db47
diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
index 468cd4ce..0386bd48 100644
01db47
--- a/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
@@ -51,8 +51,6 @@
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
-  - pause:
01db47
-
01db47
   - name: ensure forwardzone example.com has one forwarder again
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
@@ -63,7 +61,7 @@
01db47
       skip_overlap_check: true
01db47
       state: present
01db47
     register: result
01db47
-    failed_when: not result.changed
01db47
+    failed_when: result.changed
01db47
 
01db47
   - name: skip_overlap_check can only be set on creation so change nothing
01db47
     ipadnsforwardzone:
01db47
@@ -77,6 +75,22 @@
01db47
     register: result
01db47
     failed_when: result.changed
01db47
 
01db47
+  - name: ensure forwardzone example.com is absent.
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: example.com
01db47
+      state: absent
01db47
+    register: result
01db47
+    failed_when: not result.changed
01db47
+
01db47
+  - name: ensure forwardzone example.com is absent, again.
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: example.com
01db47
+      state: absent
01db47
+    register: result
01db47
+    failed_when: result.changed
01db47
+
01db47
   - name: change all the things at once
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
@@ -87,11 +101,12 @@
01db47
         - ip_address: 4.4.4.4
01db47
           port: 8053
01db47
       forwardpolicy: only
01db47
-      skip_overlap_check: false
01db47
+      skip_overlap_check: true
01db47
+      permission: yes
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
-  - name: ensure forwardzone example.com is absent for next testset
01db47
+  - name: ensure forwardzone example.com is absent.
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
@@ -156,43 +171,58 @@
01db47
     register: result
01db47
     failed_when: result.changed
01db47
 
01db47
-  - name: ensure forwardzone example.com is absent again
01db47
+  - name: Add a permission for per-forward zone access delegation.
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
-      state: absent
01db47
+      permission: yes
01db47
+      action: member
01db47
+    register: result
01db47
+    failed_when: not result.changed
01db47
 
01db47
-  - name: try to create a new forwarder with action=member
01db47
+  - name: Add a permission for per-forward zone access delegation, again.
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
-      state: present
01db47
       name: example.com
01db47
-      forwarders:
01db47
-        - ip_address: 4.4.4.4
01db47
-          port: 8053
01db47
+      permission: yes
01db47
       action: member
01db47
-      skip_overlap_check: true
01db47
     register: result
01db47
     failed_when: result.changed
01db47
 
01db47
-  - name: ensure forwardzone example.com is absent - tidy up
01db47
+  - name: Remove a permission for per-forward zone access delegation.
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
-      state: absent
01db47
+      permission: no
01db47
+      action: member
01db47
+    register: result
01db47
+    failed_when: not result.changed
01db47
 
01db47
-  - name: try to create a new forwarder is disabled state
01db47
+  - name: Remove a permission for per-forward zone access delegation, again.
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
-      state: disabled
01db47
       name: example.com
01db47
-      forwarders:
01db47
-        - ip_address: 4.4.4.4
01db47
-          port: 8053
01db47
-      skip_overlap_check: true
01db47
+      permission: no
01db47
+      action: member
01db47
+    register: result
01db47
+    failed_when: result.changed
01db47
+
01db47
+  - name: disable the forwarder
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: example.com
01db47
+      state: disabled
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
+  - name: disable the forwarder again
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: example.com
01db47
+      state: disabled
01db47
+    register: result
01db47
+    failed_when: result.changed
01db47
+
01db47
   - name: enable the forwarder
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
@@ -201,12 +231,42 @@
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
-  - name: disable the forwarder again
01db47
+  - name: enable the forwarder, again
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
-      state: disabled
01db47
+      state: enabled
01db47
+    register: result
01db47
+    failed_when: result.changed
01db47
+
01db47
+  - name: ensure forwardzone example.com is absent again
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: example.com
01db47
+      state: absent
01db47
+
01db47
+  - name: try to create a new forwarder with action=member
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      state: present
01db47
+      name: example.com
01db47
+      forwarders:
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
       action: member
01db47
+      skip_overlap_check: true
01db47
+    register: result
01db47
+    failed_when: result.changed
01db47
+
01db47
+  - name: try to create a new forwarder with disabled state
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      state: disabled
01db47
+      name: example.com
01db47
+      forwarders:
01db47
+        - ip_address: 4.4.4.4
01db47
+          port: 8053
01db47
+      skip_overlap_check: yes
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
@@ -228,5 +288,7 @@
01db47
   - name: ensure forwardzone example.com is absent - tidy up
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
-      name: example.com
01db47
+      name:
01db47
+      - example.com
01db47
+      - newfailzone.com
01db47
       state: absent
01db47
From 857fb82eb9141a44ffb91331653e1c30b43f671e Mon Sep 17 00:00:00 2001
01db47
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
01db47
Date: Mon, 15 Jun 2020 23:40:35 -0300
01db47
Subject: [PATCH] Allows modification of forward policy in existing DNS Forward
01db47
 Zone.
01db47
01db47
This patch allows the modification of the forward zone policy in
01db47
an existing DNS Forward Zone, and fixes some issues with `enable`
01db47
and `disable` state that prevented correct behavior of `forwardpolicy`.
01db47
---
01db47
 plugins/modules/ipadnsforwardzone.py         | 154 ++++++++++---------
01db47
 tests/dnsforwardzone/test_dnsforwardzone.yml |  32 ++--
01db47
 2 files changed, 97 insertions(+), 89 deletions(-)
01db47
01db47
diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py
01db47
index a729197b..1f1e85ec 100644
01db47
--- a/plugins/modules/ipadnsforwardzone.py
01db47
+++ b/plugins/modules/ipadnsforwardzone.py
01db47
@@ -217,10 +217,20 @@ def main():
01db47
     else:
01db47
         operation = "add"
01db47
 
01db47
-    if state == "disabled":
01db47
-        wants_enable = False
01db47
-    else:
01db47
-        wants_enable = True
01db47
+    if state in ["enabled", "disabled"]:
01db47
+        if action == "member":
01db47
+            ansible_module.fail_json(
01db47
+                msg="Action `member` cannot be used with state `%s`"
01db47
+                    % (state))
01db47
+        invalid = [
01db47
+            "forwarders", "forwardpolicy", "skip_overlap_check", "permission"
01db47
+        ]
01db47
+        for x in invalid:
01db47
+            if vars()[x] is not None:
01db47
+                ansible_module.fail_json(
01db47
+                    msg="Argument '%s' can not be used with action "
01db47
+                    "'%s', state `%s`" % (x, action, state))
01db47
+        wants_enable = (state == "enabled")
01db47
 
01db47
     if operation == "del":
01db47
         invalid = [
01db47
@@ -230,7 +240,7 @@ def main():
01db47
             if vars()[x] is not None:
01db47
                 ansible_module.fail_json(
01db47
                     msg="Argument '%s' can not be used with action "
01db47
-                    "'%s'" % (x, action))
01db47
+                    "'%s', state `%s`" % (x, action, state))
01db47
 
01db47
     changed = False
01db47
     exit_args = {}
01db47
@@ -262,7 +272,27 @@ def main():
01db47
                 if existing_resource is None and not forwarders:
01db47
                     ansible_module.fail_json(msg='No forwarders specified.')
01db47
 
01db47
-            if existing_resource is not None:
01db47
+            if existing_resource is None:
01db47
+                if operation == "add":
01db47
+                    # does not exist but should be present
01db47
+                    # determine args
01db47
+                    args = gen_args(forwarders, forwardpolicy,
01db47
+                                    skip_overlap_check)
01db47
+                    # set command
01db47
+                    command = "dnsforwardzone_add"
01db47
+                    # enabled or disabled?
01db47
+
01db47
+                elif operation == "update":
01db47
+                    # does not exist and is updating
01db47
+                    # trying to update something that doesn't exist, so error
01db47
+                    ansible_module.fail_json(
01db47
+                        msg="dnsforwardzone '%s' not found." % (name))
01db47
+
01db47
+                elif operation == "del":
01db47
+                    # there's nothnig to do.
01db47
+                    continue
01db47
+
01db47
+            else:   # existing_resource is not None
01db47
                 if state != "absent":
01db47
                     if forwarders:
01db47
                         forwarders = list(
01db47
@@ -274,66 +304,51 @@ def main():
01db47
                             set(existing_resource["idnsforwarders"])
01db47
                             - set(forwarders))
01db47
 
01db47
-            if existing_resource is None and operation == "update":
01db47
-                # does not exist and is updating
01db47
-                # trying to update something that doesn't exist, so error
01db47
-                ansible_module.fail_json(msg="""dnsforwardzone '%s' is not
01db47
-                                                         valid""" % (name))
01db47
-            elif existing_resource is None and operation == "del":
01db47
-                # does not exists and should be absent
01db47
-                # enabled or disabled?
01db47
-                is_enabled = "IGNORE"
01db47
-            elif existing_resource is not None and operation == "del":
01db47
-                # exists but should be absent
01db47
-                # set command
01db47
-                command = "dnsforwardzone_del"
01db47
-                args = {}
01db47
-                # enabled or disabled?
01db47
-                is_enabled = "IGNORE"
01db47
-            elif forwarders is None:
01db47
-                # forwarders are not defined its not a delete, update state?
01db47
-                # enabled or disabled?
01db47
+                if operation == "add":
01db47
+                    # exists and should be present, has it changed?
01db47
+                    # determine args
01db47
+                    args = gen_args(
01db47
+                        forwarders, forwardpolicy, skip_overlap_check)
01db47
+                    if 'skip_overlap_check' in args:
01db47
+                        del args['skip_overlap_check']
01db47
+
01db47
+                    # set command
01db47
+                    if not compare_args_ipa(
01db47
+                            ansible_module, args, existing_resource):
01db47
+                        command = "dnsforwardzone_mod"
01db47
+
01db47
+                elif operation == "del":
01db47
+                    # exists but should be absent
01db47
+                    # set command
01db47
+                    command = "dnsforwardzone_del"
01db47
+                    args = {}
01db47
+
01db47
+                elif operation == "update":
01db47
+                    # exists and is updating
01db47
+                    # calculate the new forwarders and mod
01db47
+                    args = gen_args(
01db47
+                        forwarders, forwardpolicy, skip_overlap_check)
01db47
+                    if "skip_overlap_check" in args:
01db47
+                        del args['skip_overlap_check']
01db47
+
01db47
+                    # command
01db47
+                    if not compare_args_ipa(
01db47
+                            ansible_module, args, existing_resource):
01db47
+                        command = "dnsforwardzone_mod"
01db47
+
01db47
+            if state in ['enabled', 'disabled']:
01db47
                 if existing_resource is not None:
01db47
                     is_enabled = existing_resource["idnszoneactive"][0]
01db47
                 else:
01db47
-                    is_enabled = "IGNORE"
01db47
-            elif existing_resource is not None and operation == "update":
01db47
-                # exists and is updating
01db47
-                # calculate the new forwarders and mod
01db47
-                args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
01db47
-                if "skip_overlap_check" in args:
01db47
-                    del args['skip_overlap_check']
01db47
-
01db47
-                # command
01db47
-                if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
-                    command = "dnsforwardzone_mod"
01db47
-
01db47
-                # enabled or disabled?
01db47
-                is_enabled = existing_resource["idnszoneactive"][0]
01db47
-
01db47
-            elif existing_resource is None and operation == "add":
01db47
-                # does not exist but should be present
01db47
-                # determine args
01db47
-                args = gen_args(forwarders, forwardpolicy,
01db47
-                                skip_overlap_check)
01db47
-                # set command
01db47
-                command = "dnsforwardzone_add"
01db47
-                # enabled or disabled?
01db47
-                is_enabled = "TRUE"
01db47
-
01db47
-            elif existing_resource is not None and operation == "add":
01db47
-                # exists and should be present, has it changed?
01db47
-                # determine args
01db47
-                args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
01db47
-                if 'skip_overlap_check' in args:
01db47
-                    del args['skip_overlap_check']
01db47
-
01db47
-                # set command
01db47
-                if not compare_args_ipa(ansible_module, args, existing_resource):
01db47
-                    command = "dnsforwardzone_mod"
01db47
-
01db47
-                # enabled or disabled?
01db47
-                is_enabled = existing_resource["idnszoneactive"][0]
01db47
+                    ansible_module.fail_json(
01db47
+                        msg="dnsforwardzone '%s' not found." % (name))
01db47
+
01db47
+            # does the enabled state match what we want (if we care)
01db47
+            if is_enabled != "IGNORE":
01db47
+                if wants_enable and is_enabled != "TRUE":
01db47
+                    commands.append([name, "dnsforwardzone_enable", {}])
01db47
+                elif not wants_enable and is_enabled != "FALSE":
01db47
+                    commands.append([name, "dnsforwardzone_disable", {}])
01db47
 
01db47
             # if command is set...
01db47
             if command is not None:
01db47
@@ -354,20 +369,9 @@ def main():
01db47
                     )
01db47
 
01db47
             for name, command, args in commands:
01db47
-                result = api_command(ansible_module, command, name, args)
01db47
+                api_command(ansible_module, command, name, args)
01db47
                 changed = True
01db47
 
01db47
-            # does the enabled state match what we want (if we care)
01db47
-            if is_enabled != "IGNORE":
01db47
-                if wants_enable and is_enabled != "TRUE":
01db47
-                    api_command(ansible_module, "dnsforwardzone_enable",
01db47
-                                name, {})
01db47
-                    changed = True
01db47
-                elif not wants_enable and is_enabled != "FALSE":
01db47
-                    api_command(ansible_module, "dnsforwardzone_disable",
01db47
-                                name, {})
01db47
-                    changed = True
01db47
-
01db47
     except Exception as e:
01db47
         ansible_module.fail_json(msg=str(e))
01db47
 
01db47
diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
index 0386bd48..223cf3d0 100644
01db47
--- a/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml
01db47
@@ -106,6 +106,22 @@
01db47
     register: result
01db47
     failed_when: not result.changed
01db47
 
01db47
+  - name: change zone forward policy
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: example.com
01db47
+      forwardpolicy: first
01db47
+    register: result
01db47
+    failed_when: not result.changed
01db47
+
01db47
+  - name: change zone forward policy, again
01db47
+    ipadnsforwardzone:
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
+      name: example.com
01db47
+      forwardpolicy: first
01db47
+    register: result
01db47
+    failed_when: result.changed
01db47
+
01db47
   - name: ensure forwardzone example.com is absent.
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
@@ -256,27 +272,15 @@
01db47
       action: member
01db47
       skip_overlap_check: true
01db47
     register: result
01db47
-    failed_when: result.changed
01db47
+    failed_when: not result.failed or "not found" not in result.msg
01db47
 
01db47
   - name: try to create a new forwarder with disabled state
01db47
-    ipadnsforwardzone:
01db47
-      ipaadmin_password: SomeADMINpassword
01db47
-      state: disabled
01db47
-      name: example.com
01db47
-      forwarders:
01db47
-        - ip_address: 4.4.4.4
01db47
-          port: 8053
01db47
-      skip_overlap_check: yes
01db47
-    register: result
01db47
-    failed_when: not result.changed
01db47
-
01db47
-  - name: ensure it stays disabled
01db47
     ipadnsforwardzone:
01db47
       ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: disabled
01db47
     register: result
01db47
-    failed_when: result.changed
01db47
+    failed_when: not result.failed or "not found" not in result.msg
01db47
 
01db47
   - name: Ensure forwardzone is not added without forwarders, with correct message.
01db47
     ipadnsforwardzone:
01db47
From 8da6a6937919d0c390b870113fb557649c39c815 Mon Sep 17 00:00:00 2001
01db47
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
01db47
Date: Fri, 26 Jun 2020 11:28:15 -0300
01db47
Subject: [PATCH] Change password values in README to keep consistency with
01db47
 other modules.
01db47
01db47
---
01db47
 README-dnsforwardzone.md | 10 +++++-----
01db47
 1 file changed, 5 insertions(+), 5 deletions(-)
01db47
01db47
diff --git a/README-dnsforwardzone.md b/README-dnsforwardzone.md
01db47
index 175e6f8b..32de7bfe 100644
01db47
--- a/README-dnsforwardzone.md
01db47
+++ b/README-dnsforwardzone.md
01db47
@@ -49,7 +49,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
01db47
   tasks:
01db47
   - name: ensure presence of forwardzone for DNS requests for example.com to 8.8.8.8
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -59,13 +59,13 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
01db47
 
01db47
   - name: ensure the forward zone is disabled
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: disabled
01db47
 
01db47
   - name: ensure presence of multiple upstream DNS servers for example.com
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -74,7 +74,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
01db47
 
01db47
   - name: ensure presence of another forwarder to any existing ones for example.com
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       state: present
01db47
       name: example.com
01db47
       forwarders:
01db47
@@ -83,7 +83,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
01db47
 
01db47
   - name: ensure the forwarder for example.com does not exists (delete it if needed)
01db47
     ipadnsforwardzone:
01db47
-      ipaadmin_password: password01
01db47
+      ipaadmin_password: SomeADMINpassword
01db47
       name: example.com
01db47
       state: absent
01db47
 ```