From 3ff9161ab00ce460aa0b6942a6590e2470c9aadd Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Apr 2023 15:34:50 +0200 Subject: [PATCH] [PR #6334/64e797d0 backport][stable-6] dig: Support multiple domains in a single lookup (#6346) dig: Support multiple domains in a single lookup (#6334) * dig: Support multiple domains in a single lookup (#6334) The docs for this plugin indicated that multiple domains could be specified at once, but the code did not support multiple domains. * Address review feedback. (cherry picked from commit 64e797d077b6efd904e808905c289ebb01ed08af) Co-authored-by: Kevin P. Fleming --- .../6334-dig-support-multiple-domains.yml | 3 + plugins/lookup/dig.py | 120 +++++++++++------- 2 files changed, 75 insertions(+), 48 deletions(-) create mode 100644 changelogs/fragments/6334-dig-support-multiple-domains.yml diff --git a/changelogs/fragments/6334-dig-support-multiple-domains.yml b/changelogs/fragments/6334-dig-support-multiple-domains.yml new file mode 100644 index 0000000000..db9b5222b6 --- /dev/null +++ b/changelogs/fragments/6334-dig-support-multiple-domains.yml @@ -0,0 +1,3 @@ +minor_changes: + - dig lookup plugin - Support multiple domains to be queried as indicated in docs + (https://github.com/ansible-collections/community.general/pull/6334). diff --git a/plugins/lookup/dig.py b/plugins/lookup/dig.py index d0d94e988a..fa915220b3 100644 --- a/plugins/lookup/dig.py +++ b/plugins/lookup/dig.py @@ -61,6 +61,7 @@ DOCUMENTATION = ''' description: - Return empty result without empty strings, and return empty list instead of C(NXDOMAIN). - The default for this option will likely change to C(true) in the future. + - This option will be forced to C(true) if multiple domains to be queried are specified. default: false type: bool version_added: 6.0.0 @@ -95,6 +96,21 @@ EXAMPLES = """ msg: "MX record for gmail.com {{ item }}" with_items: "{{ lookup('community.general.dig', 'gmail.com./MX', wantlist=true) }}" +- name: Lookup multiple names at once + ansible.builtin.debug: + msg: "A record found {{ item }}" + loop: "{{ query('community.general.dig', 'example.org.', 'example.com.', 'gmail.com.') }}" + +- name: Lookup multiple names at once (from list variable) + ansible.builtin.debug: + msg: "A record found {{ item }}" + loop: "{{ query('community.general.dig', *hosts) }}" + vars: + hosts: + - example.org. + - example.com. + - gmail.com. + - ansible.builtin.debug: msg: "Reverse DNS for 192.0.2.5 is {{ lookup('community.general.dig', '192.0.2.5/PTR') }}" - ansible.builtin.debug: @@ -308,7 +324,7 @@ class LookupModule(LookupBase): edns_size = 4096 myres.use_edns(0, ednsflags=dns.flags.DO, payload=edns_size) - domain = None + domains = [] qtype = self.get_option('qtype') flat = self.get_option('flat') fail_on_error = self.get_option('fail_on_error') @@ -365,63 +381,71 @@ class LookupModule(LookupBase): if '/' in t: try: domain, qtype = t.split('/') + domains.append(domain) except Exception: - domain = t + domains.append(t) else: - domain = t + domains.append(t) # print "--- domain = {0} qtype={1} rdclass={2}".format(domain, qtype, rdclass) + if qtype.upper() == 'PTR': + reversed_domains = [] + for domain in domains: + try: + n = dns.reversename.from_address(domain) + reversed_domains.append(n.to_text()) + except dns.exception.SyntaxError: + pass + except Exception as e: + raise AnsibleError("dns.reversename unhandled exception %s" % to_native(e)) + domains = reversed_domains + + if len(domains) > 1: + real_empty = True + ret = [] - if qtype.upper() == 'PTR': + for domain in domains: try: - n = dns.reversename.from_address(domain) - domain = n.to_text() - except dns.exception.SyntaxError: - pass - except Exception as e: - raise AnsibleError("dns.reversename unhandled exception %s" % to_native(e)) + answers = myres.query(domain, qtype, rdclass=rdclass) + for rdata in answers: + s = rdata.to_text() + if qtype.upper() == 'TXT': + s = s[1:-1] # Strip outside quotes on TXT rdata - try: - answers = myres.query(domain, qtype, rdclass=rdclass) - for rdata in answers: - s = rdata.to_text() - if qtype.upper() == 'TXT': - s = s[1:-1] # Strip outside quotes on TXT rdata + if flat: + ret.append(s) + else: + try: + rd = make_rdata_dict(rdata) + rd['owner'] = answers.canonical_name.to_text() + rd['type'] = dns.rdatatype.to_text(rdata.rdtype) + rd['ttl'] = answers.rrset.ttl + rd['class'] = dns.rdataclass.to_text(rdata.rdclass) - if flat: - ret.append(s) - else: - try: - rd = make_rdata_dict(rdata) - rd['owner'] = answers.canonical_name.to_text() - rd['type'] = dns.rdatatype.to_text(rdata.rdtype) - rd['ttl'] = answers.rrset.ttl - rd['class'] = dns.rdataclass.to_text(rdata.rdclass) + ret.append(rd) + except Exception as err: + if fail_on_error: + raise AnsibleError("Lookup failed: %s" % str(err)) + ret.append(str(err)) - ret.append(rd) - except Exception as err: - if fail_on_error: - raise AnsibleError("Lookup failed: %s" % str(err)) - ret.append(str(err)) - - except dns.resolver.NXDOMAIN as err: - if fail_on_error: - raise AnsibleError("Lookup failed: %s" % str(err)) - if not real_empty: - ret.append('NXDOMAIN') - except dns.resolver.NoAnswer as err: - if fail_on_error: - raise AnsibleError("Lookup failed: %s" % str(err)) - if not real_empty: - ret.append("") - except dns.resolver.Timeout as err: - if fail_on_error: - raise AnsibleError("Lookup failed: %s" % str(err)) - if not real_empty: - ret.append("") - except dns.exception.DNSException as err: - raise AnsibleError("dns.resolver unhandled exception %s" % to_native(err)) + except dns.resolver.NXDOMAIN as err: + if fail_on_error: + raise AnsibleError("Lookup failed: %s" % str(err)) + if not real_empty: + ret.append('NXDOMAIN') + except dns.resolver.NoAnswer as err: + if fail_on_error: + raise AnsibleError("Lookup failed: %s" % str(err)) + if not real_empty: + ret.append("") + except dns.resolver.Timeout as err: + if fail_on_error: + raise AnsibleError("Lookup failed: %s" % str(err)) + if not real_empty: + ret.append("") + except dns.exception.DNSException as err: + raise AnsibleError("dns.resolver unhandled exception %s" % to_native(err)) return ret