Add possibility to create networks
continuous-integration/drone/pr Build is failing Details
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Martin Reinhardt 2021-05-28 15:30:17 +02:00 committed by decentral1se
parent 3617624623
commit 6c4c20baa6
Signed by: decentral1se
GPG Key ID: 92DAD76BD9567B8A
11 changed files with 318 additions and 8 deletions

View File

@ -81,7 +81,7 @@ steps:
from_secret: HCLOUD_TOKEN from_secret: HCLOUD_TOKEN
commands: commands:
- pip install -e . - pip install -e .
- pip install "ansible>=2.10, <2.11" - pip install "ansible>=2.10, <2.11" netaddr
- export INSTANCE_UUID=$(openssl rand -hex 5) - export INSTANCE_UUID=$(openssl rand -hex 5)
- cd integration && molecule test - cd integration && molecule test
depends_on: depends_on:

View File

@ -96,11 +96,15 @@ see [#24](https://github.com/ansible-community/molecule-hetznercloud/issues/24)
for more). for more).
```yaml ```yaml
volumes: platforms:
- name: "molecule-hetznercloud-volume-1-${INSTANCE_UUID}" - name: instance
location: /foo/bar server_type: cx11
- name: "molecule-hetznercloud-volume-2-${INSTANCE_UUID}" image: debian-10
size: 20 volumes:
- name: "molecule-hetznercloud-volume-1-${INSTANCE_UUID}"
location: /foo/bar
- name: "molecule-hetznercloud-volume-2-${INSTANCE_UUID}"
size: 20
``` ```
Supported keys are: Supported keys are:
@ -109,6 +113,48 @@ Supported keys are:
- **size** (optional, default: `10GB`): size of volume - **size** (optional, default: `10GB`): size of volume
- **location** (optional, default: `omitted`): path for volume - **location** (optional, default: `omitted`): path for volume
## Network Creation
This Driver is able to generate networks and subnetworks during the test run.
This can be useful for cluster tests. You can create networks with the
following snippet:
```yaml
platforms:
- name: instance1
server_type: cx11
image: debian-10
networks:
test-network:
ip_range: 10.10.0.0/16
subnet:
ip: 10.10.10.1/24
type: cloud
network_zone: eu-central
test-network-2:
ip_range: 10.20.0.0/16
subnet:
ip: 10.20.10.1/24
- name: instance2
server_type: cx11
image: debian-10
networks:
test-network:
subnet:
ip: 10.10.10.2/24
```
The networks **ip_range** is only important for creating. If you have multiple
hosts, it is okay to only define **ip_range** once. The supported keys are:
- **networks**
- **ip_range** (required): ip range of network (usually `/16`)
- **subnet**
- **ip** (required): ip that should be assigned to host (also generates subnetwork) - prefix mandatory
- **type** (optional, default: `cloud`): type of subnetwork
- **network_zone** (optional, default: `eu-central`): network zone of subnetwork
## Only use `molecule.yml` for configuration ## Only use `molecule.yml` for configuration
It is being worked on that it is possible to remove all the files except the It is being worked on that it is possible to remove all the files except the

View File

@ -10,6 +10,17 @@ platforms:
volumes: volumes:
- name: "molecule-hetznercloud-volume-1-${INSTANCE_UUID}" - name: "molecule-hetznercloud-volume-1-${INSTANCE_UUID}"
# - name: "molecule-hetznercloud-volume-2-${INSTANCE_UUID}" # - name: "molecule-hetznercloud-volume-2-${INSTANCE_UUID}"
networks:
molecule-hetznercloud-network-1:
ip_range: 10.10.0.0/16
subnet:
ip: 10.10.10.1/24
type: cloud
network_zone: eu-central
molecule-hetznercloud-network-2:
ip_range: 10.20.0.0/16
subnet:
ip: 10.20.10.1/24
provisioner: provisioner:
name: ansible name: ansible
verifier: verifier:

View File

