From 39e745049b3bed99b3bf2a1b328c63daafa80a24 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Fri, 12 Sep 2025 00:43:46 +0200 Subject: [PATCH] Revert "Removed incorrect flavor cloud for hetzner" This reverts commit db034553a3ecbf6f9244116bbba84b1740797c07. --- .../tasks/flavors/TODO.md | 2 - .../tasks/flavors/cloud.yml | 97 ++++++++++++++++++- 2 files changed, 96 insertions(+), 3 deletions(-) delete mode 100644 roles/sys-dns-hetzner-rdns/tasks/flavors/TODO.md diff --git a/roles/sys-dns-hetzner-rdns/tasks/flavors/TODO.md b/roles/sys-dns-hetzner-rdns/tasks/flavors/TODO.md deleted file mode 100644 index fe5127f0..00000000 --- a/roles/sys-dns-hetzner-rdns/tasks/flavors/TODO.md +++ /dev/null @@ -1,2 +0,0 @@ -# To-dos -- Implement flavor cloud \ No newline at end of file diff --git a/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml b/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml index a8574f52..bf980b6b 100644 --- a/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml +++ b/roles/sys-dns-hetzner-rdns/tasks/flavors/cloud.yml @@ -1 +1,96 @@ -# Needs to be implemented \ No newline at end of file +--- +# 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 }}" + when: MODE_ASSERT | 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 }}" + when: MODE_ASSERT | 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 }}" + when: MODE_ASSERT | 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 }}"