mirror of
https://github.com/ansible-collections/hetzner.hcloud
synced 2024-11-10 06:34:13 +00:00
Add possibility to specify private network when creating or updating servers (#160)
* Add possibility to specify private network when creating or updating a server This allows creating servers without public internet access * Add integration tests
This commit is contained in:
parent
6de022e9fb
commit
ad8958a2ad
5 changed files with 190 additions and 0 deletions
|
@ -97,6 +97,12 @@ options:
|
||||||
description:
|
description:
|
||||||
- ID of the ipv6 Primary IP to use. If omitted and enable_ipv6 is true, a new ipv6 Primary IP will automatically be created.
|
- ID of the ipv6 Primary IP to use. If omitted and enable_ipv6 is true, a new ipv6 Primary IP will automatically be created.
|
||||||
type: str
|
type: str
|
||||||
|
private_networks:
|
||||||
|
description:
|
||||||
|
- List of private networks the server is attached to (name or ID)
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
default: []
|
||||||
force_upgrade:
|
force_upgrade:
|
||||||
description:
|
description:
|
||||||
- Deprecated
|
- Deprecated
|
||||||
|
@ -222,6 +228,16 @@ EXAMPLES = """
|
||||||
name: my-server
|
name: my-server
|
||||||
placement_group: null
|
placement_group: null
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Add server with private network only
|
||||||
|
hcloud_server:
|
||||||
|
name: my-server
|
||||||
|
enable_ipv4: false
|
||||||
|
enable_ipv6: false
|
||||||
|
private_networks:
|
||||||
|
- my-network
|
||||||
|
- 4711
|
||||||
|
state: present
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = """
|
||||||
|
@ -260,6 +276,12 @@ hcloud_server:
|
||||||
returned: always
|
returned: always
|
||||||
type: str
|
type: str
|
||||||
sample: 2a01:4f8:1c1c:c140::/64
|
sample: 2a01:4f8:1c1c:c140::/64
|
||||||
|
private_networks:
|
||||||
|
description: List of private networks the server is attached to (name or ID)
|
||||||
|
returned: always
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
sample: ['my-network', 'another-network', '4711']
|
||||||
location:
|
location:
|
||||||
description: Name of the location of the server
|
description: Name of the location of the server
|
||||||
returned: always
|
returned: always
|
||||||
|
@ -345,6 +367,7 @@ class AnsibleHcloudServer(Hcloud):
|
||||||
"name": to_native(self.hcloud_server.name),
|
"name": to_native(self.hcloud_server.name),
|
||||||
"ipv4_address": ipv4_address,
|
"ipv4_address": ipv4_address,
|
||||||
"ipv6": ipv6,
|
"ipv6": ipv6,
|
||||||
|
"private_networks": [to_native(net.network.name) for net in self.hcloud_server.private_net],
|
||||||
"image": image,
|
"image": image,
|
||||||
"server_type": to_native(self.hcloud_server.server_type.name),
|
"server_type": to_native(self.hcloud_server.server_type.name),
|
||||||
"datacenter": to_native(self.hcloud_server.datacenter.name),
|
"datacenter": to_native(self.hcloud_server.datacenter.name),
|
||||||
|
@ -401,6 +424,15 @@ class AnsibleHcloudServer(Hcloud):
|
||||||
p = self.client.primary_ips.get_by_id(self.module.params.get("ipv6"))
|
p = self.client.primary_ips.get_by_id(self.module.params.get("ipv6"))
|
||||||
params["public_net"].ipv6 = p
|
params["public_net"].ipv6 = p
|
||||||
|
|
||||||
|
if self.module.params.get("private_networks") is not None:
|
||||||
|
_networks = []
|
||||||
|
for network_name_or_id in self.module.params.get("private_networks"):
|
||||||
|
_networks.append(
|
||||||
|
self.client.networks.get_by_name(network_name_or_id)
|
||||||
|
or self.client.networks.get_by_id(network_name_or_id)
|
||||||
|
)
|
||||||
|
params["networks"] = _networks
|
||||||
|
|
||||||
if self.module.params.get("ssh_keys") is not None:
|
if self.module.params.get("ssh_keys") is not None:
|
||||||
params["ssh_keys"] = [
|
params["ssh_keys"] = [
|
||||||
SSHKey(name=ssh_key_name)
|
SSHKey(name=ssh_key_name)
|
||||||
|
@ -665,6 +697,34 @@ class AnsibleHcloudServer(Hcloud):
|
||||||
self.hcloud_server.public_net.primary_ipv6.unassign().wait_until_finished()
|
self.hcloud_server.public_net.primary_ipv6.unassign().wait_until_finished()
|
||||||
primary_ip.assign(self.hcloud_server.id, "server").wait_until_finished()
|
primary_ip.assign(self.hcloud_server.id, "server").wait_until_finished()
|
||||||
self._mark_as_changed()
|
self._mark_as_changed()
|
||||||
|
if "private_networks" in self.module.params:
|
||||||
|
if not bool(self.module.params["private_networks"]):
|
||||||
|
# This handles None, "" and []
|
||||||
|
networks_target = {}
|
||||||
|
else:
|
||||||
|
_networks = {}
|
||||||
|
for network_name_or_id in self.module.params.get("private_networks"):
|
||||||
|
_found_network = self.client.networks.get_by_name(network_name_or_id) \
|
||||||
|
or self.client.networks.get_by_id(network_name_or_id)
|
||||||
|
_networks.update(
|
||||||
|
{_found_network.id: _found_network}
|
||||||
|
)
|
||||||
|
networks_target = _networks
|
||||||
|
networks_is = dict()
|
||||||
|
for p_network in self.hcloud_server.private_net:
|
||||||
|
networks_is.update({p_network.network.id: p_network.network})
|
||||||
|
for network_id in set(list(networks_is) + list(networks_target)):
|
||||||
|
if network_id in networks_is and network_id not in networks_target:
|
||||||
|
self.stop_server_if_forced()
|
||||||
|
if not self.module.check_mode:
|
||||||
|
self.hcloud_server.detach_from_network(networks_is[network_id]).wait_until_finished()
|
||||||
|
self._mark_as_changed()
|
||||||
|
elif network_id in networks_target and network_id not in networks_is:
|
||||||
|
self.stop_server_if_forced()
|
||||||
|
if not self.module.check_mode:
|
||||||
|
self.hcloud_server.attach_to_network(networks_target[network_id]).wait_until_finished()
|
||||||
|
self._mark_as_changed()
|
||||||
|
|
||||||
server_type = self.module.params.get("server_type")
|
server_type = self.module.params.get("server_type")
|
||||||
if server_type is not None and self.hcloud_server.server_type.name != server_type:
|
if server_type is not None and self.hcloud_server.server_type.name != server_type:
|
||||||
self.stop_server_if_forced()
|
self.stop_server_if_forced()
|
||||||
|
@ -811,6 +871,7 @@ class AnsibleHcloudServer(Hcloud):
|
||||||
enable_ipv6={"type": "bool", "default": True},
|
enable_ipv6={"type": "bool", "default": True},
|
||||||
ipv4={"type": "str"},
|
ipv4={"type": "str"},
|
||||||
ipv6={"type": "str"},
|
ipv6={"type": "str"},
|
||||||
|
private_networks={"type": "list", "elements": "str", "default": []},
|
||||||
force={"type": "bool", "default": False},
|
force={"type": "bool", "default": False},
|
||||||
force_upgrade={"type": "bool", "default": False},
|
force_upgrade={"type": "bool", "default": False},
|
||||||
allow_deprecated_image={"type": "bool", "default": False},
|
allow_deprecated_image={"type": "bool", "default": False},
|
||||||
|
|
|
@ -87,6 +87,12 @@ hcloud_server_info:
|
||||||
returned: always
|
returned: always
|
||||||
type: str
|
type: str
|
||||||
sample: 2a01:4f8:1c1c:c140::/64
|
sample: 2a01:4f8:1c1c:c140::/64
|
||||||
|
private_networks:
|
||||||
|
description: List of private networks the server is attached to (name)
|
||||||
|
returned: always
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
sample: ['my-network', 'another-network']
|
||||||
location:
|
location:
|
||||||
description: Name of the location of the server
|
description: Name of the location of the server
|
||||||
returned: always
|
returned: always
|
||||||
|
@ -161,6 +167,7 @@ class AnsibleHcloudServerInfo(Hcloud):
|
||||||
"name": to_native(server.name),
|
"name": to_native(server.name),
|
||||||
"ipv4_address": ipv4_address,
|
"ipv4_address": ipv4_address,
|
||||||
"ipv6": ipv6,
|
"ipv6": ipv6,
|
||||||
|
"private_networks": [to_native(net.network.name) for net in server.private_net],
|
||||||
"image": image,
|
"image": image,
|
||||||
"server_type": to_native(server.server_type.name),
|
"server_type": to_native(server.server_type.name),
|
||||||
"datacenter": to_native(server.datacenter.name),
|
"datacenter": to_native(server.datacenter.name),
|
||||||
|
|
|
@ -5,3 +5,4 @@ hcloud_prefix: "tests"
|
||||||
hcloud_server_name: "{{hcloud_prefix}}-i"
|
hcloud_server_name: "{{hcloud_prefix}}-i"
|
||||||
hcloud_firewall_name: "{{hcloud_prefix}}-i"
|
hcloud_firewall_name: "{{hcloud_prefix}}-i"
|
||||||
hcloud_primary_ip_name: "{{hcloud_prefix}}-i"
|
hcloud_primary_ip_name: "{{hcloud_prefix}}-i"
|
||||||
|
hcloud_network_name: "{{hcloud_prefix}}-i"
|
||||||
|
|
|
@ -5,3 +5,4 @@
|
||||||
#- ansible.builtin.include_tasks: basic.yml
|
#- ansible.builtin.include_tasks: basic.yml
|
||||||
#- ansible.builtin.include_tasks: firewalls.yml
|
#- ansible.builtin.include_tasks: firewalls.yml
|
||||||
- ansible.builtin.include_tasks: primary_ips.yml
|
- ansible.builtin.include_tasks: primary_ips.yml
|
||||||
|
- ansible.builtin.include_tasks: private_network_only.yml
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
# Copyright: (c) 2022, Hetzner Cloud GmbH <info@hetzner-cloud.de>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
---
|
||||||
|
- name: setup create network
|
||||||
|
hcloud_network:
|
||||||
|
name: "{{ hcloud_network_name }}-1"
|
||||||
|
ip_range: 192.168.0.0/23
|
||||||
|
register: primaryNetwork
|
||||||
|
|
||||||
|
- name: setup create network subnet 1
|
||||||
|
hcloud_subnetwork:
|
||||||
|
network: "{{ hcloud_network_name }}-1"
|
||||||
|
ip_range: 192.168.0.0/24
|
||||||
|
network_zone: eu-central
|
||||||
|
type: cloud
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: setup create network subnet 2
|
||||||
|
hcloud_subnetwork:
|
||||||
|
network: "{{ hcloud_network_name }}-1"
|
||||||
|
ip_range: 192.168.1.0/24
|
||||||
|
network_zone: eu-central
|
||||||
|
type: cloud
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: setup create secondary network
|
||||||
|
hcloud_network:
|
||||||
|
name: "{{ hcloud_network_name }}-2"
|
||||||
|
ip_range: 192.168.2.0/23
|
||||||
|
register: secondaryNetwork
|
||||||
|
|
||||||
|
- name: setup create secondary network subnet 1
|
||||||
|
hcloud_subnetwork:
|
||||||
|
network: "{{ hcloud_network_name }}-2"
|
||||||
|
ip_range: 192.168.2.0/24
|
||||||
|
network_zone: eu-central
|
||||||
|
type: cloud
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: setup create secondary network subnet 2
|
||||||
|
hcloud_subnetwork:
|
||||||
|
network: "{{ hcloud_network_name }}-2"
|
||||||
|
ip_range: 192.168.3.0/24
|
||||||
|
network_zone: eu-central
|
||||||
|
type: cloud
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: test create server with primary network and no internet
|
||||||
|
hcloud_server:
|
||||||
|
name: "{{ hcloud_server_name }}"
|
||||||
|
server_type: cpx11
|
||||||
|
datacenter: "fsn1-dc14"
|
||||||
|
image: "ubuntu-20.04"
|
||||||
|
enable_ipv4: no
|
||||||
|
enable_ipv6: no
|
||||||
|
private_networks:
|
||||||
|
- "{{ primaryNetwork.hcloud_network.name }}"
|
||||||
|
ssh_keys:
|
||||||
|
- ci@ansible.hetzner.cloud
|
||||||
|
state: stopped
|
||||||
|
register: result
|
||||||
|
- name: verify test create server with primary network
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: test update server by adding secondary network
|
||||||
|
hcloud_server:
|
||||||
|
name: "{{ hcloud_server_name }}"
|
||||||
|
server_type: cpx11
|
||||||
|
datacenter: "fsn1-dc14"
|
||||||
|
image: "ubuntu-20.04"
|
||||||
|
enable_ipv4: no
|
||||||
|
enable_ipv6: no
|
||||||
|
private_networks:
|
||||||
|
- "{{ primaryNetwork.hcloud_network.name }}"
|
||||||
|
- "{{ secondaryNetwork.hcloud_network.id }}"
|
||||||
|
ssh_keys:
|
||||||
|
- ci@ansible.hetzner.cloud
|
||||||
|
state: stopped
|
||||||
|
register: result
|
||||||
|
- name: verify test update server by adding secondary network
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: test update server idem
|
||||||
|
hcloud_server:
|
||||||
|
name: "{{ hcloud_server_name }}"
|
||||||
|
server_type: cpx11
|
||||||
|
datacenter: "fsn1-dc14"
|
||||||
|
image: "ubuntu-20.04"
|
||||||
|
enable_ipv4: no
|
||||||
|
enable_ipv6: no
|
||||||
|
private_networks:
|
||||||
|
- "{{ primaryNetwork.hcloud_network.name }}"
|
||||||
|
- "{{ secondaryNetwork.hcloud_network.id }}"
|
||||||
|
ssh_keys:
|
||||||
|
- ci@ansible.hetzner.cloud
|
||||||
|
state: stopped
|
||||||
|
register: result
|
||||||
|
- name: verify test update server idem
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|
||||||
|
- name: cleanup server
|
||||||
|
hcloud_server:
|
||||||
|
name: "{{ hcloud_server_name }}"
|
||||||
|
state: absent
|
||||||
|
- name: cleanup networks
|
||||||
|
hcloud_network:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "{{ primaryNetwork.hcloud_network.name }}"
|
||||||
|
- "{{ secondaryNetwork.hcloud_network.id }}"
|
||||||
|
until: result is not failed
|
||||||
|
retries: 5
|
||||||
|
delay: 2
|
Loading…
Reference in a new issue