@ -77,6 +77,48 @@
when: volumes.changed when: volumes.changed
with_items: "{{ volumes.results }}" with_items: "{{ volumes.results }}"
- name: Create private network(s)
hcloud_network:
name: "{{ item.name }}"
ip_range: "{{ item.ip_range | default(omit) }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('networks') }}"
register: networks
async: 7200
poll: 0
- name: Wait for network(s) creation to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: hetzner_networks
until: hetzner_networks.finished
retries: 300
when:
- networks is defined
- networks.changed
with_items: "{{ networks.results }}"
- name: Create private subnetwork(s)
hcloud_subnetwork:
network: "{{ item.network_name }}"
ip_range: "{{ item.ip|ipaddr('network/prefix') }}"
network_zone: "{{ item.network_zone | default('eu-central') }}"
type: "{{ item.type | default('cloud') }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('subnetworks') }}"
register: subnetworks
- name: Attach Server to Subnetwork(s)
hcloud_server_network:
network: "{{ item.network_name }}"
server: "{{ item.server_name }}"
ip: "{{ item.ip|ipaddr('address') }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('subnetworks') }}"
- name: Populate instance config dict - name: Populate instance config dict
set_fact: set_fact:
instance_conf_dict: { instance_conf_dict: {
@ -86,7 +128,8 @@
'user': "{{ ssh_user }}", 'user': "{{ ssh_user }}",
'port': "{{ ssh_port }}", 'port': "{{ ssh_port }}",
'identity_file': "{{ ssh_path }}", 'identity_file': "{{ ssh_path }}",
'volumes': "{{ item.item.item.volumes | default({}) }}", } 'volumes': "{{ item.item.item.volumes | default({}) }}",
'networks': "{{ item.item.item.networks | default({}) | dict2items(key_name='name', value_name='data') }}", }
with_items: "{{ hetzner_jobs.results }}" with_items: "{{ hetzner_jobs.results }}"
register: instance_config_dict register: instance_config_dict
when: server.changed | bool when: server.changed | bool

View File

@ -60,6 +60,25 @@
when: volumes.changed when: volumes.changed
with_items: "{{ volumes.results }}" with_items: "{{ volumes.results }}"
- name: Destroy network(s)
hcloud_network:
name: "{{ item.1.name }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: absent
register: networks
loop: "{{ instance_conf|subelements('networks', skip_missing=True) }}"
async: 7200
poll: 0
- name: Wait for network(s) deletion to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: hetzner_networks
until: hetzner_networks.finished
retries: 300
when: networks.changed
with_items: "{{ networks.results }}"
- name: Remove registered SSH key - name: Remove registered SSH key
hcloud_ssh_key: hcloud_ssh_key:
name: "{{ instance_conf[0].ssh_key_name }}" name: "{{ instance_conf[0].ssh_key_name }}"

View File

@ -7,6 +7,19 @@ platforms:
- name: "{{ cookiecutter.role_name }}" - name: "{{ cookiecutter.role_name }}"
server_type: cx11 server_type: cx11
image: debian-10 image: debian-10
volumes:
- name: "molecule-hetznercloud-volume-1"
networks:
molecule-hetznercloud-network-1:
ip_range: 10.10.0.0/16
subnet:
ip: 10.10.10.1/24
type: cloud
network_zone: eu-central
molecule-hetznercloud-network-2:
ip_range: 10.20.0.0/16
subnet:
ip: 10.20.10.1/24
provisioner: provisioner:
name: ansible name: ansible
lint: | lint: |

View File

@ -75,6 +75,48 @@
- volumes.changed - volumes.changed
with_items: "{{ volumes.results }}" with_items: "{{ volumes.results }}"
- name: Create private network(s)
hcloud_network:
name: "{{ item.name }}"
ip_range: "{{ item.ip_range | default(omit) }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('networks') }}"
register: networks
async: 7200
poll: 0
- name: Wait for network(s) creation to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: hetzner_networks
until: hetzner_networks.finished
retries: 300
when:
- networks is defined
- networks.changed
with_items: "{{ networks.results }}"
- name: Create private subnetwork(s)
hcloud_subnetwork:
network: "{{ item.network_name }}"
ip_range: "{{ item.ip|ipaddr('network/prefix') }}"
network_zone: "{{ item.network_zone | default('eu-central') }}"
type: "{{ item.type | default('cloud') }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('subnetworks') }}"
register: subnetworks
- name: Attach Server to Subnetwork(s)
hcloud_server_network:
network: "{{ item.network_name }}"
server: "{{ item.server_name }}"
ip: "{{ item.ip|ipaddr('address') }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('subnetworks') }}"
- name: Populate instance config dict - name: Populate instance config dict
set_fact: set_fact:
instance_conf_dict: instance_conf_dict:
@ -86,6 +128,7 @@
"port": "{{ ssh_port }}", "port": "{{ ssh_port }}",
"identity_file": "{{ ssh_path }}", "identity_file": "{{ ssh_path }}",
"volumes": "{{ item.item.item.volumes | default({}) }}", "volumes": "{{ item.item.item.volumes | default({}) }}",
"networks": "{{ item.item.item.networks | default({}) | dict2items(key_name='name', value_name='data') }}",
} }
with_items: "{{ hetzner_jobs.results }}" with_items: "{{ hetzner_jobs.results }}"
register: instance_config_dict register: instance_config_dict

View File

