summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/dns/plugins/modules
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
commit975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch)
tree89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/community/dns/plugins/modules
parentInitial commit. (diff)
downloadansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.tar.xz
ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.zip
Adding upstream version 7.7.0+dfsg.upstream/7.7.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/community/dns/plugins/modules')
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py118
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_record_info.py136
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py234
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set_info.py199
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_record_sets.py129
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_zone_info.py199
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_record.py111
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_record_info.py133
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set.py233
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set_info.py198
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_record_sets.py128
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py128
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_zone_info.py185
-rw-r--r--ansible_collections/community/dns/plugins/modules/wait_for_txt.py335
14 files changed, 2466 insertions, 0 deletions
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py
new file mode 100644
index 000000000..b17e0842c
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hetzner_dns_record
+
+short_description: Add or delete a single record in Hetzner DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Creates and deletes single DNS records in Hetzner DNS service."
+ - If you do not want to add/remove values, but replace values, you will be interested in
+ modifying a B(record set) and not a single record. This is in particular important
+ when working with C(CNAME) and C(SOA) records.
+ Use the M(community.dns.hetzner_dns_record_set) module for working with record sets.
+
+extends_documentation_fragment:
+ - community.dns.hetzner
+ - community.dns.hetzner.record_default_ttl
+ - community.dns.hetzner.record_type_choices
+ - community.dns.hetzner.zone_id_type
+ - community.dns.module_record
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hetzner
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+
+options:
+ prefix:
+ aliases:
+ - name
+
+author:
+ - Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Add a new.foo.com A record
+ community.dns.hetzner_dns_record:
+ state: present
+ zone: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value: 1.1.1.1
+ hetzner_token: access_token
+
+- name: Remove a new.foo.com A record
+ community.dns.hetzner_dns_record:
+ state: absent
+ zone_name: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value: 2.2.2.2
+ hetzner_token: access_token
+'''
+
+RETURN = '''
+zone_id:
+ description: The ID of the zone.
+ type: str
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hetzner.api import (
+ create_hetzner_argument_spec,
+ create_hetzner_api,
+ create_hetzner_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record import (
+ create_module_argument_spec,
+ run_module,
+)
+
+
+def main():
+ provider_information = create_hetzner_provider_information()
+ argument_spec = create_hetzner_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ argument_spec.argument_spec['prefix']['aliases'] = ['name']
+ argument_spec.argument_spec['prefix']['deprecated_aliases'] = [dict(name='name', version='3.0.0', collection_name='community.dns')]
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_info.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_info.py
new file mode 100644
index 000000000..9d77a38d5
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_info.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hetzner_dns_record_info
+
+short_description: Retrieve records in Hetzner DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Retrieves DNS records in Hetzner DNS service."
+
+extends_documentation_fragment:
+ - community.dns.hetzner
+ - community.dns.hetzner.record_type_choices
+ - community.dns.hetzner.zone_id_type
+ - community.dns.module_record_info
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hetzner
+ - community.dns.attributes.info_module
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+
+author:
+ - Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Retrieve the details for the A records of new.foo.com
+ community.dns.hetzner_dns_record_info:
+ zone: foo.com
+ record: new.foo.com
+ type: A
+ hetzner_token: access_token
+ register: rec
+
+- name: Print the A records
+ ansible.builtin.debug:
+ msg: "{{ rec.records }}"
+'''
+
+RETURN = '''
+records:
+ description: The list of fetched records.
+ type: list
+ elements: dict
+ returned: success and I(what) is not C(single_record)
+ contains:
+ record:
+ description: The record name.
+ type: str
+ sample: sample.example.com
+ prefix:
+ description: The record prefix.
+ type: str
+ sample: sample
+ type:
+ description: The DNS record type.
+ type: str
+ sample: A
+ ttl:
+ description:
+ - The TTL.
+ - Will return C(none) if the zone's default TTL is used.
+ type: int
+ sample: 3600
+ value:
+ description: The DNS record's value.
+ type: str
+ sample: 1.2.3.4
+ extra:
+ description: Extra information on records.
+ type: dict
+ sample:
+ created: '2021-07-09T11:18:37Z'
+ modified: '2021-07-09T11:18:37Z'
+ sample:
+ - record: sample.example.com
+ type: A
+ ttl: 3600
+ value: 1.2.3.4
+ extra: {}
+
+zone_id:
+ description: The ID of the zone.
+ type: str
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hetzner.api import (
+ create_hetzner_argument_spec,
+ create_hetzner_api,
+ create_hetzner_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_info import (
+ run_module,
+ create_module_argument_spec,
+)
+
+
+def main():
+ provider_information = create_hetzner_provider_information()
+ argument_spec = create_hetzner_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py
new file mode 100644
index 000000000..0766e6465
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py
@@ -0,0 +1,234 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hetzner_dns_record_set
+
+short_description: Add or delete record sets in Hetzner DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Creates and deletes DNS record sets in Hetzner DNS service."
+
+extends_documentation_fragment:
+ - community.dns.hetzner
+ - community.dns.hetzner.record_default_ttl
+ - community.dns.hetzner.record_type_choices
+ - community.dns.hetzner.zone_id_type
+ - community.dns.module_record_set
+ - community.dns.options.bulk_operations
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hetzner
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+
+options:
+ prefix:
+ aliases:
+ - name
+
+author:
+ - Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Add new.foo.com as an A record with 3 IPs
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value: 1.1.1.1,2.2.2.2,3.3.3.3
+ hetzner_token: access_token
+
+- name: Update new.foo.com as an A record with a list of 3 IPs
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value:
+ - 1.1.1.1
+ - 2.2.2.2
+ - 3.3.3.3
+ hetzner_token: access_token
+
+- name: Retrieve the details for new.foo.com
+ community.dns.hetzner_dns_record_set_info:
+ zone: foo.com
+ record: new.foo.com
+ type: A
+ hetzner_token: access_token
+ register: rec
+
+- name: Delete new.foo.com A record using the results from the facts retrieval command
+ community.dns.hetzner_dns_record_set:
+ state: absent
+ zone: foo.com
+ record: "{{ rec.set.record }}"
+ ttl: "{{ rec.set.ttl }}"
+ type: "{{ rec.set.type }}"
+ value: "{{ rec.set.value }}"
+ hetzner_token: access_token
+
+- name: Add an AAAA record
+ # Note that because there are colons in the value that the IPv6 address must be quoted!
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: localhost.foo.com
+ type: AAAA
+ ttl: 7200
+ value: "::1"
+ hetzner_token: access_token
+
+- name: Add a TXT record
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: localhost.foo.com
+ type: TXT
+ ttl: 7200
+ value: 'bar'
+ hetzner_token: access_token
+
+- name: Remove the TXT record
+ community.dns.hetzner_dns_record_set:
+ state: absent
+ zone: foo.com
+ record: localhost.foo.com
+ type: TXT
+ ttl: 7200
+ value: 'bar'
+ hetzner_token: access_token
+
+- name: Add a CAA record
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: foo.com
+ type: CAA
+ ttl: 3600
+ value:
+ - "128 issue letsencrypt.org"
+ - "128 iodef mailto:webmaster@foo.com"
+ hetzner_token: access_token
+
+- name: Add an MX record
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: foo.com
+ type: MX
+ ttl: 3600
+ value:
+ - "10 mail.foo.com"
+ hetzner_token: access_token
+
+- name: Add a CNAME record
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: bla.foo.com
+ record: foo.com
+ type: CNAME
+ ttl: 3600
+ value:
+ - foo.foo.com
+ hetzner_token: access_token
+
+- name: Add a PTR record
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.foo.com
+ record: foo.com
+ type: PTR
+ ttl: 3600
+ value:
+ - foo.foo.com
+ hetzner_token: access_token
+
+- name: Add an SPF record
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: foo.com
+ type: SPF
+ ttl: 3600
+ value:
+ - "v=spf1 a mx ~all"
+ hetzner_token: access_token
+
+- name: Add a PTR record
+ community.dns.hetzner_dns_record_set:
+ state: present
+ zone: foo.com
+ record: foo.com
+ type: PTR
+ ttl: 3600
+ value:
+ - "10 100 3333 service.foo.com"
+ hetzner_token: access_token
+'''
+
+RETURN = '''
+zone_id:
+ description: The ID of the zone.
+ type: str
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hetzner.api import (
+ create_hetzner_argument_spec,
+ create_hetzner_api,
+ create_hetzner_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_set import (
+ create_module_argument_spec,
+ run_module,
+)
+
+
+def main():
+ provider_information = create_hetzner_provider_information()
+ argument_spec = create_hetzner_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ argument_spec.argument_spec['prefix']['aliases'] = ['name']
+ argument_spec.argument_spec['prefix']['deprecated_aliases'] = [dict(name='name', version='3.0.0', collection_name='community.dns')]
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set_info.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set_info.py
new file mode 100644
index 000000000..5c70d1fb0
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set_info.py
@@ -0,0 +1,199 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hetzner_dns_record_set_info
+
+short_description: Retrieve record sets in Hetzner DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Retrieves DNS record sets in Hetzner DNS service."
+
+extends_documentation_fragment:
+ - community.dns.hetzner
+ - community.dns.hetzner.record_type_choices
+ - community.dns.hetzner.zone_id_type
+ - community.dns.module_record_set_info
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hetzner
+ - community.dns.attributes.info_module
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+
+author:
+ - Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Retrieve the details for the A records of new.foo.com
+ community.dns.hetzner_dns_record_set_info:
+ zone: foo.com
+ record: new.foo.com
+ type: A
+ hetzner_token: access_token
+ register: rec
+
+- name: Print the A record set
+ ansible.builtin.debug:
+ msg: "{{ rec.set }}"
+'''
+
+RETURN = '''
+set:
+ description: The fetched record set. Is empty if record set does not exist.
+ type: dict
+ returned: success and I(what) is C(single_record)
+ contains:
+ record:
+ description: The record name.
+ type: str
+ sample: sample.example.com
+ prefix:
+ description: The record prefix.
+ type: str
+ sample: sample
+ version_added: 0.2.0
+ type:
+ description: The DNS record type.
+ type: str
+ sample: A
+ ttl:
+ description:
+ - The TTL.
+ - If there are records in this set with different TTLs, the minimum of the TTLs will be presented here.
+ - Will return C(none) if the zone's default TTL is used.
+ type: int
+ sample: 3600
+ ttls:
+ description:
+ - If there are records with different TTL values in this set, this will be the list of TTLs appearing
+ in the records.
+ - Every distinct TTL will appear once, and the TTLs are in ascending order.
+ returned: When there is more than one distinct TTL
+ type: list
+ elements: int
+ sample:
+ - 300
+ - 3600
+ value:
+ description: The DNS record set's value.
+ type: list
+ elements: str
+ sample:
+ - 1.2.3.4
+ - 1.2.3.5
+ sample:
+ record: sample.example.com
+ type: A
+ ttl: 3600
+ value:
+ - 1.2.3.4
+ - 1.2.3.5
+
+sets:
+ description: The list of fetched record sets.
+ type: list
+ elements: dict
+ returned: success and I(what) is not C(single_record)
+ contains:
+ record:
+ description: The record name.
+ type: str
+ sample: sample.example.com
+ prefix:
+ description: The record prefix.
+ type: str
+ sample: sample
+ version_added: 0.2.0
+ type:
+ description: The DNS record type.
+ type: str
+ sample: A
+ ttl:
+ description:
+ - The TTL.
+ - If there are records in this set with different TTLs, the minimum of the TTLs will be presented here.
+ - Will return C(none) if the zone's default TTL is used.
+ type: int
+ sample: 3600
+ ttls:
+ description:
+ - If there are records with different TTL values in this set, this will be the list of TTLs appearing
+ in the records.
+ - Every distinct TTL will appear once, and the TTLs are in ascending order.
+ returned: When there is more than one distinct TTL
+ type: list
+ elements: int
+ sample:
+ - 300
+ - 3600
+ value:
+ description: The DNS record set's value.
+ type: list
+ elements: str
+ sample:
+ - 1.2.3.4
+ - 1.2.3.5
+ sample:
+ - record: sample.example.com
+ type: A
+ ttl: 3600
+ value:
+ - 1.2.3.4
+ - 1.2.3.5
+
+zone_id:
+ description: The ID of the zone.
+ type: str
+ returned: success
+ sample: 23
+ version_added: 0.2.0
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hetzner.api import (
+ create_hetzner_argument_spec,
+ create_hetzner_api,
+ create_hetzner_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_set_info import (
+ run_module,
+ create_module_argument_spec,
+)
+
+
+def main():
+ provider_information = create_hetzner_provider_information()
+ argument_spec = create_hetzner_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_sets.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_sets.py
new file mode 100644
index 000000000..52857186c
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_sets.py
@@ -0,0 +1,129 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hetzner_dns_record_sets
+
+short_description: Bulk synchronize DNS record sets in Hetzner DNS service
+
+version_added: 2.0.0
+
+description:
+ - Bulk synchronize DNS record sets in Hetzner DNS service.
+
+extends_documentation_fragment:
+ - community.dns.hetzner
+ - community.dns.hetzner.record_type_choices_record_sets_module
+ - community.dns.hetzner.zone_id_type
+ - community.dns.module_record_sets
+ - community.dns.options.bulk_operations
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hetzner
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+
+author:
+ - Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
+ - Felix Fontein (@felixfontein)
+
+'''
+
+EXAMPLES = '''
+- name: Make sure some records exist and have the expected values
+ community.dns.hetzner_dns_record_sets:
+ zone: foo.com
+ records:
+ - prefix: new
+ type: A
+ ttl: 7200
+ value:
+ - 1.1.1.1
+ - 2.2.2.2
+ - prefix: new
+ type: AAAA
+ ttl: 7200
+ value:
+ - "::1"
+ - record: foo.com
+ type: TXT
+ value:
+ - test
+ hetzner_token: access_token
+
+- name: Synchronize DNS zone with a fixed set of records
+ # If a record exists that is not mentioned here, it will be deleted
+ community.dns.hetzner_dns_record_sets:
+ zone_id: 23
+ purge: true
+ records:
+ - prefix: ''
+ type: A
+ value: 127.0.0.1
+ - prefix: ''
+ type: AAAA
+ value: "::1"
+ - prefix: ''
+ type: NS
+ value:
+ - ns-1.hoster.com
+ - ns-2.hoster.com
+ - ns-3.hoster.com
+ hetzner_token: access_token
+'''
+
+RETURN = '''
+zone_id:
+ description: The ID of the zone.
+ type: str
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hetzner.api import (
+ create_hetzner_argument_spec,
+ create_hetzner_api,
+ create_hetzner_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_sets import (
+ create_module_argument_spec,
+ run_module,
+)
+
+
+def main():
+ provider_information = create_hetzner_provider_information()
+ argument_spec = create_hetzner_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_zone_info.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_zone_info.py
new file mode 100644
index 000000000..44cc88af5
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_zone_info.py
@@ -0,0 +1,199 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hetzner_dns_zone_info
+
+short_description: Retrieve zone information in Hetzner DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Retrieves zone information in Hetzner DNS service."
+
+extends_documentation_fragment:
+ - community.dns.hetzner
+ - community.dns.hetzner.zone_id_type
+ - community.dns.module_zone_info
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hetzner
+ - community.dns.attributes.info_module
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+
+author:
+ - Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Retrieve details for foo.com zone
+ community.dns.hetzner_dns_zone_info:
+ zone: foo.com
+ hetzner_token: access_token
+ register: rec
+
+- name: Retrieve details for zone 23
+ community.dns.hetzner_dns_zone_info:
+ zone_id: 23
+ hetzner_token: access_token
+'''
+
+RETURN = '''
+zone_name:
+ description: The name of the zone.
+ type: int
+ returned: success
+ sample: example.com
+
+zone_id:
+ description: The ID of the zone.
+ type: str
+ returned: success
+ sample: 23
+
+zone_info:
+ description:
+ - Extra information returned by the API.
+ type: dict
+ returned: success
+ contains:
+ created:
+ description:
+ - The time when the zone was created.
+ type: str
+ sample: "2021-07-15T19:23:58Z"
+ modified:
+ description:
+ - The time the zone was last modified.
+ type: str
+ sample: "2021-07-15T19:23:58Z"
+ legacy_dns_host:
+ description:
+ # TODO
+ - Unknown.
+ type: str
+ legacy_ns:
+ description:
+ - List of nameservers during import.
+ type: list
+ elements: str
+ ns:
+ description:
+ - List of nameservers the zone should have for using Hetzner's DNS.
+ type: list
+ elements: str
+ owner:
+ description:
+ - Owner of the zone.
+ type: str
+ paused:
+ description:
+ # TODO
+ - Unknown.
+ type: bool
+ sample: true
+ permission:
+ description:
+ - Zone's permissions.
+ type: str
+ project:
+ description:
+ # TODO
+ - Unknown.
+ type: str
+ registrar:
+ description:
+ # TODO
+ - Unknown.
+ type: str
+ status:
+ description:
+ - Status of the zone.
+ - Can be one of C(verified), C(failed) and C(pending).
+ type: str
+ sample: verified
+ # choices:
+ # - verified
+ # - failed
+ # - pending
+ ttl:
+ description:
+ - TTL of zone.
+ type: int
+ sample: 0
+ verified:
+ description:
+ - Time when zone was verified.
+ type: str
+ sample: "2021-07-15T19:23:58Z"
+ records_count:
+ description:
+ - Number of records associated to this zone.
+ type: int
+ sample: 0
+ is_secondary_dns:
+ description:
+ - Indicates whether the zone is a secondary DNS zone.
+ type: bool
+ sample: true
+ txt_verification:
+ description:
+ - Shape of the TXT record that has to be set to verify a zone.
+ - If name and token are empty, no TXT record needs to be set.
+ type: dict
+ sample: {'name': '', 'token': ''}
+ contains:
+ name:
+ description:
+ - The TXT record's name.
+ type: str
+ token:
+ description:
+ - The TXT record's content.
+ type: str
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hetzner.api import (
+ create_hetzner_argument_spec,
+ create_hetzner_api,
+ create_hetzner_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.zone_info import (
+ run_module,
+ create_module_argument_spec,
+)
+
+
+def main():
+ provider_information = create_hetzner_provider_information()
+ argument_spec = create_hetzner_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_record.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record.py
new file mode 100644
index 000000000..0756b6a4c
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record.py
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2017-2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hosttech_dns_record
+
+short_description: Add or delete a single record in Hosttech DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Creates and deletes single DNS records in Hosttech DNS service."
+ - This module replaces C(hosttech_dns_record) from community.dns before 2.0.0.
+ - If you do not want to add/remove values, but replace values, you will be interested in
+ modifying a B(record set) and not a single record. This is in particular important
+ when working with C(CNAME) and C(SOA) records.
+ Use the M(community.dns.hosttech_dns_record_set) module for working with record sets.
+
+extends_documentation_fragment:
+ - community.dns.hosttech
+ - community.dns.hosttech.record_default_ttl
+ - community.dns.hosttech.record_type_choices
+ - community.dns.hosttech.zone_id_type
+ - community.dns.module_record
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hosttech
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+
+author:
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Add a new.foo.com A record
+ community.dns.hosttech_dns_record:
+ state: present
+ zone: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value: 1.1.1.1
+ hosttech_token: access_token
+
+- name: Remove a new.foo.com A record
+ community.dns.hosttech_dns_record:
+ state: absent
+ zone_name: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value: 2.2.2.2
+ hosttech_token: access_token
+'''
+
+RETURN = '''
+zone_id:
+ description: The ID of the zone.
+ type: int
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
+ create_hosttech_argument_spec,
+ create_hosttech_api,
+ create_hosttech_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record import (
+ create_module_argument_spec,
+ run_module,
+)
+
+
+def main():
+ provider_information = create_hosttech_provider_information()
+ argument_spec = create_hosttech_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_info.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_info.py
new file mode 100644
index 000000000..84ee8e3b2
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_info.py
@@ -0,0 +1,133 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hosttech_dns_record_info
+
+short_description: Retrieve records in Hosttech DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Retrieves DNS records in Hosttech DNS service."
+
+extends_documentation_fragment:
+ - community.dns.hosttech
+ - community.dns.hosttech.record_type_choices
+ - community.dns.hosttech.zone_id_type
+ - community.dns.module_record_info
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hosttech
+ - community.dns.attributes.info_module
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+
+author:
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Retrieve the details for the A records of new.foo.com
+ community.dns.hosttech_dns_record_info:
+ zone_name: foo.com
+ record: new.foo.com
+ type: A
+ hosttech_token: access_token
+ register: rec
+
+- name: Print the A records
+ ansible.builtin.debug:
+ msg: "{{ rec.records }}"
+'''
+
+RETURN = '''
+records:
+ description: The list of fetched records.
+ type: list
+ elements: dict
+ returned: success and I(what) is not C(single_record)
+ contains:
+ record:
+ description: The record name.
+ type: str
+ sample: sample.example.com
+ prefix:
+ description: The record prefix.
+ type: str
+ sample: sample
+ type:
+ description: The DNS record type.
+ type: str
+ sample: A
+ ttl:
+ description:
+ - The TTL.
+ type: int
+ sample: 3600
+ value:
+ description: The DNS record's value.
+ type: str
+ sample: 1.2.3.4
+ extra:
+ description: Extra information on records.
+ type: dict
+ sample:
+ comment: ''
+ sample:
+ - record: sample.example.com
+ type: A
+ ttl: 3600
+ value: 1.2.3.4
+ extra: {}
+
+zone_id:
+ description: The ID of the zone.
+ type: int
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
+ create_hosttech_argument_spec,
+ create_hosttech_api,
+ create_hosttech_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_info import (
+ run_module,
+ create_module_argument_spec,
+)
+
+
+def main():
+ provider_information = create_hosttech_provider_information()
+ argument_spec = create_hosttech_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set.py
new file mode 100644
index 000000000..d16c82ad7
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set.py
@@ -0,0 +1,233 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2017-2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hosttech_dns_record_set
+
+short_description: Add or delete record sets in Hosttech DNS service
+
+version_added: 2.0.0
+
+description:
+ - "Creates and deletes DNS record sets in Hosttech DNS service."
+ - This module replaces C(hosttech_dns_record) from community.dns before 2.0.0.
+
+extends_documentation_fragment:
+ - community.dns.hosttech
+ - community.dns.hosttech.record_default_ttl
+ - community.dns.hosttech.record_type_choices
+ - community.dns.hosttech.zone_id_type
+ - community.dns.module_record_set
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hosttech
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+
+author:
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Add new.foo.com as an A record with 3 IPs
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value: 1.1.1.1,2.2.2.2,3.3.3.3
+ hosttech_token: access_token
+
+- name: Update new.foo.com as an A record with a list of 3 IPs
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: new.foo.com
+ type: A
+ ttl: 7200
+ value:
+ - 1.1.1.1
+ - 2.2.2.2
+ - 3.3.3.3
+ hosttech_token: access_token
+
+- name: Retrieve the details for new.foo.com
+ community.dns.hosttech_dns_record_set_info:
+ zone_name: foo.com
+ record: new.foo.com
+ type: A
+ hosttech_username: foo
+ hosttech_password: bar
+ register: rec
+
+- name: Delete new.foo.com A record using the results from the facts retrieval command
+ community.dns.hosttech_dns_record_set:
+ state: absent
+ zone_name: foo.com
+ record: "{{ rec.set.record }}"
+ ttl: "{{ rec.set.ttl }}"
+ type: "{{ rec.set.type }}"
+ value: "{{ rec.set.value }}"
+ hosttech_username: foo
+ hosttech_password: bar
+
+- name: Add an AAAA record
+ # Note that because there are colons in the value that the IPv6 address must be quoted!
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: localhost.foo.com
+ type: AAAA
+ ttl: 7200
+ value: "::1"
+ hosttech_token: access_token
+
+- name: Add a TXT record
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: localhost.foo.com
+ type: TXT
+ ttl: 7200
+ value: 'bar'
+ hosttech_username: foo
+ hosttech_password: bar
+
+- name: Remove the TXT record
+ community.dns.hosttech_dns_record_set:
+ state: absent
+ zone_name: foo.com
+ record: localhost.foo.com
+ type: TXT
+ ttl: 7200
+ value: 'bar'
+ hosttech_username: foo
+ hosttech_password: bar
+
+- name: Add a CAA record
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: foo.com
+ type: CAA
+ ttl: 3600
+ value:
+ - "128 issue letsencrypt.org"
+ - "128 iodef mailto:webmaster@foo.com"
+ hosttech_token: access_token
+
+- name: Add an MX record
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: foo.com
+ type: MX
+ ttl: 3600
+ value:
+ - "10 mail.foo.com"
+ hosttech_token: access_token
+
+- name: Add a CNAME record
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: bla.foo.com
+ record: foo.com
+ type: CNAME
+ ttl: 3600
+ value:
+ - foo.foo.com
+ hosttech_username: foo
+ hosttech_password: bar
+
+- name: Add a PTR record
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.foo.com
+ record: foo.com
+ type: PTR
+ ttl: 3600
+ value:
+ - foo.foo.com
+ hosttech_token: access_token
+
+- name: Add an SPF record
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: foo.com
+ type: SPF
+ ttl: 3600
+ value:
+ - "v=spf1 a mx ~all"
+ hosttech_username: foo
+ hosttech_password: bar
+
+- name: Add a PTR record
+ community.dns.hosttech_dns_record_set:
+ state: present
+ zone_name: foo.com
+ record: foo.com
+ type: PTR
+ ttl: 3600
+ value:
+ - "10 100 3333 service.foo.com"
+ hosttech_token: access_token
+'''
+
+RETURN = '''
+zone_id:
+ description: The ID of the zone.
+ type: int
+ returned: success
+ sample: 23
+ version_added: 0.2.0
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
+ create_hosttech_argument_spec,
+ create_hosttech_api,
+ create_hosttech_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_set import (
+ create_module_argument_spec,
+ run_module,
+)
+
+
+def main():
+ provider_information = create_hosttech_provider_information()
+ argument_spec = create_hosttech_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set_info.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set_info.py
new file mode 100644
index 000000000..5b7c576b8
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_set_info.py
@@ -0,0 +1,198 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2017-2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hosttech_dns_record_set_info
+
+short_description: Retrieve record sets in Hosttech DNS service
+
+version_added: 0.1.0
+
+description:
+ - "Retrieves DNS record sets in Hosttech DNS service."
+ - This module was renamed from C(community.dns.hosttech_dns_record_info) to C(community.dns.hosttech_dns_record_set_info)
+ in community.dns 2.0.0.
+
+extends_documentation_fragment:
+ - community.dns.hosttech
+ - community.dns.hosttech.record_type_choices
+ - community.dns.hosttech.zone_id_type
+ - community.dns.module_record_set_info
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hosttech
+ - community.dns.attributes.info_module
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+
+author:
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Retrieve the details for the A records of new.foo.com
+ community.dns.hosttech_dns_record_set_info:
+ zone_name: foo.com
+ record: new.foo.com
+ type: A
+ hosttech_token: access_token
+ register: rec
+
+- name: Print the A record set
+ ansible.builtin.debug:
+ msg: "{{ rec.set }}"
+'''
+
+RETURN = '''
+set:
+ description: The fetched record set. Is empty if record set does not exist.
+ type: dict
+ returned: success and I(what) is C(single_record)
+ contains:
+ record:
+ description: The record name.
+ type: str
+ sample: sample.example.com
+ prefix:
+ description: The record prefix.
+ type: str
+ sample: sample
+ version_added: 0.2.0
+ type:
+ description: The DNS record type.
+ type: str
+ sample: A
+ ttl:
+ description:
+ - The TTL.
+ - If there are records in this set with different TTLs, the minimum of the TTLs will be presented here.
+ type: int
+ sample: 3600
+ ttls:
+ description:
+ - If there are records with different TTL values in this set, this will be the list of TTLs appearing
+ in the records.
+ - Every distinct TTL will appear once, and the TTLs are in ascending order.
+ returned: When there is more than one distinct TTL
+ type: list
+ elements: int
+ sample:
+ - 300
+ - 3600
+ value:
+ description: The DNS record set's value.
+ type: list
+ elements: str
+ sample:
+ - 1.2.3.4
+ - 1.2.3.5
+ sample:
+ record: sample.example.com
+ type: A
+ ttl: 3600
+ value:
+ - 1.2.3.4
+ - 1.2.3.5
+
+sets:
+ description: The list of fetched record sets.
+ type: list
+ elements: dict
+ returned: success and I(what) is not C(single_record)
+ contains:
+ record:
+ description: The record name.
+ type: str
+ sample: sample.example.com
+ prefix:
+ description: The record prefix.
+ type: str
+ sample: sample
+ version_added: 0.2.0
+ type:
+ description: The DNS record type.
+ type: str
+ sample: A
+ ttl:
+ description:
+ - The TTL.
+ - If there are records in this set with different TTLs, the minimum of the TTLs will be presented here.
+ type: int
+ sample: 3600
+ ttls:
+ description:
+ - If there are records with different TTL values in this set, this will be the list of TTLs appearing
+ in the records.
+ - Every distinct TTL will appear once, and the TTLs are in ascending order.
+ returned: When there is more than one distinct TTL
+ type: list
+ elements: int
+ sample:
+ - 300
+ - 3600
+ value:
+ description: The DNS record set's value.
+ type: list
+ elements: str
+ sample:
+ - 1.2.3.4
+ - 1.2.3.5
+ sample:
+ - record: sample.example.com
+ type: A
+ ttl: 3600
+ value:
+ - 1.2.3.4
+ - 1.2.3.5
+
+zone_id:
+ description: The ID of the zone.
+ type: int
+ returned: success
+ sample: 23
+ version_added: 0.2.0
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
+ create_hosttech_argument_spec,
+ create_hosttech_api,
+ create_hosttech_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_set_info import (
+ run_module,
+ create_module_argument_spec,
+)
+
+
+def main():
+ provider_information = create_hosttech_provider_information()
+ argument_spec = create_hosttech_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_sets.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_sets.py
new file mode 100644
index 000000000..c985779ca
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hosttech_dns_record_sets.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2017-2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hosttech_dns_record_sets
+
+short_description: Bulk synchronize DNS record sets in Hosttech DNS service
+
+version_added: 2.0.0
+
+description:
+ - Bulk synchronize DNS record sets in Hosttech DNS service.
+ - This module replaces C(hosttech_dns_records) from community.dns before 2.0.0.
+
+extends_documentation_fragment:
+ - community.dns.hosttech
+ - community.dns.hosttech.record_type_choices_record_sets_module
+ - community.dns.hosttech.zone_id_type
+ - community.dns.module_record_sets
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hosttech
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+
+author:
+ - Felix Fontein (@felixfontein)
+
+'''
+
+EXAMPLES = '''
+- name: Make sure some records exist and have the expected values
+ community.dns.hosttech_dns_record_sets:
+ zone_name: foo.com
+ records:
+ - prefix: new
+ type: A
+ ttl: 7200
+ value:
+ - 1.1.1.1
+ - 2.2.2.2
+ - prefix: new
+ type: AAAA
+ ttl: 7200
+ value:
+ - "::1"
+ - record: foo.com
+ type: TXT
+ value:
+ - test
+ hosttech_token: access_token
+
+- name: Synchronize DNS zone with a fixed set of records
+ # If a record exists that is not mentioned here, it will be deleted
+ community.dns.hosttech_dns_record_sets:
+ zone_id: 23
+ purge: true
+ records:
+ - prefix: ''
+ type: A
+ value: 127.0.0.1
+ - prefix: ''
+ type: AAAA
+ value: "::1"
+ - prefix: ''
+ type: NS
+ value:
+ - ns-1.hoster.com
+ - ns-2.hoster.com
+ - ns-3.hoster.com
+ hosttech_token: access_token
+'''
+
+RETURN = '''
+zone_id:
+ description: The ID of the zone.
+ type: int
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
+ create_hosttech_argument_spec,
+ create_hosttech_api,
+ create_hosttech_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_sets import (
+ create_module_argument_spec,
+ run_module,
+)
+
+
+def main():
+ provider_information = create_hosttech_provider_information()
+ argument_spec = create_hosttech_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py
new file mode 100644
index 000000000..c985779ca
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2017-2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hosttech_dns_record_sets
+
+short_description: Bulk synchronize DNS record sets in Hosttech DNS service
+
+version_added: 2.0.0
+
+description:
+ - Bulk synchronize DNS record sets in Hosttech DNS service.
+ - This module replaces C(hosttech_dns_records) from community.dns before 2.0.0.
+
+extends_documentation_fragment:
+ - community.dns.hosttech
+ - community.dns.hosttech.record_type_choices_record_sets_module
+ - community.dns.hosttech.zone_id_type
+ - community.dns.module_record_sets
+ - community.dns.options.record_transformation
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hosttech
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+ check_mode:
+ support: full
+ diff_mode:
+ support: full
+
+author:
+ - Felix Fontein (@felixfontein)
+
+'''
+
+EXAMPLES = '''
+- name: Make sure some records exist and have the expected values
+ community.dns.hosttech_dns_record_sets:
+ zone_name: foo.com
+ records:
+ - prefix: new
+ type: A
+ ttl: 7200
+ value:
+ - 1.1.1.1
+ - 2.2.2.2
+ - prefix: new
+ type: AAAA
+ ttl: 7200
+ value:
+ - "::1"
+ - record: foo.com
+ type: TXT
+ value:
+ - test
+ hosttech_token: access_token
+
+- name: Synchronize DNS zone with a fixed set of records
+ # If a record exists that is not mentioned here, it will be deleted
+ community.dns.hosttech_dns_record_sets:
+ zone_id: 23
+ purge: true
+ records:
+ - prefix: ''
+ type: A
+ value: 127.0.0.1
+ - prefix: ''
+ type: AAAA
+ value: "::1"
+ - prefix: ''
+ type: NS
+ value:
+ - ns-1.hoster.com
+ - ns-2.hoster.com
+ - ns-3.hoster.com
+ hosttech_token: access_token
+'''
+
+RETURN = '''
+zone_id:
+ description: The ID of the zone.
+ type: int
+ returned: success
+ sample: 23
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
+ create_hosttech_argument_spec,
+ create_hosttech_api,
+ create_hosttech_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.record_sets import (
+ create_module_argument_spec,
+ run_module,
+)
+
+
+def main():
+ provider_information = create_hosttech_provider_information()
+ argument_spec = create_hosttech_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_zone_info.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_zone_info.py
new file mode 100644
index 000000000..6621893a7
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/hosttech_dns_zone_info.py
@@ -0,0 +1,185 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2021 Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: hosttech_dns_zone_info
+
+short_description: Retrieve zone information in Hosttech DNS service
+
+version_added: 0.2.0
+
+description:
+ - "Retrieves zone information in Hosttech DNS service."
+
+extends_documentation_fragment:
+ - community.dns.hosttech
+ - community.dns.hosttech.zone_id_type
+ - community.dns.module_zone_info
+ - community.dns.attributes
+ - community.dns.attributes.actiongroup_hosttech
+ - community.dns.attributes.info_module
+
+attributes:
+ action_group:
+ version_added: 2.4.0
+
+author:
+ - Felix Fontein (@felixfontein)
+'''
+
+EXAMPLES = '''
+- name: Retrieve details for foo.com zone
+ community.dns.hosttech_dns_zone_info:
+ zone_name: foo.com
+ hosttech_username: foo
+ hosttech_password: bar
+ register: rec
+
+- name: Retrieve details for zone 23
+ community.dns.hosttech_dns_zone_info:
+ zone_id: 23
+ hosttech_token: access_token
+'''
+
+RETURN = '''
+zone_name:
+ description: The name of the zone.
+ type: int
+ returned: success
+ sample: example.com
+
+zone_id:
+ description: The ID of the zone.
+ type: int
+ returned: success
+ sample: 23
+
+zone_info:
+ description:
+ - Extra information returned by the API.
+ type: dict
+ returned: success
+ version_added: 2.0.0
+ sample:
+ dnssec: true
+ dnssec_email: test@example.com
+ ds_records: []
+ email: test@example.com
+ ttl: 3600
+ contains:
+ dnssec:
+ description:
+ - Whether DNSSEC is enabled for the zone or not.
+ type: bool
+ returned: When I(hosttech_token) has been specified.
+ dnssec_email:
+ description:
+ - The email address contacted when the DNSSEC key is changed.
+ - Is C(none) if DNSSEC is not enabled.
+ type: str
+ returned: When I(hosttech_token) has been specified.
+ ds_records:
+ description:
+ - The DS records.
+ - See L(Section 5 of RFC 4034,https://datatracker.ietf.org/doc/html/rfc4034#section-5) and
+ L(Section 2.1 of RFC 4034,https://datatracker.ietf.org/doc/html/rfc4034#section-2.1) for details.
+ - Is C(none) if DNSSEC is not enabled.
+ type: list
+ elements: dict
+ returned: When I(hosttech_token) has been specified.
+ contains:
+ algorithm:
+ description:
+ - This value is the algorithm number of the DNSKEY RR referred to by the DS record.
+ - A list of values can be found in L(Appendix A.1 of RFC 4034,https://datatracker.ietf.org/doc/html/rfc4034#appendix-A.1).
+ type: int
+ sample: 8
+ digest:
+ description:
+ - A digest of the DNSKEY RR record this DS record refers to.
+ type: str
+ sample: 012356789ABCDEF0123456789ABCDEF012345678
+ digest_type:
+ description:
+ - This value identifies the algorithm used to construct the digest.
+ - A list of values can be found in L(Appendix A.2 of RFC 4034,https://datatracker.ietf.org/doc/html/rfc4034#appendix-A.2).
+ type: int
+ sample: 1
+ flags:
+ description:
+ - The Zone Key flag. See L(Section 2.1.1 of RFC 4034,https://datatracker.ietf.org/doc/html/rfc4034#section-2.1.1) for details.
+ type: int
+ sample: 257
+ key_tag:
+ description:
+ - The Key Tag field lists the key tag of the DNSKEY RR referred to by the DS record.
+ type: int
+ sample: 12345
+ protocol:
+ description:
+ - Must be 3 according to RFC 4034.
+ type: int
+ sample: 3
+ public_key:
+ description:
+ - The public key material.
+ type: str
+ sample: >-
+ MuhdzsQdqEGShwjtJDKZZjdKqUSGluFzTTinpuEeIRzLLcgkwgAPKWFa
+ eQntNlmcNDeCziGwpdvhJnvKXEMbFcZwsaDIJuWqERxAQNGABWfPlCLh
+ HQPnbpRPNKipSdBaUhuOubvFvjBpFAwiwSAapRDVsAgKvjXucfXpFfYb
+ pCundbAXBWhbpHVbqgmGoixXzFSwUsGVYLPpBCiDlLJwzjRKYYaoVYge
+ kMtKFYUVnWIKbectWkDFdVqXwkKigCUDiuTTJxOBRJRNzGiDNMWBjYSm
+ bBCAHMaMYaghLbYTwyKXltdHTHwBwtswGNfpnEdSpKFzZJonBZArQfHD
+ lfceKgmKwEF=
+ email:
+ description:
+ - The zone's DNS contact mail in the SOA record.
+ type: str
+ ttl:
+ description:
+ - The zone's TTL.
+ type: int
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.dns.plugins.module_utils.argspec import (
+ ModuleOptionProvider,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.http import (
+ ModuleHTTPHelper,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
+ create_hosttech_argument_spec,
+ create_hosttech_api,
+ create_hosttech_provider_information,
+)
+
+from ansible_collections.community.dns.plugins.module_utils.module.zone_info import (
+ run_module,
+ create_module_argument_spec,
+)
+
+
+def main():
+ provider_information = create_hosttech_provider_information()
+ argument_spec = create_hosttech_argument_spec()
+ argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
+ module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
+ run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/dns/plugins/modules/wait_for_txt.py b/ansible_collections/community/dns/plugins/modules/wait_for_txt.py
new file mode 100644
index 000000000..1a09c5ed6
--- /dev/null
+++ b/ansible_collections/community/dns/plugins/modules/wait_for_txt.py
@@ -0,0 +1,335 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r'''
+---
+module: wait_for_txt
+short_description: Wait for TXT entries to be available on all authoritative nameservers
+version_added: 0.1.0
+description:
+ - Wait for TXT entries with specific values to show up on B(all) authoritative nameservers for the DNS name.
+extends_documentation_fragment:
+ - community.dns.attributes
+attributes:
+ check_mode:
+ support: full
+ details:
+ - This action does not modify state.
+ version_added: 2.4.0
+ diff_mode:
+ support: N/A
+ details:
+ - This action does not modify state.
+author:
+ - Felix Fontein (@felixfontein)
+options:
+ records:
+ description:
+ - A list of DNS names with TXT entries to look out for.
+ required: true
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - A DNS name, like C(www.example.com).
+ type: str
+ required: true
+ values:
+ description:
+ - The TXT values to look for.
+ type: list
+ elements: str
+ required: true
+ mode:
+ description:
+ - Comparison modes for the values in I(values).
+ - If C(subset), I(values) should be a (not necessarily proper) subset of the TXT values set for
+ the DNS name.
+ - If C(superset), I(values) should be a (not necessarily proper) superset of the TXT values set
+ for the DNS name.
+ This includes the case that no TXT entries are set.
+ - If C(superset_not_empty), I(values) should be a (not necessarily proper) superset of the TXT
+ values set for the DNS name, assuming at least one TXT record is present.
+ - If C(equals), I(values) should be the same set of strings as the TXT values for the DNS name
+ (up to order).
+ - If C(equals_ordered), I(values) should be the same ordered list of strings as the TXT values
+ for the DNS name.
+ type: str
+ default: subset
+ choices:
+ - subset
+ - superset
+ - superset_not_empty
+ - equals
+ - equals_ordered
+ query_retry:
+ description:
+ - Number of retries for DNS query timeouts.
+ type: int
+ default: 3
+ query_timeout:
+ description:
+ - Timeout per DNS query in seconds.
+ type: float
+ default: 10
+ timeout:
+ description:
+ - Global timeout for waiting for all records in seconds.
+ - If not set, will wait indefinitely.
+ type: float
+ max_sleep:
+ description:
+ - Maximal amount of seconds to sleep between two rounds of probing the TXT records.
+ type: float
+ default: 10
+ always_ask_default_resolver:
+ description:
+ - When set to C(true) (default), will use the default resolver to find the authoritative nameservers
+ of a subzone.
+ - When set to C(false), will use the authoritative nameservers of the parent zone to find the
+ authoritative nameservers of a subzone. This only makes sense when the nameservers were recently
+ changed and haven't propagated.
+ type: bool
+ default: true
+requirements:
+ - dnspython >= 1.15.0 (maybe older versions also work)
+'''
+
+EXAMPLES = r'''
+- name: Wait for a TXT entry to appear
+ community.dns.wait_for_txt:
+ records:
+ # We want that www.example.com has a single TXT record with value 'Hello world!'.
+ # There should not be any other TXT record for www.example.com.
+ - name: www.example.com
+ values: "Hello world!"
+ mode: equals
+ # We want that example.com has a specific SPF record set.
+ # We do not care about other TXT records.
+ - name: www.example.com
+ values: "v=spf1 a mx -all"
+ mode: subset
+'''
+
+RETURN = r'''
+records:
+ description:
+ - Results on the TXT records queried.
+ - The entries are in a 1:1 correspondence to the entries of the I(records) parameter,
+ in exactly the same order.
+ returned: always
+ type: list
+ elements: dict
+ contains:
+ name:
+ description:
+ - The DNS name this check is for.
+ returned: always
+ type: str
+ sample: example.com
+ done:
+ description:
+ - Whether the check completed.
+ returned: always
+ type: bool
+ sample: false
+ values:
+ description:
+ - For every authoritative nameserver for the DNS name, lists the TXT records retrieved during the last lookup made.
+ - Once the check completed for all TXT records retrieved, the TXT records for this DNS name are no longer checked.
+ - If these are multiple TXT entries for a nameserver, the order is as it was received from that nameserver. This
+ might not be the same order provided in the check.
+ returned: lookup was done at least once
+ type: dict
+ elements: list
+ sample:
+ ns1.example.com:
+ - TXT value 1
+ - TXT value 2
+ ns2.example.com:
+ - TXT value 2
+ check_count:
+ description:
+ - How often the TXT records for this DNS name were checked.
+ returned: always
+ type: int
+ sample: 3
+ sample:
+ - name: example.com
+ done: true
+ values: [a, b, c]
+ check_count: 1
+ - name: foo.example.org
+ done: false
+ check_count: 0
+completed:
+ description:
+ - How many of the checks were completed.
+ returned: always
+ type: int
+ sample: 3
+'''
+
+import time
+import traceback
+
+try:
+ from time import monotonic
+except ImportError:
+ from time import clock as monotonic
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native, to_text
+
+from ansible_collections.community.dns.plugins.module_utils.resolver import (
+ ResolveDirectlyFromNameServers,
+ ResolverError,
+ assert_requirements_present,
+)
+
+try:
+ import dns.exception
+ import dns.rdatatype
+except ImportError:
+ pass # handled in assert_requirements_present()
+
+
+def lookup(resolver, name):
+ result = {}
+ txts = resolver.resolve(name, rdtype=dns.rdatatype.TXT)
+ for key, txt in txts.items():
+ res = []
+ if txt is not None:
+ for data in txt:
+ line = []
+ for str in data.strings:
+ line.append(to_text(str))
+ res.append(u''.join(line))
+ result[key] = res
+ txts[key] = []
+ return result
+
+
+def validate_check(record_values, expected_values, comparison_mode):
+ if comparison_mode == 'subset':
+ return set(expected_values) <= set(record_values)
+
+ if comparison_mode == 'superset':
+ return set(expected_values) >= set(record_values)
+
+ if comparison_mode == 'superset_not_empty':
+ return bool(record_values) and set(expected_values) >= set(record_values)
+
+ if comparison_mode == 'equals':
+ return sorted(record_values) == sorted(expected_values)
+
+ if comparison_mode == 'equals_ordered':
+ return record_values == expected_values
+
+ raise Exception('Internal error!')
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ records=dict(required=True, type='list', elements='dict', options=dict(
+ name=dict(required=True, type='str'),
+ values=dict(required=True, type='list', elements='str'),
+ mode=dict(type='str', default='subset', choices=['subset', 'superset', 'superset_not_empty', 'equals', 'equals_ordered']),
+ )),
+ query_retry=dict(type='int', default=3),
+ query_timeout=dict(type='float', default=10),
+ timeout=dict(type='float'),
+ max_sleep=dict(type='float', default=10),
+ always_ask_default_resolver=dict(type='bool', default=True),
+ ),
+ supports_check_mode=True,
+ )
+ assert_requirements_present(module)
+
+ resolver = ResolveDirectlyFromNameServers(
+ timeout=module.params['query_timeout'],
+ timeout_retries=module.params['query_retry'],
+ always_ask_default_resolver=module.params['always_ask_default_resolver'],
+ )
+ records = module.params['records']
+ timeout = module.params['timeout']
+ max_sleep = module.params['max_sleep']
+
+ results = [None] * len(records)
+ for index in range(len(records)):
+ results[index] = {
+ 'name': records[index]['name'],
+ 'done': False,
+ 'check_count': 0,
+ }
+ finished_checks = 0
+
+ start_time = monotonic()
+ try:
+ step = 0
+ while True:
+ has_timeout = False
+ if timeout is not None:
+ expired = monotonic() - start_time
+ has_timeout = expired > timeout
+
+ done = True
+ for index, record in enumerate(records):
+ if results[index]['done']:
+ continue
+ txts = lookup(resolver, record['name'])
+ results[index]['values'] = txts
+ results[index]['check_count'] += 1
+ if txts and all(validate_check(txt, record['values'], record['mode']) for txt in txts.values()):
+ results[index]['done'] = True
+ finished_checks += 1
+ else:
+ done = False
+
+ if done:
+ module.exit_json(
+ msg='All checks passed',
+ records=results,
+ completed=finished_checks)
+
+ if has_timeout:
+ module.fail_json(
+ msg='Timeout ({0} out of {1} check(s) passed).'.format(finished_checks, len(records)),
+ records=results,
+ completed=finished_checks)
+
+ # Simple quadratic sleep with maximum wait of max_sleep seconds
+ wait = min(2 + step * 0.5, max_sleep)
+ if timeout is not None:
+ # Make sure we do not exceed the timeout by much by waiting
+ expired = monotonic() - start_time
+ wait = max(min(wait, timeout - expired + 0.1), 0.1)
+
+ time.sleep(wait)
+ step += 1
+ except ResolverError as e:
+ module.fail_json(
+ msg='Unexpected resolving error: {0}'.format(to_native(e)),
+ records=results,
+ completed=finished_checks,
+ exception=traceback.format_exc())
+ except dns.exception.DNSException as e:
+ module.fail_json(
+ msg='Unexpected DNS error: {0}'.format(to_native(e)),
+ records=results,
+ completed=finished_checks,
+ exception=traceback.format_exc())
+
+
+if __name__ == "__main__":
+ main()