From 326cd31c4859f5c7f77f7ab72f94d278e867ab3b Mon Sep 17 00:00:00 2001 From: Kim Oliver Drechsel Date: Sun, 30 Jun 2024 20:19:49 +0200 Subject: [PATCH] feat: remove hetzner.hcloud ansible dependency (#9) * feat: remove hetzner.hcloud ansible dependency * refactor: rename variable hcloud_image_info to images --- README.md | 16 ------------- galaxy-requirements.yaml | 5 ---- meta/main.yml | 5 +--- tasks/main.yml | 6 ++--- tasks/rotate-snapshots.yml | 47 ++++++++++++++++++++++++++++++-------- tasks/validate.yml | 15 ++++++++---- 6 files changed, 51 insertions(+), 43 deletions(-) delete mode 100644 galaxy-requirements.yaml diff --git a/README.md b/README.md index 0e13190..673ec21 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,10 @@ Ansible role to create and rotate backups and snapshots of servers in Hetzner Cl * [Requirements](#requirements) -* [Dependencies](#dependencies) * [Role Variables](#role-variables) * [api_token](#api_token) * [Default Variables](#default-variables) * [Example Playbook](#example-playbook) -* [Dependencies](#dependencies) * [License](#license) * [Author](#author) @@ -22,20 +20,6 @@ Ansible role to create and rotate backups and snapshots of servers in Hetzner Cl - Ansible 2.15 or later -## Dependencies - -This role depends on the following collections and must be installed before using this role: - -- [hetzner.hcloud](https://galaxy.ansible.com/ui/repo/published/hetzner/hcloud/) - -```bash -ansible-galaxy collection install hetzner.hcloud -``` - -Unfortunately, the ansible dependency system does not allow roles to -depend on collections and vice versa even though it has been requested many times. -Therefore, the collection has to be installed manually. - ## Role Variables ### api_token diff --git a/galaxy-requirements.yaml b/galaxy-requirements.yaml deleted file mode 100644 index 8d23e4b..0000000 --- a/galaxy-requirements.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -collections: - - name: hetzner.hcloud - version: ">=4.0.1" - source: https://galaxy.ansible.com diff --git a/meta/main.yml b/meta/main.yml index 17cb589..6beaaeb 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -28,7 +28,4 @@ galaxy_info: versions: - all -#dependencies: -# - name: hetzner.hcloud -# src: hetzner.hcloud -# version: ">=4.0.1" +dependencies: [] diff --git a/tasks/main.yml b/tasks/main.yml index 6126286..2c5f55e 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -2,7 +2,7 @@ - name: Validate variables include_tasks: validate.yml -- name: Create {{ backup_type }} for {{ inventory_hostname }} +- name: Create {{ backup_type }} delegate_to: "{{ delegation }}" register: response uri: @@ -16,7 +16,7 @@ status_code: 201 body_format: json -- name: Wait until {{ backup_type }} is finished for {{ inventory_hostname }} with interval {{ backup_check_delay }}s +- name: Wait until {{ backup_type }} is finished with interval {{ backup_check_delay }}s delegate_to: "{{ delegation }}" register: response uri: @@ -31,6 +31,6 @@ retries: "{{ backup_check_retries }}" delay: "{{ backup_check_delay }}" -- name: Rotate snapshots for {{ inventory_hostname }} +- name: Rotate snapshots when: backup_type == "snapshot" and rotate_snapshots == true include_tasks: rotate-snapshots.yml diff --git a/tasks/rotate-snapshots.yml b/tasks/rotate-snapshots.yml index 049ac7d..67df6e5 100644 --- a/tasks/rotate-snapshots.yml +++ b/tasks/rotate-snapshots.yml @@ -1,20 +1,47 @@ --- -- name: 'Gather all snapshots with labels: "{{ label_selector }}"' +- name: Prepare label selector filter + set_fact: + label_selector_string: "{{ label_selector | items | map('join', '=') | join(',') }}" + +- name: Get number of pages for snapshots that match the label selector delegate_to: "{{ delegation }}" register: response - hetzner.hcloud.hcloud_image_info: - api_token: "{{ api_token }}" - type: snapshot - label_selector: "{{ label_selector | items | map('join', '=') | join(',') }}" - failed_when: response.hcloud_image_info | length == 0 + uri: + url: "https://api.hetzner.cloud/v1/images?type=snapshot&per_page=50&status=available&label_selector={{ label_selector_string }}" + method: GET + status_code: 200 + headers: + Authorization: "Bearer {{ api_token }}" -- name: Gather snapshots to delete for {{ inventory_hostname }} +- name: Gather all snapshots that match the label selector delegate_to: "{{ delegation }}" + register: response + uri: + url: "https://api.hetzner.cloud/v1/images?type=snapshot&per_page=50&status=available&label_selector={{ label_selector_string }}&page={{ item }}" + method: GET + status_code: 200 + headers: + Authorization: "Bearer {{ api_token }}" + loop: "{{ range(1, response.json.meta.pagination.last_page + 1) | list }}" + +- name: "Prepare list of snapshots" set_fact: - delete_list: "{{ response.hcloud_image_info[0:response.hcloud_image_info | length - keep_snapshots | int] }}" - when: response.hcloud_image_info | length - keep_snapshots | int > 0 + # workaround for selecting only snapshots created from the current host because label_selector has some problems: + # selectattr('created_from.name', 'equalto', inventory_hostname) + images: "{{ response.results | map(attribute='json.images') | flatten | selectattr('created_from.name', 'equalto', inventory_hostname) }}" + +- name: Gather snapshots to delete + delegate_to: "{{ delegation }}" + set_fact: + delete_list: "{{ images[0:images | length - keep_snapshots | int] }}" + when: images | length - keep_snapshots | int > 0 + +- name: Show number of snapshots to delete + debug: + msg: "{{ delete_list | length }} of {{ images | length }} snapshots will be deleted" + when: delete_list | length > 0 -- name: 'Delete {{ delete_list | length }} old snapshots for {{ inventory_hostname }}' +- name: "Delete old snapshots" delegate_to: "{{ delegation }}" when: delete_list | length > 0 loop: "{{ delete_list }}" diff --git a/tasks/validate.yml b/tasks/validate.yml index 749e431..89183f5 100644 --- a/tasks/validate.yml +++ b/tasks/validate.yml @@ -87,15 +87,20 @@ block: - name: Get server details delegate_to: "{{ delegation }}" - register: server - hetzner.hcloud.server_info: - api_token: "{{ api_token }}" - name: "{{ inventory_hostname }}" + register: response + uri: + url: "https://api.hetzner.cloud/v1/servers?name={{ inventory_hostname }}" + method: GET + status_code: 200 + headers: + Authorization: "Bearer {{ api_token }}" + failed_when: + - response.json.servers | length == 0 - name: Check if backups are enabled delegate_to: "{{ delegation }}" assert: quiet: yes that: - - server.hcloud_server_info[0].backup_window not in [None, ""] + - response.json.servers.0.backup_window not in [None, ""] fail_msg: "Backups are not enabled on this server."