@ -56,6 +56,25 @@
when: volumes.changed when: volumes.changed
with_items: "{{ volumes.results }}" with_items: "{{ volumes.results }}"
- name: Destroy network(s)
hcloud_network:
name: "{{ item.1.name }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: absent
register: networks
loop: "{{ instance_conf|subelements('networks', skip_missing=True) }}"
async: 7200
poll: 0
- name: Wait for network(s) deletion to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: hetzner_networks
until: hetzner_networks.finished
retries: 300
when: networks.changed
with_items: "{{ networks.results }}"
- name: Remove registered SSH key - name: Remove registered SSH key
hcloud_ssh_key: hcloud_ssh_key:
name: "{{ instance_conf[0].ssh_key_name }}" name: "{{ instance_conf[0].ssh_key_name }}"

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python
"""Usage:"""
""" loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('networks') }}" """ # noqa
""" loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('subnetworks') }}" """ # noqa
def merge_two_dicts(x, y):
z = x.copy()
z.update(y)
return z
def get_hetznercloud_networks(data, request):
network_list = {}
subnetwork_list = []
if request == "networks":
for platform in data:
if "networks" in platform:
for network_name, values in platform["networks"].items():
del values["subnet"]
values["name"] = network_name
if network_name in network_list:
network_list[network_name] = merge_two_dicts(
network_list[network_name], values
)
else:
network_list[network_name] = values
return [x for x in network_list.values()]
elif request == "subnetworks":
for platform in data:
name = platform["name"]
if "networks" in platform:
for network_name, values in platform["networks"].items():
values["name"] = network_name
if "subnet" in values:
values["subnet"]["server_name"] = name
values["subnet"]["network_name"] = network_name
subnetwork_list.append(values["subnet"])
return subnetwork_list
class FilterModule(object):
"""Core Molecule filter plugins."""
def filters(self):
return {
"molecule_get_hetznercloud_networks": get_hetznercloud_networks,
}

View File

@ -76,6 +76,48 @@
when: volumes.changed when: volumes.changed
with_items: "{{ volumes.results }}" with_items: "{{ volumes.results }}"
- name: Create private network(s)
hcloud_network:
name: "{{ item.name }}"
ip_range: "{{ item.ip_range | default(omit) }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('networks') }}"
register: networks
async: 7200
poll: 0
- name: Wait for network(s) creation to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: hetzner_networks
until: hetzner_networks.finished
retries: 300
when:
- networks is defined
- networks.changed
with_items: "{{ networks.results }}"
- name: Create private subnetwork(s)
hcloud_subnetwork:
network: "{{ item.network_name }}"
ip_range: "{{ item.ip|ipaddr('network/prefix') }}"
network_zone: "{{ item.network_zone | default('eu-central') }}"
type: "{{ item.type | default('cloud') }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('subnetworks') }}"
register: subnetworks
- name: Attach Server to Subnetwork(s)
hcloud_server_network:
network: "{{ item.network_name }}"
server: "{{ item.server_name }}"
ip: "{{ item.ip|ipaddr('address') }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: "present"
loop: "{{ molecule_yml.platforms|molecule_get_hetznercloud_networks('subnetworks') }}"
- name: Populate instance config dict - name: Populate instance config dict
set_fact: set_fact:
instance_conf_dict: { instance_conf_dict: {
@ -85,7 +127,8 @@
'user': "{{ ssh_user }}", 'user': "{{ ssh_user }}",
'port': "{{ ssh_port }}", 'port': "{{ ssh_port }}",
'identity_file': "{{ ssh_path }}", 'identity_file': "{{ ssh_path }}",
'volumes': "{{ item.item.item.volumes | default({}) }}", } 'volumes': "{{ item.item.item.volumes | default({}) }}",
'networks': "{{ item.item.item.networks | default({}) | dict2items(key_name='name', value_name='data') }}", }
with_items: "{{ hetzner_jobs.results }}" with_items: "{{ hetzner_jobs.results }}"
register: instance_config_dict register: instance_config_dict
when: server.changed | bool when: server.changed | bool

View File

@ -59,6 +59,25 @@
when: volumes.changed when: volumes.changed
with_items: "{{ volumes.results }}" with_items: "{{ volumes.results }}"
- name: Destroy network(s)
hcloud_network:
name: "{{ item.1.name }}"
api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}"
state: absent
register: networks
loop: "{{ instance_conf|subelements('networks', skip_missing=True) }}"
async: 7200
poll: 0
- name: Wait for network(s) deletion to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: hetzner_networks
until: hetzner_networks.finished
retries: 300
when: networks.changed
with_items: "{{ networks.results }}"
- name: Remove registered SSH key - name: Remove registered SSH key
hcloud_ssh_key: hcloud_ssh_key:
name: "{{ instance_conf[0].ssh_key_name }}" name: "{{ instance_conf[0].ssh_key_name }}"