- block: - name: check if item zone is valid fail: msg: '"{{ item.zone }}" does not seem to be a valid zone' when: (item.zone is defined) and ((item.zone != 'root') and (item.zone not in int_zones) or (item.zone is not string)) - name: construct record parameters set_fact: ns_zone: "{%- if (item.zone is defined) and (item.zone != 'root') -%}{{ item.zone }}.\ {%- elif item.zone is not defined and branch is defined -%}{{ branch }}.\ {%- endif -%}\ {{ int_tld }}" ns_name: "{%- if item.name is defined -%}{{ item.name }}\ {%- else -%}{{ inventory_hostname }}\ {%- endif -%}" ns_type: "{%- if item.type is defined -%}{{ item.type | upper }}\ {%- else -%}A\ {%- endif -%}" ns_value: "{%- if item.value is defined -%}{{ item.value }}\ {%- else -%}{{ ansible_host }}\ {%- endif -%}" - name: set ns_quote set_fact: ns_quote: "{{ '\"' if ns_type == 'TXT' else '' }}" - name: construct full name set_fact: ns_full_name: '{%- if ns_name != "@" -%}{{ ns_name }}.{%- endif -%}{{ ns_zone }}' - name: construct regex part set_fact: ns_regex_part: '{%- if item.allow_multiple is defined -%}{{ (ns_quote ~ ns_value ~ ns_quote) | regex_escape() }}\.?{%- else -%}{{ "" | string }}{%- endif -%}' - name: construct regex set_fact: ns_regex: '^{{ ns_full_name | regex_escape() }}\s+\d+\s+IN\s+{{ ns_type | regex_escape() }}\s+{{ ns_regex_part }}' - name: show debug info debug: msg: "{{ ns_zone }} {{ ns_name }} {{ ns_type }} {{ ns_quote ~ ns_value ~ ns_quote }} --> {{ ns_regex }}" - name: query ns zone for a list of entries command: cmd: "pdnsutil list-zone {{ ns_zone | quote }}" register: res changed_when: false failed_when: res.rc != 0 - name: enumerate stdout lines to check if an entry already exists set_fact: ns_exists: "{{ res.stdout_lines | select('search', ns_regex) | list | length > 0 }}" # this takes care of situations with wrong record values - block: - name: fail if there are multiple records fail: msg: single record is chosen, but multiple records found when: res.stdout_lines | select('search', ns_regex) | list | length > 1 - name: grab the value set_fact: ns_old_value: "{{ res.stdout_lines | select('search', ns_regex) | map('regex_search', '\\s+(\\S+?)\\.?$', '\\1') | first | join('') }}" - name: debug debug: msg: "{{ ns_old_value }} <-> {{ ns_quote ~ ns_value ~ ns_quote }}" - name: grab diff set_fact: ns_value_diff: "{{ ns_old_value != (ns_quote ~ ns_value ~ ns_quote) }}" - name: check if records table already exists include_role: name: postgres vars: function: run_query query: database: "{{ hostvars['ns']['database']['name'] | mandatory }}" text: "DELETE FROM records WHERE \ domain_id = (SELECT id FROM domains WHERE name = %s) \ AND name = %s AND type = %s AND content = %s" positional_args: - "{{ ns_zone }}" - "{{ ns_full_name }}" - "{{ ns_type }}" - "{{ ns_old_value }}" when: ns_value_diff - name: unset ns_exists flag so the record will be added set_fact: ns_exists: false when: ns_value_diff when: ns_exists and item.allow_multiple is not defined - name: add the record if it is missing command: cmd: "pdnsutil add-record {{ ns_zone | quote }} {{ ns_name | quote }} {{ ns_type | quote }} {{ ns_value | quote }}" register: res changed_when: (res.rc == 0) and ("New rrset:" in res.stdout) failed_when: res.rc != 0 when: not ns_exists delegate_to: ns