From 9c624548acace218cd665ce7731fa4cc2627c259 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Dec 11 2020 08:09:33 +0000 Subject: import ansible-freeipa-0.3.1-1.el8 --- diff --git a/.ansible-freeipa.metadata b/.ansible-freeipa.metadata index c58e727..ecf936d 100644 --- a/.ansible-freeipa.metadata +++ b/.ansible-freeipa.metadata @@ -1 +1 @@ -5d09d3b590e8568d04edb288c9c515e308f3168f SOURCES/ansible-freeipa-0.1.12.tar.gz +dc11a556890caa4a830711d7b6f4ac96e7096f75 SOURCES/ansible-freeipa-0.3.1.tar.gz diff --git a/.gitignore b/.gitignore index 7591236..dc1e5a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/ansible-freeipa-0.1.12.tar.gz +SOURCES/ansible-freeipa-0.3.1.tar.gz diff --git a/SOURCES/ansible-freeipa-0.1.12-Add-support-for-option-name_from_ip-in-ipadnszone-mo_rhbz#1845056.patch b/SOURCES/ansible-freeipa-0.1.12-Add-support-for-option-name_from_ip-in-ipadnszone-mo_rhbz#1845056.patch deleted file mode 100644 index 4adea24..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Add-support-for-option-name_from_ip-in-ipadnszone-mo_rhbz#1845056.patch +++ /dev/null @@ -1,556 +0,0 @@ -From abbd15e6f50718119b4dd0380913d2d646eb7638 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Mon, 3 Aug 2020 19:23:07 -0300 -Subject: [PATCH] Add support for option `name_from_ip` in ipadnszone module. - -IPA CLI has an option `name_from_ip` that provide a name for a zone -from the reverse IP address, so that it can be used to, for example, -manage PTR DNS records. - -This patch adds a similar attribute to ipadnszone module, where it -will try to find the proper zone name, using DNS resolve, or provide -a sane default, if a the zone name cannot be resolved. - -The option `name_from_ip` must be used instead of `name` in playbooks, -and it is a string, and not a list. - -A new example playbook was added: - - playbooks/dnszone/dnszone-reverse-from-ip.yml - -A new test playbook was added: - - tests/dnszone/test_dnszone_name_from_ip.yml ---- - README-dnszone.md | 3 +- - playbooks/dnszone/dnszone-reverse-from-ip.yml | 10 ++ - plugins/modules/ipadnszone.py | 65 +++++++++- - tests/dnszone/test_dnszone_name_from_ip.yml | 112 ++++++++++++++++++ - 4 files changed, 186 insertions(+), 4 deletions(-) - create mode 100644 playbooks/dnszone/dnszone-reverse-from-ip.yml - create mode 100644 tests/dnszone/test_dnszone_name_from_ip.yml - -diff --git a/README-dnszone.md b/README-dnszone.md -index 9c9b12c..48b019a 100644 ---- a/README-dnszone.md -+++ b/README-dnszone.md -@@ -163,7 +163,8 @@ Variable | Description | Required - -------- | ----------- | -------- - `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no - `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no --`name` \| `zone_name` | The zone name string or list of strings. | yes -+`name` \| `zone_name` | The zone name string or list of strings. | no -+`name_from_ip` | Derive zone name from reverse of IP (PTR). | no - `forwarders` | The list of forwarders dicts. Each `forwarders` dict entry has:| no -   | `ip_address` - The IPv4 or IPv6 address of the DNS server. | yes -   | `port` - The custom port that should be used on this server. | no -diff --git a/playbooks/dnszone/dnszone-reverse-from-ip.yml b/playbooks/dnszone/dnszone-reverse-from-ip.yml -new file mode 100644 -index 0000000..5693872 ---- /dev/null -+++ b/playbooks/dnszone/dnszone-reverse-from-ip.yml -@@ -0,0 +1,10 @@ -+--- -+- name: Playbook to ensure DNS zone exist -+ hosts: ipaserver -+ become: true -+ -+ tasks: -+ - name: Ensure zone exist, finding zone name from IP address. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 10.1.2.3 -diff --git a/plugins/modules/ipadnszone.py b/plugins/modules/ipadnszone.py -index c5e812a..901bfef 100644 ---- a/plugins/modules/ipadnszone.py -+++ b/plugins/modules/ipadnszone.py -@@ -43,6 +43,10 @@ options: - required: true - type: list - alises: ["zone_name"] -+ name_from_ip: -+ description: Derive zone name from reverse of IP (PTR). -+ required: false -+ type: str - forwarders: - description: The list of global DNS forwarders. - required: false -@@ -197,6 +201,12 @@ from ansible.module_utils.ansible_freeipa_module import ( - is_ipv6_addr, - is_valid_port, - ) # noqa: E402 -+import netaddr -+import six -+ -+ -+if six.PY3: -+ unicode = str - - - class DNSZoneModule(FreeIPABaseModule): -@@ -354,6 +364,31 @@ class DNSZoneModule(FreeIPABaseModule): - if not zone and self.ipa_params.skip_nameserver_check is not None: - return self.ipa_params.skip_nameserver_check - -+ def __reverse_zone_name(self, ipaddress): -+ """ -+ Infer reverse zone name from an ip address. -+ -+ This function uses the same heuristics as FreeIPA to infer the zone -+ name from ip. -+ """ -+ try: -+ ip = netaddr.IPAddress(str(ipaddress)) -+ except (netaddr.AddrFormatError, ValueError): -+ net = netaddr.IPNetwork(ipaddress) -+ items = net.ip.reverse_dns.split('.') -+ prefixlen = net.prefixlen -+ ip_version = net.version -+ else: -+ items = ip.reverse_dns.split('.') -+ prefixlen = 24 if ip.version == 4 else 64 -+ ip_version = ip.version -+ if ip_version == 4: -+ return u'.'.join(items[4 - prefixlen // 8:]) -+ elif ip_version == 6: -+ return u'.'.join(items[32 - prefixlen // 4:]) -+ else: -+ self.fail_json(msg="Invalid IP version for reverse zone.") -+ - def get_zone(self, zone_name): - get_zone_args = {"idnsname": zone_name, "all": True} - response = self.api_command("dnszone_find", args=get_zone_args) -@@ -368,14 +403,33 @@ class DNSZoneModule(FreeIPABaseModule): - return zone, is_zone_active - - def get_zone_names(self): -- if len(self.ipa_params.name) > 1 and self.ipa_params.state != "absent": -+ zone_names = self.__get_zone_names_from_params() -+ if len(zone_names) > 1 and self.ipa_params.state != "absent": - self.fail_json( - msg=("Please provide a single name. Multiple values for 'name'" - "can only be supplied for state 'absent'.") - ) - -+ return zone_names -+ -+ def __get_zone_names_from_params(self): -+ if not self.ipa_params.name: -+ return [self.__reverse_zone_name(self.ipa_params.name_from_ip)] - return self.ipa_params.name - -+ def check_ipa_params(self): -+ if not self.ipa_params.name and not self.ipa_params.name_from_ip: -+ self.fail_json( -+ msg="Either `name` or `name_from_ip` must be provided." -+ ) -+ if self.ipa_params.state != "present" and self.ipa_params.name_from_ip: -+ self.fail_json( -+ msg=( -+ "Cannot use argument `name_from_ip` with state `%s`." -+ % self.ipa_params.state -+ ) -+ ) -+ - def define_ipa_commands(self): - for zone_name in self.get_zone_names(): - # Look for existing zone in IPA -@@ -434,8 +488,9 @@ def get_argument_spec(): - ipaadmin_principal=dict(type="str", default="admin"), - ipaadmin_password=dict(type="str", required=False, no_log=True), - name=dict( -- type="list", default=None, required=True, aliases=["zone_name"] -+ type="list", default=None, required=False, aliases=["zone_name"] - ), -+ name_from_ip=dict(type="str", default=None, required=False), - forwarders=dict( - type="list", - default=None, -@@ -475,7 +530,11 @@ def get_argument_spec(): - - - def main(): -- DNSZoneModule(argument_spec=get_argument_spec()).ipa_run() -+ DNSZoneModule( -+ argument_spec=get_argument_spec(), -+ mutually_exclusive=[["name", "name_from_ip"]], -+ required_one_of=[["name", "name_from_ip"]], -+ ).ipa_run() - - - if __name__ == "__main__": -diff --git a/tests/dnszone/test_dnszone_name_from_ip.yml b/tests/dnszone/test_dnszone_name_from_ip.yml -new file mode 100644 -index 0000000..9bd2eb0 ---- /dev/null -+++ b/tests/dnszone/test_dnszone_name_from_ip.yml -@@ -0,0 +1,112 @@ -+--- -+- name: Test dnszone -+ hosts: ipaserver -+ become: yes -+ gather_facts: yes -+ -+ tasks: -+ -+ # Setup -+ - name: Ensure zone is absent. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: "{{ item }}" -+ state: absent -+ with_items: -+ - 2.0.192.in-addr.arpa. -+ - 0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.f.ip6.arpa. -+ - 1.0.0.0.e.f.a.c.8.b.d.0.1.0.0.2.ip6.arpa. -+ -+ # tests -+ - name: Ensure zone exists for reverse IP. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 192.0.2.3/24 -+ register: ipv4_zone -+ failed_when: not ipv4_zone.changed or ipv4_zone.failed -+ -+ - name: Ensure zone exists for reverse IP, again. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 192.0.2.3/24 -+ register: result -+ failed_when: result.changed or result.failed -+ -+ - name: Ensure zone exists for reverse IP, given the zone name. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: "{{ ipv4_zone.dnszone.name }}" -+ register: result -+ failed_when: result.changed or result.failed -+ -+ - name: Modify existing zone, using `name_from_ip`. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 192.0.2.3/24 -+ default_ttl: 1234 -+ register: result -+ failed_when: not result.changed -+ -+ - name: Modify existing zone, using `name_from_ip`, again. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 192.0.2.3/24 -+ default_ttl: 1234 -+ register: result -+ failed_when: result.changed or result.failed -+ -+ - name: Ensure ipv6 zone exists for reverse IPv6. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: fd00::0001 -+ register: ipv6_zone -+ failed_when: not ipv6_zone.changed or ipv6_zone.failed -+ -+ # - debug: -+ # msg: "{{ipv6_zone}}" -+ -+ - name: Ensure ipv6 zone was created. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: "{{ ipv6_zone.dnszone.name }}" -+ register: result -+ failed_when: result.changed or result.failed -+ -+ - name: Ensure ipv6 zone exists for reverse IPv6, again. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: fd00::0001 -+ register: result -+ failed_when: result.changed -+ -+ - name: Ensure second ipv6 zone exists for reverse IPv6. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 2001:db8:cafe:1::1 -+ register: ipv6_sec_zone -+ failed_when: not ipv6_sec_zone.changed or ipv6_zone.failed -+ -+ - name: Ensure second ipv6 zone was created. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: "{{ ipv6_sec_zone.dnszone.name }}" -+ register: result -+ failed_when: result.changed or result.failed -+ -+ - name: Ensure second ipv6 zone exists for reverse IPv6, again. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 2001:db8:cafe:1::1 -+ register: result -+ failed_when: result.changed -+ -+ # Cleanup -+ - name: Ensure zone is absent. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: "{{ item }}" -+ state: absent -+ with_items: -+ - "{{ ipv6_zone.dnszone.name }}" -+ - "{{ ipv6_sec_zone.dnszone.name }}" -+ - "{{ ipv4_zone.dnszone.name }}" --- -2.26.2 - -From 531e544b30e69f436d14c4ce18c67998c1a0774b Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Wed, 5 Aug 2020 15:13:46 -0300 -Subject: [PATCH] Added support for client defined result data in - FReeIPABaseModule - -Modified support for processing result of IPA API commands so that -client code can define its own processing and add return values to -self.exit_args based on command result. - -If a subclass need to process the result of IPA API commands it should -override the method `process_command_result`. The default implementation -will simply evaluate if `changed` should be true. ---- - .../module_utils/ansible_freeipa_module.py | 22 +++++++++++++------ - plugins/modules/ipadnszone.py | 8 +++++++ - 2 files changed, 23 insertions(+), 7 deletions(-) - -diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py -index 4799e5a..30302b4 100644 ---- a/plugins/module_utils/ansible_freeipa_module.py -+++ b/plugins/module_utils/ansible_freeipa_module.py -@@ -619,7 +619,7 @@ class FreeIPABaseModule(AnsibleModule): - if exc_val: - self.fail_json(msg=str(exc_val)) - -- self.exit_json(changed=self.changed, user=self.exit_args) -+ self.exit_json(changed=self.changed, **self.exit_args) - - def get_command_errors(self, command, result): - """Look for erros into command results.""" -@@ -658,14 +658,22 @@ class FreeIPABaseModule(AnsibleModule): - except Exception as excpt: - self.fail_json(msg="%s: %s: %s" % (command, name, str(excpt))) - else: -- if "completed" in result: -- if result["completed"] > 0: -- self.changed = True -- else: -- self.changed = True -- -+ self.process_command_result(name, command, args, result) - self.get_command_errors(command, result) - -+ def process_command_result(self, name, command, args, result): -+ """ -+ Process an API command result. -+ -+ This method can be overriden in subclasses, and change self.exit_values -+ to return data in the result for the controller. -+ """ -+ if "completed" in result: -+ if result["completed"] > 0: -+ self.changed = True -+ else: -+ self.changed = True -+ - def require_ipa_attrs_change(self, command_args, ipa_attrs): - """ - Compare given args with current object attributes. -diff --git a/plugins/modules/ipadnszone.py b/plugins/modules/ipadnszone.py -index 901bfef..6a90fa2 100644 ---- a/plugins/modules/ipadnszone.py -+++ b/plugins/modules/ipadnszone.py -@@ -472,6 +472,14 @@ class DNSZoneModule(FreeIPABaseModule): - } - self.add_ipa_command("dnszone_mod", zone_name, args) - -+ def process_command_result(self, name, command, args, result): -+ super(DNSZoneModule, self).process_command_result( -+ name, command, args, result -+ ) -+ if command == "dnszone_add" and self.ipa_params.name_from_ip: -+ dnszone_exit_args = self.exit_args.setdefault('dnszone', {}) -+ dnszone_exit_args['name'] = name -+ - - def get_argument_spec(): - forwarder_spec = dict( --- -2.26.2 - -From 41e8226d0c03e06816626d78cecbc2aebf547691 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Wed, 5 Aug 2020 15:14:43 -0300 -Subject: [PATCH] Return the zone_name when adding a zone with name_from_ip. - -When adding a zone using the option name_from_ip, the user have -little control over the final name of the zone, and if this name -is to be used in further processing in a playbook it might lead to -errors if the inferred name does not match what the user wanted to. - -By returning the actual inferred zone name, the name can be safely -used for other tasks in the playbook. ---- - README-dnszone.md | 11 +++++++++++ - playbooks/dnszone/dnszone-reverse-from-ip.yml | 7 ++++++- - plugins/modules/ipadnszone.py | 8 ++++++++ - 3 files changed, 25 insertions(+), 1 deletion(-) - -diff --git a/README-dnszone.md b/README-dnszone.md -index 48b019a..3f4827b 100644 ---- a/README-dnszone.md -+++ b/README-dnszone.md -@@ -190,6 +190,17 @@ Variable | Description | Required - `skip_nameserver_check` | Force DNS zone creation even if nameserver is not resolvable | no - - -+Return Values -+============= -+ -+ipadnszone -+---------- -+ -+Variable | Description | Returned When -+-------- | ----------- | ------------- -+`dnszone` | DNS Zone dict with zone name infered from `name_from_ip`.
Options: | If `state` is `present`, `name_from_ip` is used, and a zone was created. -+  | `name` - The name of the zone created, inferred from `name_from_ip`. | Always -+ - Authors - ======= - -diff --git a/playbooks/dnszone/dnszone-reverse-from-ip.yml b/playbooks/dnszone/dnszone-reverse-from-ip.yml -index 5693872..218a318 100644 ---- a/playbooks/dnszone/dnszone-reverse-from-ip.yml -+++ b/playbooks/dnszone/dnszone-reverse-from-ip.yml -@@ -7,4 +7,9 @@ - - name: Ensure zone exist, finding zone name from IP address. - ipadnszone: - ipaadmin_password: SomeADMINpassword -- name_from_ip: 10.1.2.3 -+ name_from_ip: 10.1.2.3/24 -+ register: result -+ -+ - name: Zone name inferred from `name_from_ip` -+ debug: -+ msg: "Zone created: {{ result.dnszone.name }}" -diff --git a/plugins/modules/ipadnszone.py b/plugins/modules/ipadnszone.py -index 6a90fa2..93eac07 100644 ---- a/plugins/modules/ipadnszone.py -+++ b/plugins/modules/ipadnszone.py -@@ -192,6 +192,14 @@ EXAMPLES = """ - """ - - RETURN = """ -+dnszone: -+ description: DNS Zone dict with zone name infered from `name_from_ip`. -+ returned: -+ If `state` is `present`, `name_from_ip` is used, and a zone was created. -+ options: -+ name: -+ description: The name of the zone created, inferred from `name_from_ip`. -+ returned: always - """ - - from ipapython.dnsutil import DNSName # noqa: E402 --- -2.26.2 - -From 46bbc7bbd7a4e01d07b0390aee8c799aaa5ac895 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Mon, 17 Aug 2020 15:52:38 -0300 -Subject: [PATCH] Document usage of `name_from_ip`. - -Since `name_from_ip` has a similar, but not equal, behavior to `name`, -and as the inferred DNS zone might depend on DNS configuration and -can be different than the user expects, it has some limited usage, -and the user must be aware of its effects. - -This change to the documentation enhance the documentation including -more details on the attribute usage. ---- - README-dnszone.md | 42 ++++++++++++++++++++++++++++++++++- - plugins/modules/ipadnszone.py | 4 +++- - 2 files changed, 44 insertions(+), 2 deletions(-) - -diff --git a/README-dnszone.md b/README-dnszone.md -index 3f4827b..c5a7ab3 100644 ---- a/README-dnszone.md -+++ b/README-dnszone.md -@@ -152,6 +152,46 @@ Example playbook to remove a zone: - - ``` - -+Example playbook to create a zone for reverse DNS lookup, from an IP address: -+ -+```yaml -+ -+--- -+- name: dnszone present -+ hosts: ipaserver -+ become: true -+ -+ tasks: -+ - name: Ensure zone for reverse DNS lookup is present. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 192.168.1.2 -+ state: present -+``` -+ -+Note that, on the previous example the zone created with `name_from_ip` might be "1.168.192.in-addr.arpa.", "168.192.in-addr.arpa.", or "192.in-addr.arpa.", depending on the DNS response the system get while querying for zones, and for this reason, when creating a zone using `name_from_ip`, the inferred zone name is returned to the controller, in the attribute `dnszone.name`. Since the zone inferred might not be what a user expects, `name_from_ip` can only be used with `state: present`. To have more control over the zone name, the prefix length for the IP address can be provided. -+ -+Example playbook to create a zone for reverse DNS lookup, from an IP address, given the prefix length and displaying the resulting zone name: -+ -+```yaml -+ -+--- -+- name: dnszone present -+ hosts: ipaserver -+ become: true -+ -+ tasks: -+ - name: Ensure zone for reverse DNS lookup is present. -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name_from_ip: 192.168.1.2/24 -+ state: present -+ register: result -+ - name: Display inferred zone name. -+ debug: -+ msg: "Zone name: {{ result.dnszone.name }}" -+``` -+ - - Variables - ========= -@@ -164,7 +204,7 @@ Variable | Description | Required - `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no - `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no - `name` \| `zone_name` | The zone name string or list of strings. | no --`name_from_ip` | Derive zone name from reverse of IP (PTR). | no -+`name_from_ip` | Derive zone name from reverse of IP (PTR). Can only be used with `state: present`. | no - `forwarders` | The list of forwarders dicts. Each `forwarders` dict entry has:| no -   | `ip_address` - The IPv4 or IPv6 address of the DNS server. | yes -   | `port` - The custom port that should be used on this server. | no -diff --git a/plugins/modules/ipadnszone.py b/plugins/modules/ipadnszone.py -index 93eac07..ff6bfff 100644 ---- a/plugins/modules/ipadnszone.py -+++ b/plugins/modules/ipadnszone.py -@@ -44,7 +44,9 @@ options: - type: list - alises: ["zone_name"] - name_from_ip: -- description: Derive zone name from reverse of IP (PTR). -+ description: | -+ Derive zone name from reverse of IP (PTR). -+ Can only be used with `state: present`. - required: false - type: str - forwarders: --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-Add-suppport-for-changing-password-of-symmetric-vaults_rhbz#1839197.patch b/SOURCES/ansible-freeipa-0.1.12-Add-suppport-for-changing-password-of-symmetric-vaults_rhbz#1839197.patch deleted file mode 100644 index 8ff43ea..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Add-suppport-for-changing-password-of-symmetric-vaults_rhbz#1839197.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 78b635ae78346fdfb298dd0d0c82ae1ff34b754a Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Tue, 23 Jun 2020 17:53:47 -0300 -Subject: [PATCH] Add suppport for changing password of symmetric vaults. - -Allows changing passwords of symmetric waults, using a new variable -`new_password` (or the file-base version, `new_password_file`). The -old password must be passed using the `password` or `password_file` -variables that also received new aliases `old_password` and -`old_password_file`, respectively. - -Tests were modyfied to reflect the changes. ---- - README-vault.md | 23 +++- - .../vault/change-password-symmetric-vault.yml | 2 +- - plugins/modules/ipavault.py | 129 +++++++++++++++--- - tests/vault/test_vault_symmetric.yml | 64 +++++++++ - 4 files changed, 194 insertions(+), 24 deletions(-) - -diff --git a/README-vault.md b/README-vault.md -index c7ae6916..fa1d3e11 100644 ---- a/README-vault.md -+++ b/README-vault.md -@@ -165,6 +165,22 @@ Example playbook to make sure vault data is absent in a symmetric vault: - state: absent - ``` - -+Example playbook to change the password of a symmetric: -+ -+```yaml -+--- -+- name: Playbook to handle vaults -+ hosts: ipaserver -+ become: true -+ -+ tasks: -+ - ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ old_password: SomeVAULTpassword -+ new_password: SomeNEWpassword -+``` -+ - Example playbook to make sure vault is absent: - - ```yaml -@@ -197,8 +213,11 @@ Variable | Description | Required - `name` \| `cn` | The list of vault name strings. | yes - `description` | The vault description string. | no - `nomembers` | Suppress processing of membership attributes. (bool) | no --`password ` \| `vault_password` \| `ipavaultpassword` | Vault password. | no --`public_key ` \| `vault_public_key` \| `ipavaultpublickey` | Base64 encoded vault public key. | no -+`password` \| `vault_password` \| `ipavaultpassword` \| `old_password`| Vault password. | no -+`password_file` \| `vault_password_file` \| `old_password_file`| File containing Base64 encoded Vault password. | no -+`new_password` | Vault new password. | no -+`new_password_file` | File containing Base64 encoded new Vault password. | no -+`public_key ` \| `vault_public_key` \| `old_password_file` | Base64 encoded vault public key. | no - `public_key_file` \| `vault_public_key_file` | Path to file with public key. | no - `private_key `\| `vault_private_key` | Base64 encoded vault private key. Used only to retrieve data. | no - `private_key_file` \| `vault_private_key_file` | Path to file with private key. Used only to retrieve data. | no -diff --git a/playbooks/vault/change-password-symmetric-vault.yml b/playbooks/vault/change-password-symmetric-vault.yml -index 3871f45d..396a79f6 100644 ---- a/playbooks/vault/change-password-symmetric-vault.yml -+++ b/playbooks/vault/change-password-symmetric-vault.yml -@@ -10,7 +10,7 @@ - ipaadmin_password: SomeADMINpassword - name: symvault - password: SomeVAULTpassword -- - name: Change vault passord. -+ - name: Change vault password. - ipavault: - ipaadmin_password: SomeADMINpassword - name: symvault -diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py -index ad5dd413..46c6fcdb 100644 ---- a/plugins/modules/ipavault.py -+++ b/plugins/modules/ipavault.py -@@ -69,12 +69,20 @@ - description: password to be used on symmetric vault. - required: false - type: string -- aliases: ["ipavaultpassword", "vault_password"] -+ aliases: ["ipavaultpassword", "vault_password", "old_password"] - password_file: - description: file with password to be used on symmetric vault. - required: false - type: string -- aliases: ["vault_password_file"] -+ aliases: ["vault_password_file", "old_password_file"] -+ new_password: -+ description: new password to be used on symmetric vault. -+ required: false -+ type: string -+ new_password_file: -+ description: file with new password to be used on symmetric vault. -+ required: false -+ type: string - salt: - description: Vault salt. - required: false -@@ -235,7 +243,15 @@ - state: retrieved - register: result - - debug: -- msg: "{{ result.data | b64decode }}" -+ msg: "{{ result.data }}" -+ -+# Change password of a symmetric vault -+- ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ username: admin -+ old_password: SomeVAULTpassword -+ new_password: SomeNEWpassword - - # Ensure vault symvault is absent - - ipavault: -@@ -416,18 +432,29 @@ def check_parameters(module, state, action, description, username, service, - shared, users, groups, services, owners, ownergroups, - ownerservices, vault_type, salt, password, password_file, - public_key, public_key_file, private_key, -- private_key_file, vault_data, datafile_in, datafile_out): -+ private_key_file, vault_data, datafile_in, datafile_out, -+ new_password, new_password_file): - invalid = [] - if state == "present": - invalid = ['private_key', 'private_key_file', 'datafile_out'] - -+ if all([password, password_file]) \ -+ or all([new_password, new_password_file]): -+ module.fail_json(msg="Password specified multiple times.") -+ -+ if any([new_password, new_password_file]) \ -+ and not any([password, password_file]): -+ module.fail_json( -+ msg="Either `password` or `password_file` must be provided to " -+ "change symmetric vault password.") -+ - if action == "member": - invalid.extend(['description']) - - elif state == "absent": - invalid = ['description', 'salt', 'vault_type', 'private_key', - 'private_key_file', 'datafile_in', 'datafile_out', -- 'vault_data'] -+ 'vault_data', 'new_password', 'new_password_file'] - - if action == "vault": - invalid.extend(['users', 'groups', 'services', 'owners', -@@ -437,7 +464,7 @@ def check_parameters(module, state, action, description, username, service, - elif state == "retrieved": - invalid = ['description', 'salt', 'datafile_in', 'users', 'groups', - 'owners', 'ownergroups', 'public_key', 'public_key_file', -- 'vault_data'] -+ 'vault_data', 'new_password', 'new_password_file'] - if action == 'member': - module.fail_json( - msg="State `retrieved` do not support action `member`.") -@@ -458,11 +485,17 @@ def check_parameters(module, state, action, description, username, service, - def check_encryption_params(module, state, action, vault_type, salt, - password, password_file, public_key, - public_key_file, private_key, private_key_file, -- vault_data, datafile_in, datafile_out, res_find): -+ vault_data, datafile_in, datafile_out, -+ new_password, new_password_file, res_find): - vault_type_invalid = [] -+ -+ if res_find is not None: -+ vault_type = res_find['ipavaulttype'] -+ - if vault_type == "standard": - vault_type_invalid = ['public_key', 'public_key_file', 'password', -- 'password_file', 'salt'] -+ 'password_file', 'salt', 'new_password', -+ 'new_password_file'] - - if vault_type is None or vault_type == "symmetric": - vault_type_invalid = ['public_key', 'public_key_file', -@@ -473,8 +506,14 @@ def check_encryption_params(module, state, action, vault_type, salt, - msg="Symmetric vault requires password or password_file " - "to store data or change `salt`.") - -+ if any([new_password, new_password_file]) and res_find is None: -+ module.fail_json( -+ msg="Cannot modify password of inexistent vault.") -+ - if vault_type == "asymmetric": -- vault_type_invalid = ['password', 'password_file'] -+ vault_type_invalid = [ -+ 'password', 'password_file', 'new_password', 'new_password_file' -+ ] - if not any([public_key, public_key_file]) and res_find is None: - module.fail_json( - msg="Assymmetric vault requires public_key " -@@ -487,6 +526,43 @@ def check_encryption_params(module, state, action, vault_type, salt, - (param, vault_type or 'symmetric')) - - -+def change_password(module, res_find, password, password_file, new_password, -+ new_password_file): -+ """ -+ Change the password of a symmetric vault. -+ -+ To change the password of a vault, it is needed to retrieve the stored -+ data with the current password, and store the data again, with the new -+ password, forcing it to override the old one. -+ """ -+ # verify parameters. -+ if not any([new_password, new_password_file]): -+ return [] -+ if res_find["ipavaulttype"][0] != "symmetric": -+ module.fail_json(msg="Cannot change password of `%s` vault." -+ % res_find["ipavaulttype"]) -+ -+ # prepare arguments to retrieve data. -+ name = res_find["cn"][0] -+ args = {} -+ if password: -+ args["password"] = password -+ if password_file: -+ args["password"] = password_file -+ # retrieve current stored data -+ result = api_command(module, 'vault_retrieve', name, args) -+ args['data'] = result['result']['data'] -+ -+ # modify arguments to store data with new password. -+ if password: -+ args["password"] = new_password -+ if password_file: -+ args["password"] = new_password_file -+ args["override_password"] = True -+ # return the command to store data with the new password. -+ return [(name, "vault_archive", args)] -+ -+ - def main(): - ansible_module = AnsibleModule( - argument_spec=dict( -@@ -533,10 +609,18 @@ def main(): - datafile_out=dict(type="str", required=False, default=None, - aliases=['out']), - vault_password=dict(type="str", required=False, default=None, -- aliases=['ipavaultpassword', 'password'], -- no_log=True), -+ no_log=True, -+ aliases=['ipavaultpassword', 'password', -+ "old_password"]), - vault_password_file=dict(type="str", required=False, default=None, -- no_log=False, aliases=['password_file']), -+ no_log=False, -+ aliases=[ -+ 'password_file', "old_password_file" -+ ]), -+ new_password=dict(type="str", required=False, default=None, -+ no_log=True), -+ new_password_file=dict(type="str", required=False, default=None, -+ no_log=False), - # state - action=dict(type="str", default="vault", - choices=["vault", "data", "member"]), -@@ -546,6 +630,7 @@ def main(): - supports_check_mode=True, - mutually_exclusive=[['username', 'service', 'shared'], - ['datafile_in', 'vault_data'], -+ ['new_password', 'new_password_file'], - ['vault_password', 'vault_password_file'], - ['vault_public_key', 'vault_public_key_file']], - ) -@@ -576,6 +661,8 @@ def main(): - salt = module_params_get(ansible_module, "vault_salt") - password = module_params_get(ansible_module, "vault_password") - password_file = module_params_get(ansible_module, "vault_password_file") -+ new_password = module_params_get(ansible_module, "new_password") -+ new_password_file = module_params_get(ansible_module, "new_password_file") - public_key = module_params_get(ansible_module, "vault_public_key") - public_key_file = module_params_get(ansible_module, - "vault_public_key_file") -@@ -614,7 +701,8 @@ def main(): - service, shared, users, groups, services, owners, - ownergroups, ownerservices, vault_type, salt, password, - password_file, public_key, public_key_file, private_key, -- private_key_file, vault_data, datafile_in, datafile_out) -+ private_key_file, vault_data, datafile_in, datafile_out, -+ new_password, new_password_file) - # Init - - changed = False -@@ -660,7 +748,7 @@ def main(): - ansible_module, state, action, vault_type, salt, password, - password_file, public_key, public_key_file, private_key, - private_key_file, vault_data, datafile_in, datafile_out, -- res_find) -+ new_password, new_password_file, res_find) - - # Found the vault - if action == "vault": -@@ -721,7 +809,6 @@ def main(): - owner_add_args = gen_member_args( - args, owner_add, ownergroups_add, ownerservice_add) - if owner_add_args is not None: -- # ansible_module.warn("OWNER ADD: %s" % owner_add_args) - commands.append( - [name, 'vault_add_owner', owner_add_args]) - -@@ -729,7 +816,6 @@ def main(): - owner_del_args = gen_member_args( - args, owner_del, ownergroups_del, ownerservice_del) - if owner_del_args is not None: -- # ansible_module.warn("OWNER DEL: %s" % owner_del_args) - commands.append( - [name, 'vault_remove_owner', owner_del_args]) - -@@ -758,19 +844,22 @@ def main(): - if any([vault_data, datafile_in]): - commands.append([name, "vault_archive", pwdargs]) - -+ cmds = change_password( -+ ansible_module, res_find, password, password_file, -+ new_password, new_password_file) -+ commands.extend(cmds) -+ - elif state == "retrieved": - if res_find is None: - ansible_module.fail_json( - msg="Vault `%s` not found to retrieve data." % name) - -- vault_type = res_find['cn'] -- - # verify data encription args - check_encryption_params( - ansible_module, state, action, vault_type, salt, password, - password_file, public_key, public_key_file, private_key, - private_key_file, vault_data, datafile_in, datafile_out, -- res_find) -+ new_password, new_password_file, res_find) - - pwdargs = data_storage_args( - args, vault_data, password, password_file, private_key, -@@ -813,7 +902,6 @@ def main(): - errors = [] - for name, command, args in commands: - try: -- # ansible_module.warn("RUN: %s %s %s" % (command, name, args)) - result = api_command(ansible_module, command, name, args) - - if command == 'vault_archive': -@@ -829,7 +917,6 @@ def main(): - raise Exception("No data retrieved.") - changed = False - else: -- # ansible_module.warn("RESULT: %s" % (result)) - if "completed" in result: - if result["completed"] > 0: - changed = True -diff --git a/tests/vault/test_vault_symmetric.yml b/tests/vault/test_vault_symmetric.yml -index c9429f4f..a6072d88 100644 ---- a/tests/vault/test_vault_symmetric.yml -+++ b/tests/vault/test_vault_symmetric.yml -@@ -178,6 +178,61 @@ - register: result - failed_when: result.data != 'Hello World.' or result.changed - -+ - name: Change vault password. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ password: SomeVAULTpassword -+ new_password: SomeNEWpassword -+ register: result -+ failed_when: not result.changed -+ -+ - name: Retrieve data from symmetric vault, with wrong password. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ password: SomeVAULTpassword -+ state: retrieved -+ register: result -+ failed_when: not result.failed or "Invalid credentials" not in result.msg -+ -+ - name: Change vault password, with wrong `old_password`. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ password: SomeVAULTpassword -+ new_password: SomeNEWpassword -+ register: result -+ failed_when: not result.failed or "Invalid credentials" not in result.msg -+ -+ - name: Retrieve data from symmetric vault, with new password. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ password: SomeNEWpassword -+ state: retrieved -+ register: result -+ failed_when: result.data != 'Hello World.' or result.changed -+ -+ - name: Try to add vault with multiple passwords. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: inexistentvault -+ password: SomeVAULTpassword -+ password_file: "{{ ansible_env.HOME }}/password.txt" -+ register: result -+ failed_when: not result.failed or "parameters are mutually exclusive" not in result.msg -+ -+ - name: Try to add vault with multiple new passwords. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: inexistentvault -+ password: SomeVAULTpassword -+ new_password: SomeVAULTpassword -+ new_password_file: "{{ ansible_env.HOME }}/password.txt" -+ register: result -+ failed_when: not result.failed or "parameters are mutually exclusive" not in result.msg -+ - - name: Ensure symmetric vault is absent - ipavault: - ipaadmin_password: SomeADMINpassword -@@ -194,5 +249,14 @@ - register: result - failed_when: result.changed - -+ - name: Try to change password of inexistent vault. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: inexistentvault -+ password: SomeVAULTpassword -+ new_password: SomeNEWpassword -+ register: result -+ failed_when: not result.failed or "Cannot modify password of inexistent vault" not in result.msg -+ - - name: Cleanup testing environment. - import_tasks: env_cleanup.yml diff --git a/SOURCES/ansible-freeipa-0.1.12-Allow-multiple-dns-zones-to-be-absent_rhbz#1845058.patch b/SOURCES/ansible-freeipa-0.1.12-Allow-multiple-dns-zones-to-be-absent_rhbz#1845058.patch deleted file mode 100644 index 76ae37f..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Allow-multiple-dns-zones-to-be-absent_rhbz#1845058.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 75d16c2da4a5621943873a26343eb0f2acc2a925 Mon Sep 17 00:00:00 2001 -From: Sergio Oliveira Campos -Date: Mon, 3 Aug 2020 11:54:44 -0300 -Subject: [PATCH] Allow multiple dns zones to be absent. - -This PR allow ipadnszone module to ensure that multiple dns zones -are absent at once, to be consistent with other ansible-freeipa -modules. - -To fix this issue, it was required that custom arguents must be -passed using keyword arguments so that `get_ipa_command_args()` -is kept generic. ---- - README-dnszone.md | 2 +- - .../module_utils/ansible_freeipa_module.py | 4 +- - plugins/modules/ipadnszone.py | 126 ++++++++++-------- - tests/dnszone/test_dnszone.yml | 37 +++++ - 4 files changed, 107 insertions(+), 62 deletions(-) - -diff --git a/README-dnszone.md b/README-dnszone.md -index 766efe5..9c9b12c 100644 ---- a/README-dnszone.md -+++ b/README-dnszone.md -@@ -163,7 +163,7 @@ Variable | Description | Required - -------- | ----------- | -------- - `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no - `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no --`name` \| `zone_name` | The zone name string. | yes -+`name` \| `zone_name` | The zone name string or list of strings. | yes - `forwarders` | The list of forwarders dicts. Each `forwarders` dict entry has:| no -   | `ip_address` - The IPv4 or IPv6 address of the DNS server. | yes -   | `port` - The custom port that should be used on this server. | no -diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py -index 122ea2e..1e55693 100644 ---- a/plugins/module_utils/ansible_freeipa_module.py -+++ b/plugins/module_utils/ansible_freeipa_module.py -@@ -506,7 +506,7 @@ class FreeIPABaseModule(AnsibleModule): - # when needed. - self.ipa_params = AnsibleFreeIPAParams(self) - -- def get_ipa_command_args(self): -+ def get_ipa_command_args(self, **kwargs): - """ - Return a dict to be passed to an IPA command. - -@@ -538,7 +538,7 @@ class FreeIPABaseModule(AnsibleModule): - elif hasattr(self, param_name): - method = getattr(self, param_name) - if callable(method): -- value = method() -+ value = method(**kwargs) - - # We don't have a way to guess the value so fail. - else: -diff --git a/plugins/modules/ipadnszone.py b/plugins/modules/ipadnszone.py -index 717978e..c5e812a 100644 ---- a/plugins/modules/ipadnszone.py -+++ b/plugins/modules/ipadnszone.py -@@ -41,7 +41,7 @@ options: - name: - description: The zone name string. - required: true -- type: str -+ type: list - alises: ["zone_name"] - forwarders: - description: The list of global DNS forwarders. -@@ -268,7 +268,7 @@ class DNSZoneModule(FreeIPABaseModule): - - return True - -- def get_ipa_nsec3paramrecord(self): -+ def get_ipa_nsec3paramrecord(self, **kwargs): - nsec3param_rec = self.ipa_params.nsec3param_rec - if nsec3param_rec is not None: - error_msg = ( -@@ -280,7 +280,7 @@ class DNSZoneModule(FreeIPABaseModule): - self.fail_json(msg=error_msg) - return nsec3param_rec - -- def get_ipa_idnsforwarders(self): -+ def get_ipa_idnsforwarders(self, **kwargs): - if self.ipa_params.forwarders is not None: - forwarders = [] - for forwarder in self.ipa_params.forwarders: -@@ -304,14 +304,14 @@ class DNSZoneModule(FreeIPABaseModule): - - return forwarders - -- def get_ipa_idnsallowtransfer(self): -+ def get_ipa_idnsallowtransfer(self, **kwargs): - if self.ipa_params.allow_transfer is not None: - error_msg = "Invalid ip_address for DNS allow_transfer: %s" - self.validate_ips(self.ipa_params.allow_transfer, error_msg) - - return (";".join(self.ipa_params.allow_transfer) or "none") + ";" - -- def get_ipa_idnsallowquery(self): -+ def get_ipa_idnsallowquery(self, **kwargs): - if self.ipa_params.allow_query is not None: - error_msg = "Invalid ip_address for DNS allow_query: %s" - self.validate_ips(self.ipa_params.allow_query, error_msg) -@@ -334,81 +334,89 @@ class DNSZoneModule(FreeIPABaseModule): - - return ".".join((name, domain)) - -- def get_ipa_idnssoarname(self): -+ def get_ipa_idnssoarname(self, **kwargs): - if self.ipa_params.admin_email is not None: - return DNSName( - self._replace_at_symbol_in_rname(self.ipa_params.admin_email) - ) - -- def get_ipa_idnssoamname(self): -+ def get_ipa_idnssoamname(self, **kwargs): - if self.ipa_params.name_server is not None: - return DNSName(self.ipa_params.name_server) - -- def get_ipa_skip_overlap_check(self): -- if not self.zone and self.ipa_params.skip_overlap_check is not None: -+ def get_ipa_skip_overlap_check(self, **kwargs): -+ zone = kwargs.get('zone') -+ if not zone and self.ipa_params.skip_overlap_check is not None: - return self.ipa_params.skip_overlap_check - -- def get_ipa_skip_nameserver_check(self): -- if not self.zone and self.ipa_params.skip_nameserver_check is not None: -+ def get_ipa_skip_nameserver_check(self, **kwargs): -+ zone = kwargs.get('zone') -+ if not zone and self.ipa_params.skip_nameserver_check is not None: - return self.ipa_params.skip_nameserver_check - - def get_zone(self, zone_name): - get_zone_args = {"idnsname": zone_name, "all": True} - response = self.api_command("dnszone_find", args=get_zone_args) - -+ zone = None -+ is_zone_active = False -+ - if response["count"] == 1: -- self.zone = response["result"][0] -- self.is_zone_active = self.zone.get("idnszoneactive") == ["TRUE"] -- return self.zone -+ zone = response["result"][0] -+ is_zone_active = zone.get("idnszoneactive") == ["TRUE"] - -- # Zone doesn't exist yet -- self.zone = None -- self.is_zone_active = False -+ return zone, is_zone_active -+ -+ def get_zone_names(self): -+ if len(self.ipa_params.name) > 1 and self.ipa_params.state != "absent": -+ self.fail_json( -+ msg=("Please provide a single name. Multiple values for 'name'" -+ "can only be supplied for state 'absent'.") -+ ) - -- @property -- def zone_name(self): - return self.ipa_params.name - - def define_ipa_commands(self): -- # Look for existing zone in IPA -- self.get_zone(self.zone_name) -- args = self.get_ipa_command_args() -- just_added = False -- -- if self.ipa_params.state in ["present", "enabled", "disabled"]: -- if not self.zone: -- # Since the zone doesn't exist we just create it -- # with given args -- self.add_ipa_command("dnszone_add", self.zone_name, args) -- self.is_zone_active = True -- just_added = True -- -- else: -- # Zone already exist so we need to verify if given args -- # matches the current config. If not we updated it. -- if self.require_ipa_attrs_change(args, self.zone): -- self.add_ipa_command("dnszone_mod", self.zone_name, args) -- -- if self.ipa_params.state == "enabled" and not self.is_zone_active: -- self.add_ipa_command("dnszone_enable", self.zone_name) -- -- if self.ipa_params.state == "disabled" and self.is_zone_active: -- self.add_ipa_command("dnszone_disable", self.zone_name) -- -- if self.ipa_params.state == "absent": -- if self.zone: -- self.add_ipa_command("dnszone_del", self.zone_name) -- -- # Due to a bug in FreeIPA dnszone-add won't set -- # SOA Serial. The good news is that dnszone-mod does the job. -- # See: https://pagure.io/freeipa/issue/8227 -- # Because of that, if the zone was just added with a given serial -- # we run mod just after to workaround the bug -- if just_added and self.ipa_params.serial is not None: -- args = { -- "idnssoaserial": self.ipa_params.serial, -- } -- self.add_ipa_command("dnszone_mod", self.zone_name, args) -+ for zone_name in self.get_zone_names(): -+ # Look for existing zone in IPA -+ zone, is_zone_active = self.get_zone(zone_name) -+ args = self.get_ipa_command_args(zone=zone) -+ just_added = False -+ -+ if self.ipa_params.state in ["present", "enabled", "disabled"]: -+ if not zone: -+ # Since the zone doesn't exist we just create it -+ # with given args -+ self.add_ipa_command("dnszone_add", zone_name, args) -+ is_zone_active = True -+ just_added = True -+ -+ else: -+ # Zone already exist so we need to verify if given args -+ # matches the current config. If not we updated it. -+ if self.require_ipa_attrs_change(args, zone): -+ self.add_ipa_command("dnszone_mod", zone_name, args) -+ -+ if self.ipa_params.state == "enabled" and not is_zone_active: -+ self.add_ipa_command("dnszone_enable", zone_name) -+ -+ if self.ipa_params.state == "disabled" and is_zone_active: -+ self.add_ipa_command("dnszone_disable", zone_name) -+ -+ if self.ipa_params.state == "absent": -+ if zone: -+ self.add_ipa_command("dnszone_del", zone_name) -+ -+ # Due to a bug in FreeIPA dnszone-add won't set -+ # SOA Serial. The good news is that dnszone-mod does the job. -+ # See: https://pagure.io/freeipa/issue/8227 -+ # Because of that, if the zone was just added with a given serial -+ # we run mod just after to workaround the bug -+ if just_added and self.ipa_params.serial is not None: -+ args = { -+ "idnssoaserial": self.ipa_params.serial, -+ } -+ self.add_ipa_command("dnszone_mod", zone_name, args) - - - def get_argument_spec(): -@@ -426,7 +434,7 @@ def get_argument_spec(): - ipaadmin_principal=dict(type="str", default="admin"), - ipaadmin_password=dict(type="str", required=False, no_log=True), - name=dict( -- type="str", default=None, required=True, aliases=["zone_name"] -+ type="list", default=None, required=True, aliases=["zone_name"] - ), - forwarders=dict( - type="list", -diff --git a/tests/dnszone/test_dnszone.yml b/tests/dnszone/test_dnszone.yml -index f7bd1f0..bd820df 100644 ---- a/tests/dnszone/test_dnszone.yml -+++ b/tests/dnszone/test_dnszone.yml -@@ -149,3 +149,40 @@ - forwarders: [] - register: result - failed_when: not result.changed -+ -+ - name: Create zones test1 -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: test1.testzone.local -+ -+ - name: Create zones test2 -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: test2.testzone.local -+ -+ - name: Create zones test3 -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: test3.testzone.local -+ -+ - name: Ensure multiple zones are absent -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - test1.testzone.local -+ - test2.testzone.local -+ - test3.testzone.local -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Ensure multiple zones are absent, again -+ ipadnszone: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - test1.testzone.local -+ - test2.testzone.local -+ - test3.testzone.local -+ state: absent -+ register: result -+ failed_when: result.changed --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-Fix-allow_retrieve_keytab_host-in-service-module_rhbz#1868020.patch b/SOURCES/ansible-freeipa-0.1.12-Fix-allow_retrieve_keytab_host-in-service-module_rhbz#1868020.patch deleted file mode 100644 index 1211395..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Fix-allow_retrieve_keytab_host-in-service-module_rhbz#1868020.patch +++ /dev/null @@ -1,628 +0,0 @@ -# Skipping 3ab575bcac310166e7d29c5a5349d90482f4e629 as it is reorganizing -# service module test test_service.yml and -# test_service_without_skip_host_check.yml - -From b5e93c705fc56f6592121aa09bfb9f6dce5cee35 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Tue, 11 Aug 2020 16:23:15 -0300 -Subject: [PATCH] Fix `allow_retrieve_keytab_host` in service module. - -The attribute `allow_retrieve_keytab_host` was not working due to -wrong processing of the input and verification if the values should -be updated. Both the issues are fixed by this change. - -Tests were added to better verify service keytab members. ---- - plugins/modules/ipaservice.py | 4 +- - tests/service/env_cleanup.yml | 68 +++++ - tests/service/env_setup.yml | 73 +++++ - tests/service/env_vars.yml | 15 + - tests/service/test_service_keytab.yml | 397 ++++++++++++++++++++++++++ - 5 files changed, 555 insertions(+), 2 deletions(-) - create mode 100644 tests/service/env_cleanup.yml - create mode 100644 tests/service/env_setup.yml - create mode 100644 tests/service/env_vars.yml - create mode 100644 tests/service/test_service_keytab.yml - -diff --git a/plugins/modules/ipaservice.py b/plugins/modules/ipaservice.py -index b0d2535..8bc390d 100644 ---- a/plugins/modules/ipaservice.py -+++ b/plugins/modules/ipaservice.py -@@ -460,7 +460,7 @@ def main(): - allow_retrieve_keytab_group = module_params_get( - ansible_module, "allow_retrieve_keytab_group") - allow_retrieve_keytab_host = module_params_get( -- ansible_module, "allow_create_keytab_host") -+ ansible_module, "allow_retrieve_keytab_host") - allow_retrieve_keytab_hostgroup = module_params_get( - ansible_module, "allow_retrieve_keytab_hostgroup") - delete_continue = module_params_get(ansible_module, "delete_continue") -@@ -727,7 +727,7 @@ def main(): - # Allow retrieve keytab - if len(allow_retrieve_keytab_user_add) > 0 or \ - len(allow_retrieve_keytab_group_add) > 0 or \ -- len(allow_retrieve_keytab_hostgroup_add) > 0 or \ -+ len(allow_retrieve_keytab_host_add) > 0 or \ - len(allow_retrieve_keytab_hostgroup_add) > 0: - commands.append( - [name, "service_allow_retrieve_keytab", -diff --git a/tests/service/env_cleanup.yml b/tests/service/env_cleanup.yml -new file mode 100644 -index 0000000..f96a75b ---- /dev/null -+++ b/tests/service/env_cleanup.yml -@@ -0,0 +1,68 @@ -+--- -+# Cleanup tasks for the service module tests. -+- name: Ensure services are absent. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - "HTTP/{{ svc_fqdn }}" -+ - "HTTP/{{ nohost_fqdn }}" -+ - HTTP/svc.ihavenodns.info -+ - HTTP/no.idontexist.local -+ - "cifs/{{ host1_fqdn }}" -+ state: absent -+ -+- name: Ensure host "{{ svc_fqdn }}" is absent -+ ipahost: -+ ipaadmin_password: SomeADMINpassword -+ name: "{{ svc_fqdn }}" -+ update_dns: yes -+ state: absent -+ -+- name: Ensure host is absent -+ ipahost: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ - "{{ nohost_fqdn }}" -+ - svc.ihavenodns.info -+ update_dns: no -+ state: absent -+ -+- name: Ensure testing users are absent. -+ ipauser: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - user01 -+ - user02 -+ state: absent -+ -+- name: Ensure testing groups are absent. -+ ipagroup: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - group01 -+ - group02 -+ state: absent -+ -+- name: Ensure testing hostgroup hostgroup01 is absent. -+ ipagroup: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - hostgroup01 -+ state: absent -+ -+- name: Ensure testing hostgroup hostgroup02 is absent. -+ ipagroup: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - hostgroup02 -+ state: absent -+ -+- name: Remove IP address for "nohost" host. -+ ipadnsrecord: -+ ipaadmin_password: SomeADMINpassword -+ zone_name: "{{ test_domain }}." -+ name: nohost -+ del_all: yes -+ state: absent -diff --git a/tests/service/env_setup.yml b/tests/service/env_setup.yml -new file mode 100644 -index 0000000..309cfc0 ---- /dev/null -+++ b/tests/service/env_setup.yml -@@ -0,0 +1,73 @@ -+# Setup environment for service module tests. -+--- -+- name: Setup variables and facts. -+ include_tasks: env_vars.yml -+ -+# Cleanup before setup. -+- name: Cleanup test environment. -+ include_tasks: env_cleanup.yml -+ -+- name: Add IP address for "nohost" host. -+ ipadnsrecord: -+ ipaadmin_password: SomeADMINpassword -+ zone_name: "{{ test_domain }}." -+ name: nohost -+ a_ip_address: "{{ ipv4_prefix + '.100' }}" -+ -+- name: Add hosts for tests. -+ ipahost: -+ ipaadmin_password: SomeADMINpassword -+ hosts: -+ - name: "{{ host1_fqdn }}" -+ ip_address: "{{ ipv4_prefix + '.101' }}" -+ - name: "{{ host2_fqdn }}" -+ ip_address: "{{ ipv4_prefix + '.102' }}" -+ - name: "{{ svc_fqdn }}" -+ ip_address: "{{ ipv4_prefix + '.201' }}" -+ - name: svc.ihavenodns.info -+ force: yes -+ update_dns: yes -+ -+- name: Ensure testing user user01 is present. -+ ipauser: -+ ipaadmin_password: SomeADMINpassword -+ name: user01 -+ first: user01 -+ last: last -+ -+- name: Ensure testing user user02 is present. -+ ipauser: -+ ipaadmin_password: SomeADMINpassword -+ name: user02 -+ first: user02 -+ last: last -+ -+- name: Ensure testing group group01 is present. -+ ipagroup: -+ ipaadmin_password: SomeADMINpassword -+ name: group01 -+ -+- name: Ensure testing group group02 is present. -+ ipagroup: -+ ipaadmin_password: SomeADMINpassword -+ name: group02 -+ -+- name: Ensure testing hostgroup hostgroup01 is present. -+ ipahostgroup: -+ ipaadmin_password: SomeADMINpassword -+ name: hostgroup01 -+ -+- name: Ensure testing hostgroup hostgroup02 is present. -+ ipahostgroup: -+ ipaadmin_password: SomeADMINpassword -+ name: hostgroup02 -+ -+- name: Ensure services are absent. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: -+ - "HTTP/{{ svc_fqdn }}" -+ - "HTTP/{{ nohost_fqdn }}" -+ - HTTP/svc.ihavenodns.info -+ - HTTP/no.idontexist.info -+ state: absent -diff --git a/tests/service/env_vars.yml b/tests/service/env_vars.yml -new file mode 100644 -index 0000000..eb53c7a ---- /dev/null -+++ b/tests/service/env_vars.yml -@@ -0,0 +1,15 @@ -+--- -+ - name: Get Domain from server name -+ set_fact: -+ test_domain: "{{ ansible_fqdn.split('.')[1:] | join('.') }}" -+ -+ - name: Set host1, host2 and svc hosts fqdn -+ set_fact: -+ host1_fqdn: "{{ 'host1.' + test_domain }}" -+ host2_fqdn: "{{ 'host2.' + test_domain }}" -+ svc_fqdn: "{{ 'svc.' + test_domain }}" -+ nohost_fqdn: "{{ 'nohost.' + test_domain }}" -+ -+ - name: Get IPv4 address prefix from server node -+ set_fact: -+ ipv4_prefix: "{{ ansible_default_ipv4.address.split('.')[:-1] | join('.') }}" -diff --git a/tests/service/test_service_keytab.yml b/tests/service/test_service_keytab.yml -new file mode 100644 -index 0000000..0918802 ---- /dev/null -+++ b/tests/service/test_service_keytab.yml -@@ -0,0 +1,397 @@ -+--- -+- name: Test service -+ hosts: ipaserver -+ become: yes -+ -+ tasks: -+ # setup -+ - name: Setup test envirnoment. -+ include_tasks: env_setup.yml -+ -+ # Add service to test keytab create/retrieve attributes. -+ - name: Ensure test service is present -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ pac_type: -+ - MS-PAC -+ - PAD -+ auth_ind: otp -+ force: yes -+ requires_pre_auth: yes -+ ok_as_delegate: no -+ ok_to_auth_as_delegate: no -+ -+ # tests -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for group. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for group, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for group. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for group, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for host. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for host, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for host. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for host, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for hostgroup. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for hostgroup, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for hostgroup. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ state: absent -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for hostgroup, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_create_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_user: -+ - user01 -+ - user02 -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for group. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for group, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for group. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for group, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_group: -+ - group01 -+ - group02 -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for host. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for host, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for host. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for host, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_host: -+ - "{{ host1_fqdn }}" -+ - "{{ host2_fqdn }}" -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for hostgroup. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ action: member -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for hostgroup, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for hostgroup. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ action: member -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for hostgroup, again. -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "HTTP/{{ svc_fqdn }}" -+ allow_retrieve_keytab_hostgroup: -+ - hostgroup01 -+ - hostgroup02 -+ action: member -+ state: absent -+ register: result -+ failed_when: result.changed -+ -+ # cleanup -+ - name: Clean-up envirnoment. -+ include_tasks: env_cleanup.yml --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-Fix-forwardzone-issues_rhbz#1843826,1843828,1843829,1843830,1843831.patch b/SOURCES/ansible-freeipa-0.1.12-Fix-forwardzone-issues_rhbz#1843826,1843828,1843829,1843830,1843831.patch deleted file mode 100644 index 5470d06..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Fix-forwardzone-issues_rhbz#1843826,1843828,1843829,1843830,1843831.patch +++ /dev/null @@ -1,1447 +0,0 @@ -From f0f933b4630bce810475a519e295828013d301d6 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Wed, 10 Jun 2020 20:40:45 -0300 -Subject: [PATCH] Changed admin password on tests to match other modules. - -Use of the same password on all module tests ease test automation, -and this change ensure that dnsforwardzone use the same password as -other modules. ---- - tests/dnsforwardzone/test_dnsforwardzone.yml | 42 ++++++++++---------- - 1 file changed, 21 insertions(+), 21 deletions(-) - -diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml -index 1a45e826..ac08a48f 100644 ---- a/tests/dnsforwardzone/test_dnsforwardzone.yml -+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml -@@ -7,13 +7,13 @@ - tasks: - - name: ensure forwardzone example.com is absent - prep - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: absent - - - name: ensure forwardzone example.com is created - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -25,7 +25,7 @@ - - - name: ensure forwardzone example.com is present again - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -37,7 +37,7 @@ - - - name: ensure forwardzone example.com has two forwarders - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -50,7 +50,7 @@ - - - name: ensure forwardzone example.com has one forwarder again - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - forwarders: - - 8.8.8.8 -@@ -62,7 +62,7 @@ - - - name: skip_overlap_check can only be set on creation so change nothing - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - forwarders: - - 8.8.8.8 -@@ -74,7 +74,7 @@ - - - name: change all the things at once - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -87,13 +87,13 @@ - - - name: ensure forwardzone example.com is absent for next testset - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: absent - - - name: ensure forwardzone example.com is created with minimal args - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - skip_overlap_check: true -@@ -104,7 +104,7 @@ - - - name: add a forwarder to any existing ones - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -115,7 +115,7 @@ - - - name: check the list of forwarders is what we expect - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -127,7 +127,7 @@ - - - name: remove a single forwarder - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: absent - name: example.com - forwarders: -@@ -138,7 +138,7 @@ - - - name: check the list of forwarders is what we expect now - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -149,13 +149,13 @@ - - - name: ensure forwardzone example.com is absent again - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: absent - - - name: try to create a new forwarder with action=member - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -167,13 +167,13 @@ - - - name: ensure forwardzone example.com is absent - tidy up - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: absent - - - name: try to create a new forwarder is disabled state - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: disabled - name: example.com - forwarders: -@@ -184,7 +184,7 @@ - - - name: enable the forwarder - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: enabled - register: result -@@ -192,7 +192,7 @@ - - - name: disable the forwarder again - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: disabled - action: member -@@ -201,7 +201,7 @@ - - - name: ensure it stays disabled - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: disabled - register: result -@@ -209,6 +209,6 @@ - - - name: ensure forwardzone example.com is absent - tidy up - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: absent -From f8ebca760dbaaf38c7b74b0c855b05d26e9cb812 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Wed, 10 Jun 2020 22:14:27 -0300 -Subject: [PATCH] Allow processing of multiple names for deleting - dnsforwardzones. - ---- - plugins/modules/ipadnsforwardzone.py | 189 ++++++++++++++------------- - 1 file changed, 98 insertions(+), 91 deletions(-) - -diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py -index 90bd3876..b28f28db 100644 ---- a/plugins/modules/ipadnsforwardzone.py -+++ b/plugins/modules/ipadnsforwardzone.py -@@ -134,7 +134,7 @@ def main(): - # general - ipaadmin_principal=dict(type="str", default="admin"), - ipaadmin_password=dict(type="str", required=False, no_log=True), -- name=dict(type="str", aliases=["cn"], default=None, -+ name=dict(type="list", aliases=["cn"], default=None, - required=True), - forwarders=dict(type='list', aliases=["idnsforwarders"], - required=False), -@@ -158,7 +158,7 @@ def main(): - "ipaadmin_principal") - ipaadmin_password = module_params_get(ansible_module, - "ipaadmin_password") -- name = module_params_get(ansible_module, "name") -+ names = module_params_get(ansible_module, "name") - action = module_params_get(ansible_module, "action") - forwarders = module_params_get(ansible_module, "forwarders") - forwardpolicy = module_params_get(ansible_module, "forwardpolicy") -@@ -166,6 +166,12 @@ def main(): - "skip_overlap_check") - state = module_params_get(ansible_module, "state") - -+ if state == 'present' and len(names) != 1: -+ ansible_module.fail_json( -+ msg="Only one dnsforwardzone can be added at a time.") -+ if state == 'absent' and len(names) < 1: -+ ansible_module.fail_json(msg="No name given.") -+ - # absent stae means delete if the action is NOT member but update if it is - # if action is member then update an exisiting resource - # and if action is not member then create a resource -@@ -207,101 +213,102 @@ def main(): - ipaadmin_password) - api_connect() - -- # Make sure forwardzone exists -- existing_resource = find_dnsforwardzone(ansible_module, name) -- -- if existing_resource is None and operation == "update": -- # does not exist and is updating -- # trying to update something that doesn't exist, so error -- ansible_module.fail_json(msg="""dnsforwardzone '%s' is not -- valid""" % (name)) -- elif existing_resource is None and operation == "del": -- # does not exists and should be absent -- # set command -- command = None -- # enabled or disabled? -- is_enabled = "IGNORE" -- elif existing_resource is not None and operation == "del": -- # exists but should be absent -- # set command -- command = "dnsforwardzone_del" -- # enabled or disabled? -- is_enabled = "IGNORE" -- elif forwarders is None: -- # forwarders are not defined its not a delete, update state? -- # set command -- command = None -- # enabled or disabled? -- if existing_resource is not None: -- is_enabled = existing_resource["idnszoneactive"][0] -- else: -- is_enabled = "IGNORE" -- elif existing_resource is not None and operation == "update": -- # exists and is updating -- # calculate the new forwarders and mod -- # determine args -- if state != "absent": -- forwarders = list(set(existing_resource["idnsforwarders"] -- + forwarders)) -- else: -- forwarders = list(set(existing_resource["idnsforwarders"]) -- - set(forwarders)) -- args = gen_args(forwarders, forwardpolicy, -- skip_overlap_check) -- if skip_overlap_check is not None: -- del args['skip_overlap_check'] -- -- # command -- if not compare_args_ipa(ansible_module, args, existing_resource): -- command = "dnsforwardzone_mod" -- else: -+ for name in names: -+ # Make sure forwardzone exists -+ existing_resource = find_dnsforwardzone(ansible_module, name) -+ -+ if existing_resource is None and operation == "update": -+ # does not exist and is updating -+ # trying to update something that doesn't exist, so error -+ ansible_module.fail_json(msg="""dnsforwardzone '%s' is not -+ valid""" % (name)) -+ elif existing_resource is None and operation == "del": -+ # does not exists and should be absent -+ # set command - command = None -- -- # enabled or disabled? -- is_enabled = existing_resource["idnszoneactive"][0] -- -- elif existing_resource is None and operation == "add": -- # does not exist but should be present -- # determine args -- args = gen_args(forwarders, forwardpolicy, -- skip_overlap_check) -- # set command -- command = "dnsforwardzone_add" -- # enabled or disabled? -- is_enabled = "TRUE" -- -- elif existing_resource is not None and operation == "add": -- # exists and should be present, has it changed? -- # determine args -- args = gen_args(forwarders, forwardpolicy, skip_overlap_check) -- if skip_overlap_check is not None: -- del args['skip_overlap_check'] -- -- # set command -- if not compare_args_ipa(ansible_module, args, existing_resource): -- command = "dnsforwardzone_mod" -- else: -+ # enabled or disabled? -+ is_enabled = "IGNORE" -+ elif existing_resource is not None and operation == "del": -+ # exists but should be absent -+ # set command -+ command = "dnsforwardzone_del" -+ # enabled or disabled? -+ is_enabled = "IGNORE" -+ elif forwarders is None: -+ # forwarders are not defined its not a delete, update state? -+ # set command - command = None -+ # enabled or disabled? -+ if existing_resource is not None: -+ is_enabled = existing_resource["idnszoneactive"][0] -+ else: -+ is_enabled = "IGNORE" -+ elif existing_resource is not None and operation == "update": -+ # exists and is updating -+ # calculate the new forwarders and mod -+ # determine args -+ if state != "absent": -+ forwarders = list(set(existing_resource["idnsforwarders"] -+ + forwarders)) -+ else: -+ forwarders = list(set(existing_resource["idnsforwarders"]) -+ - set(forwarders)) -+ args = gen_args(forwarders, forwardpolicy, -+ skip_overlap_check) -+ if skip_overlap_check is not None: -+ del args['skip_overlap_check'] -+ -+ # command -+ if not compare_args_ipa(ansible_module, args, existing_resource): -+ command = "dnsforwardzone_mod" -+ else: -+ command = None -+ -+ # enabled or disabled? -+ is_enabled = existing_resource["idnszoneactive"][0] - -- # enabled or disabled? -- is_enabled = existing_resource["idnszoneactive"][0] -- -- # if command is set then run it with the args -- if command is not None: -- api_command(ansible_module, command, name, args) -- changed = True -+ elif existing_resource is None and operation == "add": -+ # does not exist but should be present -+ # determine args -+ args = gen_args(forwarders, forwardpolicy, -+ skip_overlap_check) -+ # set command -+ command = "dnsforwardzone_add" -+ # enabled or disabled? -+ is_enabled = "TRUE" -+ -+ elif existing_resource is not None and operation == "add": -+ # exists and should be present, has it changed? -+ # determine args -+ args = gen_args(forwarders, forwardpolicy, skip_overlap_check) -+ if skip_overlap_check is not None: -+ del args['skip_overlap_check'] -+ -+ # set command -+ if not compare_args_ipa(ansible_module, args, existing_resource): -+ command = "dnsforwardzone_mod" -+ else: -+ command = None -+ -+ # enabled or disabled? -+ is_enabled = existing_resource["idnszoneactive"][0] - -- # does the enabled state match what we want (if we care) -- if is_enabled != "IGNORE": -- if wants_enable and is_enabled != "TRUE": -- api_command(ansible_module, "dnsforwardzone_enable", -- name, {}) -- changed = True -- elif not wants_enable and is_enabled != "FALSE": -- api_command(ansible_module, "dnsforwardzone_disable", -- name, {}) -+ # if command is set then run it with the args -+ if command is not None: -+ api_command(ansible_module, command, name, args) - changed = True - -+ # does the enabled state match what we want (if we care) -+ if is_enabled != "IGNORE": -+ if wants_enable and is_enabled != "TRUE": -+ api_command(ansible_module, "dnsforwardzone_enable", -+ name, {}) -+ changed = True -+ elif not wants_enable and is_enabled != "FALSE": -+ api_command(ansible_module, "dnsforwardzone_disable", -+ name, {}) -+ changed = True -+ - except Exception as e: - ansible_module.fail_json(msg=str(e)) - -From 3f785bc0e9fe1ab3ad874ce4f26e6897189db8aa Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Wed, 10 Jun 2020 22:20:20 -0300 -Subject: [PATCH] Fix error message when adding dnsforwardzone without - forwarders. - ---- - plugins/modules/ipadnsforwardzone.py | 5 +++++ - tests/dnsforwardzone/test_dnsforwardzone.yml | 13 +++++++++++-- - 2 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py -index b28f28db..3968e6a1 100644 ---- a/plugins/modules/ipadnsforwardzone.py -+++ b/plugins/modules/ipadnsforwardzone.py -@@ -217,6 +217,11 @@ def main(): - # Make sure forwardzone exists - existing_resource = find_dnsforwardzone(ansible_module, name) - -+ # validate parameters -+ if state == 'present': -+ if existing_resource is None and not forwarders: -+ ansible_module.fail_json(msg='No forwarders specified.') -+ - if existing_resource is None and operation == "update": - # does not exist and is updating - # trying to update something that doesn't exist, so error -diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml -index ac08a48f..d94db9e5 100644 ---- a/tests/dnsforwardzone/test_dnsforwardzone.yml -+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml -@@ -5,10 +5,12 @@ - gather_facts: false - - tasks: -- - name: ensure forwardzone example.com is absent - prep -+ - name: ensure test forwardzones are absent - prep - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -- name: example.com -+ name: -+ - example.com -+ - newfailzone.com - state: absent - - - name: ensure forwardzone example.com is created -@@ -207,6 +209,13 @@ - register: result - failed_when: result.changed - -+ - name: Ensure forwardzone is not added without forwarders, with correct message. -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: newfailzone.com -+ register: result -+ failed_when: not result.failed or "No forwarders specified" not in result.msg -+ - - name: ensure forwardzone example.com is absent - tidy up - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -From 1d223c2b63634abe86f7702a64dd83c4fbc272ce Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Mon, 15 Jun 2020 16:14:25 -0300 -Subject: [PATCH] Add support for attributes `ip_address` and `port` to - `forwarders`. - -This patch modify the was forwarders are configured, using two attributes, -`ip_address` and `port`, instead of IPA API internal string representation -of `IP port PORT`. ---- - README-dnsforwardzone.md | 6 ++- - plugins/modules/ipadnsforwardzone.py | 37 ++++++++++++++--- - tests/dnsforwardzone/test_dnsforwardzone.yml | 43 ++++++++++++-------- - 3 files changed, 62 insertions(+), 24 deletions(-) - -diff --git a/README-dnsforwardzone.md b/README-dnsforwardzone.md -index 81919295..15b2b574 100644 ---- a/README-dnsforwardzone.md -+++ b/README-dnsforwardzone.md -@@ -99,8 +99,10 @@ Variable | Description | Required - `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no - `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no - `name` \| `cn` | Zone name (FQDN). | yes if `state` == `present` --`forwarders` \| `idnsforwarders` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`) | no --`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 -+`forwarders` \| `idnsforwarders` | Per-zone forwarders. A custom port can be specified for each forwarder. Options | no -+  | `ip_address`: The forwarder IP address. | yes -+  | `port`: The forwarder IP port. | no -+`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 - `skip_overlap_check` | Force DNS zone creation even if it will overlap with an existing zone. Defaults to False. | no - `action` | Work on group or member level. It can be on of `member` or `dnsforwardzone` and defaults to `dnsforwardzone`. | no - `state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | yes -diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py -index 3968e6a1..8e5c3464 100644 ---- a/plugins/modules/ipadnsforwardzone.py -+++ b/plugins/modules/ipadnsforwardzone.py -@@ -54,9 +54,16 @@ - forwarders: - description: - - List of the DNS servers to forward to -- required: true -- type: list - aliases: ["idnsforwarders"] -+ options: -+ ip_address: -+ description: Forwarder IP address (either IPv4 or IPv6). -+ required: false -+ type: string -+ port: -+ description: Forwarder port. -+ required: false -+ type: int - forwardpolicy: - description: Per-zone conditional forwarding policy - required: false -@@ -128,6 +135,20 @@ def gen_args(forwarders, forwardpolicy, skip_overlap_check): - return _args - - -+def forwarder_list(forwarders): -+ """Convert the forwarder dict into a list compatible with IPA API.""" -+ if forwarders is None: -+ return None -+ fwd_list = [] -+ for forwarder in forwarders: -+ if forwarder.get('port', None) is not None: -+ formatter = "{ip_address} port {port}" -+ else: -+ formatter = "{ip_address}" -+ fwd_list.append(formatter.format(**forwarder)) -+ return fwd_list -+ -+ - def main(): - ansible_module = AnsibleModule( - argument_spec=dict( -@@ -136,8 +157,13 @@ def main(): - ipaadmin_password=dict(type="str", required=False, no_log=True), - name=dict(type="list", aliases=["cn"], default=None, - required=True), -- forwarders=dict(type='list', aliases=["idnsforwarders"], -- required=False), -+ forwarders=dict(type="list", default=None, required=False, -+ aliases=["idnsforwarders"], elements='dict', -+ options=dict( -+ ip_address=dict(type='str', required=True), -+ port=dict(type='int', required=False, -+ default=None), -+ )), - forwardpolicy=dict(type='str', aliases=["idnsforwardpolicy"], - required=False, - choices=['only', 'first', 'none']), -@@ -160,7 +186,8 @@ def main(): - "ipaadmin_password") - names = module_params_get(ansible_module, "name") - action = module_params_get(ansible_module, "action") -- forwarders = module_params_get(ansible_module, "forwarders") -+ forwarders = forwarder_list( -+ module_params_get(ansible_module, "forwarders")) - forwardpolicy = module_params_get(ansible_module, "forwardpolicy") - skip_overlap_check = module_params_get(ansible_module, - "skip_overlap_check") -diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml -index d94db9e5..468cd4ce 100644 ---- a/tests/dnsforwardzone/test_dnsforwardzone.yml -+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml -@@ -5,7 +5,7 @@ - gather_facts: false - - tasks: -- - name: ensure test forwardzones are absent - prep -+ - name: ensure test forwardzones are absent - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword - name: -@@ -19,7 +19,7 @@ - state: present - name: example.com - forwarders: -- - 8.8.8.8 -+ - ip_address: 8.8.8.8 - forwardpolicy: first - skip_overlap_check: true - register: result -@@ -31,7 +31,7 @@ - state: present - name: example.com - forwarders: -- - 8.8.8.8 -+ - ip_address: 8.8.8.8 - forwardpolicy: first - skip_overlap_check: true - register: result -@@ -43,19 +43,22 @@ - state: present - name: example.com - forwarders: -- - 8.8.8.8 -- - 4.4.4.4 -+ - ip_address: 8.8.8.8 -+ - ip_address: 4.4.4.4 -+ port: 8053 - forwardpolicy: first - skip_overlap_check: true - register: result - failed_when: not result.changed - -+ - pause: -+ - - name: ensure forwardzone example.com has one forwarder again - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword - name: example.com - forwarders: -- - 8.8.8.8 -+ - ip_address: 8.8.8.8 - forwardpolicy: first - skip_overlap_check: true - state: present -@@ -67,7 +70,7 @@ - ipaadmin_password: SomeADMINpassword - name: example.com - forwarders: -- - 8.8.8.8 -+ - ip_address: 8.8.8.8 - forwardpolicy: first - skip_overlap_check: false - state: present -@@ -80,8 +83,9 @@ - state: present - name: example.com - forwarders: -- - 8.8.8.8 -- - 4.4.4.4 -+ - ip_address: 8.8.8.8 -+ - ip_address: 4.4.4.4 -+ port: 8053 - forwardpolicy: only - skip_overlap_check: false - register: result -@@ -100,7 +104,7 @@ - name: example.com - skip_overlap_check: true - forwarders: -- - 8.8.8.8 -+ - ip_address: 8.8.8.8 - register: result - failed_when: not result.changed - -@@ -110,7 +114,8 @@ - state: present - name: example.com - forwarders: -- - 4.4.4.4 -+ - ip_address: 4.4.4.4 -+ port: 8053 - action: member - register: result - failed_when: not result.changed -@@ -121,8 +126,9 @@ - state: present - name: example.com - forwarders: -- - 4.4.4.4 -- - 8.8.8.8 -+ - ip_address: 4.4.4.4 -+ port: 8053 -+ - ip_address: 8.8.8.8 - action: member - register: result - failed_when: result.changed -@@ -133,7 +139,7 @@ - state: absent - name: example.com - forwarders: -- - 8.8.8.8 -+ - ip_address: 8.8.8.8 - action: member - register: result - failed_when: not result.changed -@@ -144,7 +150,8 @@ - state: present - name: example.com - forwarders: -- - 4.4.4.4 -+ - ip_address: 4.4.4.4 -+ port: 8053 - action: member - register: result - failed_when: result.changed -@@ -161,7 +168,8 @@ - state: present - name: example.com - forwarders: -- - 4.4.4.4 -+ - ip_address: 4.4.4.4 -+ port: 8053 - action: member - skip_overlap_check: true - register: result -@@ -179,7 +187,8 @@ - state: disabled - name: example.com - forwarders: -- - 4.4.4.4 -+ - ip_address: 4.4.4.4 -+ port: 8053 - skip_overlap_check: true - register: result - failed_when: not result.changed -From bf864469a1da81c6b23e9726562b21408764ac8f Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Mon, 15 Jun 2020 20:42:23 -0300 -Subject: [PATCH] Add support for attribute `permission` on dnsforwardzone - module. - -Adds missing attribute `permission to dnsforwardzone module, that -enable setting `manageby` for the DNS Forwar Zone. ---- - README-dnsforwardzone.md | 1 + - plugins/modules/ipadnsforwardzone.py | 71 ++++++++---- - tests/dnsforwardzone/test_dnsforwardzone.yml | 110 +++++++++++++++---- - 3 files changed, 136 insertions(+), 46 deletions(-) - -diff --git a/README-dnsforwardzone.md b/README-dnsforwardzone.md -index 15b2b574..175e6f8b 100644 ---- a/README-dnsforwardzone.md -+++ b/README-dnsforwardzone.md -@@ -104,6 +104,7 @@ Variable | Description | Required -   | `port`: The forwarder IP port. | no - `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 - `skip_overlap_check` | Force DNS zone creation even if it will overlap with an existing zone. Defaults to False. | no -+`permission` | Allow DNS Forward Zone to be managed. (bool) | no - `action` | Work on group or member level. It can be on of `member` or `dnsforwardzone` and defaults to `dnsforwardzone`. | no - `state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | yes - -diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py -index 8e5c3464..a729197b 100644 ---- a/plugins/modules/ipadnsforwardzone.py -+++ b/plugins/modules/ipadnsforwardzone.py -@@ -75,6 +75,11 @@ - - Force DNS zone creation even if it will overlap with an existing zone. - required: false - default: false -+ permission: -+ description: -+ - Allow DNS Forward Zone to be managed. -+ required: false -+ type: bool - ''' - - EXAMPLES = ''' -@@ -168,6 +173,8 @@ def main(): - required=False, - choices=['only', 'first', 'none']), - skip_overlap_check=dict(type='bool', required=False), -+ permission=dict(type='bool', required=False, -+ aliases=['managedby']), - action=dict(type="str", default="dnsforwardzone", - choices=["member", "dnsforwardzone"]), - # state -@@ -191,6 +198,7 @@ def main(): - forwardpolicy = module_params_get(ansible_module, "forwardpolicy") - skip_overlap_check = module_params_get(ansible_module, - "skip_overlap_check") -+ permission = module_params_get(ansible_module, "permission") - state = module_params_get(ansible_module, "state") - - if state == 'present' and len(names) != 1: -@@ -215,7 +223,9 @@ def main(): - wants_enable = True - - if operation == "del": -- invalid = ["forwarders", "forwardpolicy", "skip_overlap_check"] -+ invalid = [ -+ "forwarders", "forwardpolicy", "skip_overlap_check", "permission" -+ ] - for x in invalid: - if vars()[x] is not None: - ansible_module.fail_json( -@@ -241,6 +251,9 @@ def main(): - api_connect() - - for name in names: -+ commands = [] -+ command = None -+ - # Make sure forwardzone exists - existing_resource = find_dnsforwardzone(ansible_module, name) - -@@ -249,6 +262,18 @@ def main(): - if existing_resource is None and not forwarders: - ansible_module.fail_json(msg='No forwarders specified.') - -+ if existing_resource is not None: -+ if state != "absent": -+ if forwarders: -+ forwarders = list( -+ set(existing_resource["idnsforwarders"] -+ + forwarders)) -+ else: -+ if forwarders: -+ forwarders = list( -+ set(existing_resource["idnsforwarders"]) -+ - set(forwarders)) -+ - if existing_resource is None and operation == "update": - # does not exist and is updating - # trying to update something that doesn't exist, so error -@@ -256,20 +281,17 @@ def main(): - valid""" % (name)) - elif existing_resource is None and operation == "del": - # does not exists and should be absent -- # set command -- command = None - # enabled or disabled? - is_enabled = "IGNORE" - elif existing_resource is not None and operation == "del": - # exists but should be absent - # set command - command = "dnsforwardzone_del" -+ args = {} - # enabled or disabled? - is_enabled = "IGNORE" - elif forwarders is None: - # forwarders are not defined its not a delete, update state? -- # set command -- command = None - # enabled or disabled? - if existing_resource is not None: - is_enabled = existing_resource["idnszoneactive"][0] -@@ -278,23 +300,13 @@ def main(): - elif existing_resource is not None and operation == "update": - # exists and is updating - # calculate the new forwarders and mod -- # determine args -- if state != "absent": -- forwarders = list(set(existing_resource["idnsforwarders"] -- + forwarders)) -- else: -- forwarders = list(set(existing_resource["idnsforwarders"]) -- - set(forwarders)) -- args = gen_args(forwarders, forwardpolicy, -- skip_overlap_check) -- if skip_overlap_check is not None: -+ args = gen_args(forwarders, forwardpolicy, skip_overlap_check) -+ if "skip_overlap_check" in args: - del args['skip_overlap_check'] - - # command - if not compare_args_ipa(ansible_module, args, existing_resource): - command = "dnsforwardzone_mod" -- else: -- command = None - - # enabled or disabled? - is_enabled = existing_resource["idnszoneactive"][0] -@@ -313,21 +325,36 @@ def main(): - # exists and should be present, has it changed? - # determine args - args = gen_args(forwarders, forwardpolicy, skip_overlap_check) -- if skip_overlap_check is not None: -+ if 'skip_overlap_check' in args: - del args['skip_overlap_check'] - - # set command - if not compare_args_ipa(ansible_module, args, existing_resource): - command = "dnsforwardzone_mod" -- else: -- command = None - - # enabled or disabled? - is_enabled = existing_resource["idnszoneactive"][0] - -- # if command is set then run it with the args -+ # if command is set... - if command is not None: -- api_command(ansible_module, command, name, args) -+ commands.append([name, command, args]) -+ -+ if permission is not None: -+ if existing_resource is None: -+ managedby = None -+ else: -+ managedby = existing_resource.get('managedby', None) -+ if permission and managedby is None: -+ commands.append( -+ [name, 'dnsforwardzone_add_permission', {}] -+ ) -+ elif not permission and managedby is not None: -+ commands.append( -+ [name, 'dnsforwardzone_remove_permission', {}] -+ ) -+ -+ for name, command, args in commands: -+ result = api_command(ansible_module, command, name, args) - changed = True - - # does the enabled state match what we want (if we care) -diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml -index 468cd4ce..0386bd48 100644 ---- a/tests/dnsforwardzone/test_dnsforwardzone.yml -+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml -@@ -51,8 +51,6 @@ - register: result - failed_when: not result.changed - -- - pause: -- - - name: ensure forwardzone example.com has one forwarder again - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -@@ -63,7 +61,7 @@ - skip_overlap_check: true - state: present - register: result -- failed_when: not result.changed -+ failed_when: result.changed - - - name: skip_overlap_check can only be set on creation so change nothing - ipadnsforwardzone: -@@ -77,6 +75,22 @@ - register: result - failed_when: result.changed - -+ - name: ensure forwardzone example.com is absent. -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: example.com -+ state: absent -+ register: result -+ failed_when: not result.changed -+ -+ - name: ensure forwardzone example.com is absent, again. -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: example.com -+ state: absent -+ register: result -+ failed_when: result.changed -+ - - name: change all the things at once - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -@@ -87,11 +101,12 @@ - - ip_address: 4.4.4.4 - port: 8053 - forwardpolicy: only -- skip_overlap_check: false -+ skip_overlap_check: true -+ permission: yes - register: result - failed_when: not result.changed - -- - name: ensure forwardzone example.com is absent for next testset -+ - name: ensure forwardzone example.com is absent. - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword - name: example.com -@@ -156,43 +171,58 @@ - register: result - failed_when: result.changed - -- - name: ensure forwardzone example.com is absent again -+ - name: Add a permission for per-forward zone access delegation. - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword - name: example.com -- state: absent -+ permission: yes -+ action: member -+ register: result -+ failed_when: not result.changed - -- - name: try to create a new forwarder with action=member -+ - name: Add a permission for per-forward zone access delegation, again. - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -- state: present - name: example.com -- forwarders: -- - ip_address: 4.4.4.4 -- port: 8053 -+ permission: yes - action: member -- skip_overlap_check: true - register: result - failed_when: result.changed - -- - name: ensure forwardzone example.com is absent - tidy up -+ - name: Remove a permission for per-forward zone access delegation. - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword - name: example.com -- state: absent -+ permission: no -+ action: member -+ register: result -+ failed_when: not result.changed - -- - name: try to create a new forwarder is disabled state -+ - name: Remove a permission for per-forward zone access delegation, again. - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -- state: disabled - name: example.com -- forwarders: -- - ip_address: 4.4.4.4 -- port: 8053 -- skip_overlap_check: true -+ permission: no -+ action: member -+ register: result -+ failed_when: result.changed -+ -+ - name: disable the forwarder -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: example.com -+ state: disabled - register: result - failed_when: not result.changed - -+ - name: disable the forwarder again -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: example.com -+ state: disabled -+ register: result -+ failed_when: result.changed -+ - - name: enable the forwarder - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -@@ -201,12 +231,42 @@ - register: result - failed_when: not result.changed - -- - name: disable the forwarder again -+ - name: enable the forwarder, again - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword - name: example.com -- state: disabled -+ state: enabled -+ register: result -+ failed_when: result.changed -+ -+ - name: ensure forwardzone example.com is absent again -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: example.com -+ state: absent -+ -+ - name: try to create a new forwarder with action=member -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ state: present -+ name: example.com -+ forwarders: -+ - ip_address: 4.4.4.4 -+ port: 8053 - action: member -+ skip_overlap_check: true -+ register: result -+ failed_when: result.changed -+ -+ - name: try to create a new forwarder with disabled state -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ state: disabled -+ name: example.com -+ forwarders: -+ - ip_address: 4.4.4.4 -+ port: 8053 -+ skip_overlap_check: yes - register: result - failed_when: not result.changed - -@@ -228,5 +288,7 @@ - - name: ensure forwardzone example.com is absent - tidy up - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -- name: example.com -+ name: -+ - example.com -+ - newfailzone.com - state: absent -From 857fb82eb9141a44ffb91331653e1c30b43f671e Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Mon, 15 Jun 2020 23:40:35 -0300 -Subject: [PATCH] Allows modification of forward policy in existing DNS Forward - Zone. - -This patch allows the modification of the forward zone policy in -an existing DNS Forward Zone, and fixes some issues with `enable` -and `disable` state that prevented correct behavior of `forwardpolicy`. ---- - plugins/modules/ipadnsforwardzone.py | 154 ++++++++++--------- - tests/dnsforwardzone/test_dnsforwardzone.yml | 32 ++-- - 2 files changed, 97 insertions(+), 89 deletions(-) - -diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py -index a729197b..1f1e85ec 100644 ---- a/plugins/modules/ipadnsforwardzone.py -+++ b/plugins/modules/ipadnsforwardzone.py -@@ -217,10 +217,20 @@ def main(): - else: - operation = "add" - -- if state == "disabled": -- wants_enable = False -- else: -- wants_enable = True -+ if state in ["enabled", "disabled"]: -+ if action == "member": -+ ansible_module.fail_json( -+ msg="Action `member` cannot be used with state `%s`" -+ % (state)) -+ invalid = [ -+ "forwarders", "forwardpolicy", "skip_overlap_check", "permission" -+ ] -+ for x in invalid: -+ if vars()[x] is not None: -+ ansible_module.fail_json( -+ msg="Argument '%s' can not be used with action " -+ "'%s', state `%s`" % (x, action, state)) -+ wants_enable = (state == "enabled") - - if operation == "del": - invalid = [ -@@ -230,7 +240,7 @@ def main(): - if vars()[x] is not None: - ansible_module.fail_json( - msg="Argument '%s' can not be used with action " -- "'%s'" % (x, action)) -+ "'%s', state `%s`" % (x, action, state)) - - changed = False - exit_args = {} -@@ -262,7 +272,27 @@ def main(): - if existing_resource is None and not forwarders: - ansible_module.fail_json(msg='No forwarders specified.') - -- if existing_resource is not None: -+ if existing_resource is None: -+ if operation == "add": -+ # does not exist but should be present -+ # determine args -+ args = gen_args(forwarders, forwardpolicy, -+ skip_overlap_check) -+ # set command -+ command = "dnsforwardzone_add" -+ # enabled or disabled? -+ -+ elif operation == "update": -+ # does not exist and is updating -+ # trying to update something that doesn't exist, so error -+ ansible_module.fail_json( -+ msg="dnsforwardzone '%s' not found." % (name)) -+ -+ elif operation == "del": -+ # there's nothnig to do. -+ continue -+ -+ else: # existing_resource is not None - if state != "absent": - if forwarders: - forwarders = list( -@@ -274,66 +304,51 @@ def main(): - set(existing_resource["idnsforwarders"]) - - set(forwarders)) - -- if existing_resource is None and operation == "update": -- # does not exist and is updating -- # trying to update something that doesn't exist, so error -- ansible_module.fail_json(msg="""dnsforwardzone '%s' is not -- valid""" % (name)) -- elif existing_resource is None and operation == "del": -- # does not exists and should be absent -- # enabled or disabled? -- is_enabled = "IGNORE" -- elif existing_resource is not None and operation == "del": -- # exists but should be absent -- # set command -- command = "dnsforwardzone_del" -- args = {} -- # enabled or disabled? -- is_enabled = "IGNORE" -- elif forwarders is None: -- # forwarders are not defined its not a delete, update state? -- # enabled or disabled? -+ if operation == "add": -+ # exists and should be present, has it changed? -+ # determine args -+ args = gen_args( -+ forwarders, forwardpolicy, skip_overlap_check) -+ if 'skip_overlap_check' in args: -+ del args['skip_overlap_check'] -+ -+ # set command -+ if not compare_args_ipa( -+ ansible_module, args, existing_resource): -+ command = "dnsforwardzone_mod" -+ -+ elif operation == "del": -+ # exists but should be absent -+ # set command -+ command = "dnsforwardzone_del" -+ args = {} -+ -+ elif operation == "update": -+ # exists and is updating -+ # calculate the new forwarders and mod -+ args = gen_args( -+ forwarders, forwardpolicy, skip_overlap_check) -+ if "skip_overlap_check" in args: -+ del args['skip_overlap_check'] -+ -+ # command -+ if not compare_args_ipa( -+ ansible_module, args, existing_resource): -+ command = "dnsforwardzone_mod" -+ -+ if state in ['enabled', 'disabled']: - if existing_resource is not None: - is_enabled = existing_resource["idnszoneactive"][0] - else: -- is_enabled = "IGNORE" -- elif existing_resource is not None and operation == "update": -- # exists and is updating -- # calculate the new forwarders and mod -- args = gen_args(forwarders, forwardpolicy, skip_overlap_check) -- if "skip_overlap_check" in args: -- del args['skip_overlap_check'] -- -- # command -- if not compare_args_ipa(ansible_module, args, existing_resource): -- command = "dnsforwardzone_mod" -- -- # enabled or disabled? -- is_enabled = existing_resource["idnszoneactive"][0] -- -- elif existing_resource is None and operation == "add": -- # does not exist but should be present -- # determine args -- args = gen_args(forwarders, forwardpolicy, -- skip_overlap_check) -- # set command -- command = "dnsforwardzone_add" -- # enabled or disabled? -- is_enabled = "TRUE" -- -- elif existing_resource is not None and operation == "add": -- # exists and should be present, has it changed? -- # determine args -- args = gen_args(forwarders, forwardpolicy, skip_overlap_check) -- if 'skip_overlap_check' in args: -- del args['skip_overlap_check'] -- -- # set command -- if not compare_args_ipa(ansible_module, args, existing_resource): -- command = "dnsforwardzone_mod" -- -- # enabled or disabled? -- is_enabled = existing_resource["idnszoneactive"][0] -+ ansible_module.fail_json( -+ msg="dnsforwardzone '%s' not found." % (name)) -+ -+ # does the enabled state match what we want (if we care) -+ if is_enabled != "IGNORE": -+ if wants_enable and is_enabled != "TRUE": -+ commands.append([name, "dnsforwardzone_enable", {}]) -+ elif not wants_enable and is_enabled != "FALSE": -+ commands.append([name, "dnsforwardzone_disable", {}]) - - # if command is set... - if command is not None: -@@ -354,20 +369,9 @@ def main(): - ) - - for name, command, args in commands: -- result = api_command(ansible_module, command, name, args) -+ api_command(ansible_module, command, name, args) - changed = True - -- # does the enabled state match what we want (if we care) -- if is_enabled != "IGNORE": -- if wants_enable and is_enabled != "TRUE": -- api_command(ansible_module, "dnsforwardzone_enable", -- name, {}) -- changed = True -- elif not wants_enable and is_enabled != "FALSE": -- api_command(ansible_module, "dnsforwardzone_disable", -- name, {}) -- changed = True -- - except Exception as e: - ansible_module.fail_json(msg=str(e)) - -diff --git a/tests/dnsforwardzone/test_dnsforwardzone.yml b/tests/dnsforwardzone/test_dnsforwardzone.yml -index 0386bd48..223cf3d0 100644 ---- a/tests/dnsforwardzone/test_dnsforwardzone.yml -+++ b/tests/dnsforwardzone/test_dnsforwardzone.yml -@@ -106,6 +106,22 @@ - register: result - failed_when: not result.changed - -+ - name: change zone forward policy -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: example.com -+ forwardpolicy: first -+ register: result -+ failed_when: not result.changed -+ -+ - name: change zone forward policy, again -+ ipadnsforwardzone: -+ ipaadmin_password: SomeADMINpassword -+ name: example.com -+ forwardpolicy: first -+ register: result -+ failed_when: result.changed -+ - - name: ensure forwardzone example.com is absent. - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword -@@ -256,27 +272,15 @@ - action: member - skip_overlap_check: true - register: result -- failed_when: result.changed -+ failed_when: not result.failed or "not found" not in result.msg - - - name: try to create a new forwarder with disabled state -- ipadnsforwardzone: -- ipaadmin_password: SomeADMINpassword -- state: disabled -- name: example.com -- forwarders: -- - ip_address: 4.4.4.4 -- port: 8053 -- skip_overlap_check: yes -- register: result -- failed_when: not result.changed -- -- - name: ensure it stays disabled - ipadnsforwardzone: - ipaadmin_password: SomeADMINpassword - name: example.com - state: disabled - register: result -- failed_when: result.changed -+ failed_when: not result.failed or "not found" not in result.msg - - - name: Ensure forwardzone is not added without forwarders, with correct message. - ipadnsforwardzone: -From 8da6a6937919d0c390b870113fb557649c39c815 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Fri, 26 Jun 2020 11:28:15 -0300 -Subject: [PATCH] Change password values in README to keep consistency with - other modules. - ---- - README-dnsforwardzone.md | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/README-dnsforwardzone.md b/README-dnsforwardzone.md -index 175e6f8b..32de7bfe 100644 ---- a/README-dnsforwardzone.md -+++ b/README-dnsforwardzone.md -@@ -49,7 +49,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS: - tasks: - - name: ensure presence of forwardzone for DNS requests for example.com to 8.8.8.8 - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -59,13 +59,13 @@ Example playbook to ensure presence of a forwardzone to ipa DNS: - - - name: ensure the forward zone is disabled - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: disabled - - - name: ensure presence of multiple upstream DNS servers for example.com - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -74,7 +74,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS: - - - name: ensure presence of another forwarder to any existing ones for example.com - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - state: present - name: example.com - forwarders: -@@ -83,7 +83,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS: - - - name: ensure the forwarder for example.com does not exists (delete it if needed) - ipadnsforwardzone: -- ipaadmin_password: password01 -+ ipaadmin_password: SomeADMINpassword - name: example.com - state: absent - ``` diff --git a/SOURCES/ansible-freeipa-0.1.12-Fixed-error-msgs-on-FreeIPABaseModule-subclasses_rhbz#1845051.patch b/SOURCES/ansible-freeipa-0.1.12-Fixed-error-msgs-on-FreeIPABaseModule-subclasses_rhbz#1845051.patch deleted file mode 100644 index 3e07764..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Fixed-error-msgs-on-FreeIPABaseModule-subclasses_rhbz#1845051.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 563a03d94bfc29799ea964dab61a1ba35818b9bb Mon Sep 17 00:00:00 2001 -From: Sergio Oliveira Campos -Date: Thu, 30 Jul 2020 09:50:24 -0300 -Subject: [PATCH] Fixed error msgs on FreeIPABaseModule subclasses - -When a fail_json is called a SystemExit exeception is raised. -Since the FreeIPABaseModule has an internal context manager to deal -with exceptions this ContextManager captures the SystemExit. After -dealing destroying the kinit session the SystemExit must be raised again -to allow the fail_json to work properly. ---- - plugins/module_utils/ansible_freeipa_module.py | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py -index 122ea2e..a59e6e2 100644 ---- a/plugins/module_utils/ansible_freeipa_module.py -+++ b/plugins/module_utils/ansible_freeipa_module.py -@@ -610,12 +610,15 @@ class FreeIPABaseModule(AnsibleModule): - exit the module with proper arguments. - - """ -- if exc_val: -- self.fail_json(msg=str(exc_val)) -- - # TODO: shouldn't we also disconnect from api backend? - temp_kdestroy(self.ccache_dir, self.ccache_name) - -+ if exc_type == SystemExit: -+ raise -+ -+ if exc_val: -+ self.fail_json(msg=str(exc_val)) -+ - self.exit_json(changed=self.changed, user=self.exit_args) - - def get_command_errors(self, command, result): --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-Fixes-password-behavior-on-Vault-module_rhbz#1839200.patch b/SOURCES/ansible-freeipa-0.1.12-Fixes-password-behavior-on-Vault-module_rhbz#1839200.patch deleted file mode 100644 index bd9e951..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Fixes-password-behavior-on-Vault-module_rhbz#1839200.patch +++ /dev/null @@ -1,327 +0,0 @@ -From 3e5c54d4fdb10deda9b7e4deaf2c537b132711c9 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Fri, 31 Jul 2020 11:30:51 -0300 -Subject: [PATCH] Fix identification of existing vault type. - -In some scenarios, the value of the vault type is returned as a tuple, -rather than a string, this made some changes to existing vault to fail. -With this change, the vault type is correctly retrieved, if it was not -provided by the user. ---- - plugins/modules/ipavault.py | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py -index 6a3c73e..8562ff7 100644 ---- a/plugins/modules/ipavault.py -+++ b/plugins/modules/ipavault.py -@@ -494,8 +494,10 @@ def check_encryption_params(module, state, action, vault_type, salt, - new_password, new_password_file, res_find): - vault_type_invalid = [] - -- if res_find is not None: -+ if vault_type is None and res_find is not None: - vault_type = res_find['ipavaulttype'] -+ if isinstance(vault_type, (tuple, list)): -+ vault_type = vault_type[0] - - if vault_type == "standard": - vault_type_invalid = ['public_key', 'public_key_file', 'password', --- -2.26.2 - -From d52364bac923f2935b948882d5825e7488b0e9cf Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Fri, 31 Jul 2020 11:32:36 -0300 -Subject: [PATCH] Fix random salt generation. - -The generation of a random salt, when one was not provided, was in the -wrong place and being generated too late to be used properly. Also, the -generation of the value was duplicated. ---- - plugins/modules/ipavault.py | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - -diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py -index 8562ff7..dffd972 100644 ---- a/plugins/modules/ipavault.py -+++ b/plugins/modules/ipavault.py -@@ -768,7 +768,12 @@ def main(): - commands.append([name, "vault_mod_internal", args]) - - else: -+ if vault_type == 'symmetric' \ -+ and 'ipavaultsalt' not in args: -+ args['ipavaultsalt'] = os.urandom(32) -+ - commands.append([name, "vault_add_internal", args]) -+ - if vault_type != 'standard' and vault_data is None: - vault_data = '' - -@@ -826,14 +831,6 @@ def main(): - commands.append( - [name, 'vault_remove_owner', owner_del_args]) - -- if vault_type == 'symmetric' \ -- and 'ipavaultsalt' not in args: -- args['ipavaultsalt'] = os.urandom(32) -- -- if vault_type == 'symmetric' \ -- and 'ipavaultsalt' not in args: -- args['ipavaultsalt'] = os.urandom(32) -- - elif action in "member": - # Add users and groups - if any([users, groups, services]): --- -2.26.2 - -From daee6a6c744a740329ca231a277229567619e10c Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Fri, 31 Jul 2020 11:33:47 -0300 -Subject: [PATCH] Fix verification of parameters for modifying `salt` - attribute. - -When modifying an existing vault to change the value of `salt`, the -password must also change. It is fine to "change" the password to the -same value, thus only changing the salt value. ---- - plugins/modules/ipavault.py | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py -index dffd972..a608e64 100644 ---- a/plugins/modules/ipavault.py -+++ b/plugins/modules/ipavault.py -@@ -517,6 +517,16 @@ def check_encryption_params(module, state, action, vault_type, salt, - module.fail_json( - msg="Cannot modify password of inexistent vault.") - -+ if ( -+ salt is not None -+ and not( -+ any([password, password_file]) -+ and any([new_password, new_password_file]) -+ ) -+ ): -+ module.fail_json( -+ msg="Vault `salt` can only change when changing the password.") -+ - if vault_type == "asymmetric": - vault_type_invalid = [ - 'password', 'password_file', 'new_password', 'new_password_file' --- -2.26.2 - -From 4ef4e706b79fdbb43e462b1a7130fc2cad5894b2 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Fri, 31 Jul 2020 11:42:13 -0300 -Subject: [PATCH] Modify tests to verify password was changed correctly. - -Modify and add tests to verify that a password change has the correct -effect on ipavault. ---- - tests/vault/test_vault_symmetric.yml | 36 ++++++++++++++++++---------- - 1 file changed, 23 insertions(+), 13 deletions(-) - -diff --git a/tests/vault/test_vault_symmetric.yml b/tests/vault/test_vault_symmetric.yml -index bedc221..9294331 100644 ---- a/tests/vault/test_vault_symmetric.yml -+++ b/tests/vault/test_vault_symmetric.yml -@@ -178,6 +178,15 @@ - register: result - failed_when: result.vault.data != 'Hello World.' or result.changed - -+ - name: Retrieve data from symmetric vault, with wrong password. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ password: SomeWRONGpassword -+ state: retrieved -+ register: result -+ failed_when: not result.failed or "Invalid credentials" not in result.msg -+ - - name: Change vault password. - ipavault: - ipaadmin_password: SomeADMINpassword -@@ -187,43 +196,44 @@ - register: result - failed_when: not result.changed - -- - name: Retrieve data from symmetric vault, with wrong password. -+ - name: Retrieve data from symmetric vault, with new password. - ipavault: - ipaadmin_password: SomeADMINpassword - name: symvault -- password: SomeVAULTpassword -+ password: SomeNEWpassword - state: retrieved - register: result -- failed_when: not result.failed or "Invalid credentials" not in result.msg -+ failed_when: result.data != 'Hello World.' or result.changed - -- - name: Change vault password, with wrong `old_password`. -+ - name: Retrieve data from symmetric vault, with old password. - ipavault: - ipaadmin_password: SomeADMINpassword - name: symvault - password: SomeVAULTpassword -- new_password: SomeNEWpassword -+ state: retrieved - register: result - failed_when: not result.failed or "Invalid credentials" not in result.msg - -- - name: Retrieve data from symmetric vault, with new password. -+ - name: Change symmetric vault salt, changing password - ipavault: - ipaadmin_password: SomeADMINpassword - name: symvault - password: SomeNEWpassword -- state: retrieved -+ new_password: SomeVAULTpassword -+ salt: AAAAAAAAAAAAAAAAAAAAAAA= - register: result -- failed_when: result.vault.data != 'Hello World.' or result.changed -+ failed_when: not result.changed - -- - name: Try to add vault with multiple passwords. -+ - name: Change symmetric vault salt, without changing password - ipavault: - ipaadmin_password: SomeADMINpassword -- name: inexistentvault -+ name: symvault - password: SomeVAULTpassword -- password_file: "{{ ansible_env.HOME }}/password.txt" -+ new_password: SomeVAULTpassword -+ salt: MTIzNDU2Nzg5MDEyMzQ1Ngo= - register: result -- failed_when: not result.failed or "parameters are mutually exclusive" not in result.msg -+ failed_when: not result.changed - -- - name: Try to add vault with multiple new passwords. - ipavault: - ipaadmin_password: SomeADMINpassword - name: inexistentvault --- -2.26.2 - -From 8ca282e276477b52d0850d4c01feb3d8e7a5be6d Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Fri, 31 Jul 2020 11:44:33 -0300 -Subject: [PATCH] Modified and added tests to verify correct `salt` update - behavior. - ---- - tests/vault/test_vault_symmetric.yml | 35 ++++++++++++++++++++++++---- - 1 file changed, 31 insertions(+), 4 deletions(-) - -diff --git a/tests/vault/test_vault_symmetric.yml b/tests/vault/test_vault_symmetric.yml -index 9294331..1604a01 100644 ---- a/tests/vault/test_vault_symmetric.yml -+++ b/tests/vault/test_vault_symmetric.yml -@@ -234,14 +234,41 @@ - register: result - failed_when: not result.changed - -+ - name: Try to change symmetric vault salt, without providing any password - ipavault: - ipaadmin_password: SomeADMINpassword -- name: inexistentvault -- password: SomeVAULTpassword -+ name: symvault -+ salt: MTIzNDU2Nzg5MDEyMzQ1Ngo= -+ register: result -+ failed_when: not result.failed and "Vault `salt` can only change when changing the password." not in result.msg -+ -+ - name: Try to change symmetric vault salt, without providing `password` -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ salt: MTIzNDU2Nzg5MDEyMzQ1Ngo= - new_password: SomeVAULTpassword -- new_password_file: "{{ ansible_env.HOME }}/password.txt" - register: result -- failed_when: not result.failed or "parameters are mutually exclusive" not in result.msg -+ failed_when: not result.failed and "Vault `salt` can only change when changing the password." not in result.msg -+ -+ - name: Try to change symmetric vault salt, without providing `new_password` -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ salt: MTIzNDU2Nzg5MDEyMzQ1Ngo= -+ password: SomeVAULTpassword -+ register: result -+ failed_when: not result.failed and "Vault `salt` can only change when changing the password." not in result.msg -+ -+ - name: Try to change symmetric vault salt, using wrong password. -+ ipavault: -+ ipaadmin_password: SomeADMINpassword -+ name: symvault -+ password: SomeWRONGpassword -+ new_password: SomeWRONGpassword -+ salt: MDEyMzQ1Njc4OTAxMjM0NQo= -+ register: result -+ failed_when: not result.failed - - - name: Ensure symmetric vault is absent - ipavault: --- -2.26.2 - -From 3c2700f68beade3513e0e44415d8eb4fb23026e8 Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Fri, 14 Aug 2020 10:43:30 -0300 -Subject: [PATCH] Fixed Vault return value usage from `data` to `vault.data`. - -A test was failing due to use of old ipavault module return structure -and some places on the documentation were alse referring to it. All -ocurrences were fixed. ---- - README-vault.md | 2 +- - plugins/modules/ipavault.py | 2 +- - tests/vault/test_vault_symmetric.yml | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/README-vault.md b/README-vault.md -index 91d311d..e7a31a2 100644 ---- a/README-vault.md -+++ b/README-vault.md -@@ -197,7 +197,7 @@ Example playbook to make sure vault is absent: - state: absent - register: result - - debug: -- msg: "{{ result.data }}" -+ msg: "{{ result.vault.data }}" - ``` - - Variables -diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py -index a608e64..8060976 100644 ---- a/plugins/modules/ipavault.py -+++ b/plugins/modules/ipavault.py -@@ -243,7 +243,7 @@ EXAMPLES = """ - state: retrieved - register: result - - debug: -- msg: "{{ result.data }}" -+ msg: "{{ result.vault.data }}" - - # Change password of a symmetric vault - - ipavault: -diff --git a/tests/vault/test_vault_symmetric.yml b/tests/vault/test_vault_symmetric.yml -index 1604a01..5394c71 100644 ---- a/tests/vault/test_vault_symmetric.yml -+++ b/tests/vault/test_vault_symmetric.yml -@@ -203,7 +203,7 @@ - password: SomeNEWpassword - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Retrieve data from symmetric vault, with old password. - ipavault: --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-Fixes-service-disable-when-service-has-no-certificates-attached_rhbz#1836294.patch b/SOURCES/ansible-freeipa-0.1.12-Fixes-service-disable-when-service-has-no-certificates-attached_rhbz#1836294.patch deleted file mode 100644 index b4b8e6e..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Fixes-service-disable-when-service-has-no-certificates-attached_rhbz#1836294.patch +++ /dev/null @@ -1,112 +0,0 @@ -From e57e4908f936c524085fb5853fe4493c7711ab3f Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Thu, 25 Jun 2020 16:26:30 -0300 -Subject: [PATCH] Fixes service disable when service has no certificates - attached. - -Services without certificates, but with keytabs were not being -disabled. This change allows execution of service_disable if -there is a certificate or if has_keytab is true. - -A new test was added to verify the issue: - - tests/service/test_service_disable.yml ---- - plugins/modules/ipaservice.py | 8 +-- - tests/service/test_service_disable.yml | 68 ++++++++++++++++++++++++++ - 2 files changed, 73 insertions(+), 3 deletions(-) - create mode 100644 tests/service/test_service_disable.yml - -diff --git a/plugins/modules/ipaservice.py b/plugins/modules/ipaservice.py -index 23a0d6b3..b0d25355 100644 ---- a/plugins/modules/ipaservice.py -+++ b/plugins/modules/ipaservice.py -@@ -812,9 +812,11 @@ def main(): - - elif state == "disabled": - if action == "service": -- if res_find is not None and \ -- len(res_find.get('usercertificate', [])) > 0: -- commands.append([name, 'service_disable', {}]) -+ if res_find is not None: -+ has_cert = bool(res_find.get('usercertificate')) -+ has_keytab = res_find.get('has_keytab', False) -+ if has_cert or has_keytab: -+ commands.append([name, 'service_disable', {}]) - else: - ansible_module.fail_json( - msg="Invalid action '%s' for state '%s'" % -diff --git a/tests/service/test_service_disable.yml b/tests/service/test_service_disable.yml -new file mode 100644 -index 00000000..3b4a88fb ---- /dev/null -+++ b/tests/service/test_service_disable.yml -@@ -0,0 +1,68 @@ -+--- -+- name: Playbook to manage IPA service. -+ hosts: ipaserver -+ become: yes -+ gather_facts: yes -+ -+ tasks: -+ - name: Ensure service is absent -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "mysvc1/{{ ansible_fqdn }}" -+ -+ - name: Ensure service is present -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "mysvc1/{{ ansible_fqdn }}" -+ certificate: -+ - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq -+ force: no -+ register: result -+ failed_when: not result.changed -+ -+ - name: Obtain keytab -+ shell: ipa-getkeytab -s "{{ ansible_fqdn }}" -p "mysvc1/{{ ansible_fqdn }}" -k mysvc1.keytab -+ -+ - name: Verify keytab -+ shell: ipa service-find "mysvc1/{{ ansible_fqdn }}" -+ register: result -+ failed_when: result.failed or result.stdout | regex_search(" Keytab. true") -+ -+ - name: Ensure service is disabled -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "mysvc1/{{ ansible_fqdn }}" -+ state: disabled -+ register: result -+ failed_when: not result.changed -+ -+ - name: Verify keytab -+ shell: ipa service-find "mysvc1/{{ ansible_fqdn }}" -+ register: result -+ failed_when: result.failed or result.stdout | regex_search(" Keytab. true") -+ -+ - name: Obtain keytab -+ shell: ipa-getkeytab -s "{{ ansible_fqdn }}" -p "mysvc1/{{ ansible_fqdn }}" -k mysvc1.keytab -+ -+ - name: Verify keytab -+ shell: ipa service-find "mysvc1/{{ ansible_fqdn }}" -+ register: result -+ failed_when: result.failed or result.stdout | regex_search(" Keytab. true") -+ -+ - name: Ensure service is disabled -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "mysvc1/{{ ansible_fqdn }}" -+ state: disabled -+ register: result -+ failed_when: not result.changed -+ -+ - name: Verify keytab -+ shell: ipa service-find "mysvc1/{{ ansible_fqdn }}" -+ register: result -+ failed_when: result.failed or result.stdout | regex_search(" Keytab. true") -+ -+ - name: Ensure service is absent -+ ipaservice: -+ ipaadmin_password: SomeADMINpassword -+ name: "mysvc1/{{ ansible_fqdn }}" diff --git a/SOURCES/ansible-freeipa-0.1.12-Modified-return-value-for-ipavault-module_rhbz#1867909.patch b/SOURCES/ansible-freeipa-0.1.12-Modified-return-value-for-ipavault-module_rhbz#1867909.patch deleted file mode 100644 index 0cba294..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-Modified-return-value-for-ipavault-module_rhbz#1867909.patch +++ /dev/null @@ -1,300 +0,0 @@ -From e96ef4e98e523f20c25777308c093ebbff272b2d Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Wed, 5 Aug 2020 15:24:15 -0300 -Subject: [PATCH] Updated documentation for ipavault module in the source code. - -This change fixes a wrong parameter name in the documentation of -RESULT_VALUES, and also provide a correct YAML snippet to ensure -presence of an asymmetric vault with a formatted private key. ---- - plugins/modules/ipavault.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py -index 46c6fcd..84645c7 100644 ---- a/plugins/modules/ipavault.py -+++ b/plugins/modules/ipavault.py -@@ -267,7 +267,7 @@ EXAMPLES = """ - username: user01 - description: An asymmetric vault - vault_type: asymmetric -- public_key: -+ public_key: | - LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR - HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi - 9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM -@@ -303,7 +303,7 @@ EXAMPLES = """ - """ - - RETURN = """ --user: -+data: - description: The vault data. - returned: If state is retrieved. - type: string --- -2.26.2 - -From 7dd0b547c47b4fd617960490b8553a5036e3b30c Mon Sep 17 00:00:00 2001 -From: Rafael Guterres Jeffman -Date: Mon, 10 Aug 2020 16:02:09 -0300 -Subject: [PATCH] Modified return value for ipavault module. - -The ipavault module was returning a single string value when retrieving -data. To keep consistency with other modules, it should return a dict -with the `data` variable in it. - -This change modifies the result of ipavault to be a dict and also fixes -relevant tests, examples and documentation. ---- - README-vault.md | 5 +++++ - .../vault/retrive-data-asymmetric-vault.yml | 2 +- - .../vault/retrive-data-symmetric-vault.yml | 2 +- - plugins/modules/ipavault.py | 19 +++++++++++++------ - tests/vault/test_vault_asymmetric.yml | 12 ++++++------ - tests/vault/test_vault_standard.yml | 8 ++++---- - tests/vault/test_vault_symmetric.yml | 14 +++++++------- - 7 files changed, 37 insertions(+), 25 deletions(-) - -diff --git a/README-vault.md b/README-vault.md -index fa1d3e1..91d311d 100644 ---- a/README-vault.md -+++ b/README-vault.md -@@ -248,6 +248,11 @@ Variable | Description | Returned When - -------- | ----------- | ------------- - `data` | The data stored in the vault. | If `state` is `retrieved`. - -+Variable | Description | Returned When -+-------- | ----------- | ------------- -+`vault` | Vault dict with archived data. (dict)
Options: | If `state` is `retrieved`. -+  | `data` - The vault data. | Always -+ - - Notes - ===== -diff --git a/playbooks/vault/retrive-data-asymmetric-vault.yml b/playbooks/vault/retrive-data-asymmetric-vault.yml -index 5f67c59..f71f826 100644 ---- a/playbooks/vault/retrive-data-asymmetric-vault.yml -+++ b/playbooks/vault/retrive-data-asymmetric-vault.yml -@@ -14,4 +14,4 @@ - state: retrieved - register: result - - debug: -- msg: "Data: {{ result.data }}" -+ msg: "Data: {{ result.vault.data }}" -diff --git a/playbooks/vault/retrive-data-symmetric-vault.yml b/playbooks/vault/retrive-data-symmetric-vault.yml -index 163f8b9..24692a8 100644 ---- a/playbooks/vault/retrive-data-symmetric-vault.yml -+++ b/playbooks/vault/retrive-data-symmetric-vault.yml -@@ -14,4 +14,4 @@ - state: retrieved - register: result - - debug: -- msg: "{{ result.data | b64decode }}" -+ msg: "{{ result.vault.data }}" -diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py -index 84645c7..6a3c73e 100644 ---- a/plugins/modules/ipavault.py -+++ b/plugins/modules/ipavault.py -@@ -303,10 +303,15 @@ EXAMPLES = """ - """ - - RETURN = """ --data: -- description: The vault data. -- returned: If state is retrieved. -- type: string -+vault: -+ description: Vault dict with archived data. -+ returned: If state is `retrieved`. -+ type: dict -+ options: -+ data: -+ description: The vault data. -+ returned: always -+ type: string - """ - - import os -@@ -910,9 +915,11 @@ def main(): - if 'result' not in result: - raise Exception("No result obtained.") - if 'data' in result['result']: -- exit_args['data'] = result['result']['data'] -+ data_return = exit_args.setdefault('vault', {}) -+ data_return['data'] = result['result']['data'] - elif 'vault_data' in result['result']: -- exit_args['data'] = result['result']['vault_data'] -+ data_return = exit_args.setdefault('vault', {}) -+ data_return['data'] = result['result']['vault_data'] - else: - raise Exception("No data retrieved.") - changed = False -diff --git a/tests/vault/test_vault_asymmetric.yml b/tests/vault/test_vault_asymmetric.yml -index 1a1d3dc..268922c 100644 ---- a/tests/vault/test_vault_asymmetric.yml -+++ b/tests/vault/test_vault_asymmetric.yml -@@ -42,7 +42,7 @@ - private_key: "{{ lookup('file', 'private.pem') | b64encode }}" - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Retrieve data from asymmetric vault into file {{ ansible_env.HOME }}/data.txt. - ipavault: -@@ -75,7 +75,7 @@ - private_key: "{{ lookup('file', 'private.pem') | b64encode }}" - state: retrieved - register: result -- failed_when: result.data != 'The world of π is half rounded.' or result.changed -+ failed_when: result.vault.data != 'The world of π is half rounded.' or result.changed - - - name: Archive data in asymmetric vault, from file. - ipavault: -@@ -93,7 +93,7 @@ - private_key: "{{ lookup('file', 'private.pem') | b64encode }}" - state: retrieved - register: result -- failed_when: result.data != 'Another World.' or result.changed -+ failed_when: result.vault.data != 'Another World.' or result.changed - - - name: Archive data with single character to asymmetric vault - ipavault: -@@ -110,7 +110,7 @@ - private_key: "{{ lookup('file', 'private.pem') | b64encode }}" - state: retrieved - register: result -- failed_when: result.data != 'c' or result.changed -+ failed_when: result.vault.data != 'c' or result.changed - - - name: Ensure asymmetric vault is absent - ipavault: -@@ -161,7 +161,7 @@ - private_key: "{{ lookup('file', 'private.pem') | b64encode }}" - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Retrieve data from asymmetric vault, with password file. - ipavault: -@@ -170,7 +170,7 @@ - private_key_file: "{{ ansible_env.HOME }}/private.pem" - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Ensure asymmetric vault is absent - ipavault: -diff --git a/tests/vault/test_vault_standard.yml b/tests/vault/test_vault_standard.yml -index 5e0da98..6ccb0d5 100644 ---- a/tests/vault/test_vault_standard.yml -+++ b/tests/vault/test_vault_standard.yml -@@ -39,7 +39,7 @@ - name: stdvault - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Retrieve data from standard vault into file {{ ansible_env.HOME }}/data.txt. - ipavault: -@@ -70,7 +70,7 @@ - name: stdvault - state: retrieved - register: result -- failed_when: result.data != 'The world of π is half rounded.' or result.changed -+ failed_when: result.vault.data != 'The world of π is half rounded.' or result.changed - - - name: Archive data in standard vault, from file. - ipavault: -@@ -87,7 +87,7 @@ - name: stdvault - state: retrieved - register: result -- failed_when: result.data != 'Another World.' or result.changed -+ failed_when: result.vault.data != 'Another World.' or result.changed - - - name: Archive data with single character to standard vault - ipavault: -@@ -103,7 +103,7 @@ - name: stdvault - state: retrieved - register: result -- failed_when: result.data != 'c' or result.changed -+ failed_when: result.vault.data != 'c' or result.changed - - - name: Ensure standard vault is absent - ipavault: -diff --git a/tests/vault/test_vault_symmetric.yml b/tests/vault/test_vault_symmetric.yml -index a6072d8..bedc221 100644 ---- a/tests/vault/test_vault_symmetric.yml -+++ b/tests/vault/test_vault_symmetric.yml -@@ -43,7 +43,7 @@ - password: SomeVAULTpassword - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Retrieve data from symmetric vault into file {{ ansible_env.HOME }}/data.txt. - ipavault: -@@ -77,7 +77,7 @@ - password: SomeVAULTpassword - state: retrieved - register: result -- failed_when: result.data != 'The world of π is half rounded.' or result.changed -+ failed_when: result.vault.data != 'The world of π is half rounded.' or result.changed - - - name: Archive data in symmetric vault, from file. - ipavault: -@@ -95,7 +95,7 @@ - password: SomeVAULTpassword - state: retrieved - register: result -- failed_when: result.data != 'Another World.' or result.changed -+ failed_when: result.vault.data != 'Another World.' or result.changed - - - name: Archive data with single character to symmetric vault - ipavault: -@@ -113,7 +113,7 @@ - password: SomeVAULTpassword - state: retrieved - register: result -- failed_when: result.data != 'c' or result.changed -+ failed_when: result.vault.data != 'c' or result.changed - - - name: Ensure symmetric vault is absent - ipavault: -@@ -167,7 +167,7 @@ - password: SomeVAULTpassword - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Retrieve data from symmetric vault, with password file. - ipavault: -@@ -176,7 +176,7 @@ - password_file: "{{ ansible_env.HOME }}/password.txt" - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Change vault password. - ipavault: -@@ -212,7 +212,7 @@ - password: SomeNEWpassword - state: retrieved - register: result -- failed_when: result.data != 'Hello World.' or result.changed -+ failed_when: result.vault.data != 'Hello World.' or result.changed - - - name: Try to add vault with multiple passwords. - ipavault: --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-action_plugins-ipaclient_get_otp-Discovered-python-n_rhbz#1852714.patch b/SOURCES/ansible-freeipa-0.1.12-action_plugins-ipaclient_get_otp-Discovered-python-n_rhbz#1852714.patch deleted file mode 100644 index 14dbf4e..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-action_plugins-ipaclient_get_otp-Discovered-python-n_rhbz#1852714.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 80aac15de9026055ae2b9972859939cf7925b813 Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Tue, 30 Jun 2020 17:32:19 +0200 -Subject: [PATCH] action_plugins/ipaclient_get_otp: Discovered python needed in - task_vars - -Ansible is now also supporting discovered_python_interpreter for -action_plugins. task_vars needs to be non Null and contain a setting for -discovered_python_interpreter. The ipaclient_get_otp action_plugin -therefore needed to be adapted. ---- - roles/ipaclient/action_plugins/ipaclient_get_otp.py | 4 ++-- - roles/ipaclient/tasks/install.yml | 1 - - 2 files changed, 2 insertions(+), 3 deletions(-) - -diff --git a/roles/ipaclient/action_plugins/ipaclient_get_otp.py b/roles/ipaclient/action_plugins/ipaclient_get_otp.py -index dcddc0a..8e04ad9 100644 ---- a/roles/ipaclient/action_plugins/ipaclient_get_otp.py -+++ b/roles/ipaclient/action_plugins/ipaclient_get_otp.py -@@ -164,7 +164,8 @@ class ActionModule(ActionBase): - return result - - data = self._execute_module(module_name='ipaclient_get_facts', -- module_args=dict(), task_vars=None) -+ module_args=dict(), task_vars=task_vars) -+ - try: - domain = data['ansible_facts']['ipa']['domain'] - realm = data['ansible_facts']['ipa']['realm'] -@@ -245,4 +246,3 @@ class ActionModule(ActionBase): - finally: - # delete the local temp directory - shutil.rmtree(local_temp_dir, ignore_errors=True) -- run_cmd(['/usr/bin/kdestroy', '-c', tmp_ccache]) -diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml -index 0de3dea..4421f0c 100644 ---- a/roles/ipaclient/tasks/install.yml -+++ b/roles/ipaclient/tasks/install.yml -@@ -134,7 +134,6 @@ - "Password cannot be set on enrolled host" not - in result_ipaclient_get_otp.msg - delegate_to: "{{ result_ipaclient_test.servers[0] }}" -- delegate_facts: yes - ignore_errors: yes - - - name: Install - Report error for OTP generation --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-ipa-host-group-Fix-membermanager-unknow-user-issue_rhbz#1848426.patch b/SOURCES/ansible-freeipa-0.1.12-ipa-host-group-Fix-membermanager-unknow-user-issue_rhbz#1848426.patch deleted file mode 100644 index 69069b2..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-ipa-host-group-Fix-membermanager-unknow-user-issue_rhbz#1848426.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 6132a947e65fb9c3a1ec5c059aed34afb06a67df Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Mon, 29 Jun 2020 13:12:12 +0200 -Subject: [PATCH] ipa[host]group: Fix membermanager unknow user issue - -If a unknown membermanager user presence will be ensured, the unknown user -error was ignored. This has been fixed in ipagroup. The code for the error -handling in ipagroup and ipahostgroup has been adapted because of this. - -New tests for tests/[host]group/test_[host]group_membermnager.yml have been -added. ---- - plugins/modules/ipagroup.py | 19 +++++++++---------- - plugins/modules/ipahostgroup.py | 13 +++++++------ - tests/group/test_group_membermanager.yml | 11 ++++++++++- - .../test_hostgroup_membermanager.yml | 11 ++++++++++- - 4 files changed, 36 insertions(+), 18 deletions(-) - -diff --git a/plugins/modules/ipagroup.py b/plugins/modules/ipagroup.py -index 915bc499..903c256d 100644 ---- a/plugins/modules/ipagroup.py -+++ b/plugins/modules/ipagroup.py -@@ -507,16 +507,15 @@ def main(): - # All "already a member" and "not a member" failures in the - # result are ignored. All others are reported. - errors = [] -- if "failed" in result and len(result["failed"]) > 0: -- for item in result["failed"]: -- failed_item = result["failed"][item] -- for member_type in failed_item: -- for member, failure in failed_item[member_type]: -- if "already a member" in failure \ -- or "not a member" in failure: -- continue -- errors.append("%s: %s %s: %s" % ( -- command, member_type, member, failure)) -+ for failed_item in result.get("failed", []): -+ failed = result["failed"][failed_item] -+ for member_type in failed: -+ for member, failure in failed[member_type]: -+ if "already a member" in failure \ -+ or "not a member" in failure: -+ continue -+ errors.append("%s: %s %s: %s" % ( -+ command, member_type, member, failure)) - if len(errors) > 0: - ansible_module.fail_json(msg=", ".join(errors)) - -diff --git a/plugins/modules/ipahostgroup.py b/plugins/modules/ipahostgroup.py -index 4c18e940..5f615160 100644 ---- a/plugins/modules/ipahostgroup.py -+++ b/plugins/modules/ipahostgroup.py -@@ -423,14 +423,15 @@ def main(): - # All "already a member" and "not a member" failures in the - # result are ignored. All others are reported. - errors = [] -- if "failed" in result and "member" in result["failed"]: -- failed = result["failed"]["member"] -+ for failed_item in result.get("failed", []): -+ failed = result["failed"][failed_item] - for member_type in failed: - for member, failure in failed[member_type]: -- if "already a member" not in failure \ -- and "not a member" not in failure: -- errors.append("%s: %s %s: %s" % ( -- command, member_type, member, failure)) -+ if "already a member" in failure \ -+ or "not a member" in failure: -+ continue -+ errors.append("%s: %s %s: %s" % ( -+ command, member_type, member, failure)) - if len(errors) > 0: - ansible_module.fail_json(msg=", ".join(errors)) - -diff --git a/tests/group/test_group_membermanager.yml b/tests/group/test_group_membermanager.yml -index 1d38654f..661f26d6 100644 ---- a/tests/group/test_group_membermanager.yml -+++ b/tests/group/test_group_membermanager.yml -@@ -8,7 +8,7 @@ - - name: Ensure user manangeruser1 and manageruser2 is absent - ipauser: - ipaadmin_password: SomeADMINpassword -- name: manageruser1,manageruser2 -+ name: manageruser1,manageruser2,unknown_user - state: absent - - - name: Ensure group testgroup, managergroup1 and managergroup2 are absent -@@ -185,6 +185,15 @@ - register: result - failed_when: not result.changed - -+ - name: Ensure unknown membermanager_user member failure -+ ipagroup: -+ ipaadmin_password: SomeADMINpassword -+ name: testgroup -+ membermanager_user: unknown_user -+ action: member -+ register: result -+ failed_when: result.changed or "no such entry" not in result.msg -+ - - name: Ensure group testgroup, managergroup1 and managergroup2 are absent - ipagroup: - ipaadmin_password: SomeADMINpassword -diff --git a/tests/hostgroup/test_hostgroup_membermanager.yml b/tests/hostgroup/test_hostgroup_membermanager.yml -index c32d1088..c0f65460 100644 ---- a/tests/hostgroup/test_hostgroup_membermanager.yml -+++ b/tests/hostgroup/test_hostgroup_membermanager.yml -@@ -15,7 +15,7 @@ - - name: Ensure user manangeruser1 and manageruser2 is absent - ipauser: - ipaadmin_password: SomeADMINpassword -- name: manageruser1,manageruser2 -+ name: manageruser1,manageruser2,unknown_user - state: absent - - - name: Ensure group managergroup1 and managergroup2 are absent -@@ -200,6 +200,15 @@ - register: result - failed_when: not result.changed - -+ - name: Ensure unknown membermanager_user member failure -+ ipahostgroup: -+ ipaadmin_password: SomeADMINpassword -+ name: testhostgroup -+ membermanager_user: unknown_user -+ action: member -+ register: result -+ failed_when: result.changed or "no such entry" not in result.msg -+ - - name: Ensure host-group testhostgroup is absent - ipahostgroup: - ipaadmin_password: SomeADMINpassword diff --git a/SOURCES/ansible-freeipa-0.1.12-ipa-server-replica-Fix-pkcs12-info-regressions-intro_rhbz#1853284.patch b/SOURCES/ansible-freeipa-0.1.12-ipa-server-replica-Fix-pkcs12-info-regressions-intro_rhbz#1853284.patch deleted file mode 100644 index ab45af0..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-ipa-server-replica-Fix-pkcs12-info-regressions-intro_rhbz#1853284.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 8ce5fd147aafc34e43dbe4246565c48eace2e115 Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Thu, 2 Jul 2020 12:02:33 +0200 -Subject: [PATCH] ipa[server,replica]: Fix pkcs12 info regressions introduced - with CA-less - -With the CA-less patches the types for the pkcs12 infos have been changed -to lists in the modules. This is resulting in a bad conversion from None -to [''] for the parameters. Because of this a normal replica deployment is -failing as [''] is not a valid value. - -The install.yml files for ipareplica and also ipaserver have been changed -in the way that the pkcs12 values are checked if they are None. The -parameter will simply be omitted in this case and the parameter in the -module will become None by default. ---- - roles/ipareplica/tasks/install.yml | 18 +++++++++--------- - roles/ipaserver/tasks/install.yml | 10 +++++----- - 2 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/roles/ipareplica/tasks/install.yml b/roles/ipareplica/tasks/install.yml -index fc7f83e..c2a6222 100644 ---- a/roles/ipareplica/tasks/install.yml -+++ b/roles/ipareplica/tasks/install.yml -@@ -281,7 +281,7 @@ - ccache: "{{ result_ipareplica_prepare.ccache }}" - installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}" - _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" -- _dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}" -+ _dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info if result_ipareplica_prepare._dirsrv_pkcs12_info != None else omit }}" - subject_base: "{{ result_ipareplica_prepare.subject_base }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - _add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}" -@@ -345,7 +345,7 @@ - config_master_host_name: - "{{ result_ipareplica_install_ca_certs.config_master_host_name }}" - ccache: "{{ result_ipareplica_prepare.ccache }}" -- _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" -+ _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - - # We need to point to the master in ipa default conf when certmonger -@@ -407,8 +407,8 @@ - ccache: "{{ result_ipareplica_prepare.ccache }}" - _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" - _ca_file: "{{ result_ipareplica_prepare._ca_file }}" -- _dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}" -- _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" -+ _dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info if result_ipareplica_prepare._dirsrv_pkcs12_info != None else omit }}" -+ _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - dirman_password: "{{ ipareplica_dirman_password }}" - ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}" -@@ -429,7 +429,7 @@ - ccache: "{{ result_ipareplica_prepare.ccache }}" - _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" - _ca_file: "{{ result_ipareplica_prepare._ca_file }}" -- _http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}" -+ _http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info if result_ipareplica_prepare._http_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - dirman_password: "{{ ipareplica_dirman_password }}" - -@@ -507,7 +507,7 @@ - _kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}" - _kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}" - _ca_file: "{{ result_ipareplica_prepare._ca_file }}" -- _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" -+ _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - dirman_password: "{{ ipareplica_dirman_password }}" - -@@ -529,7 +529,7 @@ - _kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}" - _kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}" - _subject_base: "{{ result_ipareplica_prepare._subject_base }}" -- _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" -+ _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - dirman_password: "{{ ipareplica_dirman_password }}" - config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}" -@@ -554,7 +554,7 @@ - ccache: "{{ result_ipareplica_prepare.ccache }}" - _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" - _ca_file: "{{ result_ipareplica_prepare._ca_file }}" -- _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" -+ _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - dirman_password: "{{ ipareplica_dirman_password }}" - -@@ -574,7 +574,7 @@ - ccache: "{{ result_ipareplica_prepare.ccache }}" - _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" - _ca_file: "{{ result_ipareplica_prepare._ca_file }}" -- _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}" -+ _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - dirman_password: "{{ ipareplica_dirman_password }}" - ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}" -diff --git a/roles/ipaserver/tasks/install.yml b/roles/ipaserver/tasks/install.yml -index 30f9da2..687f72d 100644 ---- a/roles/ipaserver/tasks/install.yml -+++ b/roles/ipaserver/tasks/install.yml -@@ -203,7 +203,7 @@ - # no_host_dns: "{{ result_ipaserver_test.no_host_dns }}" - dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" - dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default(omit) }}" -- _dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}" -+ _dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info if result_ipaserver_test._dirsrv_pkcs12_info != None else omit }}" - external_cert_files: - "{{ ipaserver_external_cert_files | default(omit) }}" - subject_base: "{{ result_ipaserver_prepare.subject_base }}" -@@ -240,7 +240,7 @@ - no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" - idstart: "{{ result_ipaserver_test.idstart }}" - idmax: "{{ result_ipaserver_test.idmax }}" -- _pkinit_pkcs12_info: "{{ result_ipaserver_test._pkinit_pkcs12_info }}" -+ _pkinit_pkcs12_info: "{{ result_ipaserver_test._pkinit_pkcs12_info if result_ipaserver_test._pkinit_pkcs12_info != None else omit }}" - - - name: Install - Setup custodia - ipaserver_setup_custodia: -@@ -270,7 +270,7 @@ - no_pkinit: "{{ result_ipaserver_test.no_pkinit }}" - dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" - dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" -- _dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}" -+ _dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info if result_ipaserver_test._dirsrv_pkcs12_info != None else omit }}" - external_ca: "{{ ipaserver_external_ca }}" - external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}" - external_ca_profile: -@@ -334,7 +334,7 @@ - idmax: "{{ result_ipaserver_test.idmax }}" - http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" - no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" -- _http_pkcs12_info: "{{ result_ipaserver_test._http_pkcs12_info }}" -+ _http_pkcs12_info: "{{ result_ipaserver_test._http_pkcs12_info if result_ipaserver_test._http_pkcs12_info != None else omit }}" - - - name: Install - Setup KRA - ipaserver_setup_kra: -@@ -394,7 +394,7 @@ - idstart: "{{ result_ipaserver_test.idstart }}" - idmax: "{{ result_ipaserver_test.idmax }}" - dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" -- _dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}" -+ _dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info if result_ipaserver_test._dirsrv_pkcs12_info != None else omit }}" - - - name: Install - Setup client - include_role: --- -2.26.2 - diff --git a/SOURCES/ansible-freeipa-0.1.12-ipa-user,host-Fail-on-duplucate-names-in-the-users-and-hosts-lists_rhbz#1822683.patch b/SOURCES/ansible-freeipa-0.1.12-ipa-user,host-Fail-on-duplucate-names-in-the-users-and-hosts-lists_rhbz#1822683.patch deleted file mode 100644 index 1bf52b7..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-ipa-user,host-Fail-on-duplucate-names-in-the-users-and-hosts-lists_rhbz#1822683.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 1d7fb31b8bfa00babd7c753b354d7344b531cd77 Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Mon, 29 Jun 2020 14:50:56 +0200 -Subject: [PATCH] ipa[user,host]: Fail on duplucate names in the users and - hosts lists - -It was possible to have several entries for names with the hosts and users -lists. This resulted sometimes in errors but also unexpected changes. A new -check has been added to make sure that the names in the users and hosts -lists are unique. - -New tests have been added to verify this in the existing files: -- tests/host/test_hosts.yml -- tests/user/test_users.yml ---- - plugins/modules/ipahost.py | 7 +++++++ - plugins/modules/ipauser.py | 7 +++++++ - tests/host/test_hosts.yml | 15 +++++++++++++++ - tests/user/test_users.yml | 19 +++++++++++++++++++ - 4 files changed, 48 insertions(+) - -diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py -index 7a981f16..1fe11dc5 100644 ---- a/plugins/modules/ipahost.py -+++ b/plugins/modules/ipahost.py -@@ -799,10 +799,15 @@ def main(): - server_realm = api_get_realm() - - commands = [] -+ host_set = set() - - for host in names: - if isinstance(host, dict): - name = host.get("name") -+ if name in host_set: -+ ansible_module.fail_json( -+ msg="host '%s' is used more than once" % name) -+ host_set.add(name) - description = host.get("description") - locality = host.get("locality") - location = host.get("location") -@@ -1337,6 +1342,8 @@ def main(): - else: - ansible_module.fail_json(msg="Unkown state '%s'" % state) - -+ del host_set -+ - # Execute commands - - errors = [] -diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py -index b8152ee4..03713a41 100644 ---- a/plugins/modules/ipauser.py -+++ b/plugins/modules/ipauser.py -@@ -958,10 +958,15 @@ def main(): - # commands - - commands = [] -+ user_set = set() - - for user in names: - if isinstance(user, dict): - name = user.get("name") -+ if name in user_set: -+ ansible_module.fail_json( -+ msg="user '%s' is used more than once" % name) -+ user_set.add(name) - # present - first = user.get("first") - last = user.get("last") -@@ -1370,6 +1375,8 @@ def main(): - else: - ansible_module.fail_json(msg="Unkown state '%s'" % state) - -+ del user_set -+ - # Execute commands - - errors = [] -diff --git a/tests/host/test_hosts.yml b/tests/host/test_hosts.yml -index 30fd6538..f82cc612 100644 ---- a/tests/host/test_hosts.yml -+++ b/tests/host/test_hosts.yml -@@ -96,3 +96,18 @@ - state: absent - register: result - failed_when: result.changed -+ -+ - name: Duplicate names in hosts failure test -+ ipahost: -+ ipaadmin_password: SomeADMINpassword -+ hosts: -+ - name: "{{ host1_fqdn }}" -+ force: yes -+ - name: "{{ host2_fqdn }}" -+ force: yes -+ - name: "{{ host3_fqdn }}" -+ force: yes -+ - name: "{{ host3_fqdn }}" -+ force: yes -+ register: result -+ failed_when: result.changed or "is used more than once" not in result.msg -diff --git a/tests/user/test_users.yml b/tests/user/test_users.yml -index 5b5d4538..81c7b608 100644 ---- a/tests/user/test_users.yml -+++ b/tests/user/test_users.yml -@@ -85,6 +85,25 @@ - register: result - failed_when: result.changed - -+ - name: Duplicate names in users failure test -+ ipauser: -+ ipaadmin_password: SomeADMINpassword -+ users: -+ - name: user1 -+ givenname: user1 -+ last: Last -+ - name: user2 -+ first: user2 -+ last: Last -+ - name: user3 -+ first: user3 -+ last: Last -+ - name: user3 -+ first: user3 -+ last: Last -+ register: result -+ failed_when: result.changed or "is used more than once" not in result.msg -+ - - name: Remove test users - ipauser: - ipaadmin_password: SomeADMINpassword diff --git a/SOURCES/ansible-freeipa-0.1.12-ipareplica-Fix-missing-parameters-for-several-module_hbz#1855299.patch b/SOURCES/ansible-freeipa-0.1.12-ipareplica-Fix-missing-parameters-for-several-module_hbz#1855299.patch deleted file mode 100644 index ad3ce22..0000000 --- a/SOURCES/ansible-freeipa-0.1.12-ipareplica-Fix-missing-parameters-for-several-module_hbz#1855299.patch +++ /dev/null @@ -1,271 +0,0 @@ -From 7a2eaa6f535b1353d46bcfa8b0b2484b15ff3863 Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Tue, 7 Jul 2020 17:13:09 +0200 -Subject: [PATCH] ipareplica: Fix missing parameters for several modules - -The parameters master_host_name, config_setup_ca, dirman_password have not -been set for some modules. Also there was no ldap2 connection within -ipareplica_setup_kra. All this resulted in improper configuration where -for example KRA deployment failed in the end. - -A conversion warning in ipareplica_setup_adtrust has also been fixed for -the setup_ca parameter. - -Fixes #314 (IPA replica installation failure - DS enabled SSL - second part) ---- - .../library/ipareplica_create_ipa_conf.py | 1 + - .../library/ipareplica_ds_apply_updates.py | 1 + - .../library/ipareplica_ds_enable_ssl.py | 1 + - .../library/ipareplica_setup_adtrust.py | 2 +- - .../library/ipareplica_setup_custodia.py | 1 + - .../library/ipareplica_setup_http.py | 2 +- - .../ipareplica/library/ipareplica_setup_kra.py | 18 ++++++++++++++++++ - .../ipareplica/library/ipareplica_setup_krb.py | 7 +++++++ - roles/ipareplica/tasks/install.yml | 8 ++++++++ - 9 files changed, 39 insertions(+), 2 deletions(-) - -diff --git a/roles/ipareplica/library/ipareplica_create_ipa_conf.py b/roles/ipareplica/library/ipareplica_create_ipa_conf.py -index 3a85a6f..c475469 100644 ---- a/roles/ipareplica/library/ipareplica_create_ipa_conf.py -+++ b/roles/ipareplica/library/ipareplica_create_ipa_conf.py -@@ -262,6 +262,7 @@ def main(): - config.subject_base = options.subject_base - config.dirman_password = dirman_password - config.ca_host_name = ca_host_name -+ config.setup_ca = options.setup_ca - - remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) - installer._remote_api = remote_api -diff --git a/roles/ipareplica/library/ipareplica_ds_apply_updates.py b/roles/ipareplica/library/ipareplica_ds_apply_updates.py -index 3796874..71008b3 100644 ---- a/roles/ipareplica/library/ipareplica_ds_apply_updates.py -+++ b/roles/ipareplica/library/ipareplica_ds_apply_updates.py -@@ -177,6 +177,7 @@ def main(): - config = gen_ReplicaConfig() - config.dirman_password = dirman_password - config.subject_base = options.subject_base -+ config.master_host_name = master_host_name - - remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) - -diff --git a/roles/ipareplica/library/ipareplica_ds_enable_ssl.py b/roles/ipareplica/library/ipareplica_ds_enable_ssl.py -index a1b638e..3e4090d 100644 ---- a/roles/ipareplica/library/ipareplica_ds_enable_ssl.py -+++ b/roles/ipareplica/library/ipareplica_ds_enable_ssl.py -@@ -173,6 +173,7 @@ def main(): - config = gen_ReplicaConfig() - config.dirman_password = dirman_password - config.subject_base = options.subject_base -+ config.master_host_name = master_host_name - - remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) - # installer._remote_api = remote_api -diff --git a/roles/ipareplica/library/ipareplica_setup_adtrust.py b/roles/ipareplica/library/ipareplica_setup_adtrust.py -index c830ebf..734e56d 100644 ---- a/roles/ipareplica/library/ipareplica_setup_adtrust.py -+++ b/roles/ipareplica/library/ipareplica_setup_adtrust.py -@@ -110,7 +110,7 @@ def main(): - # additional - ccache=dict(required=True), - _top_dir=dict(required=True), -- setup_ca=dict(required=True), -+ setup_ca=dict(required=True, type='bool'), - config_master_host_name=dict(required=True), - ), - supports_check_mode=True, -diff --git a/roles/ipareplica/library/ipareplica_setup_custodia.py b/roles/ipareplica/library/ipareplica_setup_custodia.py -index 5a74e87..2e95c26 100644 ---- a/roles/ipareplica/library/ipareplica_setup_custodia.py -+++ b/roles/ipareplica/library/ipareplica_setup_custodia.py -@@ -169,6 +169,7 @@ def main(): - config.promote = installer.promote - config.kra_enabled = kra_enabled - config.kra_host_name = kra_host_name -+ config.setup_ca = options.setup_ca - - remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) - -diff --git a/roles/ipareplica/library/ipareplica_setup_http.py b/roles/ipareplica/library/ipareplica_setup_http.py -index 987ea95..3fa4807 100644 ---- a/roles/ipareplica/library/ipareplica_setup_http.py -+++ b/roles/ipareplica/library/ipareplica_setup_http.py -@@ -164,7 +164,7 @@ def main(): - config.subject_base = options.subject_base - config.dirman_password = dirman_password - config.setup_ca = options.setup_ca -- # config.master_host_name = master_host_name -+ config.master_host_name = master_host_name - config.ca_host_name = ca_host_name - config.promote = installer.promote - -diff --git a/roles/ipareplica/library/ipareplica_setup_kra.py b/roles/ipareplica/library/ipareplica_setup_kra.py -index 3149c10..0b2f681 100644 ---- a/roles/ipareplica/library/ipareplica_setup_kra.py -+++ b/roles/ipareplica/library/ipareplica_setup_kra.py -@@ -120,6 +120,9 @@ options: - _subject_base: - description: The installer _subject_base setting - required: no -+ dirman_password: -+ description: Directory Manager (master) password -+ required: no - author: - - Thomas Woerner - ''' -@@ -173,10 +176,12 @@ def main(): - _ca_enabled=dict(required=False, type='bool'), - _kra_enabled=dict(required=False, type='bool'), - _kra_host_name=dict(required=False), -+ _ca_host_name=dict(required=False), - _top_dir=dict(required=True), - _add_to_ipaservers=dict(required=True, type='bool'), - _ca_subject=dict(required=True), - _subject_base=dict(required=True), -+ dirman_password=dict(required=True, no_log=True), - ), - supports_check_mode=True, - ) -@@ -233,6 +238,7 @@ def main(): - ca_enabled = ansible_module.params.get('_ca_enabled') - kra_enabled = ansible_module.params.get('_kra_enabled') - kra_host_name = ansible_module.params.get('_kra_host_name') -+ ca_host_name = ansible_module.params.get('_ca_host_name') - - options.subject_base = ansible_module.params.get('subject_base') - if options.subject_base is not None: -@@ -243,6 +249,7 @@ def main(): - - options._ca_subject = ansible_module.params.get('_ca_subject') - options._subject_base = ansible_module.params.get('_subject_base') -+ dirman_password = ansible_module.params.get('dirman_password') - - # init # - -@@ -254,14 +261,25 @@ def main(): - constants.DEFAULT_CONFIG) - api_bootstrap_finalize(env) - config = gen_ReplicaConfig() -+ config.dirman_password = dirman_password - config.subject_base = options.subject_base - config.promote = installer.promote - config.kra_enabled = kra_enabled - config.kra_host_name = kra_host_name -+ config.ca_host_name = ca_host_name -+ config.master_host_name = master_host_name - - remote_api = gen_remote_api(master_host_name, paths.ETC_IPA) - installer._remote_api = remote_api - -+ conn = remote_api.Backend.ldap2 -+ ccache = os.environ['KRB5CCNAME'] -+ -+ # There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or -+ # ntpinstance -+ api.Backend.ldap2.connect() -+ conn.connect(ccache=ccache) -+ - with redirect_stdout(ansible_log): - ansible_log.debug("-- INSTALL KRA --") - -diff --git a/roles/ipareplica/library/ipareplica_setup_krb.py b/roles/ipareplica/library/ipareplica_setup_krb.py -index c8d09f7..4500a6f 100644 ---- a/roles/ipareplica/library/ipareplica_setup_krb.py -+++ b/roles/ipareplica/library/ipareplica_setup_krb.py -@@ -63,6 +63,9 @@ options: - _top_dir: - description: The installer _top_dir setting - required: no -+ dirman_password: -+ description: Directory Manager (master) password -+ required: no - author: - - Thomas Woerner - ''' -@@ -98,6 +101,7 @@ def main(): - ccache=dict(required=True), - _pkinit_pkcs12_info=dict(required=False, type='list'), - _top_dir=dict(required=True), -+ dirman_password=dict(required=True, no_log=True), - ), - supports_check_mode=True, - ) -@@ -126,6 +130,7 @@ def main(): - '_pkinit_pkcs12_info') - - options._top_dir = ansible_module.params.get('_top_dir') -+ dirman_password = ansible_module.params.get('dirman_password') - - # init # - -@@ -141,8 +146,10 @@ def main(): - constants.DEFAULT_CONFIG) - api_bootstrap_finalize(env) - config = gen_ReplicaConfig() -+ config.dirman_password = dirman_password - config.master_host_name = config_master_host_name - config.subject_base = options.subject_base -+ config.setup_ca = options.setup_ca - - ccache = os.environ['KRB5CCNAME'] - -diff --git a/roles/ipareplica/tasks/install.yml b/roles/ipareplica/tasks/install.yml -index c2a6222..ddb3f85 100644 ---- a/roles/ipareplica/tasks/install.yml -+++ b/roles/ipareplica/tasks/install.yml -@@ -226,6 +226,8 @@ - setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}" - setup_kra: "{{ result_ipareplica_test.setup_kra }}" - setup_dns: "{{ ipareplica_setup_dns }}" -+ ### server ### -+ setup_ca: "{{ ipareplica_setup_ca }}" - ### ssl certificate ### - dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}" - ### client ### -@@ -332,6 +334,7 @@ - _ca_subject: "{{ result_ipareplica_prepare._ca_subject }}" - _subject_base: "{{ result_ipareplica_prepare._subject_base }}" - dirman_password: "{{ ipareplica_dirman_password }}" -+ setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}" - - - name: Install - Setup KRB - ipareplica_setup_krb: -@@ -347,6 +350,7 @@ - ccache: "{{ result_ipareplica_prepare.ccache }}" - _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" -+ dirman_password: "{{ ipareplica_dirman_password }}" - - # We need to point to the master in ipa default conf when certmonger - # asks for HTTP certificate in newer ipa versions. In these versions -@@ -388,6 +392,7 @@ - _ca_subject: "{{ result_ipareplica_prepare._ca_subject }}" - _subject_base: "{{ result_ipareplica_prepare._subject_base }}" - dirman_password: "{{ ipareplica_dirman_password }}" -+ setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}" - master: - "{{ result_ipareplica_install_ca_certs.config_master_host_name }}" - when: result_ipareplica_test.change_master_for_certmonger -@@ -471,6 +476,7 @@ - _ca_subject: "{{ result_ipareplica_prepare._ca_subject }}" - _subject_base: "{{ result_ipareplica_prepare._subject_base }}" - dirman_password: "{{ ipareplica_dirman_password }}" -+ setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}" - when: result_ipareplica_test.change_master_for_certmonger - - - name: Install - Setup otpd -@@ -611,10 +617,12 @@ - _ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}" - _kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}" - _kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}" -+ _ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}" - _top_dir: "{{ result_ipareplica_prepare._top_dir }}" - _add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}" - _ca_subject: "{{ result_ipareplica_prepare._ca_subject }}" - _subject_base: "{{ result_ipareplica_prepare._subject_base }}" -+ dirman_password: "{{ ipareplica_dirman_password }}" - when: result_ipareplica_test.setup_kra - - - name: Install - Restart KDC --- -2.26.2 - diff --git a/SPECS/ansible-freeipa.spec b/SPECS/ansible-freeipa.spec index fe3f85d..cddffb0 100644 --- a/SPECS/ansible-freeipa.spec +++ b/SPECS/ansible-freeipa.spec @@ -1,37 +1,23 @@ # Turn off automatic python byte compilation because these are Ansible # roles and the files are transferred to the node and compiled there with -# the python verison used in the node +# the python version used in the node %define __brp_python_bytecompile %{nil} +%global python %{__python3} + Summary: Roles and playbooks to deploy FreeIPA servers, replicas and clients Name: ansible-freeipa -Version: 0.1.12 -Release: 6%{?dist} +Version: 0.3.1 +Release: 1%{?dist} URL: https://github.com/freeipa/ansible-freeipa License: GPLv3+ Source: https://github.com/freeipa/ansible-freeipa/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch1: ansible-freeipa-0.1.12-Fixes-service-disable-when-service-has-no-certificates-attached_rhbz#1836294.patch -Patch2: ansible-freeipa-0.1.12-Add-suppport-for-changing-password-of-symmetric-vaults_rhbz#1839197.patch -Patch3: ansible-freeipa-0.1.12-Fix-forwardzone-issues_rhbz#1843826,1843828,1843829,1843830,1843831.patch -Patch4: ansible-freeipa-0.1.12-ipa-host-group-Fix-membermanager-unknow-user-issue_rhbz#1848426.patch -Patch5: ansible-freeipa-0.1.12-ipa-user,host-Fail-on-duplucate-names-in-the-users-and-hosts-lists_rhbz#1822683.patch -Patch6: ansible-freeipa-0.1.12-action_plugins-ipaclient_get_otp-Discovered-python-n_rhbz#1852714.patch -Patch7: ansible-freeipa-0.1.12-ipa-server-replica-Fix-pkcs12-info-regressions-intro_rhbz#1853284.patch -Patch8: ansible-freeipa-0.1.12-ipareplica-Fix-missing-parameters-for-several-module_hbz#1855299.patch -Patch9: ansible-freeipa-0.1.12-Allow-multiple-dns-zones-to-be-absent_rhbz#1845058.patch -Patch10: ansible-freeipa-0.1.12-Fixed-error-msgs-on-FreeIPABaseModule-subclasses_rhbz#1845051.patch -Patch11: ansible-freeipa-0.1.12-Fix-allow_retrieve_keytab_host-in-service-module_rhbz#1868020.patch -Patch12: ansible-freeipa-0.1.12-Modified-return-value-for-ipavault-module_rhbz#1867909.patch -Patch13: ansible-freeipa-0.1.12-Add-support-for-option-name_from_ip-in-ipadnszone-mo_rhbz#1845056.patch -Patch14: ansible-freeipa-0.1.12-Fixes-password-behavior-on-Vault-module_rhbz#1839200.patch BuildArch: noarch -#Requires: ansible - %description ansible-freeipa provides Ansible roles and playbooks to install and uninstall -FreeIPA servers, replicas and clients. Also modules for group, host, topology -and user management. +FreeIPA servers, replicas and clients. Also modules for management. + Note: The ansible playbooks and roles require a configured ansible environment where the ansible nodes are reachable and are properly set up to have an IP @@ -43,6 +29,10 @@ Features - Cluster deployments: Server, replicas and clients in one playbook - One-time-password (OTP) support for client installation - Repair mode for clients +- Backup and restore, also to and from controller +- Modules for config management +- Modules for delegation management +- Modules for dns config management - Modules for dns forwarder management - Modules for dns record management - Modules for dns zone management @@ -52,12 +42,18 @@ Features - Modules for hbacsvcgroup management - Modules for host management - Modules for hostgroup management +- Modules for location management +- Modules for permission management +- Modules for privilege management - Modules for pwpolicy management +- Modules for role management +- Modules for self service management - Modules for service management - Modules for sudocmd management - Modules for sudocmdgroup management - Modules for sudorule management - Modules for topology management +- Modules fot trust management - Modules for user management - Modules for vault management @@ -99,32 +95,35 @@ Work is planned to have a new method to handle CSR for external signed CAs in a separate step before starting the server installation. +%package tests +Summary: ansible-freeipa tests +Requires: %{name} = %{version}-%{release} + +%description tests +ansible-freeipa tests. + +Please have a look at %{_datadir}/ansible-freeipa/requirements-tests.txt +to get the needed requrements to run the tests. + + %prep %setup -q # Do not create backup files with patches -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 + # Fix python modules and module utils: # - Remove shebang # - Remove execute flag for i in roles/ipa*/library/*.py roles/ipa*/module_utils/*.py plugins/*/*.py; do - sed -i '/\/usr\/bin\/python*/d' $i + sed -i '1{/\/usr\/bin\/python*/d;}' $i chmod a-x $i done -# Add execute flag to py3test.py scripts -chmod a+x roles/ipa*/files/py3test.py + +for i in utils/*.py utils/ansible-ipa-*-install utils/new_module \ + utils/changelog utils/ansible-doc-test; +do + sed -i '{s@/usr/bin/python*@%{python}@}' $i +done + %build @@ -136,20 +135,84 @@ cp -rp roles/ipareplica %{buildroot}%{_datadir}/ansible/roles/ cp -rp roles/ipareplica/README.md README-replica.md cp -rp roles/ipaclient %{buildroot}%{_datadir}/ansible/roles/ cp -rp roles/ipaclient/README.md README-client.md +cp -rp roles/ipabackup %{buildroot}%{_datadir}/ansible/roles/ +cp -rp roles/ipabackup/README.md README-backup.md install -m 755 -d %{buildroot}%{_datadir}/ansible/plugins/ cp -rp plugins/* %{buildroot}%{_datadir}/ansible/plugins/ +install -m 755 -d %{buildroot}%{_datadir}/ansible-freeipa +cp requirements*.txt %{buildroot}%{_datadir}/ansible-freeipa/ +cp -rp utils %{buildroot}%{_datadir}/ansible-freeipa/ +install -m 755 -d %{buildroot}%{_datadir}/ansible-freeipa/tests +cp -rp tests %{buildroot}%{_datadir}/ansible-freeipa/ + %files %license COPYING %{_datadir}/ansible/roles/ipaserver %{_datadir}/ansible/roles/ipareplica %{_datadir}/ansible/roles/ipaclient +%{_datadir}/ansible/roles/ipabackup %{_datadir}/ansible/plugins/module_utils %{_datadir}/ansible/plugins/modules %doc README*.md %doc playbooks +%{_datadir}/ansible-freeipa/requirements.txt +%{_datadir}/ansible-freeipa/requirements-dev.txt +%{_datadir}/ansible-freeipa/utils + +%files tests +%{_datadir}/ansible-freeipa/tests +%{_datadir}/ansible-freeipa/requirements-tests.txt %changelog +* Wed Dec 2 2020 Thomas Woerner - 0.3.0-2 +- Update to version 0.3.1 + https://github.com/freeipa/ansible-freeipa/releases/tag/v0.3.1 + Related: RHBZ#1891826 +- ipabackup: Fix undefined vars for conditions in shell tasks without else + Related: RHBZ#1894494 + +* Tue Dec 1 2020 Thomas Woerner - 0.3.0-2 +- Ship ipabackup role for backup and restore + Related: RHBZ#1894494 + +* Thu Nov 26 2020 Thomas Woerner - 0.3.0-1 +- Update to version 0.3.0 + https://github.com/freeipa/ansible-freeipa/releases/tag/v0.3.0 + With tests sub package + Resolves: RHBZ#1891826 +- Support for firewalld zone in ipaserver and ipareplica roles + Resolves: RHBZ#1894488 +- ipagroup: Add support for the IPA CLI option `posix` + Resolves: RHBZ#1894493 +- New ipabackup role for backup and restore + Resolves: RHBZ#1894494 +- New management module ipadelegation + Resolves: RHBZ#1894496 +- New management module ipalocation + Resolves: RHBZ#1894497 +- New management module ipaprivilege + Resolves: RHBZ#1894498 +- New management module ipapermission + Resolves: RHBZ#1894499 +- New management module iparole + Resolves: RHBZ#1894500 +- New management module ipaselfservice + Resolves: RHBZ#1894501 +- New management module ipatrust + Resolves: RHBZ#1894502 +- Fixed log of vault data return when retrieving to a file + Resolves: RHBZ#1875378 +- ipadnszone: Fix modification o SOA serial with other attributes + Resolves: RHBZ#1876896 +- Fix symmetric vault password change when using password_files + Resolves: RHBZ#1879004 +- ipadnsrecord: fix record modification behavior + Resolves: RHBZ#1880409 + Resolves: RHBZ#1881452 +- ipadnsrecord: fix record update when multiple records exist + Resolves: RHBZ#1881436 + * Tue Aug 18 2020 Thomas Woerner - 0.1.12-6 - Allow to manage multiple dnszone entries Resolves: RHBZ#1845058