diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
commit | 975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch) | |
tree | 89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/community/dns/plugins/modules | |
parent | Initial commit. (diff) | |
download | ansible-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')
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() |