--- # Cloud flavor (hcloud API) - name: Resolve effective hcloud token set_fact: _hz_token: >- {{ HETZNER_API_TOKEN | default(lookup('env','HETZNER_API_TOKEN'), true) | default('', true) }} no_log: "{{ hetzner_no_log | bool }}" - name: Assert hcloud token present ansible.builtin.assert: that: [ "_hz_token | length > 0" ] fail_msg: "HETZNER_API_TOKEN is required for the Cloud flavor." no_log: "{{ hetzner_no_log | bool }}" - name: Collect hcloud servers if needed (server records without identifier) hetzner.hcloud.server_info: api_token: "{{ _hz_token }}" register: _servers_info when: rdns_records | selectattr('resource','equalto','server') | selectattr('identifier','undefined') | list | length > 0 no_log: "{{ hetzner_no_log | bool }}" - name: Init normalized records list set_fact: _rdns_records: [] - name: Normalize records (autofill server.identifier by IPv4) vars: _match_name: >- {{ (_servers_info.servers | default([])) | selectattr('public_net.ipv4.ip','equalto', rec.ip_address | default('')) | map(attribute='name') | list | first | default('') }} _needs_autofill: >- {{ rec.resource == 'server' and (rec.identifier is not defined) and (rec.ip_address | default('') | length > 0) }} _normalized: >- {{ rec if (not _needs_autofill or _match_name == '') else (rec | combine({'identifier': _match_name})) }} set_fact: _rdns_records: "{{ _rdns_records + [ _normalized ] }}" loop: "{{ rdns_records }}" loop_control: { loop_var: rec } - name: Ensure server identifiers are resolved when required assert: that: - > ( (_rdns_records | selectattr('resource','equalto','server') | selectattr('identifier','defined') | list | length) == (_rdns_records | selectattr('resource','equalto','server') | list | length) ) fail_msg: "Could not resolve hcloud server by IPv4 for one or more records." no_log: "{{ hetzner_no_log | bool }}" - name: Validate records (cloud) ansible.builtin.assert: that: - (_rdns_records | default(rdns_records)) | length > 0 - (_rdns_records | default(rdns_records)) | selectattr('dns_ptr','defined') | list | length == ((_rdns_records | default(rdns_records)) | length) - (_rdns_records | default(rdns_records)) | selectattr('ip_address','defined') | list | length == ((_rdns_records | default(rdns_records)) | length) - (_rdns_records | default(rdns_records)) | selectattr('resource','defined') | list | length == ((_rdns_records | default(rdns_records)) | length) - ( (_rdns_records | default(rdns_records)) | selectattr('resource','equalto','server') | selectattr('identifier','defined') | list | length + ((_rdns_records | default(rdns_records)) | rejectattr('resource','equalto','server') | list | length) ) == ((_rdns_records | default(rdns_records)) | length) no_log: "{{ hetzner_no_log | bool }}" - name: Apply rDNS via hcloud hetzner.hcloud.hcloud_rdns: api_token: "{{ _hz_token }}" server: "{{ (item.resource == 'server') | ternary(item.identifier, omit) }}" primary_ip: "{{ (item.resource == 'primary_ip') | ternary(item.identifier, omit) }}" floating_ip: "{{ (item.resource == 'floating_ip') | ternary(item.identifier, omit) }}" load_balancer: "{{ (item.resource == 'load_balancer') | ternary(item.identifier, omit) }}" ip_address: "{{ item.ip_address }}" dns_ptr: "{{ item.dns_ptr }}" state: present loop: "{{ _rdns_records | default(rdns_records) }}" loop_control: label: "{{ item.resource }}[{{ item.identifier | default('auto-by-ipv4') }}] {{ item.ip_address }} -> {{ item.dns_ptr }}" async: "{{ hetzner_async_enabled | ternary(hetzner_async_time, omit) }}" poll: "{{ hetzner_async_enabled | ternary(hetzner_async_poll, omit) }}" no_log: "{{ hetzner_no_log | bool }}"