summaryrefslogtreecommitdiffstats
path: root/ansible_collections/hetzner/hcloud/plugins/modules
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
commit38b7c80217c4e72b1d8988eb1e60bb6e77334114 (patch)
tree356e9fd3762877d07cde52d21e77070aeff7e789 /ansible_collections/hetzner/hcloud/plugins/modules
parentAdding upstream version 7.7.0+dfsg. (diff)
downloadansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.tar.xz
ansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.zip
Adding upstream version 9.4.0+dfsg.upstream/9.4.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/hetzner/hcloud/plugins/modules')
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/certificate.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate.py)124
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate_info.py)80
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py192
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/firewall.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_firewall.py)311
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py246
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py243
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip.py)109
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_facts.py)101
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py160
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py160
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py185
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py219
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py159
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py244
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py183
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py183
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py169
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py186
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/image_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_info.py)108
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py206
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py)122
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_info.py)128
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_network.py)96
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_service.py)206
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_target.py)168
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_type_info.py)79
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/location_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_info.py)86
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/network.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network.py)100
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/network_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network_info.py)89
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_placement_group.py)72
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_primary_ip.py)79
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py203
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/rdns.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_rdns.py)132
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/route.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_route.py)70
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server.py)484
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_info.py)120
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server_network.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_network.py)102
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py204
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key.py)87
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_facts.py)95
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_subnetwork.py)87
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/volume.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume.py)93
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py (renamed from ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_info.py)94
43 files changed, 2997 insertions, 3567 deletions
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate.py b/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py
index 0f6dcf0f2..ea39be6ca 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_certificate
+module: certificate
short_description: Create and manage certificates on the Hetzner Cloud.
@@ -39,17 +37,17 @@ options:
certificate:
description:
- Certificate and chain in PEM format, in order so that each record directly certifies the one preceding.
- - Required if certificate does not exist.
+ - Required if certificate does not exist and I(type=uploaded).
type: str
private_key:
description:
- Certificate key in PEM format.
- - Required if certificate does not exist.
+ - Required if certificate does not exist and I(type=uploaded).
type: str
domain_names:
description:
- - Certificate key in PEM format.
- - Required if certificate does not exist.
+ - Domains and subdomains that should be contained in the Certificate issued by Let's Encrypt.
+ - Required if I(type=managed).
type: list
default: [ ]
elements: str
@@ -68,28 +66,37 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Create a basic certificate
- hcloud_certificate:
+ hetzner.hcloud.certificate:
name: my-certificate
- certificate: "ssh-rsa AAAjjk76kgf...Xt"
- private_key: "ssh-rsa AAAjjk76kgf...Xt"
+ certificate: -----BEGIN CERTIFICATE-----...
+ private_key: -----BEGIN PRIVATE KEY-----...
state: present
- name: Create a certificate with labels
- hcloud_certificate:
+ hetzner.hcloud.certificate:
name: my-certificate
- certificate: "ssh-rsa AAAjjk76kgf...Xt"
- private_key: "ssh-rsa AAAjjk76kgf...Xt"
+ certificate: -----BEGIN CERTIFICATE-----...
+ private_key: -----BEGIN PRIVATE KEY-----...
labels:
- key: value
- mylabel: 123
+ key: value
+ mylabel: 123
+ state: present
+
+- name: Create a managed certificate
+ hetzner.hcloud.certificate:
+ name: my-certificate
+ type: managed
+ domain_names:
+ - example.com
+ - www.example.com
state: present
- name: Ensure the certificate is absent (remove if needed)
- hcloud_certificate:
+ hetzner.hcloud.certificate:
name: my-certificate
state: absent
"""
@@ -139,14 +146,17 @@ hcloud_certificate:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.certificates import BoundCertificate
-class AnsibleHcloudCertificate(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_certificate")
- self.hcloud_certificate = None
+
+class AnsibleHCloudCertificate(AnsibleHCloud):
+ represent = "hcloud_certificate"
+
+ hcloud_certificate: BoundCertificate | None = None
def _prepare_result(self):
return {
@@ -158,54 +168,44 @@ class AnsibleHcloudCertificate(Hcloud):
"not_valid_before": to_native(self.hcloud_certificate.not_valid_before),
"not_valid_after": to_native(self.hcloud_certificate.not_valid_after),
"domain_names": [to_native(domain) for domain in self.hcloud_certificate.domain_names],
- "labels": self.hcloud_certificate.labels
+ "labels": self.hcloud_certificate.labels,
}
def _get_certificate(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_certificate = self.client.certificates.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_certificate = self.client.certificates.get_by_id(self.module.params.get("id"))
elif self.module.params.get("name") is not None:
- self.hcloud_certificate = self.client.certificates.get_by_name(
- self.module.params.get("name")
- )
+ self.hcloud_certificate = self.client.certificates.get_by_name(self.module.params.get("name"))
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_certificate(self):
- self.module.fail_on_missing_params(
- required_params=["name"]
- )
+ self.module.fail_on_missing_params(required_params=["name"])
params = {
"name": self.module.params.get("name"),
- "labels": self.module.params.get("labels")
+ "labels": self.module.params.get("labels"),
}
- if self.module.params.get('type') == 'uploaded':
- self.module.fail_on_missing_params(
- required_params=["certificate", "private_key"]
- )
+ if self.module.params.get("type") == "uploaded":
+ self.module.fail_on_missing_params(required_params=["certificate", "private_key"])
params["certificate"] = self.module.params.get("certificate")
params["private_key"] = self.module.params.get("private_key")
if not self.module.check_mode:
try:
self.client.certificates.create(**params)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
else:
- self.module.fail_on_missing_params(
- required_params=["domain_names"]
- )
+ self.module.fail_on_missing_params(required_params=["domain_names"])
params["domain_names"] = self.module.params.get("domain_names")
if not self.module.check_mode:
try:
resp = self.client.certificates.create_managed(**params)
resp.action.wait_until_finished(max_retries=1000)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_certificate()
@@ -214,9 +214,7 @@ class AnsibleHcloudCertificate(Hcloud):
try:
name = self.module.params.get("name")
if name is not None and self.hcloud_certificate.name != name:
- self.module.fail_on_missing_params(
- required_params=["id"]
- )
+ self.module.fail_on_missing_params(required_params=["id"])
if not self.module.check_mode:
self.hcloud_certificate.update(name=name)
self._mark_as_changed()
@@ -226,8 +224,8 @@ class AnsibleHcloudCertificate(Hcloud):
if not self.module.check_mode:
self.hcloud_certificate.update(labels=labels)
self._mark_as_changed()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._get_certificate()
def present_certificate(self):
@@ -243,13 +241,13 @@ class AnsibleHcloudCertificate(Hcloud):
if not self.module.check_mode:
try:
self.client.certificates.delete(self.hcloud_certificate)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_certificate = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -266,18 +264,18 @@ class AnsibleHcloudCertificate(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
- required_if=[['state', 'present', ['name']]],
+ required_one_of=[["id", "name"]],
+ required_if=[["state", "present", ["name"]]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudCertificate.define_module()
+ module = AnsibleHCloudCertificate.define_module()
- hcloud = AnsibleHcloudCertificate(module)
+ hcloud = AnsibleHCloudCertificate(module)
state = module.params.get("state")
if state == "absent":
hcloud.delete_certificate()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py
index 855706f1f..e074046fd 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_certificate_info
+module: certificate_info
short_description: Gather infos about your Hetzner Cloud certificates.
description:
- Gather facts about your Hetzner Cloud certificates.
@@ -20,6 +18,7 @@ options:
id:
description:
- The ID of the certificate you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -32,11 +31,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud certificate infos
- hcloud_certificate_info:
+ hetzner.hcloud.certificate_info:
register: output
- name: Print the gathered infos
debug:
@@ -86,75 +85,76 @@ hcloud_certificate_info:
returned: always
type: dict
"""
+
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.certificates import BoundCertificate
+
+class AnsibleHCloudCertificateInfo(AnsibleHCloud):
+ represent = "hcloud_certificate_info"
-class AnsibleHcloudCertificateInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_certificate_info")
- self.hcloud_certificate_info = None
+ hcloud_certificate_info: list[BoundCertificate] | None = None
def _prepare_result(self):
certificates = []
for certificate in self.hcloud_certificate_info:
if certificate:
- certificates.append({
- "id": to_native(certificate.id),
- "name": to_native(certificate.name),
- "fingerprint": to_native(certificate.fingerprint),
- "certificate": to_native(certificate.certificate),
- "not_valid_before": to_native(certificate.not_valid_before),
- "not_valid_after": to_native(certificate.not_valid_after),
- "domain_names": [to_native(domain) for domain in certificate.domain_names],
- "labels": certificate.labels
- })
+ certificates.append(
+ {
+ "id": to_native(certificate.id),
+ "name": to_native(certificate.name),
+ "fingerprint": to_native(certificate.fingerprint),
+ "certificate": to_native(certificate.certificate),
+ "not_valid_before": to_native(certificate.not_valid_before),
+ "not_valid_after": to_native(certificate.not_valid_after),
+ "domain_names": [to_native(domain) for domain in certificate.domain_names],
+ "labels": certificate.labels,
+ }
+ )
return certificates
def get_certificates(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_certificate_info = [self.client.certificates.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_certificate_info = [self.client.certificates.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None:
- self.hcloud_certificate_info = [self.client.certificates.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_certificate_info = [self.client.certificates.get_by_name(self.module.params.get("name"))]
elif self.module.params.get("label_selector") is not None:
self.hcloud_certificate_info = self.client.certificates.get_all(
- label_selector=self.module.params.get("label_selector"))
+ label_selector=self.module.params.get("label_selector")
+ )
else:
self.hcloud_certificate_info = self.client.certificates.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudCertificateInfo.define_module()
+ module = AnsibleHCloudCertificateInfo.define_module()
+ hcloud = AnsibleHCloudCertificateInfo(module)
- hcloud = AnsibleHcloudCertificateInfo(module)
hcloud.get_certificates()
result = hcloud.get_result()
- ansible_info = {
- 'hcloud_certificate_info': result['hcloud_certificate_info']
- }
+ ansible_info = {"hcloud_certificate_info": result["hcloud_certificate_info"]}
module.exit_json(**ansible_info)
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py
new file mode 100644
index 000000000..f6665a6fb
--- /dev/null
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py
@@ -0,0 +1,192 @@
+#!/usr/bin/python
+
+# Copyright: (c) 2019, 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)
+
+
+from __future__ import annotations
+
+DOCUMENTATION = """
+---
+module: datacenter_info
+
+short_description: Gather info about the Hetzner Cloud datacenters.
+
+description:
+ - Gather info about your Hetzner Cloud datacenters.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the datacenter you want to get.
+ - The module will fail if the provided ID is invalid.
+ type: int
+ name:
+ description:
+ - The name of the datacenter you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+"""
+
+EXAMPLES = """
+- name: Gather hcloud datacenter info
+ hetzner.hcloud.datacenter_info:
+ register: output
+
+- name: Print the gathered info
+ debug:
+ var: output
+
+- name: List available server_types in a datacenter
+ block:
+ - name: Gather a hcloud datacenter
+ hetzner.hcloud.datacenter_info:
+ name: fsn1-dc14
+ register: output
+
+ - name: Gather a hcloud datacenter available server_types
+ hetzner.hcloud.server_type_info:
+ id: "{{ item }}"
+ loop: "{{ output.hcloud_datacenter_info[0].server_types.available }}"
+ register: available_server_types
+
+ - name: Print a hcloud datacenter available server_types
+ ansible.builtin.debug:
+ var: available_server_types.results | map(attribute='hcloud_server_type_info')
+"""
+
+RETURN = """
+hcloud_datacenter_info:
+ description:
+ - The datacenter info as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the datacenter
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the datacenter
+ returned: always
+ type: str
+ sample: fsn1-dc8
+ description:
+ description: Detail description of the datacenter
+ returned: always
+ type: str
+ sample: Falkenstein DC 8
+ location:
+ description: Name of the location where the datacenter resides in
+ returned: always
+ type: str
+ sample: fsn1
+ city:
+ description: City of the location
+ returned: always
+ type: str
+ sample: fsn1
+ server_types:
+ description: The Server types the Datacenter can handle
+ returned: always
+ type: dict
+ contains:
+ available:
+ description: IDs of Server types that are supported and for which the Datacenter has enough resources left
+ returned: always
+ type: list
+ elements: int
+ sample: [1, 2, 3]
+ available_for_migration:
+ description: IDs of Server types that are supported and for which the Datacenter has enough resources left
+ returned: always
+ type: list
+ elements: int
+ sample: [1, 2, 3]
+ supported:
+ description: IDs of Server types that are supported in the Datacenter
+ returned: always
+ type: list
+ elements: int
+ sample: [1, 2, 3]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.datacenters import BoundDatacenter
+
+
+class AnsibleHCloudDatacenterInfo(AnsibleHCloud):
+ represent = "hcloud_datacenter_info"
+
+ hcloud_datacenter_info: list[BoundDatacenter] | None = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for datacenter in self.hcloud_datacenter_info:
+ if datacenter is None:
+ continue
+
+ tmp.append(
+ {
+ "id": to_native(datacenter.id),
+ "name": to_native(datacenter.name),
+ "description": to_native(datacenter.description),
+ "location": to_native(datacenter.location.name),
+ "server_types": {
+ "available": [o.id for o in datacenter.server_types.available],
+ "available_for_migration": [o.id for o in datacenter.server_types.available_for_migration],
+ "supported": [o.id for o in datacenter.server_types.supported],
+ },
+ }
+ )
+
+ return tmp
+
+ def get_datacenters(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_datacenter_info = [self.client.datacenters.get_by_id(self.module.params.get("id"))]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_datacenter_info = [self.client.datacenters.get_by_name(self.module.params.get("name"))]
+ else:
+ self.hcloud_datacenter_info = self.client.datacenters.get_all()
+
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
+ @classmethod
+ def define_module(cls):
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **super().base_module_arguments(),
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHCloudDatacenterInfo.define_module()
+ hcloud = AnsibleHCloudDatacenterInfo(module)
+
+ hcloud.get_datacenters()
+ result = hcloud.get_result()
+
+ ansible_info = {"hcloud_datacenter_info": result["hcloud_datacenter_info"]}
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_firewall.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py
index 34608977e..3c51b5c0a 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_firewall.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py
@@ -1,20 +1,16 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_firewall
-
+module: firewall
short_description: Create and manage firewalls on the Hetzner Cloud.
-
description:
- Create, update and manage firewalls on the Hetzner Cloud.
@@ -24,181 +20,233 @@ author:
options:
id:
description:
- - The ID of the Hetzner Cloud firewall to manage.
- - Only required if no firewall I(name) is given
+ - The ID of the Hetzner Cloud Firewall to manage.
+ - Only required if no firewall O(name) is given.
type: int
name:
description:
- - The Name of the Hetzner Cloud firewall to manage.
- - Only required if no firewall I(id) is given, or a firewall does not exist.
+ - The Name of the Hetzner Cloud Firewall to manage.
+ - Only required if no firewall O(id) is given, or the firewall does not exist.
type: str
labels:
description:
- - User-defined labels (key-value pairs)
+ - User-defined labels (key-value pairs).
type: dict
rules:
description:
- - List of rules the firewall should contain.
+ - List of rules the firewall contain.
type: list
elements: dict
suboptions:
- direction:
+ description:
description:
- - The direction of the firewall rule.
+ - User defined description of this rule.
type: str
- choices: [ in, out ]
- port:
+ direction:
description:
- - The port of the firewall rule.
+ - The direction of the firewall rule.
type: str
+ choices: [in, out]
protocol:
description:
- The protocol of the firewall rule.
type: str
- choices: [ icmp, tcp, udp, esp, gre ]
+ choices: [icmp, tcp, udp, esp, gre]
+ port:
+ description:
+ - The port or port range allowed by this rule.
+ - A port range can be specified by separating two ports with a dash, e.g 1024-5000.
+ - Only used if O(rules[].protocol=tcp) or O(rules[].protocol=udp).
+ type: str
source_ips:
description:
- - List of CIDRs that are allowed within this rule
+ - List of CIDRs that are allowed within this rule.
+ - Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses.
+ - Only used if O(rules[].direction=in).
type: list
elements: str
- default: [ ]
+ default: []
destination_ips:
description:
- - List of CIDRs that are allowed within this rule
+ - List of CIDRs that are allowed within this rule.
+ - Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses.
+ - Only used if O(rules[].direction=out).
type: list
elements: str
- default: [ ]
- description:
- description:
- - User defined description of this rule.
- type: str
+ default: []
+ force:
+ description:
+ - Force the deletion of the Firewall when still in use.
+ type: bool
+ default: false
state:
description:
- State of the firewall.
default: present
- choices: [ absent, present ]
+ choices: [absent, present]
type: str
+
extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-'''
+ - hetzner.hcloud.hcloud
+"""
EXAMPLES = """
- name: Create a basic firewall
- hcloud_firewall:
+ hetzner.hcloud.firewall:
name: my-firewall
state: present
- name: Create a firewall with rules
- hcloud_firewall:
+ hetzner.hcloud.firewall:
name: my-firewall
rules:
- - direction: in
- protocol: icmp
- source_ips:
- - 0.0.0.0/0
- - ::/0
- description: allow icmp in
+ - description: allow icmp from everywhere
+ direction: in
+ protocol: icmp
+ source_ips:
+ - 0.0.0.0/0
+ - ::/0
state: present
- name: Create a firewall with labels
- hcloud_firewall:
+ hetzner.hcloud.firewall:
name: my-firewall
labels:
- key: value
- mylabel: 123
+ key: value
+ mylabel: 123
state: present
- name: Ensure the firewall is absent (remove if needed)
- hcloud_firewall:
+ hetzner.hcloud.firewall:
name: my-firewall
state: absent
"""
RETURN = """
hcloud_firewall:
- description: The firewall instance
- returned: Always
- type: complex
+ description: The firewall instance.
+ returned: always
+ type: dict
contains:
id:
- description: Numeric identifier of the firewall
+ description: Numeric identifier of the firewall.
returned: always
type: int
sample: 1937415
name:
- description: Name of the firewall
+ description: Name of the firewall.
returned: always
type: str
- sample: my firewall
+ sample: my-firewall
+ labels:
+ description: User-defined labels (key-value pairs).
+ returned: always
+ type: dict
rules:
- description: List of Rules within this Firewall
+ description: List of rules the firewall contain.
returned: always
- type: complex
+ type: list
+ elements: dict
contains:
+ description:
+ description: User defined description of this rule.
+ type: str
+ returned: always
+ sample: allow http from anywhere
direction:
- description: Direction of the Firewall Rule
+ description: The direction of the firewall rule.
type: str
returned: always
sample: in
protocol:
- description: Protocol of the Firewall Rule
+ description: The protocol of the firewall rule.
type: str
returned: always
- sample: icmp
+ sample: tcp
port:
- description: Port of the Firewall Rule, None/Null if protocol is icmp
+ description: The port or port range allowed by this rule.
type: str
- returned: always
- sample: in
+ returned: if RV(hcloud_firewall.rules[].protocol=tcp) or RV(hcloud_firewall.rules[].protocol=udp)
+ sample: "80"
source_ips:
- description: Source IPs of the Firewall
+ description: List of source CIDRs that are allowed within this rule.
type: list
elements: str
returned: always
+ sample: ["0.0.0.0/0", "::/0"]
destination_ips:
- description: Source IPs of the Firewall
+ description: List of destination CIDRs that are allowed within this rule.
type: list
elements: str
returned: always
- description:
- description: User defined description of the Firewall Rule
- type: str
- returned: always
- labels:
- description: User-defined labels (key-value pairs)
+ sample: []
+ applied_to:
+ description: List of Resources the Firewall is applied to.
returned: always
- type: dict
+ type: list
+ elements: dict
+ contains:
+ type:
+ description: Type of the resource.
+ type: str
+ choices: [server, label_selector]
+ sample: label_selector
+ server:
+ description: ID of the server.
+ type: int
+ sample: 12345
+ label_selector:
+ description: Label selector value.
+ type: str
+ sample: env=prod
+ applied_to_resources:
+ description: List of Resources the Firewall label selector is applied to.
+ returned: if RV(hcloud_firewall.applied_to[].type=label_selector)
+ type: list
+ elements: dict
+ contains:
+ type:
+ description: Type of resource referenced.
+ type: str
+ choices: [server]
+ sample: server
+ server:
+ description: ID of the Server.
+ type: int
+ sample: 12345
"""
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
import time
-try:
- from hcloud.firewalls.domain import FirewallRule
- from hcloud import APIException
-except ImportError:
- APIException = None
- FirewallRule = None
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import APIException, HCloudException
+from ..module_utils.vendor.hcloud.firewalls import (
+ BoundFirewall,
+ FirewallResource,
+ FirewallRule,
+)
-class AnsibleHcloudFirewall(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_firewall")
- self.hcloud_firewall = None
+class AnsibleHCloudFirewall(AnsibleHCloud):
+ represent = "hcloud_firewall"
+
+ hcloud_firewall: BoundFirewall | None = None
def _prepare_result(self):
return {
"id": to_native(self.hcloud_firewall.id),
"name": to_native(self.hcloud_firewall.name),
"rules": [self._prepare_result_rule(rule) for rule in self.hcloud_firewall.rules],
- "labels": self.hcloud_firewall.labels
+ "labels": self.hcloud_firewall.labels,
+ "applied_to": [self._prepare_result_applied_to(resource) for resource in self.hcloud_firewall.applied_to],
}
- def _prepare_result_rule(self, rule):
+ def _prepare_result_rule(self, rule: FirewallRule):
return {
- "direction": rule.direction,
+ "direction": to_native(rule.direction),
"protocol": to_native(rule.protocol),
"port": to_native(rule.port) if rule.port is not None else None,
"source_ips": [to_native(cidr) for cidr in rule.source_ips],
@@ -206,27 +254,39 @@ class AnsibleHcloudFirewall(Hcloud):
"description": to_native(rule.description) if rule.description is not None else None,
}
+ def _prepare_result_applied_to(self, resource: FirewallResource):
+ result = {
+ "type": to_native(resource.type),
+ "server": to_native(resource.server.id) if resource.server is not None else None,
+ "label_selector": (
+ to_native(resource.label_selector.selector) if resource.label_selector is not None else None
+ ),
+ }
+ if resource.applied_to_resources is not None:
+ result["applied_to_resources"] = [
+ {
+ "type": to_native(item.type),
+ "server": to_native(item.server.id) if item.server is not None else None,
+ }
+ for item in resource.applied_to_resources
+ ]
+ return result
+
def _get_firewall(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_firewall = self.client.firewalls.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_firewall = self.client.firewalls.get_by_id(self.module.params.get("id"))
elif self.module.params.get("name") is not None:
- self.hcloud_firewall = self.client.firewalls.get_by_name(
- self.module.params.get("name")
- )
+ self.hcloud_firewall = self.client.firewalls.get_by_name(self.module.params.get("name"))
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_firewall(self):
- self.module.fail_on_missing_params(
- required_params=["name"]
- )
+ self.module.fail_on_missing_params(required_params=["name"])
params = {
"name": self.module.params.get("name"),
- "labels": self.module.params.get("labels")
+ "labels": self.module.params.get("labels"),
}
rules = self.module.params.get("rules")
if rules is not None:
@@ -241,20 +301,20 @@ class AnsibleHcloudFirewall(Hcloud):
)
for rule in rules
]
+
if not self.module.check_mode:
try:
self.client.firewalls.create(**params)
- except Exception as e:
- self.module.fail_json(msg=e.message, **params)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception, params=params)
+
self._mark_as_changed()
self._get_firewall()
def _update_firewall(self):
name = self.module.params.get("name")
if name is not None and self.hcloud_firewall.name != name:
- self.module.fail_on_missing_params(
- required_params=["id"]
- )
+ self.module.fail_on_missing_params(required_params=["id"])
if not self.module.check_mode:
self.hcloud_firewall.update(name=name)
self._mark_as_changed()
@@ -281,6 +341,7 @@ class AnsibleHcloudFirewall(Hcloud):
]
self.hcloud_firewall.set_rules(new_rules)
self._mark_as_changed()
+
self._get_firewall()
def present_firewall(self):
@@ -294,58 +355,76 @@ class AnsibleHcloudFirewall(Hcloud):
self._get_firewall()
if self.hcloud_firewall is not None:
if not self.module.check_mode:
+ if self.hcloud_firewall.applied_to:
+ if self.module.params.get("force"):
+ actions = self.hcloud_firewall.remove_from_resources(self.hcloud_firewall.applied_to)
+ for action in actions:
+ action.wait_until_finished()
+ else:
+ self.module.warn(
+ f"Firewall {self.hcloud_firewall.name} is currently used by "
+ "other resources. You need to unassign the resources before "
+ "deleting the Firewall or use force=true."
+ )
+
retry_count = 0
- while retry_count < 10:
+ while True:
try:
- self.client.firewalls.delete(self.hcloud_firewall)
+ self.hcloud_firewall.delete()
break
- except APIException as e:
- if "is still in use" in e.message:
- retry_count = retry_count + 1
+ except APIException as exception:
+ if "is still in use" in exception.message and retry_count < 10:
+ retry_count += 1
time.sleep(0.5 * retry_count)
- else:
- self.module.fail_json(msg=e.message)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ continue
+ self.fail_json_hcloud(exception)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
self._mark_as_changed()
self.hcloud_firewall = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
+ labels={"type": "dict"},
rules=dict(
type="list",
elements="dict",
options=dict(
+ description={"type": "str"},
direction={"type": "str", "choices": ["in", "out"]},
protocol={"type": "str", "choices": ["icmp", "udp", "tcp", "esp", "gre"]},
port={"type": "str"},
source_ips={"type": "list", "elements": "str", "default": []},
destination_ips={"type": "list", "elements": "str", "default": []},
- description={"type": "str"},
),
required_together=[["direction", "protocol"]],
+ required_if=[
+ ["protocol", "udp", ["port"]],
+ ["protocol", "tcp", ["port"]],
+ ],
),
- labels={"type": "dict"},
+ force={"type": "bool", "default": False},
state={
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
- required_if=[['state', 'present', ['name']]],
+ required_one_of=[["id", "name"]],
+ required_if=[["state", "present", ["name"]]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudFirewall.define_module()
+ module = AnsibleHCloudFirewall.define_module()
- hcloud = AnsibleHcloudFirewall(module)
+ hcloud = AnsibleHCloudFirewall(module)
state = module.params.get("state")
if state == "absent":
hcloud.delete_firewall()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py
new file mode 100644
index 000000000..7e7a623d0
--- /dev/null
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py
@@ -0,0 +1,246 @@
+#!/usr/bin/python
+
+# Copyright: (c) 2019, 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)
+
+
+from __future__ import annotations
+
+DOCUMENTATION = """
+---
+module: firewall_info
+short_description: Gather infos about the Hetzner Cloud Firewalls.
+
+description:
+ - Gather facts about your Hetzner Cloud Firewalls.
+
+author:
+ - Jonas Lammler (@jooola)
+
+options:
+ id:
+ description:
+ - The ID of the Firewall you want to get.
+ - The module will fail if the provided ID is invalid.
+ type: int
+ name:
+ description:
+ - The name for the Firewall you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the Firewalls you want to get.
+ type: str
+
+extends_documentation_fragment:
+ - hetzner.hcloud.hcloud
+"""
+
+EXAMPLES = """
+- name: Gather hcloud Firewall infos
+ hetzner.hcloud.firewall_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_firewall_info:
+ description: List of Firewalls.
+ returned: always
+ type: list
+ elements: dict
+ contains:
+ id:
+ description: Numeric identifier of the firewall.
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the firewall.
+ returned: always
+ type: str
+ sample: my-firewall
+ labels:
+ description: User-defined labels (key-value pairs).
+ returned: always
+ type: dict
+ rules:
+ description: List of rules the firewall contain.
+ returned: always
+ type: list
+ elements: dict
+ contains:
+ description:
+ description: User defined description of this rule.
+ type: str
+ returned: always
+ sample: allow http from anywhere
+ direction:
+ description: The direction of the firewall rule.
+ type: str
+ returned: always
+ sample: in
+ protocol:
+ description: The protocol of the firewall rule.
+ type: str
+ returned: always
+ sample: tcp
+ port:
+ description: The port or port range allowed by this rule.
+ type: str
+ returned: if RV(hcloud_firewall_info[].rules[].protocol=tcp) or RV(hcloud_firewall_info[].rules[].protocol=udp)
+ sample: "80"
+ source_ips:
+ description: List of source CIDRs that are allowed within this rule.
+ type: list
+ elements: str
+ returned: always
+ sample: ["0.0.0.0/0", "::/0"]
+ destination_ips:
+ description: List of destination CIDRs that are allowed within this rule.
+ type: list
+ elements: str
+ returned: always
+ sample: []
+ applied_to:
+ description: List of Resources the Firewall is applied to.
+ returned: always
+ type: list
+ elements: dict
+ contains:
+ type:
+ description: Type of the resource.
+ type: str
+ choices: [server, label_selector]
+ sample: label_selector
+ server:
+ description: ID of the server.
+ type: int
+ sample: 12345
+ label_selector:
+ description: Label selector value.
+ type: str
+ sample: env=prod
+ applied_to_resources:
+ description: List of Resources the Firewall label selector is applied to.
+ returned: if RV(hcloud_firewall_info[].applied_to[].type=label_selector)
+ type: list
+ elements: dict
+ contains:
+ type:
+ description: Type of resource referenced.
+ type: str
+ choices: [server]
+ sample: server
+ server:
+ description: ID of the Server.
+ type: int
+ sample: 12345
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.firewalls import (
+ BoundFirewall,
+ FirewallResource,
+ FirewallRule,
+)
+
+
+class AnsibleHCloudFirewallInfo(AnsibleHCloud):
+ represent = "hcloud_firewall_info"
+
+ hcloud_firewall_info: list[BoundFirewall] | None = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for firewall in self.hcloud_firewall_info:
+ if firewall is None:
+ continue
+
+ tmp.append(
+ {
+ "id": to_native(firewall.id),
+ "name": to_native(firewall.name),
+ "labels": firewall.labels,
+ "rules": [self._prepare_result_rule(rule) for rule in firewall.rules],
+ "applied_to": [self._prepare_result_applied_to(resource) for resource in firewall.applied_to],
+ }
+ )
+
+ return tmp
+
+ def _prepare_result_rule(self, rule: FirewallRule):
+ return {
+ "description": to_native(rule.description) if rule.description is not None else None,
+ "direction": to_native(rule.direction),
+ "protocol": to_native(rule.protocol),
+ "port": to_native(rule.port) if rule.port is not None else None,
+ "source_ips": [to_native(cidr) for cidr in rule.source_ips],
+ "destination_ips": [to_native(cidr) for cidr in rule.destination_ips],
+ }
+
+ def _prepare_result_applied_to(self, resource: FirewallResource):
+ result = {
+ "type": to_native(resource.type),
+ "server": to_native(resource.server.id) if resource.server is not None else None,
+ "label_selector": (
+ to_native(resource.label_selector.selector) if resource.label_selector is not None else None
+ ),
+ }
+ if resource.applied_to_resources is not None:
+ result["applied_to_resources"] = [
+ {
+ "type": to_native(item.type),
+ "server": to_native(item.server.id) if item.server is not None else None,
+ }
+ for item in resource.applied_to_resources
+ ]
+ return result
+
+ def get_firewalls(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_firewall_info = [self.client.firewalls.get_by_id(self.module.params.get("id"))]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_firewall_info = [self.client.firewalls.get_by_name(self.module.params.get("name"))]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_firewall_info = self.client.firewalls.get_all(
+ label_selector=self.module.params.get("label_selector")
+ )
+ else:
+ self.hcloud_firewall_info = self.client.firewalls.get_all()
+
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
+ @classmethod
+ def define_module(cls):
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **super().base_module_arguments(),
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHCloudFirewallInfo.define_module()
+ hcloud = AnsibleHCloudFirewallInfo(module)
+
+ hcloud.get_firewalls()
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py
new file mode 100644
index 000000000..207f27092
--- /dev/null
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py
@@ -0,0 +1,243 @@
+#!/usr/bin/python
+
+# Copyright: (c) 2019, 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)
+
+
+from __future__ import annotations
+
+DOCUMENTATION = """
+---
+module: firewall_resource
+short_description: Manage Resources a Hetzner Cloud Firewall is applied to.
+
+description:
+ - Add and Remove Resources a Hetzner Cloud Firewall is applied to.
+
+author:
+ - Jonas Lammler (@jooola)
+
+version_added: 2.5.0
+options:
+ firewall:
+ description:
+ - Name or ID of the Hetzner Cloud Firewall.
+ type: str
+ required: true
+ servers:
+ description:
+ - List of Server Name or ID.
+ type: list
+ elements: str
+ label_selectors:
+ description:
+ - List of Label Selector.
+ type: list
+ elements: str
+ state:
+ description:
+ - State of the firewall resources.
+ default: present
+ choices: [absent, present]
+ type: str
+
+extends_documentation_fragment:
+ - hetzner.hcloud.hcloud
+"""
+
+EXAMPLES = """
+- name: Apply a firewall to a list of servers
+ hetzner.hcloud.firewall_resource:
+ name: my-firewall
+ servers:
+ - my-server
+ - 3456789
+ state: present
+
+- name: Remove a firewall from a list of servers
+ hetzner.hcloud.firewall_resource:
+ name: my-firewall
+ servers:
+ - my-server
+ - 3456789
+ state: absent
+
+- name: Apply a firewall to resources using label selectors
+ hetzner.hcloud.firewall_resource:
+ name: my-firewall
+ label_selectors:
+ - env=prod
+ state: present
+
+- name: Remove a firewall from resources using label selectors
+ hetzner.hcloud.firewall_resource:
+ name: my-firewall
+ label_selectors:
+ - env=prod
+ state: absent
+"""
+
+RETURN = """
+hcloud_firewall_resource:
+ description: The Resources a Hetzner Cloud Firewall is applied to.
+ returned: always
+ type: dict
+ contains:
+ firewall:
+ description:
+ - Name of the Hetzner Cloud Firewall.
+ type: str
+ sample: my-firewall
+ servers:
+ description:
+ - List of Server Name.
+ type: list
+ elements: str
+ sample: [my-server1, my-server2]
+ label_selectors:
+ description:
+ - List of Label Selector.
+ type: list
+ elements: str
+ sample: [env=prod]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.firewalls import (
+ BoundFirewall,
+ FirewallResource,
+ FirewallResourceLabelSelector,
+)
+from ..module_utils.vendor.hcloud.servers import BoundServer
+
+
+class AnsibleHCloudFirewallResource(AnsibleHCloud):
+ represent = "hcloud_firewall_resource"
+
+ hcloud_firewall_resource: BoundFirewall | None = None
+
+ def _prepare_result(self):
+ servers = []
+ label_selectors = []
+ for resource in self.hcloud_firewall_resource.applied_to:
+ if resource.type == FirewallResource.TYPE_SERVER:
+ servers.append(to_native(resource.server.name))
+ elif resource.type == FirewallResource.TYPE_LABEL_SELECTOR:
+ label_selectors.append(to_native(resource.label_selector.selector))
+
+ return {
+ "firewall": to_native(self.hcloud_firewall_resource.name),
+ "servers": servers,
+ "label_selectors": label_selectors,
+ }
+
+ def _get_firewall(self):
+ try:
+ self.hcloud_firewall_resource = self._client_get_by_name_or_id(
+ "firewalls",
+ self.module.params.get("firewall"),
+ )
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
+ def _diff_firewall_resources(self, operator) -> list[FirewallResource]:
+ before = self._prepare_result()
+
+ resources: list[FirewallResource] = []
+
+ servers: list[str] | None = self.module.params.get("servers")
+ if servers:
+ for server_param in servers:
+ try:
+ server: BoundServer = self._client_get_by_name_or_id("servers", server_param)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
+ if operator(server.name, before["servers"]):
+ resources.append(
+ FirewallResource(
+ type=FirewallResource.TYPE_SERVER,
+ server=server,
+ )
+ )
+
+ label_selectors = self.module.params.get("label_selectors")
+ if label_selectors:
+ for label_selector in label_selectors:
+ if operator(label_selector, before["label_selectors"]):
+ resources.append(
+ FirewallResource(
+ type=FirewallResource.TYPE_LABEL_SELECTOR,
+ label_selector=FirewallResourceLabelSelector(selector=label_selector),
+ )
+ )
+
+ return resources
+
+ def present_firewall_resources(self):
+ self._get_firewall()
+ resources = self._diff_firewall_resources(
+ lambda to_add, before: to_add not in before,
+ )
+ if resources:
+ if not self.module.check_mode:
+ actions = self.hcloud_firewall_resource.apply_to_resources(resources=resources)
+ for action in actions:
+ action.wait_until_finished()
+
+ self.hcloud_firewall_resource.reload()
+
+ self._mark_as_changed()
+
+ def absent_firewall_resources(self):
+ self._get_firewall()
+ resources = self._diff_firewall_resources(
+ lambda to_remove, before: to_remove in before,
+ )
+ if resources:
+ if not self.module.check_mode:
+ actions = self.hcloud_firewall_resource.remove_from_resources(resources=resources)
+ for action in actions:
+ action.wait_until_finished()
+
+ self.hcloud_firewall_resource.reload()
+
+ self._mark_as_changed()
+
+ @classmethod
+ def define_module(cls):
+ return AnsibleModule(
+ argument_spec={
+ "firewall": {"type": "str", "required": True},
+ "servers": {"type": "list", "elements": "str"},
+ "label_selectors": {"type": "list", "elements": "str"},
+ "state": {
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **super().base_module_arguments(),
+ },
+ required_one_of=[["servers", "label_selectors"]],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHCloudFirewallResource.define_module()
+
+ hcloud = AnsibleHCloudFirewallResource(module)
+ state = module.params.get("state")
+ if state == "absent":
+ hcloud.absent_firewall_resources()
+ elif state == "present":
+ hcloud.present_firewall_resources()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip.py b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py
index 1ee61ea13..e037dd7a1 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_floating_ip
+module: floating_ip
short_description: Create and manage cloud Floating IPs on the Hetzner Cloud.
@@ -71,40 +69,36 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.6.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a basic IPv4 Floating IP
- hcloud_floating_ip:
+ hetzner.hcloud.floating_ip:
name: my-floating-ip
home_location: fsn1
type: ipv4
state: present
- name: Create a basic IPv6 Floating IP
- hcloud_floating_ip:
+ hetzner.hcloud.floating_ip:
name: my-floating-ip
home_location: fsn1
type: ipv6
state: present
- name: Assign a Floating IP to a server
- hcloud_floating_ip:
+ hetzner.hcloud.floating_ip:
name: my-floating-ip
server: 1234
state: present
- name: Assign a Floating IP to another server
- hcloud_floating_ip:
+ hetzner.hcloud.floating_ip:
name: my-floating-ip
server: 1234
- force: yes
+ force: true
state: present
- name: Floating IP should be absent
- hcloud_floating_ip:
+ hetzner.hcloud.floating_ip:
name: my-floating-ip
state: absent
"""
@@ -166,14 +160,17 @@ hcloud_floating_ip:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.floating_ips import BoundFloatingIP
-class AnsibleHcloudFloatingIP(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_floating_ip")
- self.hcloud_floating_ip = None
+class AnsibleHCloudFloatingIP(AnsibleHCloud):
+ represent = "hcloud_floating_ip"
+
+ hcloud_floating_ip: BoundFloatingIP | None = None
def _prepare_result(self):
server = None
@@ -195,20 +192,14 @@ class AnsibleHcloudFloatingIP(Hcloud):
def _get_floating_ip(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_floating_ip = self.client.floating_ips.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_floating_ip = self.client.floating_ips.get_by_id(self.module.params.get("id"))
else:
- self.hcloud_floating_ip = self.client.floating_ips.get_by_name(
- self.module.params.get("name")
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_floating_ip = self.client.floating_ips.get_by_name(self.module.params.get("name"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_floating_ip(self):
- self.module.fail_on_missing_params(
- required_params=["type"]
- )
+ self.module.fail_on_missing_params(required_params=["type"])
try:
params = {
"description": self.module.params.get("description"),
@@ -216,13 +207,9 @@ class AnsibleHcloudFloatingIP(Hcloud):
"name": self.module.params.get("name"),
}
if self.module.params.get("home_location") is not None:
- params["home_location"] = self.client.locations.get_by_name(
- self.module.params.get("home_location")
- )
+ params["home_location"] = self.client.locations.get_by_name(self.module.params.get("home_location"))
elif self.module.params.get("server") is not None:
- params["server"] = self.client.servers.get_by_name(
- self.module.params.get("server")
- )
+ params["server"] = self.client.servers.get_by_name(self.module.params.get("server"))
else:
self.module.fail_json(msg="one of the following is required: home_location, server")
@@ -235,8 +222,8 @@ class AnsibleHcloudFloatingIP(Hcloud):
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None:
self.hcloud_floating_ip.change_protection(delete=delete_protection).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_floating_ip()
@@ -258,21 +245,18 @@ class AnsibleHcloudFloatingIP(Hcloud):
if server is not None and self.hcloud_floating_ip.server is not None:
if self.module.params.get("force") and server != self.hcloud_floating_ip.server.name:
if not self.module.check_mode:
- self.hcloud_floating_ip.assign(
- self.client.servers.get_by_name(server)
- )
+ self.hcloud_floating_ip.assign(self.client.servers.get_by_name(server))
self._mark_as_changed()
elif server != self.hcloud_floating_ip.server.name:
self.module.warn(
- "Floating IP is already assigned to another server %s. You need to unassign the Floating IP or use force=yes."
- % self.hcloud_floating_ip.server.name
+ "Floating IP is already assigned to another server "
+ f"{self.hcloud_floating_ip.server.name}. You need to "
+ "unassign the Floating IP or use force=true."
)
self._mark_as_changed()
elif server is not None and self.hcloud_floating_ip.server is None:
if not self.module.check_mode:
- self.hcloud_floating_ip.assign(
- self.client.servers.get_by_name(server)
- )
+ self.hcloud_floating_ip.assign(self.client.servers.get_by_name(server))
self._mark_as_changed()
elif server is None and self.hcloud_floating_ip.server is not None:
if not self.module.check_mode:
@@ -286,8 +270,8 @@ class AnsibleHcloudFloatingIP(Hcloud):
self._mark_as_changed()
self._get_floating_ip()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def present_floating_ip(self):
self._get_floating_ip()
@@ -305,16 +289,17 @@ class AnsibleHcloudFloatingIP(Hcloud):
self.client.floating_ips.delete(self.hcloud_floating_ip)
else:
self.module.warn(
- "Floating IP is currently assigned to server %s. You need to unassign the Floating IP or use force=yes."
- % self.hcloud_floating_ip.server.name
+ "Floating IP is currently assigned to server "
+ f"{self.hcloud_floating_ip.server.name}. You need to "
+ "unassign the Floating IP or use force=true."
)
self._mark_as_changed()
self.hcloud_floating_ip = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -330,18 +315,18 @@ class AnsibleHcloudFloatingIP(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
- mutually_exclusive=[['home_location', 'server']],
+ required_one_of=[["id", "name"]],
+ mutually_exclusive=[["home_location", "server"]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudFloatingIP.define_module()
+ module = AnsibleHCloudFloatingIP.define_module()
- hcloud = AnsibleHcloudFloatingIP(module)
+ hcloud = AnsibleHCloudFloatingIP(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_floating_ip()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py
index 2ec359600..663d29622 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_facts.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py
@@ -1,23 +1,19 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_floating_ip_info
+module: floating_ip_info
short_description: Gather infos about the Hetzner Cloud Floating IPs.
description:
- Gather facts about your Hetzner Cloud Floating IPs.
- - This module was called C(hcloud_floating_ip_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_floating_ip_facts).
- Note that the M(hetzner.hcloud.hcloud_floating_ip_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_floating_ip_info)!
author:
- Lukas Kaemmerling (@LKaemmerling)
@@ -26,7 +22,12 @@ options:
id:
description:
- The ID of the Floating IP you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
+ name:
+ description:
+ - The name for the Floating IP you want to get.
+ type: str
label_selector:
description:
- The label selector for the Floating IP you want to get.
@@ -34,11 +35,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud Floating ip infos
- hcloud_floating_ip_info:
+ hetzner.hcloud.floating_ip_info:
register: output
- name: Print the gathered infos
debug:
@@ -99,14 +100,17 @@ hcloud_floating_ip_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.floating_ips import BoundFloatingIP
-class AnsibleHcloudFloatingIPInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_floating_ip_info")
- self.hcloud_floating_ip_info = None
+class AnsibleHCloudFloatingIPInfo(AnsibleHCloud):
+ represent = "hcloud_floating_ip_info"
+
+ hcloud_floating_ip_info: list[BoundFloatingIP] | None = None
def _prepare_result(self):
tmp = []
@@ -116,69 +120,60 @@ class AnsibleHcloudFloatingIPInfo(Hcloud):
server_name = None
if floating_ip.server is not None:
server_name = floating_ip.server.name
- tmp.append({
- "id": to_native(floating_ip.id),
- "name": to_native(floating_ip.name),
- "description": to_native(floating_ip.description),
- "ip": to_native(floating_ip.ip),
- "type": to_native(floating_ip.type),
- "server": to_native(server_name),
- "home_location": to_native(floating_ip.home_location.name),
- "labels": floating_ip.labels,
- "delete_protection": floating_ip.protection["delete"],
- })
+ tmp.append(
+ {
+ "id": to_native(floating_ip.id),
+ "name": to_native(floating_ip.name),
+ "description": to_native(floating_ip.description),
+ "ip": to_native(floating_ip.ip),
+ "type": to_native(floating_ip.type),
+ "server": to_native(server_name),
+ "home_location": to_native(floating_ip.home_location.name),
+ "labels": floating_ip.labels,
+ "delete_protection": floating_ip.protection["delete"],
+ }
+ )
return tmp
def get_floating_ips(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_floating_ip_info = [self.client.floating_ips.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_floating_ip_info = [self.client.floating_ips.get_by_id(self.module.params.get("id"))]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_floating_ip_info = [self.client.floating_ips.get_by_name(self.module.params.get("name"))]
elif self.module.params.get("label_selector") is not None:
self.hcloud_floating_ip_info = self.client.floating_ips.get_all(
- label_selector=self.module.params.get("label_selector"))
+ label_selector=self.module.params.get("label_selector")
+ )
else:
self.hcloud_floating_ip_info = self.client.floating_ips.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
+ name={"type": "str"},
label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudFloatingIPInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_floating_ip_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_floating_ip_facts' module has been renamed to 'hcloud_floating_ip_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudFloatingIPInfo(module)
+ module = AnsibleHCloudFloatingIPInfo.define_module()
+ hcloud = AnsibleHCloudFloatingIPInfo(module)
hcloud.get_floating_ips()
result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_floating_ip_facts': result['hcloud_floating_ip_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_floating_ip_info': result['hcloud_floating_ip_info']
- }
- module.exit_json(**ansible_info)
+
+ ansible_info = {"hcloud_floating_ip_info": result["hcloud_floating_ip_info"]}
+ module.exit_json(**ansible_info)
if __name__ == "__main__":
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py
deleted file mode 100644
index 8cebabf8c..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_datacenter_info
-
-short_description: Gather info about the Hetzner Cloud datacenters.
-
-description:
- - Gather info about your Hetzner Cloud datacenters.
- - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
- Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the datacenter you want to get.
- type: int
- name:
- description:
- - The name of the datacenter you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud datacenter info
- hcloud_datacenter_info:
- register: output
-- name: Print the gathered info
- debug:
- var: output
-"""
-
-RETURN = """
-hcloud_datacenter_info:
- description:
- - The datacenter info as list
- - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
- Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the datacenter
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the datacenter
- returned: always
- type: str
- sample: fsn1-dc8
- description:
- description: Detail description of the datacenter
- returned: always
- type: str
- sample: Falkenstein DC 8
- location:
- description: Name of the location where the datacenter resides in
- returned: always
- type: str
- sample: fsn1
- city:
- description: City of the location
- returned: always
- type: str
- sample: fsn1
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudDatacenterInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_datacenter_info")
- self.hcloud_datacenter_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for datacenter in self.hcloud_datacenter_info:
- if datacenter is not None:
- tmp.append({
- "id": to_native(datacenter.id),
- "name": to_native(datacenter.name),
- "description": to_native(datacenter.description),
- "location": to_native(datacenter.location.name)
- })
-
- return tmp
-
- def get_datacenters(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_datacenter_info = [self.client.datacenters.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_datacenter_info = [self.client.datacenters.get_by_name(
- self.module.params.get("name")
- )]
- else:
- self.hcloud_datacenter_info = self.client.datacenters.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudDatacenterInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_datacenter_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_datacenter_facts' module has been renamed to 'hcloud_datacenter_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
- hcloud = AnsibleHcloudDatacenterInfo(module)
-
- hcloud.get_datacenters()
- result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_datacenter_facts': result['hcloud_datacenter_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_datacenter_info': result['hcloud_datacenter_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py
deleted file mode 100644
index 8cebabf8c..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_datacenter_info
-
-short_description: Gather info about the Hetzner Cloud datacenters.
-
-description:
- - Gather info about your Hetzner Cloud datacenters.
- - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
- Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the datacenter you want to get.
- type: int
- name:
- description:
- - The name of the datacenter you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud datacenter info
- hcloud_datacenter_info:
- register: output
-- name: Print the gathered info
- debug:
- var: output
-"""
-
-RETURN = """
-hcloud_datacenter_info:
- description:
- - The datacenter info as list
- - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
- Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the datacenter
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the datacenter
- returned: always
- type: str
- sample: fsn1-dc8
- description:
- description: Detail description of the datacenter
- returned: always
- type: str
- sample: Falkenstein DC 8
- location:
- description: Name of the location where the datacenter resides in
- returned: always
- type: str
- sample: fsn1
- city:
- description: City of the location
- returned: always
- type: str
- sample: fsn1
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudDatacenterInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_datacenter_info")
- self.hcloud_datacenter_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for datacenter in self.hcloud_datacenter_info:
- if datacenter is not None:
- tmp.append({
- "id": to_native(datacenter.id),
- "name": to_native(datacenter.name),
- "description": to_native(datacenter.description),
- "location": to_native(datacenter.location.name)
- })
-
- return tmp
-
- def get_datacenters(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_datacenter_info = [self.client.datacenters.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_datacenter_info = [self.client.datacenters.get_by_name(
- self.module.params.get("name")
- )]
- else:
- self.hcloud_datacenter_info = self.client.datacenters.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudDatacenterInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_datacenter_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_datacenter_facts' module has been renamed to 'hcloud_datacenter_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
- hcloud = AnsibleHcloudDatacenterInfo(module)
-
- hcloud.get_datacenters()
- result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_datacenter_facts': result['hcloud_datacenter_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_datacenter_info': result['hcloud_datacenter_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py
deleted file mode 100644
index 2ec359600..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_floating_ip_info
-
-short_description: Gather infos about the Hetzner Cloud Floating IPs.
-
-description:
- - Gather facts about your Hetzner Cloud Floating IPs.
- - This module was called C(hcloud_floating_ip_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_floating_ip_facts).
- Note that the M(hetzner.hcloud.hcloud_floating_ip_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_floating_ip_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the Floating IP you want to get.
- type: int
- label_selector:
- description:
- - The label selector for the Floating IP you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud Floating ip infos
- hcloud_floating_ip_info:
- register: output
-- name: Print the gathered infos
- debug:
- var: output
-"""
-
-RETURN = """
-hcloud_floating_ip_info:
- description: The Floating ip infos as list
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the Floating IP
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the Floating IP
- returned: Always
- type: str
- sample: my-floating-ip
- version_added: "0.1.0"
- description:
- description: Description of the Floating IP
- returned: always
- type: str
- sample: Falkenstein DC 8
- ip:
- description: IP address of the Floating IP
- returned: always
- type: str
- sample: 131.232.99.1
- type:
- description: Type of the Floating IP
- returned: always
- type: str
- sample: ipv4
- server:
- description: Name of the server where the Floating IP is assigned to.
- returned: always
- type: str
- sample: my-server
- home_location:
- description: Location the Floating IP was created in
- returned: always
- type: str
- sample: fsn1
- delete_protection:
- description: True if the Floating IP is protected for deletion
- returned: always
- type: bool
- version_added: "0.1.0"
- labels:
- description: User-defined labels (key-value pairs)
- returned: always
- type: dict
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudFloatingIPInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_floating_ip_info")
- self.hcloud_floating_ip_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for floating_ip in self.hcloud_floating_ip_info:
- if floating_ip is not None:
- server_name = None
- if floating_ip.server is not None:
- server_name = floating_ip.server.name
- tmp.append({
- "id": to_native(floating_ip.id),
- "name": to_native(floating_ip.name),
- "description": to_native(floating_ip.description),
- "ip": to_native(floating_ip.ip),
- "type": to_native(floating_ip.type),
- "server": to_native(server_name),
- "home_location": to_native(floating_ip.home_location.name),
- "labels": floating_ip.labels,
- "delete_protection": floating_ip.protection["delete"],
- })
-
- return tmp
-
- def get_floating_ips(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_floating_ip_info = [self.client.floating_ips.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("label_selector") is not None:
- self.hcloud_floating_ip_info = self.client.floating_ips.get_all(
- label_selector=self.module.params.get("label_selector"))
- else:
- self.hcloud_floating_ip_info = self.client.floating_ips.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudFloatingIPInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_floating_ip_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_floating_ip_facts' module has been renamed to 'hcloud_floating_ip_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudFloatingIPInfo(module)
-
- hcloud.get_floating_ips()
- result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_floating_ip_facts': result['hcloud_floating_ip_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_floating_ip_info': result['hcloud_floating_ip_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py
deleted file mode 100644
index 8acd8846a..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py
+++ /dev/null
@@ -1,219 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_image_info
-
-short_description: Gather infos about your Hetzner Cloud images.
-
-
-description:
- - Gather infos about your Hetzner Cloud images.
- - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
- Note that the M(hetzner.hcloud.hcloud_image_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_image_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the image you want to get.
- type: int
- name:
- description:
- - The name of the image you want to get.
- type: str
- label_selector:
- description:
- - The label selector for the images you want to get.
- type: str
- type:
- description:
- - The type for the images you want to get.
- default: system
- choices: [ system, snapshot, backup ]
- type: str
- architecture:
- description:
- - The architecture for the images you want to get.
- type: str
- choices: [ x86, arm ]
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud image infos
- hcloud_image_info:
- register: output
-
-- name: Print the gathered infos
- debug:
- var: output
-"""
-
-RETURN = """
-hcloud_image_info:
- description: The image infos as list
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the image
- returned: always
- type: int
- sample: 1937415
- type:
- description: Type of the image
- returned: always
- type: str
- sample: system
- status:
- description: Status of the image
- returned: always
- type: str
- sample: available
- name:
- description: Name of the image
- returned: always
- type: str
- sample: ubuntu-18.04
- description:
- description: Detail description of the image
- returned: always
- type: str
- sample: Ubuntu 18.04 Standard 64 bit
- os_flavor:
- description: OS flavor of the image
- returned: always
- type: str
- sample: ubuntu
- os_version:
- description: OS version of the image
- returned: always
- type: str
- sample: 18.04
- architecture:
- description: Image is compatible with this architecture
- returned: always
- type: str
- sample: x86
- labels:
- description: User-defined labels (key-value pairs)
- returned: always
- type: dict
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudImageInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_image_info")
- self.hcloud_image_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for image in self.hcloud_image_info:
- if image is not None:
- tmp.append({
- "id": to_native(image.id),
- "status": to_native(image.status),
- "type": to_native(image.type),
- "name": to_native(image.name),
- "description": to_native(image.description),
- "os_flavor": to_native(image.os_flavor),
- "os_version": to_native(image.os_version),
- "architecture": to_native(image.architecture),
- "labels": image.labels,
- })
- return tmp
-
- def get_images(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_image_info = [self.client.images.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None and self.module.params.get("architecture") is not None:
- self.hcloud_image_info = [self.client.images.get_by_name_and_architecture(
- self.module.params.get("name"),
- self.module.params.get("architecture")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_image_info = [self.client.images.get_by_name(
- self.module.params.get("name")
- )]
- else:
- params = {}
- label_selector = self.module.params.get("label_selector")
- if label_selector:
- params["label_selector"] = label_selector
-
- image_type = self.module.params.get("type")
- if image_type:
- params["type"] = image_type
-
- architecture = self.module.params.get("architecture")
- if architecture:
- params["architecture"] = architecture
-
- self.hcloud_image_info = self.client.images.get_all(**params)
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- label_selector={"type": "str"},
- type={"choices": ["system", "snapshot", "backup"], "default": "system", "type": "str"},
- architecture={"choices": ["x86", "arm"], "type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudImageInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_image_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_image_facts' module has been renamed to 'hcloud_image_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudImageInfo(module)
- hcloud.get_images()
- result = hcloud.get_result()
-
- if is_old_facts:
- ansible_info = {
- 'hcloud_imagen_facts': result['hcloud_image_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_image_info': result['hcloud_image_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py
deleted file mode 100644
index 623c6ab68..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_location_info
-
-short_description: Gather infos about your Hetzner Cloud locations.
-
-
-description:
- - Gather infos about your Hetzner Cloud locations.
- - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
- Note that the M(hetzner.hcloud.hcloud_location_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_location_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the location you want to get.
- type: int
- name:
- description:
- - The name of the location you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud location infos
- hcloud_location_info:
- register: output
-
-- name: Print the gathered infos
- debug:
- var: output
-"""
-
-RETURN = """
-hcloud_location_info:
- description: The location infos as list
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the location
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the location
- returned: always
- type: str
- sample: fsn1
- description:
- description: Detail description of the location
- returned: always
- type: str
- sample: Falkenstein DC Park 1
- country:
- description: Country code of the location
- returned: always
- type: str
- sample: DE
- city:
- description: City of the location
- returned: always
- type: str
- sample: Falkenstein
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudLocationInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_location_info")
- self.hcloud_location_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for location in self.hcloud_location_info:
- if location is not None:
- tmp.append({
- "id": to_native(location.id),
- "name": to_native(location.name),
- "description": to_native(location.description),
- "city": to_native(location.city),
- "country": to_native(location.country)
- })
- return tmp
-
- def get_locations(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_location_info = [self.client.locations.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_location_info = [self.client.locations.get_by_name(
- self.module.params.get("name")
- )]
- else:
- self.hcloud_location_info = self.client.locations.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudLocationInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_location_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_location_info' module has been renamed to 'hcloud_location_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudLocationInfo(module)
- hcloud.get_locations()
- result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_location_facts': result['hcloud_location_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_location_info': result['hcloud_location_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py
deleted file mode 100644
index 102ceec0d..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_server_info
-
-short_description: Gather infos about your Hetzner Cloud servers.
-
-
-description:
- - Gather infos about your Hetzner Cloud servers.
- - This module was called C(hcloud_server_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_facts).
- Note that the M(hetzner.hcloud.hcloud_server_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the server you want to get.
- type: int
- name:
- description:
- - The name of the server you want to get.
- type: str
- label_selector:
- description:
- - The label selector for the server you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud server infos
- hcloud_server_info:
- register: output
-
-- name: Print the gathered infos
- debug:
- var: output.hcloud_server_info
-"""
-
-RETURN = """
-hcloud_server_info:
- description: The server infos as list
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the server
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the server
- returned: always
- type: str
- sample: my-server
- status:
- description: Status of the server
- returned: always
- type: str
- sample: running
- server_type:
- description: Name of the server type of the server
- returned: always
- type: str
- sample: cx11
- ipv4_address:
- description: Public IPv4 address of the server
- returned: always
- type: str
- sample: 116.203.104.109
- ipv6:
- description: IPv6 network of the server
- returned: always
- type: str
- 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']
- private_networks_info:
- description: List of private networks the server is attached to (dict with name and ip)
- returned: always
- type: list
- elements: dict
- sample: [{'name': 'my-network', 'ip': '192.168.1.1'}, {'name': 'another-network', 'ip': '10.185.50.40'}]
- location:
- description: Name of the location of the server
- returned: always
- type: str
- sample: fsn1
- placement_group:
- description: Placement Group of the server
- type: str
- returned: always
- sample: 4711
- version_added: "1.5.0"
- datacenter:
- description: Name of the datacenter of the server
- returned: always
- type: str
- sample: fsn1-dc14
- rescue_enabled:
- description: True if rescue mode is enabled, Server will then boot into rescue system on next reboot
- returned: always
- type: bool
- sample: false
- backup_window:
- description: Time window (UTC) in which the backup will run, or null if the backups are not enabled
- returned: always
- type: bool
- sample: 22-02
- labels:
- description: User-defined labels (key-value pairs)
- returned: always
- type: dict
- delete_protection:
- description: True if server is protected for deletion
- type: bool
- returned: always
- sample: false
- version_added: "0.1.0"
- rebuild_protection:
- description: True if server is protected for rebuild
- type: bool
- returned: always
- sample: false
- version_added: "0.1.0"
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudServerInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_server_info")
- self.hcloud_server_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for server in self.hcloud_server_info:
- if server is not None:
- image = None if server.image is None else to_native(server.image.name)
- placement_group = None if server.placement_group is None else to_native(server.placement_group.name)
- ipv4_address = None if server.public_net.ipv4 is None else to_native(server.public_net.ipv4.ip)
- ipv6 = None if server.public_net.ipv6 is None else to_native(server.public_net.ipv6.ip)
- backup_window = None if server.backup_window is None else to_native(server.backup_window)
- tmp.append({
- "id": to_native(server.id),
- "name": to_native(server.name),
- "ipv4_address": ipv4_address,
- "ipv6": ipv6,
- "private_networks": [to_native(net.network.name) for net in server.private_net],
- "private_networks_info": [{"name": to_native(net.network.name), "ip": net.ip} for net in server.private_net],
- "image": image,
- "server_type": to_native(server.server_type.name),
- "datacenter": to_native(server.datacenter.name),
- "location": to_native(server.datacenter.location.name),
- "placement_group": placement_group,
- "rescue_enabled": server.rescue_enabled,
- "backup_window": backup_window,
- "labels": server.labels,
- "status": to_native(server.status),
- "delete_protection": server.protection["delete"],
- "rebuild_protection": server.protection["rebuild"],
- })
- return tmp
-
- def get_servers(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_server_info = [self.client.servers.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_server_info = [self.client.servers.get_by_name(
- self.module.params.get("name")
- )]
- elif self.module.params.get("label_selector") is not None:
- self.hcloud_server_info = self.client.servers.get_all(
- label_selector=self.module.params.get("label_selector"))
- else:
- self.hcloud_server_info = self.client.servers.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudServerInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_server_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_server_facts' module has been renamed to 'hcloud_server_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudServerInfo(module)
- hcloud.get_servers()
- result = hcloud.get_result()
-
- if is_old_facts:
- ansible_info = {
- 'hcloud_server_facts': result['hcloud_server_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_server_info': result['hcloud_server_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py
deleted file mode 100644
index a84067c32..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_server_type_info
-
-short_description: Gather infos about the Hetzner Cloud server types.
-
-
-description:
- - Gather infos about your Hetzner Cloud server types.
- - This module was called C(hcloud_server_type_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_type_facts).
- Note that the M(hetzner.hcloud.hcloud_server_type_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_type_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the server type you want to get.
- type: int
- name:
- description:
- - The name of the server type you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud server type infos
- hcloud_server_type_info:
- register: output
-
-- name: Print the gathered infos
- debug:
- var: output.hcloud_server_type_info
-"""
-
-RETURN = """
-hcloud_server_type_info:
- description: The server type infos as list
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the server type
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the server type
- returned: always
- type: str
- sample: fsn1
- description:
- description: Detail description of the server type
- returned: always
- type: str
- sample: Falkenstein DC Park 1
- cores:
- description: Number of cpu cores a server of this type will have
- returned: always
- type: int
- sample: 1
- memory:
- description: Memory a server of this type will have in GB
- returned: always
- type: int
- sample: 1
- disk:
- description: Disk size a server of this type will have in GB
- returned: always
- type: int
- sample: 25
- storage_type:
- description: Type of server boot drive
- returned: always
- type: str
- sample: local
- cpu_type:
- description: Type of cpu
- returned: always
- type: str
- sample: shared
- architecture:
- description: Architecture of cpu
- returned: always
- type: str
- sample: x86
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudServerTypeInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_server_type_info")
- self.hcloud_server_type_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for server_type in self.hcloud_server_type_info:
- if server_type is not None:
- tmp.append({
- "id": to_native(server_type.id),
- "name": to_native(server_type.name),
- "description": to_native(server_type.description),
- "cores": server_type.cores,
- "memory": server_type.memory,
- "disk": server_type.disk,
- "storage_type": to_native(server_type.storage_type),
- "cpu_type": to_native(server_type.cpu_type),
- "architecture": to_native(server_type.architecture)
- })
- return tmp
-
- def get_server_types(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_server_type_info = [self.client.server_types.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_server_type_info = [self.client.server_types.get_by_name(
- self.module.params.get("name")
- )]
- else:
- self.hcloud_server_type_info = self.client.server_types.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudServerTypeInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_server_type_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_server_type_info' module has been renamed to 'hcloud_server_type_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudServerTypeInfo(module)
- hcloud.get_server_types()
- result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_server_type_info': result['hcloud_server_type_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_server_type_info': result['hcloud_server_type_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py
deleted file mode 100644
index a84067c32..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_server_type_info
-
-short_description: Gather infos about the Hetzner Cloud server types.
-
-
-description:
- - Gather infos about your Hetzner Cloud server types.
- - This module was called C(hcloud_server_type_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_type_facts).
- Note that the M(hetzner.hcloud.hcloud_server_type_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_type_info)!
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the server type you want to get.
- type: int
- name:
- description:
- - The name of the server type you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud server type infos
- hcloud_server_type_info:
- register: output
-
-- name: Print the gathered infos
- debug:
- var: output.hcloud_server_type_info
-"""
-
-RETURN = """
-hcloud_server_type_info:
- description: The server type infos as list
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the server type
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the server type
- returned: always
- type: str
- sample: fsn1
- description:
- description: Detail description of the server type
- returned: always
- type: str
- sample: Falkenstein DC Park 1
- cores:
- description: Number of cpu cores a server of this type will have
- returned: always
- type: int
- sample: 1
- memory:
- description: Memory a server of this type will have in GB
- returned: always
- type: int
- sample: 1
- disk:
- description: Disk size a server of this type will have in GB
- returned: always
- type: int
- sample: 25
- storage_type:
- description: Type of server boot drive
- returned: always
- type: str
- sample: local
- cpu_type:
- description: Type of cpu
- returned: always
- type: str
- sample: shared
- architecture:
- description: Architecture of cpu
- returned: always
- type: str
- sample: x86
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudServerTypeInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_server_type_info")
- self.hcloud_server_type_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for server_type in self.hcloud_server_type_info:
- if server_type is not None:
- tmp.append({
- "id": to_native(server_type.id),
- "name": to_native(server_type.name),
- "description": to_native(server_type.description),
- "cores": server_type.cores,
- "memory": server_type.memory,
- "disk": server_type.disk,
- "storage_type": to_native(server_type.storage_type),
- "cpu_type": to_native(server_type.cpu_type),
- "architecture": to_native(server_type.architecture)
- })
- return tmp
-
- def get_server_types(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_server_type_info = [self.client.server_types.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_server_type_info = [self.client.server_types.get_by_name(
- self.module.params.get("name")
- )]
- else:
- self.hcloud_server_type_info = self.client.server_types.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudServerTypeInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_server_type_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_server_type_info' module has been renamed to 'hcloud_server_type_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudServerTypeInfo(module)
- hcloud.get_server_types()
- result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_server_type_info': result['hcloud_server_type_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_server_type_info': result['hcloud_server_type_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py
deleted file mode 100644
index aab98ed60..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_ssh_key_info
-short_description: Gather infos about your Hetzner Cloud ssh_keys.
-description:
- - Gather facts about your Hetzner Cloud ssh_keys.
- - This module was called C(hcloud_ssh_key_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_ssh_key_facts).
- Note that the M(hetzner.hcloud.hcloud_ssh_key_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_ssh_key_info)!
-author:
- - Christopher Schmitt (@cschmitt-hcloud)
-options:
- id:
- description:
- - The ID of the ssh key you want to get.
- type: int
- name:
- description:
- - The name of the ssh key you want to get.
- type: str
- fingerprint:
- description:
- - The fingerprint of the ssh key you want to get.
- type: str
- label_selector:
- description:
- - The label selector for the ssh key you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud sshkey infos
- hcloud_ssh_key_info:
- register: output
-- name: Print the gathered infos
- debug:
- var: output.hcloud_ssh_key_info
-"""
-
-RETURN = """
-hcloud_ssh_key_info:
- description: The ssh key instances
- returned: Always
- type: complex
- contains:
- id:
- description: Numeric identifier of the ssh_key
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the ssh_key
- returned: always
- type: str
- sample: my-ssh-key
- fingerprint:
- description: Fingerprint of the ssh key
- returned: always
- type: str
- sample: 0e:e0:bd:c7:2d:1f:69:49:94:44:91:f1:19:fd:35:f3
- public_key:
- description: The actual public key
- returned: always
- type: str
- sample: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGpl/tnk74nnQJxxLAtutUApUZMRJxryKh7VXkNbd4g9 john@example.com"
- labels:
- description: User-defined labels (key-value pairs)
- returned: always
- type: dict
-"""
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudSSHKeyInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_ssh_key_info")
- self.hcloud_ssh_key_info = None
-
- def _prepare_result(self):
- ssh_keys = []
-
- for ssh_key in self.hcloud_ssh_key_info:
- if ssh_key:
- ssh_keys.append({
- "id": to_native(ssh_key.id),
- "name": to_native(ssh_key.name),
- "fingerprint": to_native(ssh_key.fingerprint),
- "public_key": to_native(ssh_key.public_key),
- "labels": ssh_key.labels
- })
- return ssh_keys
-
- def get_ssh_keys(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_name(
- self.module.params.get("name")
- )]
- elif self.module.params.get("fingerprint") is not None:
- self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_fingerprint(
- self.module.params.get("fingerprint")
- )]
- elif self.module.params.get("label_selector") is not None:
- self.hcloud_ssh_key_info = self.client.ssh_keys.get_all(
- label_selector=self.module.params.get("label_selector"))
- else:
- self.hcloud_ssh_key_info = self.client.ssh_keys.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- fingerprint={"type": "str"},
- label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudSSHKeyInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_ssh_key_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_ssh_key_facts' module has been renamed to 'hcloud_ssh_key_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudSSHKeyInfo(module)
- hcloud.get_ssh_keys()
- result = hcloud.get_result()
-
- if is_old_facts:
- ansible_info = {
- 'hcloud_ssh_key_facts': result['hcloud_ssh_key_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_ssh_key_info': result['hcloud_ssh_key_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py
deleted file mode 100644
index 9520bfa14..000000000
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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)
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-DOCUMENTATION = '''
----
-module: hcloud_volume_info
-
-short_description: Gather infos about your Hetzner Cloud Volumes.
-
-description:
- - Gather infos about your Hetzner Cloud Volumes.
-
-author:
- - Lukas Kaemmerling (@LKaemmerling)
-
-options:
- id:
- description:
- - The ID of the Volume you want to get.
- type: int
- name:
- description:
- - The name of the Volume you want to get.
- type: str
- label_selector:
- description:
- - The label selector for the Volume you want to get.
- type: str
-extends_documentation_fragment:
-- hetzner.hcloud.hcloud
-
-'''
-
-EXAMPLES = """
-- name: Gather hcloud Volume infos
- hcloud_volume_info:
- register: output
-- name: Print the gathered infos
- debug:
- var: output.hcloud_volume_info
-"""
-
-RETURN = """
-hcloud_volume_info:
- description: The Volume infos as list
- returned: always
- type: complex
- contains:
- id:
- description: Numeric identifier of the Volume
- returned: always
- type: int
- sample: 1937415
- name:
- description: Name of the Volume
- returned: always
- type: str
- sample: my-volume
- size:
- description: Size of the Volume
- returned: always
- type: str
- sample: 10
- linux_device:
- description: Path to the device that contains the Volume.
- returned: always
- type: str
- sample: /dev/disk/by-id/scsi-0HC_Volume_12345
- version_added: "0.1.0"
- location:
- description: Name of the location where the Volume resides in
- returned: always
- type: str
- sample: fsn1
- server:
- description: Name of the server where the Volume is attached to
- returned: always
- type: str
- sample: my-server
- delete_protection:
- description: True if the Volume is protected for deletion
- returned: always
- type: bool
- version_added: "0.1.0"
- labels:
- description: User-defined labels (key-value pairs)
- returned: always
- type: dict
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-
-
-class AnsibleHcloudVolumeInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_volume_info")
- self.hcloud_volume_info = None
-
- def _prepare_result(self):
- tmp = []
-
- for volume in self.hcloud_volume_info:
- if volume is not None:
- server_name = None
- if volume.server is not None:
- server_name = to_native(volume.server.name)
- tmp.append({
- "id": to_native(volume.id),
- "name": to_native(volume.name),
- "size": volume.size,
- "location": to_native(volume.location.name),
- "labels": volume.labels,
- "server": server_name,
- "linux_device": to_native(volume.linux_device),
- "delete_protection": volume.protection["delete"],
- })
-
- return tmp
-
- def get_volumes(self):
- try:
- if self.module.params.get("id") is not None:
- self.hcloud_volume_info = [self.client.volumes.get_by_id(
- self.module.params.get("id")
- )]
- elif self.module.params.get("name") is not None:
- self.hcloud_volume_info = [self.client.volumes.get_by_name(
- self.module.params.get("name")
- )]
- elif self.module.params.get("label_selector") is not None:
- self.hcloud_volume_info = self.client.volumes.get_all(
- label_selector=self.module.params.get("label_selector"))
- else:
- self.hcloud_volume_info = self.client.volumes.get_all()
-
- except Exception as e:
- self.module.fail_json(msg=e.message)
-
- @staticmethod
- def define_module():
- return AnsibleModule(
- argument_spec=dict(
- id={"type": "int"},
- name={"type": "str"},
- label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
- ),
- supports_check_mode=True,
- )
-
-
-def main():
- module = AnsibleHcloudVolumeInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_volume_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_volume_facts' module has been renamed to 'hcloud_volume_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudVolumeInfo(module)
-
- hcloud.get_volumes()
- result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_volume_facts': result['hcloud_volume_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_volume_info': result['hcloud_volume_info']
- }
- module.exit_json(**ansible_info)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py
index 8acd8846a..b0d7fc482 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py
@@ -1,24 +1,20 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_image_info
+module: image_info
short_description: Gather infos about your Hetzner Cloud images.
description:
- Gather infos about your Hetzner Cloud images.
- - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
- Note that the M(hetzner.hcloud.hcloud_image_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_image_info)!
author:
- Lukas Kaemmerling (@LKaemmerling)
@@ -27,6 +23,7 @@ options:
id:
description:
- The ID of the image you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -50,11 +47,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud image infos
- hcloud_image_info:
+ hetzner.hcloud.image_info:
register: output
- name: Print the gathered infos
@@ -87,7 +84,7 @@ hcloud_image_info:
description: Name of the image
returned: always
type: str
- sample: ubuntu-18.04
+ sample: ubuntu-22.04
description:
description: Detail description of the image
returned: always
@@ -115,48 +112,54 @@ hcloud_image_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.images import BoundImage
-class AnsibleHcloudImageInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_image_info")
- self.hcloud_image_info = None
+class AnsibleHCloudImageInfo(AnsibleHCloud):
+ represent = "hcloud_image_info"
+
+ hcloud_image_info: list[BoundImage] | None = None
def _prepare_result(self):
tmp = []
for image in self.hcloud_image_info:
if image is not None:
- tmp.append({
- "id": to_native(image.id),
- "status": to_native(image.status),
- "type": to_native(image.type),
- "name": to_native(image.name),
- "description": to_native(image.description),
- "os_flavor": to_native(image.os_flavor),
- "os_version": to_native(image.os_version),
- "architecture": to_native(image.architecture),
- "labels": image.labels,
- })
+ tmp.append(
+ {
+ "id": to_native(image.id),
+ "status": to_native(image.status),
+ "type": to_native(image.type),
+ "name": to_native(image.name),
+ "description": to_native(image.description),
+ "os_flavor": to_native(image.os_flavor),
+ "os_version": to_native(image.os_version),
+ "architecture": to_native(image.architecture),
+ "labels": image.labels,
+ }
+ )
return tmp
def get_images(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_image_info = [self.client.images.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_image_info = [self.client.images.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None and self.module.params.get("architecture") is not None:
- self.hcloud_image_info = [self.client.images.get_by_name_and_architecture(
- self.module.params.get("name"),
- self.module.params.get("architecture")
- )]
+ self.hcloud_image_info = [
+ self.client.images.get_by_name_and_architecture(
+ self.module.params.get("name"),
+ self.module.params.get("architecture"),
+ )
+ ]
elif self.module.params.get("name") is not None:
- self.hcloud_image_info = [self.client.images.get_by_name(
- self.module.params.get("name")
- )]
+ self.module.warn(
+ "This module only returns x86 images by default. Please set architecture:x86|arm to hide this message."
+ )
+ self.hcloud_image_info = [self.client.images.get_by_name(self.module.params.get("name"))]
else:
params = {}
label_selector = self.module.params.get("label_selector")
@@ -173,11 +176,11 @@ class AnsibleHcloudImageInfo(Hcloud):
self.hcloud_image_info = self.client.images.get_all(**params)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -185,34 +188,21 @@ class AnsibleHcloudImageInfo(Hcloud):
label_selector={"type": "str"},
type={"choices": ["system", "snapshot", "backup"], "default": "system", "type": "str"},
architecture={"choices": ["x86", "arm"], "type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudImageInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_image_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_image_facts' module has been renamed to 'hcloud_image_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+ module = AnsibleHCloudImageInfo.define_module()
+ hcloud = AnsibleHCloudImageInfo(module)
- hcloud = AnsibleHcloudImageInfo(module)
hcloud.get_images()
result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_imagen_facts': result['hcloud_image_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_image_info': result['hcloud_image_info']
- }
- module.exit_json(**ansible_info)
+ ansible_info = {"hcloud_image_info": result["hcloud_image_info"]}
+ module.exit_json(**ansible_info)
if __name__ == "__main__":
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py
new file mode 100644
index 000000000..e623d1714
--- /dev/null
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py
@@ -0,0 +1,206 @@
+#!/usr/bin/python
+
+# Copyright: (c) 2022, Patrice Le Guyader
+# heavily inspired by the work of @LKaemmerling
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+
+from __future__ import annotations
+
+DOCUMENTATION = """
+---
+module: iso_info
+
+short_description: Gather infos about the Hetzner Cloud ISO list.
+
+description:
+ - Gather infos about the Hetzner Cloud ISO list.
+
+author:
+ - Patrice Le Guyader (@patlegu)
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the ISO image you want to get.
+ - The module will fail if the provided ID is invalid.
+ type: int
+ name:
+ description:
+ - The name of the ISO you want to get.
+ type: str
+ architecture:
+ description:
+ - Filter ISOs with compatible architecture.
+ type: str
+ choices: [x86, arm]
+ include_architecture_wildcard:
+ description:
+ - Include ISOs with wildcard architecture (architecture is null).
+ - Works only if architecture filter is specified.
+ type: bool
+
+extends_documentation_fragment:
+ - hetzner.hcloud.hcloud
+"""
+
+EXAMPLES = """
+- name: Gather hcloud ISO type infos
+ hetzner.hcloud.iso_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_iso_info
+"""
+
+RETURN = """
+hcloud_iso_info:
+ description: The ISO type infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: ID of the ISO
+ returned: always
+ type: int
+ sample: 22110
+ name:
+ description: Unique identifier of the ISO. Only set for public ISOs
+ returned: always
+ type: str
+ sample: debian-12.0.0-amd64-netinst.iso
+ description:
+ description: Description of the ISO
+ returned: always
+ type: str
+ sample: Debian 12.0 (amd64/netinstall)
+ architecture:
+ description: >
+ Type of cpu architecture this ISO is compatible with.
+ None indicates no restriction on the architecture (wildcard).
+ returned: when supported
+ type: str
+ sample: x86
+ type:
+ description: Type of the ISO, can be one of `public`, `private`.
+ returned: always
+ type: str
+ sample: public
+ deprecated:
+ description: >
+ ISO 8601 timestamp of deprecation, None if ISO is still available.
+ After the deprecation time it will no longer be possible to attach the
+ ISO to servers. This field is deprecated. Use `deprecation` instead.
+ returned: always
+ type: str
+ sample: "2024-12-01T00:00:00+00:00"
+ deprecation:
+ description: >
+ Describes if, when & how the resources was deprecated. If this field is
+ set to None the resource is not deprecated. If it has a value, it is
+ considered deprecated.
+ returned: if the resource is deprecated
+ type: dict
+ contains:
+ announced:
+ description: Date of when the deprecation was announced.
+ returned: always
+ type: str
+ sample: "2021-11-01T00:00:00+00:00"
+ unavailable_after:
+ description: >
+ After the time in this field, the resource will not be available
+ from the general listing endpoint of the resource type, and it can
+ not be used in new resources. For example, if this is an image,
+ you can not create new servers with this image after the mentioned
+ date.
+ returned: always
+ type: str
+ sample: "2021-12-01T00:00:00+00:00"
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.isos import BoundIso
+
+
+class AnsibleHCloudIsoInfo(AnsibleHCloud):
+ represent = "hcloud_iso_info"
+
+ hcloud_iso_info: list[BoundIso] | None = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for iso_info in self.hcloud_iso_info:
+ if iso_info is None:
+ continue
+
+ tmp.append(
+ {
+ "id": to_native(iso_info.id),
+ "name": to_native(iso_info.name),
+ "description": to_native(iso_info.description),
+ "type": iso_info.type,
+ "architecture": iso_info.architecture,
+ "deprecated": (
+ iso_info.deprecation.unavailable_after if iso_info.deprecation is not None else None
+ ),
+ "deprecation": (
+ {
+ "announced": iso_info.deprecation.announced.isoformat(),
+ "unavailable_after": iso_info.deprecation.unavailable_after.isoformat(),
+ }
+ if iso_info.deprecation is not None
+ else None
+ ),
+ }
+ )
+
+ return tmp
+
+ def get_iso_infos(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_iso_info = [self.client.isos.get_by_id(self.module.params.get("id"))]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_iso_info = [self.client.isos.get_by_name(self.module.params.get("name"))]
+ else:
+ self.hcloud_iso_info = self.client.isos.get_all(
+ architecture=self.module.params.get("architecture"),
+ include_wildcard_architecture=self.module.params.get("include_wildcard_architecture"),
+ )
+
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
+ @classmethod
+ def define_module(cls):
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ architecture={"type": "str", "choices": ["x86", "arm"]},
+ include_architecture_wildcard={"type": "bool"},
+ **super().base_module_arguments(),
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHCloudIsoInfo.define_module()
+ hcloud = AnsibleHCloudIsoInfo(module)
+ hcloud.get_iso_infos()
+ result = hcloud.get_result()
+ ansible_info = {"hcloud_iso_info": result["hcloud_iso_info"]}
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py
index 9c6c2bbaf..1a0d8712a 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py
@@ -1,20 +1,17 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_load_balancer
+module: load_balancer
short_description: Create and manage cloud Load Balancers on the Hetzner Cloud.
-
description:
- Create, update and manage cloud Load Balancers on the Hetzner Cloud.
@@ -37,6 +34,12 @@ options:
- The Load Balancer Type of the Hetzner Cloud Load Balancer to manage.
- Required if Load Balancer does not exist.
type: str
+ algorithm:
+ description:
+ - Algorithm of the Load Balancer.
+ type: str
+ default: round_robin
+ choices: [round_robin, least_connections]
location:
description:
- Location of Load Balancer.
@@ -68,24 +71,21 @@ options:
type: str
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-requirements:
- - hcloud-python >= 1.8.0
-'''
+"""
EXAMPLES = """
- name: Create a basic Load Balancer
- hcloud_load_balancer:
+ hetzner.hcloud.load_balancer:
name: my-Load Balancer
load_balancer_type: lb11
+ algorithm: round_robin
location: fsn1
state: present
- name: Ensure the Load Balancer is absent (remove if needed)
- hcloud_load_balancer:
+ hetzner.hcloud.load_balancer:
name: my-Load Balancer
state: absent
-
"""
RETURN = """
@@ -114,6 +114,12 @@ hcloud_load_balancer:
returned: always
type: str
sample: cx11
+ algorithm:
+ description: Algorithm of the Load Balancer.
+ returned: always
+ type: str
+ choices: [round_robin, least_connections]
+ sample: round_robin
ipv4_address:
description: Public IPv4 address of the Load Balancer
returned: always
@@ -146,18 +152,27 @@ hcloud_load_balancer:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.load_balancers import (
+ BoundLoadBalancer,
+ LoadBalancerAlgorithm,
+)
-class AnsibleHcloudLoadBalancer(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_load_balancer")
- self.hcloud_load_balancer = None
+
+class AnsibleHCloudLoadBalancer(AnsibleHCloud):
+ represent = "hcloud_load_balancer"
+
+ hcloud_load_balancer: BoundLoadBalancer | None = None
def _prepare_result(self):
- private_ipv4_address = None if len(self.hcloud_load_balancer.private_net) == 0 else to_native(
- self.hcloud_load_balancer.private_net[0].ip)
+ private_ipv4_address = (
+ None
+ if len(self.hcloud_load_balancer.private_net) == 0
+ else to_native(self.hcloud_load_balancer.private_net[0].ip)
+ )
return {
"id": to_native(self.hcloud_load_balancer.id),
"name": to_native(self.hcloud_load_balancer.name),
@@ -165,6 +180,7 @@ class AnsibleHcloudLoadBalancer(Hcloud):
"ipv6_address": to_native(self.hcloud_load_balancer.public_net.ipv6.ip),
"private_ipv4_address": private_ipv4_address,
"load_balancer_type": to_native(self.hcloud_load_balancer.load_balancer_type.name),
+ "algorithm": to_native(self.hcloud_load_balancer.algorithm.type),
"location": to_native(self.hcloud_load_balancer.location.name),
"labels": self.hcloud_load_balancer.labels,
"delete_protection": self.hcloud_load_balancer.protection["delete"],
@@ -174,24 +190,18 @@ class AnsibleHcloudLoadBalancer(Hcloud):
def _get_load_balancer(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_load_balancer = self.client.load_balancers.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_load_balancer = self.client.load_balancers.get_by_id(self.module.params.get("id"))
else:
- self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
- self.module.params.get("name")
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_load_balancer = self.client.load_balancers.get_by_name(self.module.params.get("name"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_load_balancer(self):
-
- self.module.fail_on_missing_params(
- required_params=["name", "load_balancer_type"]
- )
+ self.module.fail_on_missing_params(required_params=["name", "load_balancer_type"])
try:
params = {
"name": self.module.params.get("name"),
+ "algorithm": LoadBalancerAlgorithm(type=self.module.params.get("algorithm", "round_robin")),
"load_balancer_type": self.client.load_balancer_types.get_by_name(
self.module.params.get("load_balancer_type")
),
@@ -201,9 +211,7 @@ class AnsibleHcloudLoadBalancer(Hcloud):
if self.module.params.get("location") is None and self.module.params.get("network_zone") is None:
self.module.fail_json(msg="one of the following is required: location, network_zone")
elif self.module.params.get("location") is not None and self.module.params.get("network_zone") is None:
- params["location"] = self.client.locations.get_by_name(
- self.module.params.get("location")
- )
+ params["location"] = self.client.locations.get_by_name(self.module.params.get("location"))
elif self.module.params.get("location") is None and self.module.params.get("network_zone") is not None:
params["network_zone"] = self.module.params.get("network_zone")
@@ -215,8 +223,8 @@ class AnsibleHcloudLoadBalancer(Hcloud):
if delete_protection is not None:
self._get_load_balancer()
self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_load_balancer()
@@ -236,7 +244,9 @@ class AnsibleHcloudLoadBalancer(Hcloud):
self._get_load_balancer()
disable_public_interface = self.module.params.get("disable_public_interface")
- if disable_public_interface is not None and disable_public_interface != (not self.hcloud_load_balancer.public_net.enabled):
+ if disable_public_interface is not None and disable_public_interface != (
+ not self.hcloud_load_balancer.public_net.enabled
+ ):
if not self.module.check_mode:
if disable_public_interface is True:
self.hcloud_load_balancer.disable_public_interface().wait_until_finished()
@@ -245,7 +255,10 @@ class AnsibleHcloudLoadBalancer(Hcloud):
self._mark_as_changed()
load_balancer_type = self.module.params.get("load_balancer_type")
- if load_balancer_type is not None and self.hcloud_load_balancer.load_balancer_type.name != load_balancer_type:
+ if (
+ load_balancer_type is not None
+ and self.hcloud_load_balancer.load_balancer_type.name != load_balancer_type
+ ):
new_load_balancer_type = self.client.load_balancer_types.get_by_name(load_balancer_type)
if not new_load_balancer_type:
self.module.fail_json(msg="unknown load balancer type")
@@ -255,9 +268,17 @@ class AnsibleHcloudLoadBalancer(Hcloud):
).wait_until_finished(max_retries=1000)
self._mark_as_changed()
+
+ algorithm = self.module.params.get("algorithm")
+ if algorithm is not None and self.hcloud_load_balancer.algorithm.type != algorithm:
+ self.hcloud_load_balancer.change_algorithm(
+ algorithm=LoadBalancerAlgorithm(type=algorithm)
+ ).wait_until_finished()
+ self._mark_as_changed()
+
self._get_load_balancer()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def present_load_balancer(self):
self._get_load_balancer()
@@ -274,16 +295,17 @@ class AnsibleHcloudLoadBalancer(Hcloud):
self.client.load_balancers.delete(self.hcloud_load_balancer)
self._mark_as_changed()
self.hcloud_load_balancer = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
load_balancer_type={"type": "str"},
+ algorithm={"choices": ["round_robin", "least_connections"], "default": "round_robin"},
location={"type": "str"},
network_zone={"type": "str"},
labels={"type": "dict"},
@@ -293,18 +315,18 @@ class AnsibleHcloudLoadBalancer(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
+ required_one_of=[["id", "name"]],
mutually_exclusive=[["location", "network_zone"]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudLoadBalancer.define_module()
+ module = AnsibleHCloudLoadBalancer.define_module()
- hcloud = AnsibleHcloudLoadBalancer(module)
+ hcloud = AnsibleHCloudLoadBalancer(module)
state = module.params.get("state")
if state == "absent":
hcloud.delete_load_balancer()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py
index 159dad258..19ead98c2 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_load_balancer_info
+module: load_balancer_info
short_description: Gather infos about your Hetzner Cloud Load Balancers.
@@ -25,6 +23,7 @@ options:
id:
description:
- The ID of the Load Balancers you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -37,11 +36,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud load_balancer infos
- hcloud_load_balancer_info:
+ hetzner.hcloud.load_balancer_info:
register: output
- name: Print the gathered infos
@@ -137,10 +136,27 @@ hcloud_load_balancer_info:
use_private_ip:
description:
- Route the traffic over the private IP of the Load Balancer through a Hetzner Cloud Network.
- - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.hcloud.hcloud_load_balancer_network)
+ - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.load_balancer_network)
type: bool
sample: true
returned: always
+ health_status:
+ description:
+ - List of health statuses of the services on this target. Only present for target types "server" and "ip".
+ type: list
+ returned: if I(type) is server or ip
+ contains:
+ listen_port:
+ description: Load Balancer Target listen port
+ type: int
+ returned: always
+ sample: 80
+ status:
+ description: Load Balancer Target status
+ type: str
+ choices: [healthy, unhealthy, unknown]
+ returned: always
+ sample: healthy
services:
description: all services from this Load Balancer
returned: Always
@@ -261,14 +277,17 @@ hcloud_load_balancer_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.load_balancers import BoundLoadBalancer
+
+class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud):
+ represent = "hcloud_load_balancer_info"
-class AnsibleHcloudLoadBalancerInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_load_balancer_info")
- self.hcloud_load_balancer_info = None
+ hcloud_load_balancer_info: list[BoundLoadBalancer] | None = None
def _prepare_result(self):
tmp = []
@@ -278,22 +297,25 @@ class AnsibleHcloudLoadBalancerInfo(Hcloud):
services = [self._prepare_service_result(service) for service in load_balancer.services]
targets = [self._prepare_target_result(target) for target in load_balancer.targets]
- private_ipv4_address = None if len(load_balancer.private_net) == 0 else to_native(
- load_balancer.private_net[0].ip)
- tmp.append({
- "id": to_native(load_balancer.id),
- "name": to_native(load_balancer.name),
- "ipv4_address": to_native(load_balancer.public_net.ipv4.ip),
- "ipv6_address": to_native(load_balancer.public_net.ipv6.ip),
- "private_ipv4_address": private_ipv4_address,
- "load_balancer_type": to_native(load_balancer.load_balancer_type.name),
- "location": to_native(load_balancer.location.name),
- "labels": load_balancer.labels,
- "delete_protection": load_balancer.protection["delete"],
- "disable_public_interface": False if load_balancer.public_net.enabled else True,
- "targets": targets,
- "services": services
- })
+ private_ipv4_address = (
+ None if len(load_balancer.private_net) == 0 else to_native(load_balancer.private_net[0].ip)
+ )
+ tmp.append(
+ {
+ "id": to_native(load_balancer.id),
+ "name": to_native(load_balancer.name),
+ "ipv4_address": to_native(load_balancer.public_net.ipv4.ip),
+ "ipv6_address": to_native(load_balancer.public_net.ipv6.ip),
+ "private_ipv4_address": private_ipv4_address,
+ "load_balancer_type": to_native(load_balancer.load_balancer_type.name),
+ "location": to_native(load_balancer.location.name),
+ "labels": load_balancer.labels,
+ "delete_protection": load_balancer.protection["delete"],
+ "disable_public_interface": False if load_balancer.public_net.enabled else True,
+ "targets": targets,
+ "services": services,
+ }
+ )
return tmp
@staticmethod
@@ -305,8 +327,7 @@ class AnsibleHcloudLoadBalancerInfo(Hcloud):
"cookie_lifetime": service.http.cookie_name,
"redirect_http": service.http.redirect_http,
"sticky_sessions": service.http.sticky_sessions,
- "certificates": [to_native(certificate.name) for certificate in
- service.http.certificates],
+ "certificates": [to_native(certificate.name) for certificate in service.http.certificates],
}
health_check = {
"protocol": to_native(service.health_check.protocol),
@@ -320,8 +341,7 @@ class AnsibleHcloudLoadBalancerInfo(Hcloud):
"domain": to_native(service.health_check.http.domain),
"path": to_native(service.health_check.http.path),
"response": to_native(service.health_check.http.response),
- "certificates": [to_native(status_code) for status_code in
- service.health_check.http.status_codes],
+ "certificates": [to_native(status_code) for status_code in service.health_check.http.status_codes],
"tls": service.health_check.http.tls,
}
return {
@@ -337,7 +357,7 @@ class AnsibleHcloudLoadBalancerInfo(Hcloud):
def _prepare_target_result(target):
result = {
"type": to_native(target.type),
- "use_private_ip": target.use_private_ip
+ "use_private_ip": target.use_private_ip,
}
if target.type == "server":
result["server"] = to_native(target.server.name)
@@ -345,18 +365,26 @@ class AnsibleHcloudLoadBalancerInfo(Hcloud):
result["label_selector"] = to_native(target.label_selector.selector)
elif target.type == "ip":
result["ip"] = to_native(target.ip.ip)
+
+ if target.health_status is not None:
+ result["health_status"] = [
+ {
+ "listen_port": item.listen_port,
+ "status": item.status,
+ }
+ for item in target.health_status
+ ]
+
return result
def get_load_balancers(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_load_balancer_info = [self.client.load_balancers.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_load_balancer_info = [self.client.load_balancers.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None:
- self.hcloud_load_balancer_info = [self.client.load_balancers.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_load_balancer_info = [
+ self.client.load_balancers.get_by_name(self.module.params.get("name"))
+ ]
else:
params = {}
label_selector = self.module.params.get("label_selector")
@@ -365,32 +393,30 @@ class AnsibleHcloudLoadBalancerInfo(Hcloud):
self.hcloud_load_balancer_info = self.client.load_balancers.get_all(**params)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudLoadBalancerInfo.define_module()
+ module = AnsibleHCloudLoadBalancerInfo.define_module()
+ hcloud = AnsibleHCloudLoadBalancerInfo(module)
- hcloud = AnsibleHcloudLoadBalancerInfo(module)
hcloud.get_load_balancers()
result = hcloud.get_result()
- ansible_info = {
- 'hcloud_load_balancer_info': result['hcloud_load_balancer_info']
- }
+ ansible_info = {"hcloud_load_balancer_info": result["hcloud_load_balancer_info"]}
module.exit_json(**ansible_info)
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_network.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py
index 63a7c5471..4560f8735 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_network.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_load_balancer_network
+module: load_balancer_network
short_description: Manage the relationship between Hetzner Cloud Networks and Load Balancers
@@ -24,12 +22,12 @@ version_added: 0.1.0
options:
network:
description:
- - The name of the Hetzner Cloud Networks.
+ - Name or ID of the Hetzner Cloud Networks.
type: str
required: true
load_balancer:
description:
- - The name of the Hetzner Cloud Load Balancer.
+ - Name or ID of the Hetzner Cloud Load Balancer.
type: str
required: true
ip:
@@ -43,30 +41,26 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.8.1
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a basic Load Balancer network
- hcloud_load_balancer_network:
+ hetzner.hcloud.load_balancer_network:
network: my-network
load_balancer: my-LoadBalancer
state: present
- name: Create a Load Balancer network and specify the ip address
- hcloud_load_balancer_network:
+ hetzner.hcloud.load_balancer_network:
network: my-network
load_balancer: my-LoadBalancer
ip: 10.0.0.1
state: present
- name: Ensure the Load Balancer network is absent (remove if needed)
- hcloud_load_balancer_network:
+ hetzner.hcloud.load_balancer_network:
network: my-network
load_balancer: my-LoadBalancer
state: absent
@@ -96,16 +90,20 @@ hcloud_load_balancer_network:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.load_balancers import BoundLoadBalancer, PrivateNet
+from ..module_utils.vendor.hcloud.networks import BoundNetwork
-class AnsibleHcloudLoadBalancerNetwork(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_load_balancer_network")
- self.hcloud_network = None
- self.hcloud_load_balancer = None
- self.hcloud_load_balancer_network = None
+
+class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud):
+ represent = "hcloud_load_balancer_network"
+
+ hcloud_network: BoundNetwork | None = None
+ hcloud_load_balancer: BoundLoadBalancer | None = None
+ hcloud_load_balancer_network: PrivateNet | None = None
def _prepare_result(self):
return {
@@ -116,31 +114,26 @@ class AnsibleHcloudLoadBalancerNetwork(Hcloud):
def _get_load_balancer_and_network(self):
try:
- network = self.module.params.get("network")
- self.hcloud_network = self.client.networks.get_by_name(network)
- if not self.hcloud_network:
- self.module.fail_json(msg="Network does not exist: %s" % network)
-
- load_balancer_name = self.module.params.get("load_balancer")
- self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
- load_balancer_name
+ self.hcloud_network = self._client_get_by_name_or_id(
+ "networks",
+ self.module.params.get("network"),
+ )
+ self.hcloud_load_balancer = self._client_get_by_name_or_id(
+ "load_balancers",
+ self.module.params.get("load_balancer"),
)
- if not self.hcloud_load_balancer:
- self.module.fail_json(msg="Load balancer does not exist: %s" % load_balancer_name)
self.hcloud_load_balancer_network = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _get_load_balancer_network(self):
- for privateNet in self.hcloud_load_balancer.private_net:
- if privateNet.network.id == self.hcloud_network.id:
- self.hcloud_load_balancer_network = privateNet
+ for private_net in self.hcloud_load_balancer.private_net:
+ if private_net.network.id == self.hcloud_network.id:
+ self.hcloud_load_balancer_network = private_net
def _create_load_balancer_network(self):
- params = {
- "network": self.hcloud_network
- }
+ params = {"network": self.hcloud_network}
if self.module.params.get("ip") is not None:
params["ip"] = self.module.params.get("ip")
@@ -148,8 +141,8 @@ class AnsibleHcloudLoadBalancerNetwork(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_load_balancer.attach_to_network(**params).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_load_balancer_and_network()
@@ -168,15 +161,16 @@ class AnsibleHcloudLoadBalancerNetwork(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_load_balancer.detach_from_network(
- self.hcloud_load_balancer_network.network).wait_until_finished()
+ self.hcloud_load_balancer_network.network
+ ).wait_until_finished()
self._mark_as_changed()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self.hcloud_load_balancer_network = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
network={"type": "str", "required": True},
@@ -186,16 +180,16 @@ class AnsibleHcloudLoadBalancerNetwork(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudLoadBalancerNetwork.define_module()
+ module = AnsibleHCloudLoadBalancerNetwork.define_module()
- hcloud = AnsibleHcloudLoadBalancerNetwork(module)
+ hcloud = AnsibleHCloudLoadBalancerNetwork(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_load_balancer_network()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_service.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py
index b5edcc6b5..1fc18deef 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_service.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_load_balancer_service
+module: load_balancer_service
short_description: Create and manage the services of cloud Load Balancers on the Hetzner Cloud.
@@ -24,7 +22,7 @@ version_added: 0.1.0
options:
load_balancer:
description:
- - The Name of the Hetzner Cloud Load Balancer the service belongs to
+ - Name or ID of the Hetzner Cloud Load Balancer the service belongs to
type: str
required: true
listen_port:
@@ -137,21 +135,18 @@ options:
type: str
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-requirements:
- - hcloud-python >= 1.8.1
-'''
+"""
EXAMPLES = """
- name: Create a basic Load Balancer service with Port 80
- hcloud_load_balancer_service:
+ hetzner.hcloud.load_balancer_service:
load_balancer: my-load-balancer
protocol: http
listen_port: 80
state: present
- name: Ensure the Load Balancer is absent (remove if needed)
- hcloud_load_balancer_service:
+ hetzner.hcloud.load_balancer_service:
load_balancer: my-Load Balancer
protocol: http
listen_port: 80
@@ -284,22 +279,24 @@ hcloud_load_balancer_service:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import APIException, HCloudException
+from ..module_utils.vendor.hcloud.load_balancers import (
+ BoundLoadBalancer,
+ LoadBalancerHealtCheckHttp,
+ LoadBalancerHealthCheck,
+ LoadBalancerService,
+ LoadBalancerServiceHttp,
+)
-try:
- from hcloud.load_balancers.domain import LoadBalancerService, LoadBalancerServiceHttp, \
- LoadBalancerHealthCheck, LoadBalancerHealtCheckHttp
- from hcloud import APIException
-except ImportError:
- APIException = None
+class AnsibleHCloudLoadBalancerService(AnsibleHCloud):
+ represent = "hcloud_load_balancer_service"
-class AnsibleHcloudLoadBalancerService(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_load_balancer_service")
- self.hcloud_load_balancer = None
- self.hcloud_load_balancer_service = None
+ hcloud_load_balancer: BoundLoadBalancer | None = None
+ hcloud_load_balancer_service: LoadBalancerService | None = None
def _prepare_result(self):
http = None
@@ -309,8 +306,9 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
"cookie_lifetime": self.hcloud_load_balancer_service.http.cookie_name,
"redirect_http": self.hcloud_load_balancer_service.http.redirect_http,
"sticky_sessions": self.hcloud_load_balancer_service.http.sticky_sessions,
- "certificates": [to_native(certificate.name) for certificate in
- self.hcloud_load_balancer_service.http.certificates],
+ "certificates": [
+ to_native(certificate.name) for certificate in self.hcloud_load_balancer_service.http.certificates
+ ],
}
health_check = {
"protocol": to_native(self.hcloud_load_balancer_service.health_check.protocol),
@@ -324,8 +322,10 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
"domain": to_native(self.hcloud_load_balancer_service.health_check.http.domain),
"path": to_native(self.hcloud_load_balancer_service.health_check.http.path),
"response": to_native(self.hcloud_load_balancer_service.health_check.http.response),
- "certificates": [to_native(status_code) for status_code in
- self.hcloud_load_balancer_service.health_check.http.status_codes],
+ "status_codes": [
+ to_native(status_code)
+ for status_code in self.hcloud_load_balancer_service.health_check.http.status_codes
+ ],
"tls": self.hcloud_load_balancer_service.health_check.http.tls,
}
return {
@@ -340,31 +340,23 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
def _get_load_balancer(self):
try:
- load_balancer_name = self.module.params.get("load_balancer")
- self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
- load_balancer_name
+ self.hcloud_load_balancer = self._client_get_by_name_or_id(
+ "load_balancers",
+ self.module.params.get("load_balancer"),
)
- if not self.hcloud_load_balancer:
- self.module.fail_json(msg="Load balancer does not exist: %s" % load_balancer_name)
-
self._get_load_balancer_service()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_load_balancer_service(self):
-
- self.module.fail_on_missing_params(
- required_params=["protocol"]
- )
+ self.module.fail_on_missing_params(required_params=["protocol"])
if self.module.params.get("protocol") == "tcp":
- self.module.fail_on_missing_params(
- required_params=["destination_port"]
- )
+ self.module.fail_on_missing_params(required_params=["destination_port"])
params = {
"protocol": self.module.params.get("protocol"),
"listen_port": self.module.params.get("listen_port"),
- "proxyprotocol": self.module.params.get("proxyprotocol")
+ "proxyprotocol": self.module.params.get("proxyprotocol"),
}
if self.module.params.get("destination_port"):
@@ -375,14 +367,16 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
if self.module.params.get("health_check"):
params["health_check"] = self.__get_service_health_checks(
- health_check=self.module.params.get("health_check"))
+ health_check=self.module.params.get("health_check")
+ )
if not self.module.check_mode:
try:
self.hcloud_load_balancer.add_service(LoadBalancerService(**params)).wait_until_finished(
- max_retries=1000)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ max_retries=1000
+ )
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_load_balancer()
self._get_load_balancer_service()
@@ -404,15 +398,11 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
hcloud_cert = None
try:
try:
- hcloud_cert = self.client.certificates.get_by_name(
- certificate
- )
+ hcloud_cert = self.client.certificates.get_by_name(certificate)
except Exception:
- hcloud_cert = self.client.certificates.get_by_id(
- certificate
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ hcloud_cert = self.client.certificates.get_by_id(certificate)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
service_http.certificates.append(hcloud_cert)
return service_http
@@ -473,14 +463,16 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
if self.module.params.get("health_check") is not None:
params["health_check"] = self.__get_service_health_checks(
- health_check=self.module.params.get("health_check"))
+ health_check=self.module.params.get("health_check")
+ )
changed = True
if not self.module.check_mode:
self.hcloud_load_balancer.update_service(LoadBalancerService(**params)).wait_until_finished(
- max_retries=1000)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ max_retries=1000
+ )
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._get_load_balancer()
if changed:
@@ -505,16 +497,17 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service).wait_until_finished(
- max_retries=1000)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ max_retries=1000
+ )
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_load_balancer_service = None
- except APIException as e:
- self.module.fail_json(msg=e.message)
+ except APIException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
load_balancer={"type": "str", "required": True},
@@ -528,26 +521,12 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
http={
"type": "dict",
"options": dict(
- cookie_name={
- "type": "str"
- },
- cookie_lifetime={
- "type": "int"
- },
- sticky_sessions={
- "type": "bool",
- "default": False
- },
- redirect_http={
- "type": "bool",
- "default": False
- },
- certificates={
- "type": "list",
- "elements": "str"
- },
-
- )
+ cookie_name={"type": "str"},
+ cookie_lifetime={"type": "int"},
+ sticky_sessions={"type": "bool", "default": False},
+ redirect_http={"type": "bool", "default": False},
+ certificates={"type": "list", "elements": "str"},
+ ),
},
health_check={
"type": "dict",
@@ -556,57 +535,36 @@ class AnsibleHcloudLoadBalancerService(Hcloud):
"type": "str",
"choices": ["http", "https", "tcp"],
},
- port={
- "type": "int"
- },
- interval={
- "type": "int"
- },
- timeout={
- "type": "int"
- },
- retries={
- "type": "int"
- },
+ port={"type": "int"},
+ interval={"type": "int"},
+ timeout={"type": "int"},
+ retries={"type": "int"},
http={
"type": "dict",
"options": dict(
- domain={
- "type": "str"
- },
- path={
- "type": "str"
- },
- response={
- "type": "str"
- },
- status_codes={
- "type": "list",
- "elements": "str"
- },
- tls={
- "type": "bool",
- "default": False
- },
- )
- }
- )
-
+ domain={"type": "str"},
+ path={"type": "str"},
+ response={"type": "str"},
+ status_codes={"type": "list", "elements": "str"},
+ tls={"type": "bool", "default": False},
+ ),
+ },
+ ),
},
state={
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudLoadBalancerService.define_module()
+ module = AnsibleHCloudLoadBalancerService.define_module()
- hcloud = AnsibleHcloudLoadBalancerService(module)
+ hcloud = AnsibleHCloudLoadBalancerService(module)
state = module.params.get("state")
if state == "absent":
hcloud.delete_load_balancer_service()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_target.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py
index 760884466..36e7f608f 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_target.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_load_balancer_target
+module: load_balancer_target
short_description: Manage Hetzner Cloud Load Balancer targets
@@ -30,12 +28,12 @@ options:
required: true
load_balancer:
description:
- - The name of the Hetzner Cloud Load Balancer.
+ - Name or ID of the Hetzner Cloud Load Balancer.
type: str
required: true
server:
description:
- - The name of the Hetzner Cloud Server.
+ - Name or ID of the Hetzner Cloud Server.
- Required if I(type) is server
type: str
label_selector:
@@ -51,7 +49,7 @@ options:
use_private_ip:
description:
- Route the traffic over the private IP of the Load Balancer through a Hetzner Cloud Network.
- - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.hcloud.hcloud_load_balancer_network)
+ - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.load_balancer_network)
type: bool
default: False
state:
@@ -61,38 +59,34 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.8.1
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a server Load Balancer target
- hetzner.hcloud.hcloud_load_balancer_target:
+ hetzner.hcloud.load_balancer_target:
type: server
load_balancer: my-LoadBalancer
server: my-server
state: present
- name: Create a label_selector Load Balancer target
- hetzner.hcloud.hcloud_load_balancer_target:
+ hetzner.hcloud.load_balancer_target:
type: label_selector
load_balancer: my-LoadBalancer
label_selector: application=backend
state: present
- name: Create an IP Load Balancer target
- hetzner.hcloud.hcloud_load_balancer_target:
+ hetzner.hcloud.load_balancer_target:
type: ip
load_balancer: my-LoadBalancer
ip: 127.0.0.1
state: present
- name: Ensure the Load Balancer target is absent (remove if needed)
- hetzner.hcloud.hcloud_load_balancer_target:
+ hetzner.hcloud.load_balancer_target:
type: server
load_balancer: my-LoadBalancer
server: my-server
@@ -133,36 +127,38 @@ hcloud_load_balancer_target:
use_private_ip:
description:
- Route the traffic over the private IP of the Load Balancer through a Hetzner Cloud Network.
- - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.hcloud.hcloud_load_balancer_network)
+ - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.load_balancer_network)
type: bool
sample: true
returned: always
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
-try:
- from hcloud.load_balancers.domain import LoadBalancerTarget, LoadBalancerTargetLabelSelector, LoadBalancerTargetIP
-except ImportError:
- LoadBalancerTarget = None
- LoadBalancerTargetLabelSelector = None
- LoadBalancerTargetIP = None
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import APIException, HCloudException
+from ..module_utils.vendor.hcloud.load_balancers import (
+ BoundLoadBalancer,
+ LoadBalancerTarget,
+ LoadBalancerTargetIP,
+ LoadBalancerTargetLabelSelector,
+)
+from ..module_utils.vendor.hcloud.servers import BoundServer
-class AnsibleHcloudLoadBalancerTarget(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_load_balancer_target")
- self.hcloud_load_balancer = None
- self.hcloud_load_balancer_target = None
- self.hcloud_server = None
+class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud):
+ represent = "hcloud_load_balancer_target"
+
+ hcloud_load_balancer: BoundLoadBalancer | None = None
+ hcloud_load_balancer_target: LoadBalancerTarget | None = None
+ hcloud_server: BoundServer | None = None
def _prepare_result(self):
result = {
"type": to_native(self.hcloud_load_balancer_target.type),
"load_balancer": to_native(self.hcloud_load_balancer.name),
- "use_private_ip": self.hcloud_load_balancer_target.use_private_ip
+ "use_private_ip": self.hcloud_load_balancer_target.use_private_ip,
}
if self.hcloud_load_balancer_target.type == "server":
@@ -175,22 +171,20 @@ class AnsibleHcloudLoadBalancerTarget(Hcloud):
def _get_load_balancer_and_target(self):
try:
- load_balancer_name = self.module.params.get("load_balancer")
- self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
- load_balancer_name
+ self.hcloud_load_balancer = self._client_get_by_name_or_id(
+ "load_balancers",
+ self.module.params.get("load_balancer"),
)
- if not self.hcloud_load_balancer:
- self.module.fail_json(msg="Load balancer does not exist: %s" % load_balancer_name)
if self.module.params.get("type") == "server":
- server_name = self.module.params.get("server")
- self.hcloud_server = self.client.servers.get_by_name(server_name)
- if not self.hcloud_server:
- self.module.fail_json(msg="Server not found: %s" % server_name)
+ self.hcloud_server = self._client_get_by_name_or_id(
+ "servers",
+ self.module.params.get("server"),
+ )
self.hcloud_load_balancer_target = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _get_load_balancer_target(self):
for target in self.hcloud_load_balancer.targets:
@@ -205,40 +199,40 @@ class AnsibleHcloudLoadBalancerTarget(Hcloud):
self.hcloud_load_balancer_target = target
def _create_load_balancer_target(self):
- params = {
- "target": None
- }
+ params = {"target": None}
if self.module.params.get("type") == "server":
- self.module.fail_on_missing_params(
- required_params=["server"]
+ self.module.fail_on_missing_params(required_params=["server"])
+ params["target"] = LoadBalancerTarget(
+ type=self.module.params.get("type"),
+ server=self.hcloud_server,
+ use_private_ip=self.module.params.get("use_private_ip"),
)
- params["target"] = LoadBalancerTarget(type=self.module.params.get("type"), server=self.hcloud_server,
- use_private_ip=self.module.params.get("use_private_ip"))
elif self.module.params.get("type") == "label_selector":
- self.module.fail_on_missing_params(
- required_params=["label_selector"]
+ self.module.fail_on_missing_params(required_params=["label_selector"])
+ params["target"] = LoadBalancerTarget(
+ type=self.module.params.get("type"),
+ label_selector=LoadBalancerTargetLabelSelector(selector=self.module.params.get("label_selector")),
+ use_private_ip=self.module.params.get("use_private_ip"),
)
- params["target"] = LoadBalancerTarget(type=self.module.params.get("type"),
- label_selector=LoadBalancerTargetLabelSelector(
- selector=self.module.params.get("label_selector")),
- use_private_ip=self.module.params.get("use_private_ip"))
elif self.module.params.get("type") == "ip":
- self.module.fail_on_missing_params(
- required_params=["ip"]
+ self.module.fail_on_missing_params(required_params=["ip"])
+ params["target"] = LoadBalancerTarget(
+ type=self.module.params.get("type"),
+ ip=LoadBalancerTargetIP(ip=self.module.params.get("ip")),
+ use_private_ip=False,
)
- params["target"] = LoadBalancerTarget(type=self.module.params.get("type"),
- ip=LoadBalancerTargetIP(ip=self.module.params.get("ip")),
- use_private_ip=False)
if not self.module.check_mode:
try:
self.hcloud_load_balancer.add_target(**params).wait_until_finished()
- except Exception as e:
- if e.code == "locked" or e.code == "conflict":
+ except APIException as exception:
+ if exception.code == "locked" or exception.code == "conflict":
self._create_load_balancer_target()
else:
- self.module.fail_json(msg=e.message)
+ self.fail_json_hcloud(exception)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_load_balancer_and_target()
@@ -257,35 +251,33 @@ class AnsibleHcloudLoadBalancerTarget(Hcloud):
if not self.module.check_mode:
target = None
if self.module.params.get("type") == "server":
- self.module.fail_on_missing_params(
- required_params=["server"]
- )
- target = LoadBalancerTarget(type=self.module.params.get("type"),
- server=self.hcloud_server)
+ self.module.fail_on_missing_params(required_params=["server"])
+ target = LoadBalancerTarget(type=self.module.params.get("type"), server=self.hcloud_server)
elif self.module.params.get("type") == "label_selector":
- self.module.fail_on_missing_params(
- required_params=["label_selector"]
+ self.module.fail_on_missing_params(required_params=["label_selector"])
+ target = LoadBalancerTarget(
+ type=self.module.params.get("type"),
+ label_selector=LoadBalancerTargetLabelSelector(
+ selector=self.module.params.get("label_selector")
+ ),
+ use_private_ip=self.module.params.get("use_private_ip"),
)
- target = LoadBalancerTarget(type=self.module.params.get("type"),
- label_selector=LoadBalancerTargetLabelSelector(
- selector=self.module.params.get("label_selector")),
- use_private_ip=self.module.params.get("use_private_ip"))
elif self.module.params.get("type") == "ip":
- self.module.fail_on_missing_params(
- required_params=["ip"]
+ self.module.fail_on_missing_params(required_params=["ip"])
+ target = LoadBalancerTarget(
+ type=self.module.params.get("type"),
+ ip=LoadBalancerTargetIP(ip=self.module.params.get("ip")),
+ use_private_ip=False,
)
- target = LoadBalancerTarget(type=self.module.params.get("type"),
- ip=LoadBalancerTargetIP(ip=self.module.params.get("ip")),
- use_private_ip=False)
try:
self.hcloud_load_balancer.remove_target(target).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_load_balancer_target = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
type={"type": "str", "required": True, "choices": ["server", "label_selector", "ip"]},
@@ -298,16 +290,16 @@ class AnsibleHcloudLoadBalancerTarget(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudLoadBalancerTarget.define_module()
+ module = AnsibleHCloudLoadBalancerTarget.define_module()
- hcloud = AnsibleHcloudLoadBalancerTarget(module)
+ hcloud = AnsibleHCloudLoadBalancerTarget(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_load_balancer_target()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_type_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py
index a481ea9c9..67feafd59 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_type_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_load_balancer_type_info
+module: load_balancer_type_info
short_description: Gather infos about the Hetzner Cloud Load Balancer types.
@@ -25,6 +23,7 @@ options:
id:
description:
- The ID of the Load Balancer type you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -33,11 +32,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud Load Balancer type infos
- hcloud_load_balancer_type_info:
+ hetzner.hcloud.load_balancer_type_info:
register: output
- name: Print the gathered infos
@@ -89,68 +88,72 @@ hcloud_load_balancer_type_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.load_balancer_types import BoundLoadBalancerType
-class AnsibleHcloudLoadBalancerTypeInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_load_balancer_type_info")
- self.hcloud_load_balancer_type_info = None
+class AnsibleHCloudLoadBalancerTypeInfo(AnsibleHCloud):
+ represent = "hcloud_load_balancer_type_info"
+
+ hcloud_load_balancer_type_info: list[BoundLoadBalancerType] | None = None
def _prepare_result(self):
tmp = []
for load_balancer_type in self.hcloud_load_balancer_type_info:
if load_balancer_type is not None:
- tmp.append({
- "id": to_native(load_balancer_type.id),
- "name": to_native(load_balancer_type.name),
- "description": to_native(load_balancer_type.description),
- "max_connections": load_balancer_type.max_connections,
- "max_services": load_balancer_type.max_services,
- "max_targets": load_balancer_type.max_targets,
- "max_assigned_certificates": load_balancer_type.max_assigned_certificates
- })
+ tmp.append(
+ {
+ "id": to_native(load_balancer_type.id),
+ "name": to_native(load_balancer_type.name),
+ "description": to_native(load_balancer_type.description),
+ "max_connections": load_balancer_type.max_connections,
+ "max_services": load_balancer_type.max_services,
+ "max_targets": load_balancer_type.max_targets,
+ "max_assigned_certificates": load_balancer_type.max_assigned_certificates,
+ }
+ )
return tmp
def get_load_balancer_types(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_load_balancer_type_info = [self.client.load_balancer_types.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_load_balancer_type_info = [
+ self.client.load_balancer_types.get_by_id(self.module.params.get("id"))
+ ]
elif self.module.params.get("name") is not None:
- self.hcloud_load_balancer_type_info = [self.client.load_balancer_types.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_load_balancer_type_info = [
+ self.client.load_balancer_types.get_by_name(self.module.params.get("name"))
+ ]
else:
self.hcloud_load_balancer_type_info = self.client.load_balancer_types.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudLoadBalancerTypeInfo.define_module()
+ module = AnsibleHCloudLoadBalancerTypeInfo.define_module()
+ hcloud = AnsibleHCloudLoadBalancerTypeInfo(module)
- hcloud = AnsibleHcloudLoadBalancerTypeInfo(module)
hcloud.get_load_balancer_types()
result = hcloud.get_result()
- ansible_info = {
- 'hcloud_load_balancer_type_info': result['hcloud_load_balancer_type_info']
- }
+
+ ansible_info = {"hcloud_load_balancer_type_info": result["hcloud_load_balancer_type_info"]}
module.exit_json(**ansible_info)
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py
index 623c6ab68..ac495c6c8 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py
@@ -1,24 +1,20 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_location_info
+module: location_info
short_description: Gather infos about your Hetzner Cloud locations.
description:
- Gather infos about your Hetzner Cloud locations.
- - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
- Note that the M(hetzner.hcloud.hcloud_location_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_location_info)!
author:
- Lukas Kaemmerling (@LKaemmerling)
@@ -27,6 +23,7 @@ options:
id:
description:
- The ID of the location you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -35,11 +32,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud location infos
- hcloud_location_info:
+ hetzner.hcloud.location_info:
register: output
- name: Print the gathered infos
@@ -81,78 +78,67 @@ hcloud_location_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.locations import BoundLocation
+
+class AnsibleHCloudLocationInfo(AnsibleHCloud):
+ represent = "hcloud_location_info"
-class AnsibleHcloudLocationInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_location_info")
- self.hcloud_location_info = None
+ hcloud_location_info: list[BoundLocation] | None = None
def _prepare_result(self):
tmp = []
for location in self.hcloud_location_info:
if location is not None:
- tmp.append({
- "id": to_native(location.id),
- "name": to_native(location.name),
- "description": to_native(location.description),
- "city": to_native(location.city),
- "country": to_native(location.country)
- })
+ tmp.append(
+ {
+ "id": to_native(location.id),
+ "name": to_native(location.name),
+ "description": to_native(location.description),
+ "city": to_native(location.city),
+ "country": to_native(location.country),
+ }
+ )
return tmp
def get_locations(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_location_info = [self.client.locations.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_location_info = [self.client.locations.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None:
- self.hcloud_location_info = [self.client.locations.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_location_info = [self.client.locations.get_by_name(self.module.params.get("name"))]
else:
self.hcloud_location_info = self.client.locations.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudLocationInfo.define_module()
+ module = AnsibleHCloudLocationInfo.define_module()
+ hcloud = AnsibleHCloudLocationInfo(module)
- is_old_facts = module._name == 'hcloud_location_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_location_info' module has been renamed to 'hcloud_location_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudLocationInfo(module)
hcloud.get_locations()
result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_location_facts': result['hcloud_location_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_location_info': result['hcloud_location_info']
- }
- module.exit_json(**ansible_info)
+
+ ansible_info = {"hcloud_location_info": result["hcloud_location_info"]}
+ module.exit_json(**ansible_info)
if __name__ == "__main__":
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network.py b/ansible_collections/hetzner/hcloud/plugins/modules/network.py
index 9c005d29f..24e45a48d 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/network.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_network
+module: network
short_description: Create and manage cloud Networks on the Hetzner Cloud.
@@ -38,6 +36,11 @@ options:
- IP range of the Network.
- Required if Network does not exist.
type: str
+ expose_routes_to_vswitch:
+ description:
+ - Indicates if the routes from this network should be exposed to the vSwitch connection.
+ - The exposing only takes effect if a vSwitch connection is active.
+ type: bool
labels:
description:
- User-defined labels (key-value pairs).
@@ -53,23 +56,19 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.3.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a basic network
- hcloud_network:
+ hetzner.hcloud.network:
name: my-network
ip_range: 10.0.0.0/8
state: present
- name: Ensure the Network is absent (remove if needed)
- hcloud_network:
+ hetzner.hcloud.network:
name: my-network
state: absent
"""
@@ -95,6 +94,11 @@ hcloud_network:
type: str
returned: always
sample: 10.0.0.0/8
+ expose_routes_to_vswitch:
+ description: Indicates if the routes from this network should be exposed to the vSwitch connection.
+ type: bool
+ returned: always
+ sample: false
delete_protection:
description: True if Network is protected for deletion
type: bool
@@ -111,20 +115,24 @@ hcloud_network:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.networks import BoundNetwork
-class AnsibleHcloudNetwork(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_network")
- self.hcloud_network = None
+
+class AnsibleHCloudNetwork(AnsibleHCloud):
+ represent = "hcloud_network"
+
+ hcloud_network: BoundNetwork | None = None
def _prepare_result(self):
return {
"id": to_native(self.hcloud_network.id),
"name": to_native(self.hcloud_network.name),
"ip_range": to_native(self.hcloud_network.ip_range),
+ "expose_routes_to_vswitch": self.hcloud_network.expose_routes_to_vswitch,
"delete_protection": self.hcloud_network.protection["delete"],
"labels": self.hcloud_network.labels,
}
@@ -132,26 +140,24 @@ class AnsibleHcloudNetwork(Hcloud):
def _get_network(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_network = self.client.networks.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_network = self.client.networks.get_by_id(self.module.params.get("id"))
else:
- self.hcloud_network = self.client.networks.get_by_name(
- self.module.params.get("name")
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("name"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_network(self):
-
- self.module.fail_on_missing_params(
- required_params=["name", "ip_range"]
- )
+ self.module.fail_on_missing_params(required_params=["name", "ip_range"])
params = {
"name": self.module.params.get("name"),
"ip_range": self.module.params.get("ip_range"),
"labels": self.module.params.get("labels"),
}
+
+ expose_routes_to_vswitch = self.module.params.get("expose_routes_to_vswitch")
+ if expose_routes_to_vswitch is not None:
+ params["expose_routes_to_vswitch"] = expose_routes_to_vswitch
+
try:
if not self.module.check_mode:
self.client.networks.create(**params)
@@ -160,8 +166,8 @@ class AnsibleHcloudNetwork(Hcloud):
if delete_protection is not None:
self._get_network()
self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_network()
@@ -179,13 +185,22 @@ class AnsibleHcloudNetwork(Hcloud):
self.hcloud_network.change_ip_range(ip_range=ip_range).wait_until_finished()
self._mark_as_changed()
+ expose_routes_to_vswitch = self.module.params.get("expose_routes_to_vswitch")
+ if (
+ expose_routes_to_vswitch is not None
+ and expose_routes_to_vswitch != self.hcloud_network.expose_routes_to_vswitch
+ ):
+ if not self.module.check_mode:
+ self.hcloud_network.update(expose_routes_to_vswitch=expose_routes_to_vswitch)
+ self._mark_as_changed()
+
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None and delete_protection != self.hcloud_network.protection["delete"]:
if not self.module.check_mode:
self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished()
self._mark_as_changed()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._get_network()
def present_network(self):
@@ -202,34 +217,35 @@ class AnsibleHcloudNetwork(Hcloud):
if not self.module.check_mode:
self.client.networks.delete(self.hcloud_network)
self._mark_as_changed()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self.hcloud_network = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
ip_range={"type": "str"},
+ expose_routes_to_vswitch={"type": "bool"},
labels={"type": "dict"},
delete_protection={"type": "bool"},
state={
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
+ required_one_of=[["id", "name"]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudNetwork.define_module()
+ module = AnsibleHCloudNetwork.define_module()
- hcloud = AnsibleHcloudNetwork(module)
+ hcloud = AnsibleHCloudNetwork(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_network()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py
index 382e447aa..4008352b4 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_network_info
+module: network_info
short_description: Gather info about your Hetzner Cloud networks.
@@ -25,6 +23,7 @@ options:
id:
description:
- The ID of the network you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -37,7 +36,7 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud network info
@@ -110,6 +109,11 @@ hcloud_network_info:
returned: always
type: str
sample: 10.0.0.1
+ expose_routes_to_vswitch:
+ description: Indicates if the routes from this network should be exposed to the vSwitch connection.
+ returned: always
+ type: bool
+ sample: false
servers:
description: Servers attached to the network
returned: always
@@ -181,14 +185,17 @@ hcloud_network_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.networks import BoundNetwork
-class AnsibleHcloudNetworkInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_network_info")
- self.hcloud_network_info = None
+class AnsibleHCloudNetworkInfo(AnsibleHCloud):
+ represent = "hcloud_network_info"
+
+ hcloud_network_info: list[BoundNetwork] | None = None
def _prepare_result(self):
tmp = []
@@ -206,10 +213,7 @@ class AnsibleHcloudNetworkInfo(Hcloud):
subnets.append(prepared_subnet)
routes = []
for route in network.routes:
- prepared_route = {
- "destination": route.destination,
- "gateway": route.gateway
- }
+ prepared_route = {"destination": route.destination, "gateway": route.gateway}
routes.append(prepared_route)
servers = []
@@ -233,59 +237,58 @@ class AnsibleHcloudNetworkInfo(Hcloud):
}
servers.append(prepared_server)
- tmp.append({
- "id": to_native(network.id),
- "name": to_native(network.name),
- "ip_range": to_native(network.ip_range),
- "subnetworks": subnets,
- "routes": routes,
- "servers": servers,
- "labels": network.labels,
- "delete_protection": network.protection["delete"],
- })
+ tmp.append(
+ {
+ "id": to_native(network.id),
+ "name": to_native(network.name),
+ "ip_range": to_native(network.ip_range),
+ "subnetworks": subnets,
+ "routes": routes,
+ "expose_routes_to_vswitch": network.expose_routes_to_vswitch,
+ "servers": servers,
+ "labels": network.labels,
+ "delete_protection": network.protection["delete"],
+ }
+ )
return tmp
def get_networks(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_network_info = [self.client.networks.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_network_info = [self.client.networks.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None:
- self.hcloud_network_info = [self.client.networks.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_network_info = [self.client.networks.get_by_name(self.module.params.get("name"))]
elif self.module.params.get("label_selector") is not None:
self.hcloud_network_info = self.client.networks.get_all(
- label_selector=self.module.params.get("label_selector"))
+ label_selector=self.module.params.get("label_selector")
+ )
else:
self.hcloud_network_info = self.client.networks.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudNetworkInfo.define_module()
+ module = AnsibleHCloudNetworkInfo.define_module()
+ hcloud = AnsibleHCloudNetworkInfo(module)
- hcloud = AnsibleHcloudNetworkInfo(module)
hcloud.get_networks()
result = hcloud.get_result()
- info = {
- 'hcloud_network_info': result['hcloud_network_info']
- }
+
+ info = {"hcloud_network_info": result["hcloud_network_info"]}
module.exit_json(**info)
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_placement_group.py b/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py
index 522bb679d..ba26fad22 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_placement_group.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2020, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
DOCUMENTATION = """
---
-module: hcloud_placement_group
+module: placement_group
short_description: Create and manage placement groups on the Hetzner Cloud.
@@ -47,31 +45,28 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.15.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
"""
EXAMPLES = """
- name: Create a basic placement group
- hcloud_placement_group:
+ hetzner.hcloud.placement_group:
name: my-placement-group
state: present
type: spread
- name: Create a placement group with labels
- hcloud_placement_group:
+ hetzner.hcloud.placement_group:
name: my-placement-group
type: spread
labels:
- key: value
- mylabel: 123
+ key: value
+ mylabel: 123
state: present
- name: Ensure the placement group is absent (remove if needed)
- hcloud_placement_group:
+ hetzner.hcloud.placement_group:
name: my-placement-group
state: absent
"""
@@ -111,15 +106,18 @@ hcloud_placement_group:
- 4712
"""
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.placement_groups import BoundPlacementGroup
-class AnsibleHcloudPlacementGroup(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_placement_group")
- self.hcloud_placement_group = None
+
+class AnsibleHCloudPlacementGroup(AnsibleHCloud):
+ represent = "hcloud_placement_group"
+
+ hcloud_placement_group: BoundPlacementGroup | None = None
def _prepare_result(self):
return {
@@ -133,20 +131,14 @@ class AnsibleHcloudPlacementGroup(Hcloud):
def _get_placement_group(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_placement_group = self.client.placement_groups.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_placement_group = self.client.placement_groups.get_by_id(self.module.params.get("id"))
elif self.module.params.get("name") is not None:
- self.hcloud_placement_group = self.client.placement_groups.get_by_name(
- self.module.params.get("name")
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_placement_group = self.client.placement_groups.get_by_name(self.module.params.get("name"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_placement_group(self):
- self.module.fail_on_missing_params(
- required_params=["name"]
- )
+ self.module.fail_on_missing_params(required_params=["name"])
params = {
"name": self.module.params.get("name"),
"type": self.module.params.get("type"),
@@ -155,17 +147,15 @@ class AnsibleHcloudPlacementGroup(Hcloud):
if not self.module.check_mode:
try:
self.client.placement_groups.create(**params)
- except Exception as e:
- self.module.fail_json(msg=e.message, **params)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception, params=params)
self._mark_as_changed()
self._get_placement_group()
def _update_placement_group(self):
name = self.module.params.get("name")
if name is not None and self.hcloud_placement_group.name != name:
- self.module.fail_on_missing_params(
- required_params=["id"]
- )
+ self.module.fail_on_missing_params(required_params=["id"])
if not self.module.check_mode:
self.hcloud_placement_group.update(name=name)
self._mark_as_changed()
@@ -193,8 +183,8 @@ class AnsibleHcloudPlacementGroup(Hcloud):
self._mark_as_changed()
self.hcloud_placement_group = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -205,18 +195,18 @@ class AnsibleHcloudPlacementGroup(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
- required_if=[['state', 'present', ['name']]],
+ required_one_of=[["id", "name"]],
+ required_if=[["state", "present", ["name"]]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudPlacementGroup.define_module()
+ module = AnsibleHCloudPlacementGroup.define_module()
- hcloud = AnsibleHcloudPlacementGroup(module)
+ hcloud = AnsibleHCloudPlacementGroup(module)
state = module.params.get("state")
if state == "absent":
hcloud.delete_placement_group()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_primary_ip.py b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py
index c192d5fec..607f6c7e1 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_primary_ip.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_primary_ip
+module: primary_ip
short_description: Create and manage cloud Primary IPs on the Hetzner Cloud.
@@ -63,29 +61,25 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.9.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a basic IPv4 Primary IP
- hcloud_primary_ip:
+ hetzner.hcloud.primary_ip:
name: my-primary-ip
datacenter: fsn1-dc14
type: ipv4
state: present
- name: Create a basic IPv6 Primary IP
- hcloud_primary_ip:
+ hetzner.hcloud.primary_ip:
name: my-primary-ip
datacenter: fsn1-dc14
type: ipv6
state: present
- name: Primary IP should be absent
- hcloud_primary_ip:
+ hetzner.hcloud.primary_ip:
name: my-primary-ip
state: absent
"""
@@ -136,14 +130,17 @@ hcloud_primary_ip:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.primary_ips import BoundPrimaryIP
-class AnsibleHcloudPrimaryIP(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_primary_ip")
- self.hcloud_primary_ip = None
+
+class AnsibleHCloudPrimaryIP(AnsibleHCloud):
+ represent = "hcloud_primary_ip"
+
+ hcloud_primary_ip: BoundPrimaryIP | None = None
def _prepare_result(self):
return {
@@ -159,27 +156,19 @@ class AnsibleHcloudPrimaryIP(Hcloud):
def _get_primary_ip(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_primary_ip = self.client.primary_ips.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_primary_ip = self.client.primary_ips.get_by_id(self.module.params.get("id"))
else:
- self.hcloud_primary_ip = self.client.primary_ips.get_by_name(
- self.module.params.get("name")
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_primary_ip = self.client.primary_ips.get_by_name(self.module.params.get("name"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_primary_ip(self):
- self.module.fail_on_missing_params(
- required_params=["type", "datacenter"]
- )
+ self.module.fail_on_missing_params(required_params=["type", "datacenter"])
try:
params = {
"type": self.module.params.get("type"),
"name": self.module.params.get("name"),
- "datacenter": self.client.datacenters.get_by_name(
- self.module.params.get("datacenter")
- )
+ "datacenter": self.client.datacenters.get_by_name(self.module.params.get("datacenter")),
}
if self.module.params.get("labels") is not None:
@@ -191,8 +180,8 @@ class AnsibleHcloudPrimaryIP(Hcloud):
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None:
self.hcloud_primary_ip.change_protection(delete=delete_protection).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_primary_ip()
@@ -211,8 +200,8 @@ class AnsibleHcloudPrimaryIP(Hcloud):
self._mark_as_changed()
self._get_primary_ip()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def present_primary_ip(self):
self._get_primary_ip()
@@ -229,11 +218,11 @@ class AnsibleHcloudPrimaryIP(Hcloud):
self.client.primary_ips.delete(self.hcloud_primary_ip)
self._mark_as_changed()
self.hcloud_primary_ip = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -247,17 +236,17 @@ class AnsibleHcloudPrimaryIP(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
+ required_one_of=[["id", "name"]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudPrimaryIP.define_module()
+ module = AnsibleHCloudPrimaryIP.define_module()
- hcloud = AnsibleHcloudPrimaryIP(module)
+ hcloud = AnsibleHCloudPrimaryIP(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_primary_ip()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py
new file mode 100644
index 000000000..c0bfdbb35
--- /dev/null
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py
@@ -0,0 +1,203 @@
+#!/usr/bin/python
+
+# Copyright: (c) 2019, 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)
+
+
+from __future__ import annotations
+
+DOCUMENTATION = """
+---
+module: primary_ip_info
+
+short_description: Gather infos about the Hetzner Cloud Primary IPs.
+
+description:
+ - Gather facts about your Hetzner Cloud Primary IPs.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+ - Kevin Castner (@kcastner)
+
+options:
+ id:
+ description:
+ - The ID of the Primary IP you want to get.
+ - The module will fail if the provided ID is invalid.
+ type: int
+ name:
+ description:
+ - The name for the Primary IP you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the Primary IP you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+"""
+
+EXAMPLES = """
+- name: Gather hcloud Primary IP infos
+ hetzner.hcloud.primary_ip_info:
+ register: output
+
+- name: Gather hcloud Primary IP infos by id
+ hetzner.hcloud.primary_ip_info:
+ id: 673954
+ register: output
+
+- name: Gather hcloud Primary IP infos by name
+ hetzner.hcloud.primary_ip_info:
+ name: srv1-v4
+ register: output
+
+- name: Gather hcloud Primary IP infos by label
+ hetzner.hcloud.primary_ip_info:
+ label_selector: srv03-ips
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_primary_ip_info:
+ description: The Primary IP infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Primary IP
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Primary IP
+ returned: always
+ type: str
+ sample: my-primary-ip
+ ip:
+ description: IP address of the Primary IP
+ returned: always
+ type: str
+ sample: 131.232.99.1
+ type:
+ description: Type of the Primary IP
+ returned: always
+ type: str
+ sample: ipv4
+ assignee_id:
+ description: Numeric identifier of the ressource where the Primary IP is assigned to.
+ returned: always
+ type: int
+ sample: 19584637
+ assignee_type:
+ description: Name of the type where the Primary IP is assigned to.
+ returned: always
+ type: str
+ sample: server
+ home_location:
+ description: Location with datacenter where the Primary IP was created in
+ returned: always
+ type: str
+ sample: fsn1-dc1
+ dns_ptr:
+ description: Shows the DNS PTR Record for Primary IP.
+ returned: always
+ type: str
+ sample: srv01.example.com
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+ delete_protection:
+ description: True if the Primary IP is protected for deletion
+ returned: always
+ type: bool
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.primary_ips import BoundPrimaryIP
+
+
+class AnsibleHCloudPrimaryIPInfo(AnsibleHCloud):
+ represent = "hcloud_primary_ip_info"
+
+ hcloud_primary_ip_info: list[BoundPrimaryIP] | None = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for primary_ip in self.hcloud_primary_ip_info:
+ if primary_ip is not None:
+ dns_ptr = None
+ if len(primary_ip.dns_ptr) > 0:
+ dns_ptr = primary_ip.dns_ptr[0]["dns_ptr"]
+ tmp.append(
+ {
+ "id": to_native(primary_ip.id),
+ "name": to_native(primary_ip.name),
+ "ip": to_native(primary_ip.ip),
+ "type": to_native(primary_ip.type),
+ "assignee_id": (
+ to_native(primary_ip.assignee_id) if primary_ip.assignee_id is not None else None
+ ),
+ "assignee_type": to_native(primary_ip.assignee_type),
+ "home_location": to_native(primary_ip.datacenter.name),
+ "dns_ptr": to_native(dns_ptr) if dns_ptr is not None else None,
+ "labels": primary_ip.labels,
+ "delete_protection": primary_ip.protection["delete"],
+ }
+ )
+
+ return tmp
+
+ def get_primary_ips(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_primary_ip_info = [self.client.primary_ips.get_by_id(self.module.params.get("id"))]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_primary_ip_info = [self.client.primary_ips.get_by_name(self.module.params.get("name"))]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_primary_ip_info = self.client.primary_ips.get_all(
+ label_selector=self.module.params.get("label_selector")
+ )
+ else:
+ self.hcloud_primary_ip_info = self.client.primary_ips.get_all()
+
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
+ @classmethod
+ def define_module(cls):
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ label_selector={"type": "str"},
+ name={"type": "str"},
+ **super().base_module_arguments(),
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHCloudPrimaryIPInfo.define_module()
+ hcloud = AnsibleHCloudPrimaryIPInfo(module)
+
+ hcloud.get_primary_ips()
+ result = hcloud.get_result()
+
+ ansible_info = {"hcloud_primary_ip_info": result["hcloud_primary_ip_info"]}
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_rdns.py b/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py
index 9f79fbe70..b2decdec8 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_rdns.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_rdns
+module: rdns
short_description: Create and manage reverse DNS entries on the Hetzner Cloud.
@@ -24,19 +22,19 @@ author:
options:
server:
description:
- - The name of the Hetzner Cloud server you want to add the reverse DNS entry to.
+ - Name or ID of the Hetzner Cloud server you want to add the reverse DNS entry to.
type: str
floating_ip:
description:
- - The name of the Hetzner Cloud Floating IP you want to add the reverse DNS entry to.
+ - Name or ID of the Hetzner Cloud Floating IP you want to add the reverse DNS entry to.
type: str
primary_ip:
description:
- - The name of the Hetzner Cloud Primary IP you want to add the reverse DNS entry to.
+ - Name or ID of the Hetzner Cloud Primary IP you want to add the reverse DNS entry to.
type: str
load_balancer:
description:
- - The name of the Hetzner Cloud Load Balancer you want to add the reverse DNS entry to.
+ - Name or ID of the Hetzner Cloud Load Balancer you want to add the reverse DNS entry to.
type: str
ip_address:
description:
@@ -55,45 +53,41 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.3.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a reverse DNS entry for a server
- hcloud_rdns:
+ hetzner.hcloud.rdns:
server: my-server
ip_address: 123.123.123.123
dns_ptr: example.com
state: present
- name: Create a reverse DNS entry for a Floating IP
- hcloud_rdns:
+ hetzner.hcloud.rdns:
floating_ip: my-floating-ip
ip_address: 123.123.123.123
dns_ptr: example.com
state: present
- name: Create a reverse DNS entry for a Primary IP
- hcloud_rdns:
+ hetzner.hcloud.rdns:
primary_ip: my-primary-ip
ip_address: 123.123.123.123
dns_ptr: example.com
state: present
- name: Create a reverse DNS entry for a Load Balancer
- hcloud_rdns:
+ hetzner.hcloud.rdns:
load_balancer: my-load-balancer
ip_address: 123.123.123.123
dns_ptr: example.com
state: present
- name: Ensure the reverse DNS entry is absent (remove if needed)
- hcloud_rdns:
+ hetzner.hcloud.rdns:
server: my-server
ip_address: 123.123.123.123
dns_ptr: example.com
@@ -138,17 +132,25 @@ hcloud_rdns:
sample: example.com
"""
+import ipaddress
+from typing import Any
+
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.floating_ips import BoundFloatingIP
+from ..module_utils.vendor.hcloud.load_balancers import BoundLoadBalancer
+from ..module_utils.vendor.hcloud.primary_ips import BoundPrimaryIP
+from ..module_utils.vendor.hcloud.servers import BoundServer
-class AnsibleHcloudReverseDNS(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_rdns")
- self.hcloud_resource = None
- self.hcloud_rdns = None
+
+class AnsibleHCloudReverseDNS(AnsibleHCloud):
+ represent = "hcloud_rdns"
+
+ hcloud_resource: BoundServer | BoundFloatingIP | BoundLoadBalancer | BoundPrimaryIP | None = None
+ hcloud_rdns: dict[str, Any] | None = None
def _prepare_result(self):
result = {
@@ -172,35 +174,37 @@ class AnsibleHcloudReverseDNS(Hcloud):
def _get_resource(self):
try:
if self.module.params.get("server"):
- self.hcloud_resource = self.client.servers.get_by_name(
- self.module.params.get("server")
+ self.hcloud_resource = self._client_get_by_name_or_id(
+ "servers",
+ self.module.params.get("server"),
)
- if self.hcloud_resource is None:
- self.module.fail_json(msg="The selected server does not exist")
elif self.module.params.get("floating_ip"):
- self.hcloud_resource = self.client.floating_ips.get_by_name(
- self.module.params.get("floating_ip")
+ self.hcloud_resource = self._client_get_by_name_or_id(
+ "floating_ips",
+ self.module.params.get("floating_ip"),
)
- if self.hcloud_resource is None:
- self.module.fail_json(msg="The selected Floating IP does not exist")
elif self.module.params.get("primary_ip"):
- self.hcloud_resource = self.client.primary_ips.get_by_name(
- self.module.params.get("primary_ip")
+ self.hcloud_resource = self._client_get_by_name_or_id(
+ "primary_ips",
+ self.module.params.get("primary_ip"),
)
- if self.hcloud_resource is None:
- self.module.fail_json(msg="The selected Floating IP does not exist")
elif self.module.params.get("load_balancer"):
- self.hcloud_resource = self.client.load_balancers.get_by_name(
- self.module.params.get("load_balancer")
+ self.hcloud_resource = self._client_get_by_name_or_id(
+ "load_balancers",
+ self.module.params.get("load_balancer"),
)
- if self.hcloud_resource is None:
- self.module.fail_json(msg="The selected Load Balancer does not exist")
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _get_rdns(self):
ip_address = self.module.params.get("ip_address")
- if utils.validate_ip_address(ip_address):
+
+ try:
+ ip_address_obj = ipaddress.ip_address(ip_address)
+ except ValueError:
+ self.module.fail_json(msg=f"The given IP address is not valid: {ip_address}")
+
+ if ip_address_obj.version == 4:
if self.module.params.get("server"):
if self.hcloud_resource.public_net.ipv4.ip == ip_address:
self.hcloud_rdns = {
@@ -234,7 +238,7 @@ class AnsibleHcloudReverseDNS(Hcloud):
else:
self.module.fail_json(msg="The selected Load Balancer does not have this IP address")
- elif utils.validate_ip_v6_address(ip_address):
+ elif ip_address_obj.version == 6:
if self.module.params.get("server"):
for ipv6_address_dns_ptr in self.hcloud_resource.public_net.ipv6.dns_ptr:
if ipv6_address_dns_ptr["ip"] == ip_address:
@@ -263,13 +267,9 @@ class AnsibleHcloudReverseDNS(Hcloud):
"ip_address": ipv6_address_dns_ptr["ip"],
"dns_ptr": ipv6_address_dns_ptr["dns_ptr"],
}
- else:
- self.module.fail_json(msg="The given IP address is not valid")
def _create_rdns(self):
- self.module.fail_on_missing_params(
- required_params=["dns_ptr"]
- )
+ self.module.fail_on_missing_params(required_params=["dns_ptr"])
params = {
"ip": self.module.params.get("ip_address"),
"dns_ptr": self.module.params.get("dns_ptr"),
@@ -278,8 +278,8 @@ class AnsibleHcloudReverseDNS(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_resource.change_dns_ptr(**params).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_resource()
self._get_rdns()
@@ -295,8 +295,8 @@ class AnsibleHcloudReverseDNS(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_resource.change_dns_ptr(**params).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_resource()
self._get_rdns()
@@ -315,14 +315,14 @@ class AnsibleHcloudReverseDNS(Hcloud):
if self.hcloud_rdns is not None:
if not self.module.check_mode:
try:
- self.hcloud_resource.change_dns_ptr(ip=self.hcloud_rdns['ip_address'], dns_ptr=None)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_resource.change_dns_ptr(ip=self.hcloud_rdns["ip_address"], dns_ptr=None)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_rdns = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
server={"type": "str"},
@@ -335,18 +335,18 @@ class AnsibleHcloudReverseDNS(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['server', 'floating_ip', 'load_balancer', 'primary_ip']],
- mutually_exclusive=[["server", "floating_ip", 'load_balancer', 'primary_ip']],
+ required_one_of=[["server", "floating_ip", "load_balancer", "primary_ip"]],
+ mutually_exclusive=[["server", "floating_ip", "load_balancer", "primary_ip"]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudReverseDNS.define_module()
+ module = AnsibleHCloudReverseDNS.define_module()
- hcloud = AnsibleHcloudReverseDNS(module)
+ hcloud = AnsibleHCloudReverseDNS(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_rdns()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_route.py b/ansible_collections/hetzner/hcloud/plugins/modules/route.py
index c75177953..3c96a7382 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_route.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/route.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_route
+module: route
short_description: Create and delete cloud routes on the Hetzner Cloud.
@@ -24,7 +22,7 @@ author:
options:
network:
description:
- - The name of the Hetzner Cloud Network.
+ - Name or ID of the Hetzner Cloud Network.
type: str
required: true
destination:
@@ -44,24 +42,20 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.3.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a basic route
- hcloud_route:
+ hetzner.hcloud.route:
network: my-network
destination: 10.100.1.0/24
gateway: 10.0.1.1
state: present
- name: Ensure the route is absent
- hcloud_route:
+ hetzner.hcloud.route:
network: my-network
destination: 10.100.1.0/24
gateway: 10.0.1.1
@@ -92,20 +86,18 @@ hcloud_route:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
-try:
- from hcloud.networks.domain import NetworkRoute
-except ImportError:
- NetworkRoute = None
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.networks import BoundNetwork, NetworkRoute
-class AnsibleHcloudRoute(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_route")
- self.hcloud_network = None
- self.hcloud_route = None
+class AnsibleHCloudRoute(AnsibleHCloud):
+ represent = "hcloud_route"
+
+ hcloud_network: BoundNetwork | None = None
+ hcloud_route: NetworkRoute | None = None
def _prepare_result(self):
return {
@@ -116,10 +108,13 @@ class AnsibleHcloudRoute(Hcloud):
def _get_network(self):
try:
- self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
+ self.hcloud_network = self._client_get_by_name_or_id(
+ "networks",
+ self.module.params.get("network"),
+ )
self.hcloud_route = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _get_route(self):
destination = self.module.params.get("destination")
@@ -130,15 +125,14 @@ class AnsibleHcloudRoute(Hcloud):
def _create_route(self):
route = NetworkRoute(
- destination=self.module.params.get("destination"),
- gateway=self.module.params.get('gateway')
+ destination=self.module.params.get("destination"), gateway=self.module.params.get("gateway")
)
if not self.module.check_mode:
try:
self.hcloud_network.add_route(route=route).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_network()
@@ -157,13 +151,13 @@ class AnsibleHcloudRoute(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_network.delete_route(self.hcloud_route).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_route = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
network={"type": "str", "required": True},
@@ -173,16 +167,16 @@ class AnsibleHcloudRoute(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudRoute.define_module()
+ module = AnsibleHCloudRoute.define_module()
- hcloud = AnsibleHcloudRoute(module)
+ hcloud = AnsibleHCloudRoute(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_route()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server.py b/ansible_collections/hetzner/hcloud/plugins/modules/server.py
index 3a77da695..f5cadb807 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_server
+module: server
short_description: Create and manage cloud servers on the Hetzner Cloud.
@@ -67,7 +65,7 @@ options:
datacenter:
description:
- Datacenter of Server.
- - Required of no I(location) is given and server does not exist.
+ - Required if no I(location) is given and server does not exist.
type: str
backups:
description:
@@ -78,17 +76,17 @@ options:
- Resize the disk size, when resizing a server.
- If you want to downgrade the server later, this value should be False.
type: bool
- default: no
+ default: false
enable_ipv4:
description:
- Enables the public ipv4 address
type: bool
- default: yes
+ default: true
enable_ipv6:
description:
- Enables the public ipv6 address
type: bool
- default: yes
+ default: true
ipv4:
description:
- ID of the ipv4 Primary IP to use. If omitted and enable_ipv4 is true, a new ipv4 Primary IP will automatically be created
@@ -110,18 +108,17 @@ options:
- Force the upgrade of the server.
- Power off the server if it is running on upgrade.
type: bool
- default: no
force:
description:
- Force the update of the server.
- May power off the server if update.
type: bool
- default: no
+ default: false
allow_deprecated_image:
description:
- Allows the creation of servers with deprecated images.
type: bool
- default: no
+ default: false
user_data:
description:
- User Data to be passed to the server on creation.
@@ -158,80 +155,80 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Create a basic server
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
server_type: cx11
- image: ubuntu-18.04
+ image: ubuntu-22.04
state: present
- name: Create a basic server with ssh key
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
server_type: cx11
- image: ubuntu-18.04
+ image: ubuntu-22.04
location: fsn1
ssh_keys:
- me@myorganisation
state: present
- name: Resize an existing server
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
server_type: cx21
- upgrade_disk: yes
+ upgrade_disk: true
state: present
- name: Ensure the server is absent (remove if needed)
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
state: absent
- name: Ensure the server is started
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
state: started
- name: Ensure the server is stopped
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
state: stopped
- name: Ensure the server is restarted
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
state: restarted
- name: Ensure the server is will be booted in rescue mode and therefore restarted
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
rescue_mode: linux64
state: restarted
- name: Ensure the server is rebuild
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
- image: ubuntu-18.04
+ image: ubuntu-22.04
state: rebuild
- name: Add server to placement group
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
placement_group: my-placement-group
- force: True
+ force: true
state: present
- name: Remove server from placement group
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
- placement_group: null
+ placement_group:
state: present
- name: Add server with private network only
- hcloud_server:
+ hetzner.hcloud.server:
name: my-server
enable_ipv4: false
enable_ipv6: false
@@ -257,6 +254,11 @@ hcloud_server:
returned: always
type: str
sample: my-server
+ created:
+ description: Point in time when the Server was created (in ISO-8601 format)
+ returned: always
+ type: str
+ sample: "2023-11-06T13:36:56+00:00"
status:
description: Status of the server
returned: always
@@ -333,44 +335,50 @@ hcloud_server:
version_added: "0.1.0"
"""
+from datetime import datetime, timedelta, timezone
+
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
-from datetime import timedelta
-
-try:
- from hcloud.volumes.domain import Volume
- from hcloud.ssh_keys.domain import SSHKey
- from hcloud.servers.domain import Server, ServerCreatePublicNetwork
- from hcloud.firewalls.domain import FirewallResource
-except ImportError:
- Volume = None
- SSHKey = None
- Server = None
- ServerCreatePublicNetwork = None
- FirewallResource = None
-
-
-class AnsibleHcloudServer(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_server")
- self.hcloud_server = None
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.firewalls import FirewallResource
+from ..module_utils.vendor.hcloud.servers import (
+ BoundServer,
+ Server,
+ ServerCreatePublicNetwork,
+)
+from ..module_utils.vendor.hcloud.ssh_keys import SSHKey
+from ..module_utils.vendor.hcloud.volumes import Volume
+
+
+class AnsibleHCloudServer(AnsibleHCloud):
+ represent = "hcloud_server"
+
+ hcloud_server: BoundServer | None = None
def _prepare_result(self):
image = None if self.hcloud_server.image is None else to_native(self.hcloud_server.image.name)
- placement_group = None if self.hcloud_server.placement_group is None else to_native(
- self.hcloud_server.placement_group.name)
- ipv4_address = None if self.hcloud_server.public_net.ipv4 is None else to_native(
- self.hcloud_server.public_net.ipv4.ip)
+ placement_group = (
+ None if self.hcloud_server.placement_group is None else to_native(self.hcloud_server.placement_group.name)
+ )
+ ipv4_address = (
+ None if self.hcloud_server.public_net.ipv4 is None else to_native(self.hcloud_server.public_net.ipv4.ip)
+ )
ipv6 = None if self.hcloud_server.public_net.ipv6 is None else to_native(self.hcloud_server.public_net.ipv6.ip)
- backup_window = None if self.hcloud_server.backup_window is None else to_native(self.hcloud_server.backup_window)
+ backup_window = (
+ None if self.hcloud_server.backup_window is None else to_native(self.hcloud_server.backup_window)
+ )
return {
"id": to_native(self.hcloud_server.id),
"name": to_native(self.hcloud_server.name),
+ "created": to_native(self.hcloud_server.created.isoformat()),
"ipv4_address": ipv4_address,
"ipv6": ipv6,
"private_networks": [to_native(net.network.name) for net in self.hcloud_server.private_net],
- "private_networks_info": [{"name": to_native(net.network.name), "ip": net.ip} for net in self.hcloud_server.private_net],
+ "private_networks_info": [
+ {"name": to_native(net.network.name), "ip": net.ip} for net in self.hcloud_server.private_net
+ ],
"image": image,
"server_type": to_native(self.hcloud_server.server_type.name),
"datacenter": to_native(self.hcloud_server.datacenter.name),
@@ -387,20 +395,14 @@ class AnsibleHcloudServer(Hcloud):
def _get_server(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_server = self.client.servers.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_server = self.client.servers.get_by_id(self.module.params.get("id"))
else:
- self.hcloud_server = self.client.servers.get_by_name(
- self.module.params.get("name")
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_server = self.client.servers.get_by_name(self.module.params.get("name"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_server(self):
- self.module.fail_on_missing_params(
- required_params=["name", "server_type", "image"]
- )
+ self.module.fail_on_missing_params(required_params=["name", "server_type", "image"])
server_type = self._get_server_type()
@@ -413,21 +415,21 @@ class AnsibleHcloudServer(Hcloud):
"placement_group": self._get_placement_group(),
"public_net": ServerCreatePublicNetwork(
enable_ipv4=self.module.params.get("enable_ipv4"),
- enable_ipv6=self.module.params.get("enable_ipv6")
- )
+ enable_ipv6=self.module.params.get("enable_ipv6"),
+ ),
}
if self.module.params.get("ipv4") is not None:
- p = self.client.primary_ips.get_by_name(self.module.params.get("ipv4"))
- if not p:
- p = self.client.primary_ips.get_by_id(self.module.params.get("ipv4"))
- params["public_net"].ipv4 = p
+ primary_ip = self.client.primary_ips.get_by_name(self.module.params.get("ipv4"))
+ if not primary_ip:
+ primary_ip = self.client.primary_ips.get_by_id(self.module.params.get("ipv4"))
+ params["public_net"].ipv4 = primary_ip
if self.module.params.get("ipv6") is not None:
- p = self.client.primary_ips.get_by_name(self.module.params.get("ipv6"))
- if not p:
- p = self.client.primary_ips.get_by_id(self.module.params.get("ipv6"))
- params["public_net"].ipv6 = p
+ primary_ip = self.client.primary_ips.get_by_name(self.module.params.get("ipv6"))
+ if not primary_ip:
+ primary_ip = self.client.primary_ips.get_by_id(self.module.params.get("ipv6"))
+ params["public_net"].ipv6 = primary_ip
if self.module.params.get("private_networks") is not None:
_networks = []
@@ -439,37 +441,28 @@ class AnsibleHcloudServer(Hcloud):
params["networks"] = _networks
if self.module.params.get("ssh_keys") is not None:
- params["ssh_keys"] = [
- SSHKey(name=ssh_key_name)
- for ssh_key_name in self.module.params.get("ssh_keys")
- ]
+ params["ssh_keys"] = [SSHKey(name=ssh_key_name) for ssh_key_name in self.module.params.get("ssh_keys")]
if self.module.params.get("volumes") is not None:
- params["volumes"] = [
- Volume(id=volume_id) for volume_id in self.module.params.get("volumes")
- ]
+ params["volumes"] = [Volume(id=volume_id) for volume_id in self.module.params.get("volumes")]
if self.module.params.get("firewalls") is not None:
params["firewalls"] = []
- for fw in self.module.params.get("firewalls"):
- f = self.client.firewalls.get_by_name(fw)
- if f is not None:
+ for firewall_param in self.module.params.get("firewalls"):
+ firewall = self.client.firewalls.get_by_name(firewall_param)
+ if firewall is not None:
# When firewall name is not available look for id instead
- params["firewalls"].append(f)
+ params["firewalls"].append(firewall)
else:
- params["firewalls"].append(self.client.firewalls.get_by_id(fw))
+ params["firewalls"].append(self.client.firewalls.get_by_id(firewall_param))
if self.module.params.get("location") is None and self.module.params.get("datacenter") is None:
# When not given, the API will choose the location.
params["location"] = None
params["datacenter"] = None
elif self.module.params.get("location") is not None and self.module.params.get("datacenter") is None:
- params["location"] = self.client.locations.get_by_name(
- self.module.params.get("location")
- )
+ params["location"] = self.client.locations.get_by_name(self.module.params.get("location"))
elif self.module.params.get("location") is None and self.module.params.get("datacenter") is not None:
- params["datacenter"] = self.client.datacenters.get_by_name(
- self.module.params.get("datacenter")
- )
+ params["datacenter"] = self.client.datacenters.get_by_name(self.module.params.get("datacenter"))
if self.module.params.get("state") == "stopped":
params["start_after_create"] = False
@@ -494,16 +487,22 @@ class AnsibleHcloudServer(Hcloud):
rebuild_protection = self.module.params.get("rebuild_protection")
if delete_protection is not None and rebuild_protection is not None:
self._get_server()
- self.hcloud_server.change_protection(delete=delete_protection,
- rebuild=rebuild_protection).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_server.change_protection(
+ delete=delete_protection,
+ rebuild=rebuild_protection,
+ ).wait_until_finished()
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_server()
def _get_image(self, server_type):
- image_resp = self.client.images.get_list(name=self.module.params.get("image"), architecture=server_type.architecture, include_deprecated=True)
- images = getattr(image_resp, 'images')
+ image_resp = self.client.images.get_list(
+ name=self.module.params.get("image"),
+ architecture=server_type.architecture,
+ include_deprecated=True,
+ )
+ images = getattr(image_resp, "images")
image = None
if images is not None and len(images) > 0:
# If image name is not available look for id instead
@@ -511,46 +510,76 @@ class AnsibleHcloudServer(Hcloud):
else:
try:
image = self.client.images.get_by_id(self.module.params.get("image"))
- except Exception:
- self.module.fail_json(msg="Image %s was not found" % self.module.params.get('image'))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception, msg=f"Image {self.module.params.get('image')} was not found")
if image.deprecated is not None:
available_until = image.deprecated + timedelta(days=90)
if self.module.params.get("allow_deprecated_image"):
self.module.warn(
- "You try to use a deprecated image. The image %s will continue to be available until %s.") % (
- image.name, available_until.strftime('%Y-%m-%d'))
+ f"You try to use a deprecated image. The image {image.name} will "
+ f"continue to be available until {available_until.strftime('%Y-%m-%d')}."
+ )
else:
self.module.fail_json(
- msg=("You try to use a deprecated image. The image %s will continue to be available until %s." +
- " If you want to use this image use allow_deprecated_image=yes."
- ) % (image.name, available_until.strftime('%Y-%m-%d')))
+ msg=(
+ f"You try to use a deprecated image. The image {image.name} will "
+ f"continue to be available until {available_until.strftime('%Y-%m-%d')}. "
+ "If you want to use this image use allow_deprecated_image=true."
+ )
+ )
return image
def _get_server_type(self):
- server_type = self.client.server_types.get_by_name(
- self.module.params.get("server_type")
- )
+ server_type = self.client.server_types.get_by_name(self.module.params.get("server_type"))
if server_type is None:
try:
server_type = self.client.server_types.get_by_id(self.module.params.get("server_type"))
- except Exception:
- self.module.fail_json(msg="server_type %s was not found" % self.module.params.get('server_type'))
+ except HCloudException as exception:
+ self.fail_json_hcloud(
+ exception,
+ msg=f"server_type {self.module.params.get('server_type')} was not found",
+ )
+
+ self._check_and_warn_deprecated_server(server_type)
return server_type
+ def _check_and_warn_deprecated_server(self, server_type):
+ if server_type.deprecation is None:
+ return
+
+ if server_type.deprecation.unavailable_after < datetime.now(timezone.utc):
+ self.module.warn(
+ f"Attention: The server plan {server_type.name} is deprecated and can "
+ "no longer be ordered. Existing servers of that plan will continue to "
+ "work as before and no action is required on your part. "
+ "It is possible to migrate this server to another server plan by setting "
+ "the server_type parameter on the hetzner.hcloud.server module."
+ )
+ else:
+ server_type_unavailable_date = server_type.deprecation.unavailable_after.strftime("%Y-%m-%d")
+ self.module.warn(
+ f"Attention: The server plan {server_type.name} is deprecated and will "
+ f"no longer be available for order as of {server_type_unavailable_date}. "
+ "Existing servers of that plan will continue to work as before and no "
+ "action is required on your part. "
+ "It is possible to migrate this server to another server plan by setting "
+ "the server_type parameter on the hetzner.hcloud.server module."
+ )
+
def _get_placement_group(self):
if self.module.params.get("placement_group") is None:
return None
- placement_group = self.client.placement_groups.get_by_name(
- self.module.params.get("placement_group")
- )
+ placement_group = self.client.placement_groups.get_by_name(self.module.params.get("placement_group"))
if placement_group is None:
try:
placement_group = self.client.placement_groups.get_by_id(self.module.params.get("placement_group"))
- except Exception:
- self.module.fail_json(
- msg="placement_group %s was not found" % self.module.params.get("placement_group"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(
+ exception,
+ msg=f"placement_group {self.module.params.get('placement_group')} was not found",
+ )
return placement_group
@@ -558,20 +587,17 @@ class AnsibleHcloudServer(Hcloud):
if self.module.params.get(field) is None:
return None
- primary_ip = self.client.primary_ips.get_by_name(
- self.module.params.get(field)
- )
+ primary_ip = self.client.primary_ips.get_by_name(self.module.params.get(field))
if primary_ip is None:
try:
primary_ip = self.client.primary_ips.get_by_id(self.module.params.get(field))
- except Exception as e:
- self.module.fail_json(
- msg="primary_ip %s was not found" % self.module.params.get(field))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception, msg=f"primary_ip {self.module.params.get(field)} was not found")
return primary_ip
def _update_server(self):
- if "force_upgrade" in self.module.params:
+ if "force_upgrade" in self.module.params and self.module.params.get("force_upgrade") is not None:
self.module.warn("force_upgrade is deprecated, use force instead")
try:
@@ -609,30 +635,35 @@ class AnsibleHcloudServer(Hcloud):
for current_firewall in self.hcloud_server.public_net.firewalls:
if current_firewall.firewall.name not in wanted_firewalls:
self._mark_as_changed()
- if not self.module.check_mode:
- r = FirewallResource(type="server", server=self.hcloud_server)
- actions = self.client.firewalls.remove_from_resources(current_firewall.firewall, [r])
- for a in actions:
- a.wait_until_finished()
+ if self.module.check_mode:
+ continue
+
+ firewall_resource = FirewallResource(type="server", server=self.hcloud_server)
+ actions = self.client.firewalls.remove_from_resources(
+ current_firewall.firewall,
+ [firewall_resource],
+ )
+ for action in actions:
+ action.wait_until_finished()
# Adding wanted firewalls that doesn't exist yet
- for fname in wanted_firewalls:
+ for firewall_name in wanted_firewalls:
found = False
- for f in self.hcloud_server.public_net.firewalls:
- if f.firewall.name == fname:
+ for firewall in self.hcloud_server.public_net.firewalls:
+ if firewall.firewall.name == firewall_name:
found = True
break
if not found:
self._mark_as_changed()
if not self.module.check_mode:
- fw = self.client.firewalls.get_by_name(fname)
- if fw is None:
- self.module.fail_json(msg="firewall %s was not found" % fname)
- r = FirewallResource(type="server", server=self.hcloud_server)
- actions = self.client.firewalls.apply_to_resources(fw, [r])
- for a in actions:
- a.wait_until_finished()
+ firewall = self.client.firewalls.get_by_name(firewall_name)
+ if firewall is None:
+ self.module.fail_json(msg=f"firewall {firewall_name} was not found")
+ firewall_resource = FirewallResource(type="server", server=self.hcloud_server)
+ actions = self.client.firewalls.apply_to_resources(firewall, [firewall_resource])
+ for action in actions:
+ action.wait_until_finished()
if "placement_group" in self.module.params:
if self.module.params["placement_group"] is None and self.hcloud_server.placement_group is not None:
@@ -641,12 +672,9 @@ class AnsibleHcloudServer(Hcloud):
self._mark_as_changed()
else:
placement_group = self._get_placement_group()
- if (
- placement_group is not None and
- (
- self.hcloud_server.placement_group is None or
- self.hcloud_server.placement_group.id != placement_group.id
- )
+ if placement_group is not None and (
+ self.hcloud_server.placement_group is None
+ or self.hcloud_server.placement_group.id != placement_group.id
):
self.stop_server_if_forced()
if not self.module.check_mode:
@@ -655,9 +683,9 @@ class AnsibleHcloudServer(Hcloud):
if "ipv4" in self.module.params:
if (
- self.module.params["ipv4"] is None and
- self.hcloud_server.public_net.primary_ipv4 is not None and
- not self.module.params.get("enable_ipv4")
+ self.module.params["ipv4"] is None
+ and self.hcloud_server.public_net.primary_ipv4 is not None
+ and not self.module.params.get("enable_ipv4")
):
self.stop_server_if_forced()
if not self.module.check_mode:
@@ -665,12 +693,9 @@ class AnsibleHcloudServer(Hcloud):
self._mark_as_changed()
else:
primary_ip = self._get_primary_ip("ipv4")
- if (
- primary_ip is not None and
- (
- self.hcloud_server.public_net.primary_ipv4 is None or
- self.hcloud_server.public_net.primary_ipv4.id != primary_ip.id
- )
+ if primary_ip is not None and (
+ self.hcloud_server.public_net.primary_ipv4 is None
+ or self.hcloud_server.public_net.primary_ipv4.id != primary_ip.id
):
self.stop_server_if_forced()
if not self.module.check_mode:
@@ -680,9 +705,9 @@ class AnsibleHcloudServer(Hcloud):
self._mark_as_changed()
if "ipv6" in self.module.params:
if (
- (self.module.params["ipv6"] is None or self.module.params["ipv6"] == "") and
- self.hcloud_server.public_net.primary_ipv6 is not None and
- not self.module.params.get("enable_ipv6")
+ (self.module.params["ipv6"] is None or self.module.params["ipv6"] == "")
+ and self.hcloud_server.public_net.primary_ipv6 is not None
+ and not self.module.params.get("enable_ipv6")
):
self.stop_server_if_forced()
if not self.module.check_mode:
@@ -690,12 +715,9 @@ class AnsibleHcloudServer(Hcloud):
self._mark_as_changed()
else:
primary_ip = self._get_primary_ip("ipv6")
- if (
- primary_ip is not None and
- (
- self.hcloud_server.public_net.primary_ipv6 is None or
- self.hcloud_server.public_net.primary_ipv6.id != primary_ip.id
- )
+ if primary_ip is not None and (
+ self.hcloud_server.public_net.primary_ipv6 is None
+ or self.hcloud_server.public_net.primary_ipv6.id != primary_ip.id
):
self.stop_server_if_forced()
if not self.module.check_mode:
@@ -710,11 +732,10 @@ class AnsibleHcloudServer(Hcloud):
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}
- )
+ _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:
@@ -732,53 +753,56 @@ class AnsibleHcloudServer(Hcloud):
self._mark_as_changed()
server_type = self.module.params.get("server_type")
- if server_type is not None and self.hcloud_server.server_type.name != server_type:
- self.stop_server_if_forced()
-
- timeout = 100
- if self.module.params.get("upgrade_disk"):
- timeout = (
- 1000
- ) # When we upgrade the disk to the resize progress takes some more time.
- if not self.module.check_mode:
- self.hcloud_server.change_type(
- server_type=self._get_server_type(),
- upgrade_disk=self.module.params.get("upgrade_disk"),
- ).wait_until_finished(timeout)
- self._mark_as_changed()
+ if server_type is not None:
+ if self.hcloud_server.server_type.name == server_type:
+ # Check if we should warn for using an deprecated server type
+ self._check_and_warn_deprecated_server(self.hcloud_server.server_type)
- if (
- not self.module.check_mode and
- (
- (
- self.module.params.get("state") == "present" and
- previous_server_status == Server.STATUS_RUNNING
- ) or
- self.module.params.get("state") == "started"
- )
+ else:
+ # Server type should be changed
+ self.stop_server_if_forced()
+
+ timeout = 100
+ if self.module.params.get("upgrade_disk"):
+ timeout = 1000 # When we upgrade the disk to the resize progress takes some more time.
+ if not self.module.check_mode:
+ self.hcloud_server.change_type(
+ server_type=self._get_server_type(),
+ upgrade_disk=self.module.params.get("upgrade_disk"),
+ ).wait_until_finished(timeout)
+ self._mark_as_changed()
+
+ if not self.module.check_mode and (
+ (self.module.params.get("state") == "present" and previous_server_status == Server.STATUS_RUNNING)
+ or self.module.params.get("state") == "started"
):
self.start_server()
delete_protection = self.module.params.get("delete_protection")
rebuild_protection = self.module.params.get("rebuild_protection")
if (delete_protection is not None and rebuild_protection is not None) and (
- delete_protection != self.hcloud_server.protection["delete"] or rebuild_protection !=
- self.hcloud_server.protection["rebuild"]):
+ delete_protection != self.hcloud_server.protection["delete"]
+ or rebuild_protection != self.hcloud_server.protection["rebuild"]
+ ):
if not self.module.check_mode:
- self.hcloud_server.change_protection(delete=delete_protection,
- rebuild=rebuild_protection).wait_until_finished()
+ self.hcloud_server.change_protection(
+ delete=delete_protection,
+ rebuild=rebuild_protection,
+ ).wait_until_finished()
self._mark_as_changed()
self._get_server()
- except Exception as e:
- self.module.fail_json(msg=e)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _set_rescue_mode(self, rescue_mode):
if self.module.params.get("ssh_keys"):
- resp = self.hcloud_server.enable_rescue(type=rescue_mode,
- ssh_keys=[self.client.ssh_keys.get_by_name(ssh_key_name).id
- for
- ssh_key_name in
- self.module.params.get("ssh_keys")])
+ resp = self.hcloud_server.enable_rescue(
+ type=rescue_mode,
+ ssh_keys=[
+ self.client.ssh_keys.get_by_name(ssh_key_name).id
+ for ssh_key_name in self.module.params.get("ssh_keys")
+ ],
+ )
else:
resp = self.hcloud_server.enable_rescue(type=rescue_mode)
resp.action.wait_until_finished()
@@ -792,8 +816,8 @@ class AnsibleHcloudServer(Hcloud):
self.client.servers.power_on(self.hcloud_server).wait_until_finished()
self._mark_as_changed()
self._get_server()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def stop_server(self):
try:
@@ -803,40 +827,40 @@ class AnsibleHcloudServer(Hcloud):
self.client.servers.power_off(self.hcloud_server).wait_until_finished()
self._mark_as_changed()
self._get_server()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def stop_server_if_forced(self):
previous_server_status = self.hcloud_server.status
if previous_server_status == Server.STATUS_RUNNING and not self.module.check_mode:
if (
- self.module.params.get("force_upgrade") or
- self.module.params.get("force") or
- self.module.params.get("state") == "stopped"
+ self.module.params.get("force_upgrade")
+ or self.module.params.get("force")
+ or self.module.params.get("state") == "stopped"
):
self.stop_server() # Only stopped server can be upgraded
return previous_server_status
else:
self.module.warn(
- "You can not upgrade a running instance %s. You need to stop the instance or use force=yes."
- % self.hcloud_server.name
+ f"You can not upgrade a running instance {self.hcloud_server.name}. "
+ "You need to stop the instance or use force=true."
)
return None
def rebuild_server(self):
- self.module.fail_on_missing_params(
- required_params=["image"]
- )
+ self.module.fail_on_missing_params(required_params=["image"])
try:
if not self.module.check_mode:
image = self._get_image(self.hcloud_server.server_type)
- self.client.servers.rebuild(self.hcloud_server, image).wait_until_finished(1000) # When we rebuild the server progress takes some more time.
+ # When we rebuild the server progress takes some more time.
+ resp = self.client.servers.rebuild(self.hcloud_server, image, return_response=True)
+ resp.action.wait_until_finished(1000)
self._mark_as_changed()
self._get_server()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def present_server(self):
self._get_server()
@@ -853,11 +877,11 @@ class AnsibleHcloudServer(Hcloud):
self.client.servers.delete(self.hcloud_server).wait_until_finished()
self._mark_as_changed()
self.hcloud_server = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -879,7 +903,7 @@ class AnsibleHcloudServer(Hcloud):
ipv6={"type": "str"},
private_networks={"type": "list", "elements": "str", "default": None},
force={"type": "bool", "default": False},
- force_upgrade={"type": "bool", "default": False},
+ force_upgrade={"type": "bool"},
allow_deprecated_image={"type": "bool", "default": False},
rescue_mode={"type": "str"},
delete_protection={"type": "bool"},
@@ -889,9 +913,9 @@ class AnsibleHcloudServer(Hcloud):
"choices": ["absent", "present", "restarted", "started", "stopped", "rebuild"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
+ required_one_of=[["id", "name"]],
mutually_exclusive=[["location", "datacenter"]],
required_together=[["delete_protection", "rebuild_protection"]],
supports_check_mode=True,
@@ -899,9 +923,9 @@ class AnsibleHcloudServer(Hcloud):
def main():
- module = AnsibleHcloudServer.define_module()
+ module = AnsibleHCloudServer.define_module()
- hcloud = AnsibleHcloudServer(module)
+ hcloud = AnsibleHCloudServer(module)
state = module.params.get("state")
if state == "absent":
hcloud.delete_server()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py
index 102ceec0d..cee1634cb 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py
@@ -1,24 +1,20 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_server_info
+module: server_info
short_description: Gather infos about your Hetzner Cloud servers.
description:
- Gather infos about your Hetzner Cloud servers.
- - This module was called C(hcloud_server_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_facts).
- Note that the M(hetzner.hcloud.hcloud_server_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_info)!
author:
- Lukas Kaemmerling (@LKaemmerling)
@@ -27,6 +23,7 @@ options:
id:
description:
- The ID of the server you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -39,11 +36,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud server infos
- hcloud_server_info:
+ hetzner.hcloud.server_info:
register: output
- name: Print the gathered infos
@@ -67,6 +64,11 @@ hcloud_server_info:
returned: always
type: str
sample: my-server
+ created:
+ description: Point in time when the Server was created (in ISO-8601 format)
+ returned: always
+ type: str
+ sample: "2023-11-06T13:36:56+00:00"
status:
description: Status of the server
returned: always
@@ -144,14 +146,17 @@ hcloud_server_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.servers import BoundServer
-class AnsibleHcloudServerInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_server_info")
- self.hcloud_server_info = None
+
+class AnsibleHCloudServerInfo(AnsibleHCloud):
+ represent = "hcloud_server_info"
+
+ hcloud_server_info: list[BoundServer] | None = None
def _prepare_result(self):
tmp = []
@@ -163,81 +168,70 @@ class AnsibleHcloudServerInfo(Hcloud):
ipv4_address = None if server.public_net.ipv4 is None else to_native(server.public_net.ipv4.ip)
ipv6 = None if server.public_net.ipv6 is None else to_native(server.public_net.ipv6.ip)
backup_window = None if server.backup_window is None else to_native(server.backup_window)
- tmp.append({
- "id": to_native(server.id),
- "name": to_native(server.name),
- "ipv4_address": ipv4_address,
- "ipv6": ipv6,
- "private_networks": [to_native(net.network.name) for net in server.private_net],
- "private_networks_info": [{"name": to_native(net.network.name), "ip": net.ip} for net in server.private_net],
- "image": image,
- "server_type": to_native(server.server_type.name),
- "datacenter": to_native(server.datacenter.name),
- "location": to_native(server.datacenter.location.name),
- "placement_group": placement_group,
- "rescue_enabled": server.rescue_enabled,
- "backup_window": backup_window,
- "labels": server.labels,
- "status": to_native(server.status),
- "delete_protection": server.protection["delete"],
- "rebuild_protection": server.protection["rebuild"],
- })
+ tmp.append(
+ {
+ "id": to_native(server.id),
+ "name": to_native(server.name),
+ "created": to_native(server.created.isoformat()),
+ "ipv4_address": ipv4_address,
+ "ipv6": ipv6,
+ "private_networks": [to_native(net.network.name) for net in server.private_net],
+ "private_networks_info": [
+ {"name": to_native(net.network.name), "ip": net.ip} for net in server.private_net
+ ],
+ "image": image,
+ "server_type": to_native(server.server_type.name),
+ "datacenter": to_native(server.datacenter.name),
+ "location": to_native(server.datacenter.location.name),
+ "placement_group": placement_group,
+ "rescue_enabled": server.rescue_enabled,
+ "backup_window": backup_window,
+ "labels": server.labels,
+ "status": to_native(server.status),
+ "delete_protection": server.protection["delete"],
+ "rebuild_protection": server.protection["rebuild"],
+ }
+ )
return tmp
def get_servers(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_server_info = [self.client.servers.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_server_info = [self.client.servers.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None:
- self.hcloud_server_info = [self.client.servers.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_server_info = [self.client.servers.get_by_name(self.module.params.get("name"))]
elif self.module.params.get("label_selector") is not None:
self.hcloud_server_info = self.client.servers.get_all(
- label_selector=self.module.params.get("label_selector"))
+ label_selector=self.module.params.get("label_selector")
+ )
else:
self.hcloud_server_info = self.client.servers.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudServerInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_server_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_server_facts' module has been renamed to 'hcloud_server_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+ module = AnsibleHCloudServerInfo.define_module()
+ hcloud = AnsibleHCloudServerInfo(module)
- hcloud = AnsibleHcloudServerInfo(module)
hcloud.get_servers()
result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_server_facts': result['hcloud_server_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_server_info': result['hcloud_server_info']
- }
- module.exit_json(**ansible_info)
+ ansible_info = {"hcloud_server_info": result["hcloud_server_info"]}
+ module.exit_json(**ansible_info)
if __name__ == "__main__":
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_network.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py
index 79f6838fd..ca80a8a76 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_network.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_server_network
+module: server_network
short_description: Manage the relationship between Hetzner Cloud Networks and servers
@@ -24,12 +22,12 @@ author:
options:
network:
description:
- - The name of the Hetzner Cloud Networks.
+ - Name or ID of the Hetzner Cloud Networks.
type: str
required: true
server:
description:
- - The name of the Hetzner Cloud server.
+ - Name or ID of the Hetzner Cloud server.
type: str
required: true
ip:
@@ -48,40 +46,36 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.3.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a basic server network
- hcloud_server_network:
+ hetzner.hcloud.server_network:
network: my-network
server: my-server
state: present
- name: Create a server network and specify the ip address
- hcloud_server_network:
+ hetzner.hcloud.server_network:
network: my-network
server: my-server
ip: 10.0.0.1
state: present
- name: Create a server network and add alias ips
- hcloud_server_network:
+ hetzner.hcloud.server_network:
network: my-network
server: my-server
ip: 10.0.0.1
alias_ips:
- - 10.1.0.1
- - 10.2.0.1
+ - 10.1.0.1
+ - 10.2.0.1
state: present
- name: Ensure the server network is absent (remove if needed)
- hcloud_server_network:
+ hetzner.hcloud.server_network:
network: my-network
server: my-server
state: absent
@@ -110,27 +104,27 @@ hcloud_server_network:
sample: 10.0.0.8
alias_ips:
description: Alias IPs of the server within the Network ip range
- type: str
+ type: list
+ elements: str
returned: always
sample: [10.1.0.1, ...]
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
-try:
- from hcloud import APIException
-except ImportError:
- APIException = None
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import APIException, HCloudException
+from ..module_utils.vendor.hcloud.networks import BoundNetwork
+from ..module_utils.vendor.hcloud.servers import BoundServer, PrivateNet
-class AnsibleHcloudServerNetwork(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_server_network")
- self.hcloud_network = None
- self.hcloud_server = None
- self.hcloud_server_network = None
+class AnsibleHCloudServerNetwork(AnsibleHCloud):
+ represent = "hcloud_server_network"
+
+ hcloud_network: BoundNetwork | None = None
+ hcloud_server: BoundServer | None = None
+ hcloud_server_network: PrivateNet | None = None
def _prepare_result(self):
return {
@@ -142,20 +136,26 @@ class AnsibleHcloudServerNetwork(Hcloud):
def _get_server_and_network(self):
try:
- self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
- self.hcloud_server = self.client.servers.get_by_name(self.module.params.get("server"))
+ self.hcloud_network = self._client_get_by_name_or_id(
+ "networks",
+ self.module.params.get("network"),
+ )
+ self.hcloud_server = self._client_get_by_name_or_id(
+ "servers",
+ self.module.params.get("server"),
+ )
self.hcloud_server_network = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _get_server_network(self):
- for privateNet in self.hcloud_server.private_net:
- if privateNet.network.id == self.hcloud_network.id:
- self.hcloud_server_network = privateNet
+ for private_net in self.hcloud_server.private_net:
+ if private_net.network.id == self.hcloud_network.id:
+ self.hcloud_server_network = private_net
def _create_server_network(self):
params = {
- "network": self.hcloud_network
+ "network": self.hcloud_network,
}
if self.module.params.get("ip") is not None:
@@ -166,8 +166,8 @@ class AnsibleHcloudServerNetwork(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_server.attach_to_network(**params).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_server_and_network()
@@ -175,7 +175,7 @@ class AnsibleHcloudServerNetwork(Hcloud):
def _update_server_network(self):
params = {
- "network": self.hcloud_network
+ "network": self.hcloud_network,
}
alias_ips = self.module.params.get("alias_ips")
if alias_ips is not None and sorted(self.hcloud_server_network.alias_ips) != sorted(alias_ips):
@@ -184,8 +184,8 @@ class AnsibleHcloudServerNetwork(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_server.change_alias_ips(**params).wait_until_finished()
- except APIException as e:
- self.module.fail_json(msg=e.message)
+ except APIException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_server_and_network()
@@ -206,13 +206,13 @@ class AnsibleHcloudServerNetwork(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_server.detach_from_network(self.hcloud_server_network.network).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_server_network = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
network={"type": "str", "required": True},
@@ -223,16 +223,16 @@ class AnsibleHcloudServerNetwork(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudServerNetwork.define_module()
+ module = AnsibleHCloudServerNetwork.define_module()
- hcloud = AnsibleHcloudServerNetwork(module)
+ hcloud = AnsibleHCloudServerNetwork(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_server_network()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py
new file mode 100644
index 000000000..61f1f5011
--- /dev/null
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py
@@ -0,0 +1,204 @@
+#!/usr/bin/python
+
+# Copyright: (c) 2019, 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)
+
+
+from __future__ import annotations
+
+DOCUMENTATION = """
+---
+module: server_type_info
+
+short_description: Gather infos about the Hetzner Cloud server types.
+
+
+description:
+ - Gather infos about your Hetzner Cloud server types.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the server type you want to get.
+ - The module will fail if the provided ID is invalid.
+ type: int
+ name:
+ description:
+ - The name of the server type you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+"""
+
+EXAMPLES = """
+- name: Gather hcloud server type infos
+ hetzner.hcloud.server_type_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_server_type_info
+"""
+
+RETURN = """
+hcloud_server_type_info:
+ description: The server type infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the server type
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the server type
+ returned: always
+ type: str
+ sample: fsn1
+ description:
+ description: Detail description of the server type
+ returned: always
+ type: str
+ sample: Falkenstein DC Park 1
+ cores:
+ description: Number of cpu cores a server of this type will have
+ returned: always
+ type: int
+ sample: 1
+ memory:
+ description: Memory a server of this type will have in GB
+ returned: always
+ type: int
+ sample: 1
+ disk:
+ description: Disk size a server of this type will have in GB
+ returned: always
+ type: int
+ sample: 25
+ storage_type:
+ description: Type of server boot drive
+ returned: always
+ type: str
+ sample: local
+ cpu_type:
+ description: Type of cpu
+ returned: always
+ type: str
+ sample: shared
+ architecture:
+ description: Architecture of cpu
+ returned: always
+ type: str
+ sample: x86
+ included_traffic:
+ description: Free traffic per month in bytes
+ returned: always
+ type: int
+ sample: 21990232555520
+ deprecation:
+ description: |
+ Describes if, when & how the resources was deprecated.
+ If this field is set to None the resource is not deprecated. If it has a value, it is considered deprecated.
+ returned: success
+ type: dict
+ contains:
+ announced:
+ description: Date of when the deprecation was announced.
+ returned: success
+ type: str
+ sample: "2021-11-09T09:00:00+00:00"
+ unavailable_after:
+ description: |
+ After the time in this field, the resource will not be available from the general listing
+ endpoint of the resource type, and it can not be used in new resources. For example, if this is
+ an image, you can not create new servers with this image after the mentioned date.
+ returned: success
+ type: str
+ sample: "2021-12-01T00:00:00+00:00"
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.server_types import BoundServerType
+
+
+class AnsibleHCloudServerTypeInfo(AnsibleHCloud):
+ represent = "hcloud_server_type_info"
+
+ hcloud_server_type_info: list[BoundServerType] | None = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for server_type in self.hcloud_server_type_info:
+ if server_type is not None:
+ tmp.append(
+ {
+ "id": to_native(server_type.id),
+ "name": to_native(server_type.name),
+ "description": to_native(server_type.description),
+ "cores": server_type.cores,
+ "memory": server_type.memory,
+ "disk": server_type.disk,
+ "storage_type": to_native(server_type.storage_type),
+ "cpu_type": to_native(server_type.cpu_type),
+ "architecture": to_native(server_type.architecture),
+ "included_traffic": server_type.included_traffic,
+ "deprecation": (
+ {
+ "announced": server_type.deprecation.announced.isoformat(),
+ "unavailable_after": server_type.deprecation.unavailable_after.isoformat(),
+ }
+ if server_type.deprecation is not None
+ else None
+ ),
+ }
+ )
+ return tmp
+
+ def get_server_types(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_server_type_info = [self.client.server_types.get_by_id(self.module.params.get("id"))]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_server_type_info = [self.client.server_types.get_by_name(self.module.params.get("name"))]
+ else:
+ self.hcloud_server_type_info = self.client.server_types.get_all()
+
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
+
+ @classmethod
+ def define_module(cls):
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **super().base_module_arguments(),
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHCloudServerTypeInfo.define_module()
+ hcloud = AnsibleHCloudServerTypeInfo(module)
+
+ hcloud.get_server_types()
+ result = hcloud.get_result()
+
+ ansible_info = {"hcloud_server_type_info": result["hcloud_server_type_info"]}
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key.py b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py
index 59a5197f5..349c52c68 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_ssh_key
+module: ssh_key
short_description: Create and manage ssh keys on the Hetzner Cloud.
@@ -55,26 +53,26 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Create a basic ssh_key
- hcloud_ssh_key:
+ hetzner.hcloud.ssh_key:
name: my-ssh_key
- public_key: "ssh-rsa AAAjjk76kgf...Xt"
+ public_key: ssh-rsa AAAjjk76kgf...Xt
state: present
- name: Create a ssh_key with labels
- hcloud_ssh_key:
+ hetzner.hcloud.ssh_key:
name: my-ssh_key
- public_key: "ssh-rsa AAAjjk76kgf...Xt"
+ public_key: ssh-rsa AAAjjk76kgf...Xt
labels:
- key: value
- mylabel: 123
+ key: value
+ mylabel: 123
state: present
- name: Ensure the ssh_key is absent (remove if needed)
- hcloud_ssh_key:
+ hetzner.hcloud.ssh_key:
name: my-ssh_key
state: absent
"""
@@ -115,14 +113,17 @@ hcloud_ssh_key:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.ssh_keys import BoundSSHKey
-class AnsibleHcloudSSHKey(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_ssh_key")
- self.hcloud_ssh_key = None
+
+class AnsibleHCloudSSHKey(AnsibleHCloud):
+ represent = "hcloud_ssh_key"
+
+ hcloud_ssh_key: BoundSSHKey | None = None
def _prepare_result(self):
return {
@@ -136,45 +137,35 @@ class AnsibleHcloudSSHKey(Hcloud):
def _get_ssh_key(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_ssh_key = self.client.ssh_keys.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_ssh_key = self.client.ssh_keys.get_by_id(self.module.params.get("id"))
elif self.module.params.get("fingerprint") is not None:
- self.hcloud_ssh_key = self.client.ssh_keys.get_by_fingerprint(
- self.module.params.get("fingerprint")
- )
+ self.hcloud_ssh_key = self.client.ssh_keys.get_by_fingerprint(self.module.params.get("fingerprint"))
elif self.module.params.get("name") is not None:
- self.hcloud_ssh_key = self.client.ssh_keys.get_by_name(
- self.module.params.get("name")
- )
+ self.hcloud_ssh_key = self.client.ssh_keys.get_by_name(self.module.params.get("name"))
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_ssh_key(self):
- self.module.fail_on_missing_params(
- required_params=["name", "public_key"]
- )
+ self.module.fail_on_missing_params(required_params=["name", "public_key"])
params = {
"name": self.module.params.get("name"),
"public_key": self.module.params.get("public_key"),
- "labels": self.module.params.get("labels")
+ "labels": self.module.params.get("labels"),
}
if not self.module.check_mode:
try:
self.client.ssh_keys.create(**params)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_ssh_key()
def _update_ssh_key(self):
name = self.module.params.get("name")
if name is not None and self.hcloud_ssh_key.name != name:
- self.module.fail_on_missing_params(
- required_params=["id"]
- )
+ self.module.fail_on_missing_params(required_params=["id"])
if not self.module.check_mode:
self.hcloud_ssh_key.update(name=name)
self._mark_as_changed()
@@ -200,13 +191,13 @@ class AnsibleHcloudSSHKey(Hcloud):
if not self.module.check_mode:
try:
self.client.ssh_keys.delete(self.hcloud_ssh_key)
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_ssh_key = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -218,18 +209,18 @@ class AnsibleHcloudSSHKey(Hcloud):
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name', 'fingerprint']],
- required_if=[['state', 'present', ['name']]],
+ required_one_of=[["id", "name", "fingerprint"]],
+ required_if=[["state", "present", ["name"]]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudSSHKey.define_module()
+ module = AnsibleHCloudSSHKey.define_module()
- hcloud = AnsibleHcloudSSHKey(module)
+ hcloud = AnsibleHCloudSSHKey(module)
state = module.params.get("state")
if state == "absent":
hcloud.delete_ssh_key()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_facts.py b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py
index aab98ed60..7a4ab5928 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_facts.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py
@@ -1,27 +1,24 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_ssh_key_info
+module: ssh_key_info
short_description: Gather infos about your Hetzner Cloud ssh_keys.
description:
- Gather facts about your Hetzner Cloud ssh_keys.
- - This module was called C(hcloud_ssh_key_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_ssh_key_facts).
- Note that the M(hetzner.hcloud.hcloud_ssh_key_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_ssh_key_info)!
author:
- Christopher Schmitt (@cschmitt-hcloud)
options:
id:
description:
- The ID of the ssh key you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -38,11 +35,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud sshkey infos
- hcloud_ssh_key_info:
+ hetzner.hcloud.ssh_key_info:
register: output
- name: Print the gathered infos
debug:
@@ -80,89 +77,79 @@ hcloud_ssh_key_info:
returned: always
type: dict
"""
+
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.ssh_keys import BoundSSHKey
-class AnsibleHcloudSSHKeyInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_ssh_key_info")
- self.hcloud_ssh_key_info = None
+class AnsibleHCloudSSHKeyInfo(AnsibleHCloud):
+ represent = "hcloud_ssh_key_info"
+
+ hcloud_ssh_key_info: list[BoundSSHKey] | None = None
def _prepare_result(self):
ssh_keys = []
for ssh_key in self.hcloud_ssh_key_info:
if ssh_key:
- ssh_keys.append({
- "id": to_native(ssh_key.id),
- "name": to_native(ssh_key.name),
- "fingerprint": to_native(ssh_key.fingerprint),
- "public_key": to_native(ssh_key.public_key),
- "labels": ssh_key.labels
- })
+ ssh_keys.append(
+ {
+ "id": to_native(ssh_key.id),
+ "name": to_native(ssh_key.name),
+ "fingerprint": to_native(ssh_key.fingerprint),
+ "public_key": to_native(ssh_key.public_key),
+ "labels": ssh_key.labels,
+ }
+ )
return ssh_keys
def get_ssh_keys(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None:
- self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_name(self.module.params.get("name"))]
elif self.module.params.get("fingerprint") is not None:
- self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_fingerprint(
- self.module.params.get("fingerprint")
- )]
+ self.hcloud_ssh_key_info = [
+ self.client.ssh_keys.get_by_fingerprint(self.module.params.get("fingerprint"))
+ ]
elif self.module.params.get("label_selector") is not None:
self.hcloud_ssh_key_info = self.client.ssh_keys.get_all(
- label_selector=self.module.params.get("label_selector"))
+ label_selector=self.module.params.get("label_selector")
+ )
else:
self.hcloud_ssh_key_info = self.client.ssh_keys.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
fingerprint={"type": "str"},
label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudSSHKeyInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_ssh_key_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_ssh_key_facts' module has been renamed to 'hcloud_ssh_key_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+ module = AnsibleHCloudSSHKeyInfo.define_module()
+ hcloud = AnsibleHCloudSSHKeyInfo(module)
- hcloud = AnsibleHcloudSSHKeyInfo(module)
hcloud.get_ssh_keys()
result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_ssh_key_facts': result['hcloud_ssh_key_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_ssh_key_info': result['hcloud_ssh_key_info']
- }
- module.exit_json(**ansible_info)
+ ansible_info = {"hcloud_ssh_key_info": result["hcloud_ssh_key_info"]}
+ module.exit_json(**ansible_info)
if __name__ == "__main__":
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_subnetwork.py b/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py
index c2ba66d80..aea40bb13 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_subnetwork.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_subnetwork
+module: subnetwork
short_description: Manage cloud subnetworks on the Hetzner Cloud.
@@ -24,7 +22,7 @@ author:
options:
network:
description:
- - The ID or Name of the Hetzner Cloud Networks.
+ - The name or ID of the Hetzner Cloud Networks.
type: str
required: true
ip_range:
@@ -55,17 +53,13 @@ options:
choices: [ absent, present ]
type: str
-requirements:
- - hcloud-python >= 1.10.0
-
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-
-'''
+"""
EXAMPLES = """
- name: Create a basic subnetwork
- hcloud_subnetwork:
+ hetzner.hcloud.subnetwork:
network: my-network
ip_range: 10.0.0.0/16
network_zone: eu-central
@@ -73,7 +67,7 @@ EXAMPLES = """
state: present
- name: Create a basic subnetwork
- hcloud_subnetwork:
+ hetzner.hcloud.subnetwork:
network: my-vswitch-network
ip_range: 10.0.0.0/24
network_zone: eu-central
@@ -82,7 +76,7 @@ EXAMPLES = """
state: present
- name: Ensure the subnetwork is absent (remove if needed)
- hcloud_subnetwork:
+ hetzner.hcloud.subnetwork:
network: my-network
ip_range: 10.0.0.0/8
network_zone: eu-central
@@ -129,20 +123,18 @@ hcloud_subnetwork:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
-try:
- from hcloud.networks.domain import NetworkSubnet
-except ImportError:
- NetworkSubnet = None
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.networks import BoundNetwork, NetworkSubnet
-class AnsibleHcloudSubnetwork(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_subnetwork")
- self.hcloud_network = None
- self.hcloud_subnetwork = None
+class AnsibleHCloudSubnetwork(AnsibleHCloud):
+ represent = "hcloud_subnetwork"
+
+ hcloud_network: BoundNetwork | None = None
+ hcloud_subnetwork: NetworkSubnet | None = None
def _prepare_result(self):
return {
@@ -156,10 +148,13 @@ class AnsibleHcloudSubnetwork(Hcloud):
def _get_network(self):
try:
- self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
+ self.hcloud_network = self._client_get_by_name_or_id(
+ "networks",
+ self.module.params.get("network"),
+ )
self.hcloud_subnetwork = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _get_subnetwork(self):
subnet_ip_range = self.module.params.get("ip_range")
@@ -170,20 +165,18 @@ class AnsibleHcloudSubnetwork(Hcloud):
def _create_subnetwork(self):
params = {
"ip_range": self.module.params.get("ip_range"),
- "type": self.module.params.get('type'),
- "network_zone": self.module.params.get('network_zone')
+ "type": self.module.params.get("type"),
+ "network_zone": self.module.params.get("network_zone"),
}
- if self.module.params.get('type') == NetworkSubnet.TYPE_VSWITCH:
- self.module.fail_on_missing_params(
- required_params=["vswitch_id"]
- )
- params["vswitch_id"] = self.module.params.get('vswitch_id')
+ if self.module.params.get("type") == NetworkSubnet.TYPE_VSWITCH:
+ self.module.fail_on_missing_params(required_params=["vswitch_id"])
+ params["vswitch_id"] = self.module.params.get("vswitch_id")
if not self.module.check_mode:
try:
self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params)).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_network()
@@ -202,38 +195,34 @@ class AnsibleHcloudSubnetwork(Hcloud):
if not self.module.check_mode:
try:
self.hcloud_network.delete_subnet(self.hcloud_subnetwork).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self.hcloud_subnetwork = None
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
network={"type": "str", "required": True},
network_zone={"type": "str", "required": True},
- type={
- "type": "str",
- "required": True,
- "choices": ["server", "cloud", "vswitch"]
- },
+ type={"type": "str", "required": True, "choices": ["server", "cloud", "vswitch"]},
ip_range={"type": "str", "required": True},
vswitch_id={"type": "int"},
state={
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudSubnetwork.define_module()
+ module = AnsibleHCloudSubnetwork.define_module()
- hcloud = AnsibleHcloudSubnetwork(module)
+ hcloud = AnsibleHCloudSubnetwork(module)
state = module.params["state"]
if state == "absent":
hcloud.delete_subnetwork()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume.py b/ansible_collections/hetzner/hcloud/plugins/modules/volume.py
index 623a399b4..8442ed90b 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/volume.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_volume
+module: volume
short_description: Create and manage block Volume on the Hetzner Cloud.
@@ -75,36 +73,36 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Create a Volume
- hcloud_volume:
+ hetzner.hcloud.volume:
name: my-volume
location: fsn1
size: 100
state: present
- name: Create a Volume and format it with ext4
- hcloud_volume:
+ hetzner.hcloud.volume:
name: my-volume
location: fsn
format: ext4
size: 100
state: present
- name: Mount a existing Volume and automount
- hcloud_volume:
+ hetzner.hcloud.volume:
name: my-volume
server: my-server
- automount: yes
+ automount: true
state: present
- name: Mount a existing Volume and automount
- hcloud_volume:
+ hetzner.hcloud.volume:
name: my-volume
server: my-server
- automount: yes
+ automount: true
state: present
- name: Ensure the Volume is absent (remove if needed)
- hcloud_volume:
+ hetzner.hcloud.volume:
name: my-volume
state: absent
"""
@@ -162,14 +160,17 @@ hcloud_volume:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.volumes import BoundVolume
+
+class AnsibleHCloudVolume(AnsibleHCloud):
+ represent = "hcloud_volume"
-class AnsibleHcloudVolume(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_volume")
- self.hcloud_volume = None
+ hcloud_volume: BoundVolume | None = None
def _prepare_result(self):
server_name = None
@@ -190,31 +191,25 @@ class AnsibleHcloudVolume(Hcloud):
def _get_volume(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_volume = self.client.volumes.get_by_id(
- self.module.params.get("id")
- )
+ self.hcloud_volume = self.client.volumes.get_by_id(self.module.params.get("id"))
else:
- self.hcloud_volume = self.client.volumes.get_by_name(
- self.module.params.get("name")
- )
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ self.hcloud_volume = self.client.volumes.get_by_name(self.module.params.get("name"))
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def _create_volume(self):
- self.module.fail_on_missing_params(
- required_params=["name", "size"]
- )
+ self.module.fail_on_missing_params(required_params=["name", "size"])
params = {
"name": self.module.params.get("name"),
"size": self.module.params.get("size"),
"automount": self.module.params.get("automount"),
"format": self.module.params.get("format"),
- "labels": self.module.params.get("labels")
+ "labels": self.module.params.get("labels"),
}
if self.module.params.get("server") is not None:
- params['server'] = self.client.servers.get_by_name(self.module.params.get("server"))
+ params["server"] = self.client.servers.get_by_name(self.module.params.get("server"))
elif self.module.params.get("location") is not None:
- params['location'] = self.client.locations.get_by_name(self.module.params.get("location"))
+ params["location"] = self.client.locations.get_by_name(self.module.params.get("location"))
else:
self.module.fail_json(msg="server or location is required")
@@ -227,8 +222,8 @@ class AnsibleHcloudVolume(Hcloud):
if delete_protection is not None:
self._get_volume()
self.hcloud_volume.change_protection(delete=delete_protection).wait_until_finished()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_volume()
@@ -270,8 +265,8 @@ class AnsibleHcloudVolume(Hcloud):
self._mark_as_changed()
self._get_volume()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
def present_volume(self):
self._get_volume()
@@ -290,11 +285,11 @@ class AnsibleHcloudVolume(Hcloud):
self.client.volumes.delete(self.hcloud_volume)
self._mark_as_changed()
self.hcloud_volume = None
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
@@ -304,31 +299,27 @@ class AnsibleHcloudVolume(Hcloud):
server={"type": "str"},
labels={"type": "dict"},
automount={"type": "bool", "default": False},
- format={"type": "str",
- "choices": ['xfs', 'ext4'],
- },
+ format={"type": "str", "choices": ["xfs", "ext4"]},
delete_protection={"type": "bool"},
state={
"choices": ["absent", "present"],
"default": "present",
},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
- required_one_of=[['id', 'name']],
+ required_one_of=[["id", "name"]],
mutually_exclusive=[["location", "server"]],
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudVolume.define_module()
+ module = AnsibleHCloudVolume.define_module()
- hcloud = AnsibleHcloudVolume(module)
+ hcloud = AnsibleHCloudVolume(module)
state = module.params.get("state")
if state == "absent":
- module.fail_on_missing_params(
- required_params=["name"]
- )
+ module.fail_on_missing_params(required_params=["name"])
hcloud.delete_volume()
else:
hcloud.present_volume()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py
index 9520bfa14..1e507690e 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py
@@ -1,16 +1,14 @@
#!/usr/bin/python
-# -*- coding: utf-8 -*-
# Copyright: (c) 2019, 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)
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+from __future__ import annotations
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
-module: hcloud_volume_info
+module: volume_info
short_description: Gather infos about your Hetzner Cloud Volumes.
@@ -24,6 +22,7 @@ options:
id:
description:
- The ID of the Volume you want to get.
+ - The module will fail if the provided ID is invalid.
type: int
name:
description:
@@ -36,11 +35,11 @@ options:
extends_documentation_fragment:
- hetzner.hcloud.hcloud
-'''
+"""
EXAMPLES = """
- name: Gather hcloud Volume infos
- hcloud_volume_info:
+ hetzner.hcloud.volume_info:
register: output
- name: Print the gathered infos
debug:
@@ -96,14 +95,17 @@ hcloud_volume_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native
-from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible.module_utils.common.text.converters import to_native
+
+from ..module_utils.hcloud import AnsibleHCloud
+from ..module_utils.vendor.hcloud import HCloudException
+from ..module_utils.vendor.hcloud.volumes import BoundVolume
+
+class AnsibleHCloudVolumeInfo(AnsibleHCloud):
+ represent = "hcloud_volume_info"
-class AnsibleHcloudVolumeInfo(Hcloud):
- def __init__(self, module):
- Hcloud.__init__(self, module, "hcloud_volume_info")
- self.hcloud_volume_info = None
+ hcloud_volume_info: list[BoundVolume] | None = None
def _prepare_result(self):
tmp = []
@@ -113,73 +115,59 @@ class AnsibleHcloudVolumeInfo(Hcloud):
server_name = None
if volume.server is not None:
server_name = to_native(volume.server.name)
- tmp.append({
- "id": to_native(volume.id),
- "name": to_native(volume.name),
- "size": volume.size,
- "location": to_native(volume.location.name),
- "labels": volume.labels,
- "server": server_name,
- "linux_device": to_native(volume.linux_device),
- "delete_protection": volume.protection["delete"],
- })
+ tmp.append(
+ {
+ "id": to_native(volume.id),
+ "name": to_native(volume.name),
+ "size": volume.size,
+ "location": to_native(volume.location.name),
+ "labels": volume.labels,
+ "server": server_name,
+ "linux_device": to_native(volume.linux_device),
+ "delete_protection": volume.protection["delete"],
+ }
+ )
return tmp
def get_volumes(self):
try:
if self.module.params.get("id") is not None:
- self.hcloud_volume_info = [self.client.volumes.get_by_id(
- self.module.params.get("id")
- )]
+ self.hcloud_volume_info = [self.client.volumes.get_by_id(self.module.params.get("id"))]
elif self.module.params.get("name") is not None:
- self.hcloud_volume_info = [self.client.volumes.get_by_name(
- self.module.params.get("name")
- )]
+ self.hcloud_volume_info = [self.client.volumes.get_by_name(self.module.params.get("name"))]
elif self.module.params.get("label_selector") is not None:
self.hcloud_volume_info = self.client.volumes.get_all(
- label_selector=self.module.params.get("label_selector"))
+ label_selector=self.module.params.get("label_selector")
+ )
else:
self.hcloud_volume_info = self.client.volumes.get_all()
- except Exception as e:
- self.module.fail_json(msg=e.message)
+ except HCloudException as exception:
+ self.fail_json_hcloud(exception)
- @staticmethod
- def define_module():
+ @classmethod
+ def define_module(cls):
return AnsibleModule(
argument_spec=dict(
id={"type": "int"},
name={"type": "str"},
label_selector={"type": "str"},
- **Hcloud.base_module_arguments()
+ **super().base_module_arguments(),
),
supports_check_mode=True,
)
def main():
- module = AnsibleHcloudVolumeInfo.define_module()
-
- is_old_facts = module._name == 'hcloud_volume_facts'
- if is_old_facts:
- module.deprecate("The 'hcloud_volume_facts' module has been renamed to 'hcloud_volume_info', "
- "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
-
- hcloud = AnsibleHcloudVolumeInfo(module)
+ module = AnsibleHCloudVolumeInfo.define_module()
+ hcloud = AnsibleHCloudVolumeInfo(module)
hcloud.get_volumes()
result = hcloud.get_result()
- if is_old_facts:
- ansible_info = {
- 'hcloud_volume_facts': result['hcloud_volume_info']
- }
- module.exit_json(ansible_facts=ansible_info)
- else:
- ansible_info = {
- 'hcloud_volume_info': result['hcloud_volume_info']
- }
- module.exit_json(**ansible_info)
+
+ ansible_info = {"hcloud_volume_info": result["hcloud_volume_info"]}
+ module.exit_json(**ansible_info)
if __name__ == "__main__":