From 6f230cdf3b951c58fd1ac4da3083ae8b3b6fce99 Mon Sep 17 00:00:00 2001 From: Martin Reinhardt Date: Mon, 15 Nov 2021 12:58:14 +0100 Subject: [PATCH] Add floating ip feature --- README.md | 39 +++++++++++++++++++ molecule_hetznercloud/playbooks/create.yml | 28 +++++++++++++ molecule_hetznercloud/playbooks/destroy.yml | 7 ++++ .../filter_plugins/get_platforms_data.py | 17 ++++++++ .../integration/molecule/default/molecule.yml | 3 ++ 5 files changed, 94 insertions(+) diff --git a/README.md b/README.md index 129731e..08316af 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,45 @@ platforms: ip: 10.1.0.1/24 ``` +**Floating IP** + +You can create an floating ip assigned to your host during molecule run. + +```yaml +platforms: + - name: instance1 + server_type: cx11 + image: debian-10 + floating_ips: + test_ip_1: + type: ipv4 + test_ip_2: + type: ipv6 +``` + +- **floating_ips** + - **type** (required): type of floating ip ('ipv4' or 'ipv6') + +Note that you have to assign the ip to the specific interface on the host. +You can do something like this in your `Converge.yaml` or `Prepare.yaml`: + +```yaml +- name: set floating_ip + changed_when: false + vars: + instance_conf: "{{ lookup('file', molecule_instance_config, errors='warn') | from_yaml }}" + shell: | + set -o pipefail; + if ip a | grep -q {{ item.1.ip }}; + then echo "ip already assigned"; + else ip addr add {{ item.1.ip }} dev eth0; + fi + args: + executable: /bin/bash + when: "item.0.instance == inventory_hostname" + loop: "{{ instance_conf|subelements('floating_ips', skip_missing=True) }}" +``` + > [!NOTE] > The `networks.ip_range` is important for creating. If you have multiple > hosts, you may only define it once. diff --git a/molecule_hetznercloud/playbooks/create.yml b/molecule_hetznercloud/playbooks/create.yml index ec5cf9a..f1c11b5 100644 --- a/molecule_hetznercloud/playbooks/create.yml +++ b/molecule_hetznercloud/playbooks/create.yml @@ -91,6 +91,34 @@ | rejectattr('type', '==', 'vswitch') }} + - name: Create floating ip(s) and assign it to server + hetzner.hcloud.hcloud_floating_ip: + name: "{{ item.name }}" + server: "{{ item.server_name }}" + type: "{{ item.type }}" + home_location: "{{ item.home_location | default(omit) }}" + state: "present" + register: "floating_ip" + loop: "{{ molecule_yml.platforms | molecule_get_hetznercloud_floating_ips() }}" + + - name: Set floating_ips list + ansible.builtin.set_fact: + server_floating_ips: > + {{ + server_floating_ips | default([]) + [ + { + 'instance': item.hcloud_floating_ip.server, + 'floating_ips': { + 'ip_name': item.hcloud_floating_ip.name, + 'ip': item.hcloud_floating_ip.ip, + 'type': item.hcloud_floating_ip.type, + 'home_location': item.hcloud_floating_ip.home_location, + } + } + ] + }} + loop: "{{ floating_ip.results }}" + - name: Create instance config block: - name: Populate instance config dict diff --git a/molecule_hetznercloud/playbooks/destroy.yml b/molecule_hetznercloud/playbooks/destroy.yml index 12c4250..6e2e89c 100644 --- a/molecule_hetznercloud/playbooks/destroy.yml +++ b/molecule_hetznercloud/playbooks/destroy.yml @@ -52,6 +52,13 @@ loop: "{{ instance_conf | subelements('networks', skip_missing=True) }}" register: networks + - name: Destroy floating_ip(s) + hetzner.hcloud.hcloud_floating_ip: + name: "{{ item.1.ip_name }}" + force: true + state: absent + loop: "{{ instance_conf | subelements('floating_ips', skip_missing=True) }}" + - name: Remove registered SSH key when: instance_conf | length hetzner.hcloud.hcloud_ssh_key: diff --git a/molecule_hetznercloud/playbooks/filter_plugins/get_platforms_data.py b/molecule_hetznercloud/playbooks/filter_plugins/get_platforms_data.py index a990b61..c9ee5ec 100755 --- a/molecule_hetznercloud/playbooks/filter_plugins/get_platforms_data.py +++ b/molecule_hetznercloud/playbooks/filter_plugins/get_platforms_data.py @@ -49,6 +49,22 @@ def get_hetznercloud_subnetworks(platforms: list[dict]) -> list[dict]: return all_subnetworks +def get_hetznercloud_floating_ips(platforms: list[dict]) -> list[dict]: + all_floating_ips = [] + + for platform in platforms: + if "floating_ips" not in platform: + continue + + for floating_ip_name, floating_ip in platform["floating_ips"].items(): + floating_ip["server_name"] = platform["name"] + floating_ip["name"] = floating_ip_name + + all_floating_ips.append(floating_ip) + + return all_floating_ips + + def get_hetznercloud_volumes(platforms: list[dict]) -> list[dict]: all_volumes = [] for platform in platforms: @@ -69,5 +85,6 @@ def filters(self): return { "molecule_get_hetznercloud_networks": get_hetznercloud_networks, "molecule_get_hetznercloud_subnetworks": get_hetznercloud_subnetworks, + "molecule_get_hetznercloud_floating_ips": get_hetznercloud_floating_ips, "molecule_get_hetznercloud_volumes": get_hetznercloud_volumes, } diff --git a/tests/integration/molecule/default/molecule.yml b/tests/integration/molecule/default/molecule.yml index 4230ba8..88fb302 100644 --- a/tests/integration/molecule/default/molecule.yml +++ b/tests/integration/molecule/default/molecule.yml @@ -26,6 +26,9 @@ platforms: shared: subnet: ip: 10.10.10.2/24 + floating_ips: + floating-1: + type: ipv4 volumes: - name: volume-1 - name: volume-2