๐Ÿ“— Ansible playbooks and roles for building an idempotent, interconnected and scalable infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ansible-playbooks/roles/ns/tasks/add_record.yml

122 lines
3.8 KiB

2 years ago
- 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