---
- name: Set list of all host IP addresses
  ansible.builtin.set_fact:
    named_host_all_addresses: "{{ ansible_all_ipv4_addresses | union(ansible_all_ipv6_addresses) }}"
  tags: bind

- name: Read forward zone hashes
  ansible.builtin.shell: grep -s "^; Hash:" {{ named_zone_dir }}/{{ item.name }} || true
  changed_when: false
  check_mode: false
  register: named_forward_hashes_temp
  with_items:
    - "{{ named_zones }}"
  run_once: true
  loop_control:
    label: "{{ item.name }}"
  tags: bind

- name: Create dict of forward hashes
  ansible.builtin.set_fact:
    named_forward_hashes: "{{ named_forward_hashes | default([]) + [{'hash': item.stdout | default(), 'name': item.item.name}] }}"
  with_items:
    - "{{ named_forward_hashes_temp.results }}"
  run_once: true
  loop_control:
    label: "{{ item.item.name }}"
  tags: bind

- name: Read reverse ipv4 zone hashes
  ansible.builtin.shell: grep -s "^; Hash:" {{ named_zone_dir }}/{{ ('.'.join(item.1.replace(item.1+'.','').split('.')[::-1])) }}.in-addr.arpa || true
  changed_when: false
  check_mode: false
  register: named_reverse_hashes_temp
  with_subelements:
    - "{{ named_zones }}"
    - networks
    - flags:
      skip_missing: true
  run_once: true
  loop_control:
    label: "{{ item.1 }}"
  tags: bind

- name: Create dict of reverse hashes
  ansible.builtin.set_fact:
    named_reverse_hashes: "{{ named_reverse_hashes | default([]) + [{'hash': item.0.stdout | default(), 'network': item.1}] }}"
  with_subelements:
    - "{{ named_reverse_hashes_temp.results }}"
    - item
  run_once: true
  loop_control:
    label: "{{ item.1.name | default(item.0.cmd.split(' ')[4]) }}"
  tags: bind

- name: Read reverse ipv6 zone hashes
  ansible.builtin.shell: grep -s "^; Hash:" {{ named_zone_dir }}/{{ (item.1 | ipaddr('revdns'))[-(9+(item.1|regex_replace('^.*/','')|int)//2):-1] }} || true
  changed_when: false
  check_mode: false
  register: named_reverse_hashes_ipv6_temp
  with_subelements:
    - "{{ named_zones }}"
    - ipv6_networks
    - flags:
      skip_missing: true
  run_once: true
  loop_control:
    label: "{{ item.1 }}"
  tags: bind

- name: Create dict of reverse ipv6 hashes
  ansible.builtin.set_fact:
    named_reverse_hashes_ipv6: "{{ named_reverse_hashes_ipv6 | default([]) + [{'hash': item.0.stdout | default(), 'network': item.1}] }}"
  with_subelements:
    - "{{ named_reverse_hashes_ipv6_temp.results }}"
    - item
  run_once: true
  loop_control:
    label: "{{ item.1.name | default(item.0.cmd.split(' ')[4]) }}"
  tags: bind

- name: Read standalone reverse zone hashes
  ansible.builtin.shell: grep -s "^; Hash:" {{ named_zone_dir }}/{{ item.name }} || true
  changed_when: false
  check_mode: false
  register: named_reverse_standalone_hashes_temp
  with_items: "{{ named_zones | selectattr('reverse_zone', 'defined') | selectattr('reverse_zone') | list }}"
  run_once: true
  loop_control:
    label: "{{ item.name }}"
  tags: bind

- name: Create dict of standalone reverse hashes
  ansible.builtin.set_fact:
    named_reverse_standalone_hashes: >-
      {{ named_reverse_standalone_hashes | default([]) +
         [{'hash': item.stdout | default(), 'name': item.item.name}] }}
  with_items: "{{ named_reverse_standalone_hashes_temp.results | default([]) }}"
  run_once: true
  loop_control:
    label: "{{ item.item.name }}"
  tags: bind

- name: Create forward lookup zone file
  ansible.builtin.template:
    src: bind_zone.j2
    dest: "{{ named_zone_dir }}/{{ item.name }}"
    owner: "{{ named_owner }}"
    group: "{{ named_group }}"
    mode: "{{ named_zone_file_mode }}"
    setype: named_zone_t
    validate: named-checkzone -d {{ item.name }} %s
  become: true
  with_items:
    - "{{ named_zones }}"
  loop_control:
    label: "{{ item.name }}"
  when: >
    (item.reverse_zone is not defined or not item.reverse_zone) and
    (item.create_forward_zones is not defined or item.create_forward_zones) and
    ((item.type is defined and item.type == 'primary') or
    (item.type is not defined and item.primaries is defined and
    (named_host_all_addresses | intersect(item.primaries) | length > 0)))
  notify: Reload bind
  tags: bind

- name: Create reverse lookup zone file
  ansible.builtin.template:
    src: reverse_zone.j2
    dest: "{{ named_zone_dir }}/{{ ('.'.join(item.1.replace(item.1+'.','').split('.')[::-1])) }}.in-addr.arpa"
    owner: "{{ named_owner }}"
    group: "{{ named_group }}"
    mode: "{{ named_zone_file_mode }}"
    setype: named_zone_t
    validate: named-checkzone {{ ('.'.join(item.1.replace(item.1+'.','').split('.')[::-1])) }}.in-addr.arpa %s
  become: true
  with_subelements:
    - "{{ named_zones }}"
    - networks
    - flags:
      skip_missing: true
  loop_control:
    label: "{{ item.1 }}"
  when: >
    (item.create_reverse_zones is not defined or item.create_reverse_zones) and
    ((item[0].type is defined and item[0].type == 'primary') or
    (item[0].type is not defined and item[0].primaries is defined and
    (named_host_all_addresses | intersect(item[0].primaries) | length > 0)))
  notify: Reload bind
  tags: bind

- name: Create reverse IPv6 lookup zone file
  ansible.builtin.template:
    src: reverse_zone_ipv6.j2
    dest: "{{ named_zone_dir }}/{{ (item.1 | ipaddr('revdns'))[-(9+(item.1|regex_replace('^.*/','')|int)//2):-1] }}"
    owner: "{{ named_owner }}"
    group: "{{ named_group }}"
    mode: "{{ named_zone_file_mode }}"
    setype: named_zone_t
    validate: named-checkzone {{ (item.1 | ipaddr('revdns'))[-(9+(item.1|regex_replace('^.*/','')|int)//2):] }} %s
  become: true
  with_subelements:
    - "{{ named_zones }}"
    - ipv6_networks
    - flags:
      skip_missing: true
  loop_control:
    label: "{{ item.1 }}"
  when: >
    (item.create_reverse_zones is not defined or item.create_reverse_zones) and
    ((item[0].type is defined and item[0].type == 'primary') or
    (item[0].type is not defined and item[0].primaries is defined and
    (named_host_all_addresses | intersect(item[0].primaries) | length > 0)))
  notify: Reload bind
  tags: bind

- name: Create standalone reverse lookup zone file
  ansible.builtin.template:
    src: reverse_zone_standalone.j2
    dest: "{{ named_zone_dir }}/{{ item.name }}"
    owner: "{{ named_owner }}"
    group: "{{ named_group }}"
    mode: "{{ named_zone_file_mode }}"
    setype: named_zone_t
    validate: named-checkzone {{ item.name }} %s
  become: true
  with_items: "{{ named_zones | selectattr('reverse_zone', 'defined') | selectattr('reverse_zone') | list }}"
  loop_control:
    label: "{{ item.name }}"
  when: >
    (item.type is defined and item.type == 'primary') or
    (item.type is not defined and item.primaries is defined and
    (named_host_all_addresses | intersect(item.primaries) | length > 0))
  notify: Reload bind
  tags: bind
