mirror of
https://github.com/ansible-collections/hetzner.hcloud.git
synced 2026-02-04 08:01:49 +00:00
Implement Load Balancers and Certificates and prepare release (#13)
This commit is contained in:
parent
6d83275ffa
commit
769a63ff22
50 changed files with 2817 additions and 18 deletions
264
plugins/modules/hcloud_certificate.py
Normal file
264
plugins/modules/hcloud_certificate.py
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
#!/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
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.1",
|
||||
"status": ["preview"],
|
||||
"supported_by": "community",
|
||||
}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: hcloud_certificate
|
||||
|
||||
short_description: Create and manage certificates on the Hetzner Cloud.
|
||||
|
||||
|
||||
description:
|
||||
- Create, update and manage certificates on the Hetzner Cloud.
|
||||
|
||||
author:
|
||||
- Lukas Kaemmerling (@lkaemmerling)
|
||||
|
||||
options:
|
||||
id:
|
||||
description:
|
||||
- The ID of the Hetzner Cloud certificate to manage.
|
||||
- Only required if no certificate I(name) is given
|
||||
type: int
|
||||
name:
|
||||
description:
|
||||
- The Name of the Hetzner Cloud certificate to manage.
|
||||
- Only required if no certificate I(id) is given or a certificate does not exists.
|
||||
type: str
|
||||
labels:
|
||||
description:
|
||||
- User-defined labels (key-value pairs)
|
||||
type: dict
|
||||
certificate:
|
||||
description:
|
||||
- Certificate and chain in PEM format, in order so that each record directly certifies the one preceding.
|
||||
- Required if certificate does not exists.
|
||||
type: str
|
||||
private_key:
|
||||
description:
|
||||
- Certificate key in PEM format.
|
||||
- Required if certificate does not exists.
|
||||
type: str
|
||||
state:
|
||||
description:
|
||||
- State of the certificate.
|
||||
default: present
|
||||
choices: [ absent, present ]
|
||||
type: str
|
||||
extends_documentation_fragment:
|
||||
- hetzner.hcloud.hcloud
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Create a basic certificate
|
||||
hcloud_certificate:
|
||||
name: my-certificate
|
||||
certificate: "ssh-rsa AAAjjk76kgf...Xt"
|
||||
private_key: "ssh-rsa AAAjjk76kgf...Xt"
|
||||
state: present
|
||||
|
||||
- name: Create a certificate with labels
|
||||
hcloud_certificate:
|
||||
name: my-certificate
|
||||
certificate: "ssh-rsa AAAjjk76kgf...Xt"
|
||||
private_key: "ssh-rsa AAAjjk76kgf...Xt"
|
||||
labels:
|
||||
key: value
|
||||
mylabel: 123
|
||||
state: present
|
||||
|
||||
- name: Ensure the certificate is absent (remove if needed)
|
||||
hcloud_certificate:
|
||||
name: my-certificate
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
hcloud_certificate:
|
||||
description: The certificate instance
|
||||
returned: Always
|
||||
type: complex
|
||||
contains:
|
||||
id:
|
||||
description: Numeric identifier of the certificate
|
||||
returned: always
|
||||
type: int
|
||||
sample: 1937415
|
||||
name:
|
||||
description: Name of the certificate
|
||||
returned: always
|
||||
type: str
|
||||
sample: my website cert
|
||||
fingerprint:
|
||||
description: Fingerprint of the certificate
|
||||
returned: always
|
||||
type: str
|
||||
sample: "03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f"
|
||||
certificate:
|
||||
description: Certificate and chain in PEM format
|
||||
returned: always
|
||||
type: str
|
||||
sample: "-----BEGIN CERTIFICATE-----..."
|
||||
domain_names:
|
||||
description: List of Domains and Subdomains covered by the Certificate
|
||||
returned: always
|
||||
type: dict
|
||||
not_valid_before:
|
||||
description: Point in time when the Certificate becomes valid (in ISO-8601 format)
|
||||
returned: always
|
||||
type: str
|
||||
not_valid_after:
|
||||
description: Point in time when the Certificate stops being valid (in ISO-8601 format)
|
||||
returned: always
|
||||
type: str
|
||||
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
|
||||
|
||||
try:
|
||||
from hcloud.certificates.domain import Certificate
|
||||
from hcloud.certificates.domain import Server
|
||||
from hcloud import APIException
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class AnsibleHcloudCertificate(Hcloud):
|
||||
def __init__(self, module):
|
||||
Hcloud.__init__(self, module, "hcloud_certificate")
|
||||
self.hcloud_certificate = None
|
||||
|
||||
def _prepare_result(self):
|
||||
return {
|
||||
"id": to_native(self.hcloud_certificate.id),
|
||||
"name": to_native(self.hcloud_certificate.name),
|
||||
"fingerprint": to_native(self.hcloud_certificate.fingerprint),
|
||||
"certificate": to_native(self.hcloud_certificate.certificate),
|
||||
"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
|
||||
}
|
||||
|
||||
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")
|
||||
)
|
||||
elif self.module.params.get("name") is not None:
|
||||
self.hcloud_certificate = self.client.certificates.get_by_name(
|
||||
self.module.params.get("name")
|
||||
)
|
||||
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
def _create_certificate(self):
|
||||
self.module.fail_on_missing_params(
|
||||
required_params=["name", "certificate", "private_key"]
|
||||
)
|
||||
params = {
|
||||
"name": self.module.params.get("name"),
|
||||
"certificate": self.module.params.get("certificate"),
|
||||
"private_key": self.module.params.get("private_key"),
|
||||
"labels": self.module.params.get("labels")
|
||||
}
|
||||
|
||||
if not self.module.check_mode:
|
||||
try:
|
||||
self.client.certificates.create(**params)
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
self._mark_as_changed()
|
||||
self._get_certificate()
|
||||
|
||||
def _update_certificate(self):
|
||||
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"]
|
||||
)
|
||||
if not self.module.check_mode:
|
||||
self.hcloud_certificate.update(name=name)
|
||||
self._mark_as_changed()
|
||||
|
||||
labels = self.module.params.get("labels")
|
||||
if labels is not None and self.hcloud_certificate.labels != labels:
|
||||
if not self.module.check_mode:
|
||||
self.hcloud_certificate.update(labels=labels)
|
||||
self._mark_as_changed()
|
||||
|
||||
self._get_certificate()
|
||||
|
||||
def present_certificate(self):
|
||||
self._get_certificate()
|
||||
if self.hcloud_certificate is None:
|
||||
self._create_certificate()
|
||||
else:
|
||||
self._update_certificate()
|
||||
|
||||
def delete_certificate(self):
|
||||
self._get_certificate()
|
||||
if self.hcloud_certificate is not None:
|
||||
if not self.module.check_mode:
|
||||
self.client.certificates.delete(self.hcloud_certificate)
|
||||
self._mark_as_changed()
|
||||
self.hcloud_certificate = None
|
||||
|
||||
@staticmethod
|
||||
def define_module():
|
||||
return AnsibleModule(
|
||||
argument_spec=dict(
|
||||
id={"type": "int"},
|
||||
name={"type": "str"},
|
||||
certificate={"type": "str"},
|
||||
private_key={"type": "str"},
|
||||
labels={"type": "dict"},
|
||||
state={
|
||||
"choices": ["absent", "present"],
|
||||
"default": "present",
|
||||
},
|
||||
**Hcloud.base_module_arguments()
|
||||
),
|
||||
required_one_of=[['id', 'name']],
|
||||
required_if=[['state', 'present', ['name']]],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleHcloudCertificate.define_module()
|
||||
|
||||
hcloud = AnsibleHcloudCertificate(module)
|
||||
state = module.params.get("state")
|
||||
if state == "absent":
|
||||
hcloud.delete_certificate()
|
||||
elif state == "present":
|
||||
hcloud.present_certificate()
|
||||
|
||||
module.exit_json(**hcloud.get_result())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
173
plugins/modules/hcloud_certificate_info.py
Normal file
173
plugins/modules/hcloud_certificate_info.py
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#!/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
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.1",
|
||||
"status": ["preview"],
|
||||
"supported_by": "community",
|
||||
}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: hcloud_certificate_info
|
||||
short_description: Gather infos about your Hetzner Cloud certificates.
|
||||
description:
|
||||
- Gather facts about your Hetzner Cloud certificates.
|
||||
author:
|
||||
- Lukas Kaemmerling (@LKaemmerling)
|
||||
options:
|
||||
id:
|
||||
description:
|
||||
- The ID of the certificate you want to get.
|
||||
type: int
|
||||
name:
|
||||
description:
|
||||
- The name of the certificate you want to get.
|
||||
type: str
|
||||
label_selector:
|
||||
description:
|
||||
- The label selector for the certificate you want to get.
|
||||
type: str
|
||||
extends_documentation_fragment:
|
||||
- hetzner.hcloud.hcloud
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Gather hcloud certificate infos
|
||||
hcloud_certificate_info:
|
||||
register: output
|
||||
- name: Print the gathered infos
|
||||
debug:
|
||||
var: output.hcloud_certificate_info
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
hcloud_certificate_info:
|
||||
description: The certificate instances
|
||||
returned: Always
|
||||
type: complex
|
||||
contains:
|
||||
id:
|
||||
description: Numeric identifier of the certificate
|
||||
returned: always
|
||||
type: int
|
||||
sample: 1937415
|
||||
name:
|
||||
description: Name of the certificate
|
||||
returned: always
|
||||
type: str
|
||||
sample: my website cert
|
||||
fingerprint:
|
||||
description: Fingerprint of the certificate
|
||||
returned: always
|
||||
type: str
|
||||
sample: "03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f"
|
||||
certificate:
|
||||
description: Certificate and chain in PEM format
|
||||
returned: always
|
||||
type: str
|
||||
sample: "-----BEGIN CERTIFICATE-----..."
|
||||
domain_names:
|
||||
description: List of Domains and Subdomains covered by the Certificate
|
||||
returned: always
|
||||
type: dict
|
||||
not_valid_before:
|
||||
description: Point in time when the Certificate becomes valid (in ISO-8601 format)
|
||||
returned: always
|
||||
type: str
|
||||
not_valid_after:
|
||||
description: Point in time when the Certificate stops being valid (in ISO-8601 format)
|
||||
returned: always
|
||||
type: str
|
||||
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
|
||||
|
||||
try:
|
||||
from hcloud import APIException
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class AnsibleHcloudCertificateInfo(Hcloud):
|
||||
def __init__(self, module):
|
||||
Hcloud.__init__(self, module, "hcloud_certificate_info")
|
||||
self.hcloud_certificate_info = 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
|
||||
})
|
||||
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")
|
||||
)]
|
||||
elif self.module.params.get("name") is not None:
|
||||
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"))
|
||||
else:
|
||||
self.hcloud_certificate_info = self.client.certificates.get_all()
|
||||
|
||||
except APIException 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 = AnsibleHcloudCertificateInfo.define_module()
|
||||
|
||||
hcloud = AnsibleHcloudCertificateInfo(module)
|
||||
hcloud.get_certificates()
|
||||
result = hcloud.get_result()
|
||||
|
||||
ansible_info = {
|
||||
'hcloud_certificate_info': result['hcloud_certificate_info']
|
||||
}
|
||||
module.exit_json(**ansible_info)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -20,7 +20,7 @@ description:
|
|||
|
||||
author:
|
||||
- Lukas Kaemmerling (@lkaemmerling)
|
||||
|
||||
version_added: 0.1.0
|
||||
options:
|
||||
id:
|
||||
description:
|
||||
|
|
@ -155,7 +155,7 @@ hcloud_floating_ip:
|
|||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
labels:
|
||||
description: User-defined labels (key-value pairs)
|
||||
type: dict
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ hcloud_floating_ip_info:
|
|||
returned: Always
|
||||
type: str
|
||||
sample: my-floating-ip
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
description:
|
||||
description: Description of the Floating IP
|
||||
returned: always
|
||||
|
|
@ -91,7 +91,7 @@ hcloud_floating_ip_info:
|
|||
description: True if the Floating IP is protected for deletion
|
||||
returned: always
|
||||
type: bool
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
labels:
|
||||
description: User-defined labels (key-value pairs)
|
||||
returned: always
|
||||
|
|
|
|||
307
plugins/modules/hcloud_load_balancer.py
Normal file
307
plugins/modules/hcloud_load_balancer.py
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
#!/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
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: hcloud_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.
|
||||
|
||||
author:
|
||||
- Lukas Kaemmerling (@LKaemmerling)
|
||||
version_added: 0.1.0
|
||||
options:
|
||||
id:
|
||||
description:
|
||||
- The ID of the Hetzner Cloud Load Balancer to manage.
|
||||
- Only required if no Load Balancer I(name) is given
|
||||
type: int
|
||||
name:
|
||||
description:
|
||||
- The Name of the Hetzner Cloud Load Balancer to manage.
|
||||
- Only required if no Load Balancer I(id) is given or a Load Balancer does not exists.
|
||||
type: str
|
||||
load_balancer_type:
|
||||
description:
|
||||
- The Load Balancer Type of the Hetzner Cloud Load Balancer to manage.
|
||||
- Required if Load Balancer does not exists.
|
||||
type: str
|
||||
location:
|
||||
description:
|
||||
- Location of Load Balancer.
|
||||
- Required if no I(network_zone) is given and Load Balancer does not exists.
|
||||
type: str
|
||||
network_zone:
|
||||
description:
|
||||
- Network Zone of Load Balancer.
|
||||
- Required of no I(location) is given and Load Balancer does not exists.
|
||||
type: str
|
||||
labels:
|
||||
description:
|
||||
- User-defined labels (key-value pairs).
|
||||
type: dict
|
||||
disable_public_interface:
|
||||
description:
|
||||
- Disables the public interface.
|
||||
type: bool
|
||||
default: False
|
||||
delete_protection:
|
||||
description:
|
||||
- Protect the Load Balancer for deletion.
|
||||
type: bool
|
||||
state:
|
||||
description:
|
||||
- State of the Load Balancer.
|
||||
default: present
|
||||
choices: [ absent, present ]
|
||||
type: str
|
||||
extends_documentation_fragment:
|
||||
- hetzner.hcloud.hcloud
|
||||
|
||||
requirements:
|
||||
- hcloud-python >= 1.8.0
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Create a basic Load Balancer
|
||||
hcloud_load_balancer:
|
||||
name: my-Load Balancer
|
||||
load_balancer_type: lb11
|
||||
location: fsn1
|
||||
state: present
|
||||
|
||||
- name: Ensure the Load Balancer is absent (remove if needed)
|
||||
hcloud_load_balancer:
|
||||
name: my-Load Balancer
|
||||
state: absent
|
||||
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
hcloud_load_balancer:
|
||||
description: The Load Balancer instance
|
||||
returned: Always
|
||||
type: complex
|
||||
contains:
|
||||
id:
|
||||
description: Numeric identifier of the Load Balancer
|
||||
returned: always
|
||||
type: int
|
||||
sample: 1937415
|
||||
name:
|
||||
description: Name of the Load Balancer
|
||||
returned: always
|
||||
type: str
|
||||
sample: my-Load-Balancer
|
||||
status:
|
||||
description: Status of the Load Balancer
|
||||
returned: always
|
||||
type: str
|
||||
sample: running
|
||||
load_balancer_type:
|
||||
description: Name of the Load Balancer type of the Load Balancer
|
||||
returned: always
|
||||
type: str
|
||||
sample: cx11
|
||||
ipv4_address:
|
||||
description: Public IPv4 address of the Load Balancer
|
||||
returned: always
|
||||
type: str
|
||||
sample: 116.203.104.109
|
||||
ipv6_address:
|
||||
description: Public IPv6 address of the Load Balancer
|
||||
returned: always
|
||||
type: str
|
||||
sample: 2a01:4f8:1c1c:c140::1
|
||||
location:
|
||||
description: Name of the location of the Load Balancer
|
||||
returned: always
|
||||
type: str
|
||||
sample: fsn1
|
||||
labels:
|
||||
description: User-defined labels (key-value pairs)
|
||||
returned: always
|
||||
type: dict
|
||||
delete_protection:
|
||||
description: True if Load Balancer is protected for deletion
|
||||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
disable_public_interface:
|
||||
description: True if Load Balancer public interface is disabled
|
||||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
try:
|
||||
from hcloud.load_balancers.domain import LoadBalancer
|
||||
from hcloud import APIException
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class AnsibleHcloudLoadBalancer(Hcloud):
|
||||
def __init__(self, module):
|
||||
Hcloud.__init__(self, module, "hcloud_load_balancer")
|
||||
self.hcloud_load_balancer = 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)
|
||||
return {
|
||||
"id": to_native(self.hcloud_load_balancer.id),
|
||||
"name": to_native(self.hcloud_load_balancer.name),
|
||||
"ipv4_address": to_native(self.hcloud_load_balancer.public_net.ipv4.ip),
|
||||
"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),
|
||||
"location": to_native(self.hcloud_load_balancer.location.name),
|
||||
"labels": self.hcloud_load_balancer.labels,
|
||||
"delete_protection": self.hcloud_load_balancer.protection["delete"],
|
||||
"disable_public_interface": self.hcloud_load_balancer.public_net.enabled
|
||||
}
|
||||
|
||||
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")
|
||||
)
|
||||
else:
|
||||
self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
|
||||
self.module.params.get("name")
|
||||
)
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
def _create_load_balancer(self):
|
||||
|
||||
self.module.fail_on_missing_params(
|
||||
required_params=["name", "load_balancer_type"]
|
||||
)
|
||||
|
||||
params = {
|
||||
"name": self.module.params.get("name"),
|
||||
"load_balancer_type": self.client.load_balancer_types.get_by_name(
|
||||
self.module.params.get("load_balancer_type")
|
||||
),
|
||||
"labels": self.module.params.get("labels"),
|
||||
}
|
||||
|
||||
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")
|
||||
)
|
||||
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")
|
||||
|
||||
if not self.module.check_mode:
|
||||
resp = self.client.load_balancers.create(**params)
|
||||
resp.action.wait_until_finished(max_retries=1000)
|
||||
|
||||
self._mark_as_changed()
|
||||
self._get_load_balancer()
|
||||
self._update_load_balancer()
|
||||
|
||||
def _update_load_balancer(self):
|
||||
try:
|
||||
labels = self.module.params.get("labels")
|
||||
if labels is not None and labels != self.hcloud_load_balancer.labels:
|
||||
if not self.module.check_mode:
|
||||
self.hcloud_load_balancer.update(labels=labels)
|
||||
self._mark_as_changed()
|
||||
|
||||
delete_protection = self.module.params.get("delete_protection")
|
||||
if delete_protection is not None and delete_protection != self.hcloud_load_balancer.protection["delete"]:
|
||||
if not self.module.check_mode:
|
||||
self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished()
|
||||
self._mark_as_changed()
|
||||
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 != 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()
|
||||
else:
|
||||
self.hcloud_load_balancer.enable_public_interface().wait_until_finished()
|
||||
self._mark_as_changed()
|
||||
self._get_load_balancer()
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
def present_load_balancer(self):
|
||||
self._get_load_balancer()
|
||||
if self.hcloud_load_balancer is None:
|
||||
self._create_load_balancer()
|
||||
else:
|
||||
self._update_load_balancer()
|
||||
|
||||
def delete_load_balancer(self):
|
||||
try:
|
||||
self._get_load_balancer()
|
||||
if self.hcloud_load_balancer is not None:
|
||||
if not self.module.check_mode:
|
||||
self.client.load_balancers.delete(self.hcloud_load_balancer)
|
||||
self._mark_as_changed()
|
||||
self.hcloud_load_balancer = None
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
@staticmethod
|
||||
def define_module():
|
||||
return AnsibleModule(
|
||||
argument_spec=dict(
|
||||
id={"type": "int"},
|
||||
name={"type": "str"},
|
||||
load_balancer_type={"type": "str"},
|
||||
location={"type": "str"},
|
||||
network_zone={"type": "str"},
|
||||
labels={"type": "dict"},
|
||||
delete_protection={"type": "bool"},
|
||||
disable_public_interface={"type": "bool", "default": False},
|
||||
state={
|
||||
"choices": ["absent", "present"],
|
||||
"default": "present",
|
||||
},
|
||||
**Hcloud.base_module_arguments()
|
||||
),
|
||||
required_one_of=[['id', 'name']],
|
||||
mutually_exclusive=[["location", "network_zone"]],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleHcloudLoadBalancer.define_module()
|
||||
|
||||
hcloud = AnsibleHcloudLoadBalancer(module)
|
||||
state = module.params.get("state")
|
||||
if state == "absent":
|
||||
hcloud.delete_load_balancer()
|
||||
elif state == "present":
|
||||
hcloud.present_load_balancer()
|
||||
|
||||
module.exit_json(**hcloud.get_result())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
201
plugins/modules/hcloud_load_balancer_network.py
Normal file
201
plugins/modules/hcloud_load_balancer_network.py
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
#!/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
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: hcloud_load_balancer_network
|
||||
|
||||
short_description: Manage the relationship between Hetzner Cloud Networks and Load Balancers
|
||||
|
||||
|
||||
description:
|
||||
- Create and delete the relationship Hetzner Cloud Networks and Load Balancers
|
||||
|
||||
author:
|
||||
- Lukas Kaemmerling (@lkaemmerling)
|
||||
version_added: 0.1.0
|
||||
options:
|
||||
network:
|
||||
description:
|
||||
- The name of the Hetzner Cloud Networks.
|
||||
type: str
|
||||
required: true
|
||||
load_balancer:
|
||||
description:
|
||||
- The name of the Hetzner Cloud Load Balancer.
|
||||
type: str
|
||||
required: true
|
||||
ip:
|
||||
description:
|
||||
- The IP the Load Balancer should have.
|
||||
type: str
|
||||
state:
|
||||
description:
|
||||
- State of the load_balancer_network.
|
||||
default: present
|
||||
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:
|
||||
network: my-network
|
||||
load_balancer: my-LoadBalancer
|
||||
state: present
|
||||
|
||||
- name: Create a Load Balancer network and specify the ip address
|
||||
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:
|
||||
network: my-network
|
||||
load_balancer: my-LoadBalancer
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
hcloud_load_balancer_network:
|
||||
description: The relationship between a Load Balancer and a network
|
||||
returned: always
|
||||
type: complex
|
||||
contains:
|
||||
network:
|
||||
description: Name of the Network
|
||||
type: str
|
||||
returned: always
|
||||
sample: my-network
|
||||
load_balancer:
|
||||
description: Name of the Load Balancer
|
||||
type: str
|
||||
returned: always
|
||||
sample: my-LoadBalancer
|
||||
ip:
|
||||
description: IP of the Load Balancer within the Network ip range
|
||||
type: str
|
||||
returned: always
|
||||
sample: 10.0.0.8
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
try:
|
||||
from hcloud import APIException
|
||||
except ImportError:
|
||||
APIException = None
|
||||
NetworkSubnet = None
|
||||
|
||||
|
||||
class AnsibleHcloudLoadBalancerNetwork(Hcloud):
|
||||
def __init__(self, module):
|
||||
super(AnsibleHcloudLoadBalancerNetwork, self).__init__(module, "hcloud_load_balancer_network")
|
||||
self.hcloud_network = None
|
||||
self.hcloud_load_balancer = None
|
||||
self.hcloud_load_balancer_network = None
|
||||
|
||||
def _prepare_result(self):
|
||||
return {
|
||||
"network": to_native(self.hcloud_network.name),
|
||||
"load_balancer": to_native(self.hcloud_load_balancer.name),
|
||||
"ip": to_native(self.hcloud_load_balancer_network.ip),
|
||||
}
|
||||
|
||||
def _get_load_balancer_and_network(self):
|
||||
try:
|
||||
self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
|
||||
self.hcloud_load_balancer = self.client.load_balancers.get_by_name(self.module.params.get("load_balancer"))
|
||||
self.hcloud_load_balancer_network = None
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
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
|
||||
|
||||
def _create_load_balancer_network(self):
|
||||
params = {
|
||||
"network": self.hcloud_network
|
||||
}
|
||||
|
||||
if self.module.params.get("ip") is not None:
|
||||
params["ip"] = self.module.params.get("ip")
|
||||
|
||||
if not self.module.check_mode:
|
||||
try:
|
||||
self.hcloud_load_balancer.attach_to_network(**params).wait_until_finished()
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
self._mark_as_changed()
|
||||
self._get_load_balancer_and_network()
|
||||
self._get_load_balancer_network()
|
||||
|
||||
def present_load_balancer_network(self):
|
||||
self._get_load_balancer_and_network()
|
||||
self._get_load_balancer_network()
|
||||
if self.hcloud_load_balancer_network is None:
|
||||
self._create_load_balancer_network()
|
||||
|
||||
def delete_load_balancer_network(self):
|
||||
self._get_load_balancer_and_network()
|
||||
self._get_load_balancer_network()
|
||||
if self.hcloud_load_balancer_network is not None and self.hcloud_load_balancer is not None:
|
||||
if not self.module.check_mode:
|
||||
self.hcloud_load_balancer.detach_from_network(
|
||||
self.hcloud_load_balancer_network.network).wait_until_finished()
|
||||
self._mark_as_changed()
|
||||
self.hcloud_load_balancer_network = None
|
||||
|
||||
@staticmethod
|
||||
def define_module():
|
||||
return AnsibleModule(
|
||||
argument_spec=dict(
|
||||
network={"type": "str", "required": True},
|
||||
load_balancer={"type": "str", "required": True},
|
||||
ip={"type": "str"},
|
||||
state={
|
||||
"choices": ["absent", "present"],
|
||||
"default": "present",
|
||||
},
|
||||
**Hcloud.base_module_arguments()
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleHcloudLoadBalancerNetwork.define_module()
|
||||
|
||||
hcloud = AnsibleHcloudLoadBalancerNetwork(module)
|
||||
state = module.params["state"]
|
||||
if state == "absent":
|
||||
hcloud.delete_load_balancer_network()
|
||||
elif state == "present":
|
||||
hcloud.present_load_balancer_network()
|
||||
|
||||
module.exit_json(**hcloud.get_result())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
609
plugins/modules/hcloud_load_balancer_service.py
Normal file
609
plugins/modules/hcloud_load_balancer_service.py
Normal file
|
|
@ -0,0 +1,609 @@
|
|||
#!/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
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: hcloud_load_balancer_service
|
||||
|
||||
short_description: Create and manage the services of cloud Load Balancers on the Hetzner Cloud.
|
||||
|
||||
|
||||
description:
|
||||
- Create, update and manage the services of cloud Load Balancers on the Hetzner Cloud.
|
||||
|
||||
author:
|
||||
- Lukas Kaemmerling (@LKaemmerling)
|
||||
version_added: 0.1.0
|
||||
options:
|
||||
load_balancer:
|
||||
description:
|
||||
- The Name of the Hetzner Cloud Load Balancer the service belongs to
|
||||
type: str
|
||||
required: true
|
||||
listen_port:
|
||||
description:
|
||||
- The port the service listens on, i.e. the port users can connect to.
|
||||
type: int
|
||||
required: true
|
||||
destination_port:
|
||||
description:
|
||||
- The port traffic is forwarded to, i.e. the port the targets are listening and accepting connections on.
|
||||
- Required if services does not exists and protocol is tcp.
|
||||
type: int
|
||||
protocol:
|
||||
description:
|
||||
- Protocol of the service.
|
||||
- Required if Load Balancer does not exists.
|
||||
type: str
|
||||
choices: [ http, https, tcp ]
|
||||
proxyprotocol:
|
||||
description:
|
||||
- Enable the PROXY protocol.
|
||||
type: bool
|
||||
http:
|
||||
description:
|
||||
- Configuration for HTTP and HTTPS services
|
||||
type: dict
|
||||
suboptions:
|
||||
cookie_name:
|
||||
description:
|
||||
- Name of the cookie which will be set when you enable sticky sessions
|
||||
type: str
|
||||
cookie_lifetime:
|
||||
description:
|
||||
- Lifetime of the cookie which will be set when you enable sticky sessions, in seconds
|
||||
type: int
|
||||
certificates:
|
||||
description:
|
||||
- List of Names or IDs of certificates
|
||||
type: list
|
||||
elements: str
|
||||
sticky_sessions:
|
||||
description:
|
||||
- Enable or disable sticky_sessions
|
||||
type: bool
|
||||
redirect_http:
|
||||
description:
|
||||
- Redirect Traffic from Port 80 to Port 443, only available if protocol is https
|
||||
type: bool
|
||||
health_check:
|
||||
description:
|
||||
- Configuration for health checks
|
||||
type: dict
|
||||
suboptions:
|
||||
protocol:
|
||||
description:
|
||||
- Protocol the health checks will be performed over
|
||||
type: str
|
||||
choices: [ http, https, tcp ]
|
||||
port:
|
||||
description:
|
||||
- Port the health check will be performed on
|
||||
type: int
|
||||
interval:
|
||||
description:
|
||||
- Interval of health checks, in seconds
|
||||
type: int
|
||||
timeout:
|
||||
description:
|
||||
- Timeout of health checks, in seconds
|
||||
type: int
|
||||
retries:
|
||||
description:
|
||||
- Number of retries until a target is marked as unhealthy
|
||||
type: int
|
||||
http:
|
||||
description:
|
||||
- Additional Configuration of health checks with protocol http/https
|
||||
type: dict
|
||||
suboptions:
|
||||
domain:
|
||||
description:
|
||||
- Domain we will set within the HTTP HOST header
|
||||
type: str
|
||||
path:
|
||||
description:
|
||||
- Path we will try to access
|
||||
type: str
|
||||
response:
|
||||
description:
|
||||
- Response we expect, if response is not within the health check response the target is unhealthy
|
||||
type: str
|
||||
status_codes:
|
||||
description:
|
||||
- List of HTTP status codes we expect to get when we perform the health check.
|
||||
type: list
|
||||
elements: str
|
||||
tls:
|
||||
description:
|
||||
- Verify the TLS certificate, only available if health check protocol is https
|
||||
type: bool
|
||||
state:
|
||||
description:
|
||||
- State of the Load Balancer.
|
||||
default: present
|
||||
choices: [ absent, present ]
|
||||
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:
|
||||
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:
|
||||
load_balancer: my-Load Balancer
|
||||
protocol: http
|
||||
listen_port: 80
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
hcloud_load_balancer_service:
|
||||
description: The Load Balancer service instance
|
||||
returned: Always
|
||||
type: complex
|
||||
contains:
|
||||
load_balancer:
|
||||
description: The name of the Load Balancer where the service belongs to
|
||||
returned: always
|
||||
type: str
|
||||
sample: my-load-balancer
|
||||
listen_port:
|
||||
description: The port the service listens on, i.e. the port users can connect to.
|
||||
returned: always
|
||||
type: int
|
||||
sample: 443
|
||||
protocol:
|
||||
description: Protocol of the service
|
||||
returned: always
|
||||
type: str
|
||||
sample: http
|
||||
destination_port:
|
||||
description:
|
||||
- The port traffic is forwarded to, i.e. the port the targets are listening and accepting connections on.
|
||||
returned: always
|
||||
type: int
|
||||
sample: 80
|
||||
proxyprotocol:
|
||||
description:
|
||||
- Enable the PROXY protocol.
|
||||
returned: always
|
||||
type: bool
|
||||
sample: false
|
||||
http:
|
||||
description: Configuration for HTTP and HTTPS services
|
||||
returned: always
|
||||
type: complex
|
||||
contains:
|
||||
cookie_name:
|
||||
description: Name of the cookie which will be set when you enable sticky sessions
|
||||
returned: always
|
||||
type: str
|
||||
sample: HCLBSTICKY
|
||||
cookie_lifetime:
|
||||
description: Lifetime of the cookie which will be set when you enable sticky sessions, in seconds
|
||||
returned: always
|
||||
type: int
|
||||
sample: 3600
|
||||
certificates:
|
||||
description: List of Names or IDs of certificates
|
||||
returned: always
|
||||
type: list
|
||||
elements: str
|
||||
sticky_sessions:
|
||||
description: Enable or disable sticky_sessions
|
||||
returned: always
|
||||
type: bool
|
||||
sample: true
|
||||
redirect_http:
|
||||
description: Redirect Traffic from Port 80 to Port 443, only available if protocol is https
|
||||
returned: always
|
||||
type: bool
|
||||
sample: false
|
||||
health_check:
|
||||
description: Configuration for health checks
|
||||
returned: always
|
||||
type: complex
|
||||
contains:
|
||||
protocol:
|
||||
description: Protocol the health checks will be performed over
|
||||
returned: always
|
||||
type: str
|
||||
sample: http
|
||||
port:
|
||||
description: Port the health check will be performed on
|
||||
returned: always
|
||||
type: int
|
||||
sample: 80
|
||||
interval:
|
||||
description: Interval of health checks, in seconds
|
||||
returned: always
|
||||
type: int
|
||||
sample: 15
|
||||
timeout:
|
||||
description: Timeout of health checks, in seconds
|
||||
returned: always
|
||||
type: int
|
||||
sample: 10
|
||||
retries:
|
||||
description: Number of retries until a target is marked as unhealthy
|
||||
returned: always
|
||||
type: int
|
||||
sample: 3
|
||||
http:
|
||||
description: Additional Configuration of health checks with protocol http/https
|
||||
returned: always
|
||||
type: complex
|
||||
contains:
|
||||
domain:
|
||||
description: Domain we will set within the HTTP HOST header
|
||||
returned: always
|
||||
type: str
|
||||
sample: example.com
|
||||
path:
|
||||
description: Path we will try to access
|
||||
returned: always
|
||||
type: str
|
||||
sample: /
|
||||
response:
|
||||
description: Response we expect, if response is not within the health check response the target is unhealthy
|
||||
returned: always
|
||||
type: str
|
||||
status_codes:
|
||||
description: List of HTTP status codes we expect to get when we perform the health check.
|
||||
returned: always
|
||||
type: list
|
||||
elements: str
|
||||
sample: ["2??","3??"]
|
||||
tls:
|
||||
description: Verify the TLS certificate, only available if health check protocol is https
|
||||
returned: always
|
||||
type: bool
|
||||
sample: false
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
try:
|
||||
from hcloud.load_balancers.domain import LoadBalancer, LoadBalancerService, LoadBalancerServiceHttp, \
|
||||
LoadBalancerServiceHealthCheck, LoadBalancerServiceHealthCheckHttp
|
||||
from hcloud import APIException
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
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
|
||||
|
||||
def _prepare_result(self):
|
||||
http = None
|
||||
if self.hcloud_load_balancer_service.protocol != "tcp":
|
||||
http = {
|
||||
"cookie_name": to_native(self.hcloud_load_balancer_service.http.cookie_name),
|
||||
"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],
|
||||
}
|
||||
health_check = {
|
||||
"protocol": to_native(self.hcloud_load_balancer_service.health_check.protocol),
|
||||
"port": self.hcloud_load_balancer_service.health_check.port,
|
||||
"interval": self.hcloud_load_balancer_service.health_check.interval,
|
||||
"timeout": self.hcloud_load_balancer_service.health_check.timeout,
|
||||
"retries": self.hcloud_load_balancer_service.health_check.retries,
|
||||
}
|
||||
if self.hcloud_load_balancer_service.health_check.protocol != "tcp":
|
||||
health_check["http"] = {
|
||||
"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],
|
||||
"tls": self.hcloud_load_balancer_service.health_check.tls,
|
||||
}
|
||||
return {
|
||||
"load_balancer": to_native(self.hcloud_load_balancer.name),
|
||||
"protocol": to_native(self.hcloud_load_balancer_service.protocol),
|
||||
"listen_port": self.hcloud_load_balancer_service.listen_port,
|
||||
"destination_port": self.hcloud_load_balancer_service.destination_port,
|
||||
"proxyprotocol": self.hcloud_load_balancer_service.proxyprotocol,
|
||||
"http": http,
|
||||
"health_check": health_check,
|
||||
}
|
||||
|
||||
def _get_load_balancer(self):
|
||||
try:
|
||||
self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
|
||||
self.module.params.get("load_balancer")
|
||||
)
|
||||
self._get_load_balancer_service()
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
def _create_load_balancer_service(self):
|
||||
|
||||
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"]
|
||||
)
|
||||
|
||||
params = {
|
||||
"protocol": self.module.params.get("protocol"),
|
||||
"listen_port": self.module.params.get("listen_port"),
|
||||
"proxyprotocol": self.module.params.get("proxyprotocol")
|
||||
}
|
||||
|
||||
if self.module.params.get("destination_port"):
|
||||
params["destination_port"] = self.module.params.get("destination_port")
|
||||
|
||||
if self.module.params.get("http"):
|
||||
params["http"] = self.__get_service_http(http_arg=self.module.params.get("http"))
|
||||
|
||||
if self.module.params.get("health_check"):
|
||||
params["health_check"] = self.__get_service_health_checks(
|
||||
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 APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
self._mark_as_changed()
|
||||
self._get_load_balancer()
|
||||
self._get_load_balancer_service()
|
||||
|
||||
def __get_service_http(self, http_arg):
|
||||
service_http = LoadBalancerServiceHttp(certificates=[])
|
||||
if http_arg.get("cookie_name") is not None:
|
||||
service_http.cookie_name = http_arg.get("cookie_name")
|
||||
if http_arg.get("cookie_lifetime") is not None:
|
||||
service_http.cookie_lifetime = http_arg.get("cookie_lifetime")
|
||||
if http_arg.get("sticky_sessions") is not None:
|
||||
service_http.sticky_sessions = http_arg.get("sticky_sessions")
|
||||
if http_arg.get("redirect_http") is not None:
|
||||
service_http.redirect_http = http_arg.get("redirect_http")
|
||||
if http_arg.get("certificates") is not None:
|
||||
certificates = http_arg.get("certificates")
|
||||
if certificates is not None:
|
||||
for certificate in certificates:
|
||||
hcloud_cert = None
|
||||
try:
|
||||
try:
|
||||
hcloud_cert = self.client.certificates.get_by_name(
|
||||
certificate
|
||||
)
|
||||
except APIException:
|
||||
hcloud_cert = self.client.certificates.get_by_id(
|
||||
certificate
|
||||
)
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
service_http.certificates.append(hcloud_cert)
|
||||
|
||||
return service_http
|
||||
|
||||
def __get_service_health_checks(self, health_check):
|
||||
service_health_check = LoadBalancerServiceHealthCheck()
|
||||
if health_check.get("protocol") is not None:
|
||||
service_health_check.protocol = health_check.get("protocol")
|
||||
if health_check.get("port") is not None:
|
||||
service_health_check.port = health_check.get("port")
|
||||
if health_check.get("interval") is not None:
|
||||
service_health_check.interval = health_check.get("interval")
|
||||
if health_check.get("timeout") is not None:
|
||||
service_health_check.timeout = health_check.get("timeout")
|
||||
if health_check.get("retries") is not None:
|
||||
service_health_check.retries = health_check.get("retries")
|
||||
if health_check.get("http") is not None:
|
||||
health_check_http = health_check.get("http")
|
||||
service_health_check.http = LoadBalancerServiceHealthCheckHttp()
|
||||
if health_check_http.get("domain") is not None:
|
||||
service_health_check.http.domain = health_check_http.get("domain")
|
||||
if health_check_http.get("path") is not None:
|
||||
service_health_check.http.path = health_check_http.get("path")
|
||||
if health_check_http.get("response") is not None:
|
||||
service_health_check.http.response = health_check_http.get("response")
|
||||
if health_check_http.get("status_codes") is not None:
|
||||
service_health_check.http.status_codes = health_check_http.get("status_codes")
|
||||
if health_check_http.get("tls") is not None:
|
||||
service_health_check.http.tls = health_check_http.get("tls")
|
||||
|
||||
return service_health_check
|
||||
|
||||
def _update_load_balancer_service(self):
|
||||
changed = False
|
||||
try:
|
||||
params = {
|
||||
"listen_port": self.module.params.get("listen_port"),
|
||||
}
|
||||
|
||||
if self.module.params.get("destination_port") is not None:
|
||||
if self.hcloud_load_balancer_service.destination_port != self.module.params.get("destination_port"):
|
||||
params["destination_port"] = self.module.params.get("destination_port")
|
||||
changed = True
|
||||
|
||||
if self.module.params.get("protocol") is not None:
|
||||
if self.hcloud_load_balancer_service.protocol != self.module.params.get("protocol"):
|
||||
params["protocol"] = self.module.params.get("protocol")
|
||||
changed = True
|
||||
|
||||
if self.module.params.get("proxyprotocol") is not None:
|
||||
if self.hcloud_load_balancer_service.proxyprotocol != self.module.params.get("proxyprotocol"):
|
||||
params["proxyprotocol"] = self.module.params.get("proxyprotocol")
|
||||
changed = True
|
||||
|
||||
if self.module.params.get("http") is not None:
|
||||
params["http"] = self.__get_service_http(http_arg=self.module.params.get("http"))
|
||||
changed = True
|
||||
|
||||
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"))
|
||||
changed = True
|
||||
|
||||
if not self.module.check_mode:
|
||||
self.hcloud_load_balancer.update_service(LoadBalancerService(**params)).wait_until_finished(
|
||||
max_retries=1000)
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
self._get_load_balancer()
|
||||
|
||||
if changed:
|
||||
self._mark_as_changed()
|
||||
|
||||
def _get_load_balancer_service(self):
|
||||
for service in self.hcloud_load_balancer.services:
|
||||
if self.module.params.get("listen_port") == service.listen_port:
|
||||
self.hcloud_load_balancer_service = service
|
||||
|
||||
def present_load_balancer_service(self):
|
||||
self._get_load_balancer()
|
||||
if self.hcloud_load_balancer_service is None:
|
||||
self._create_load_balancer_service()
|
||||
else:
|
||||
self._update_load_balancer_service()
|
||||
|
||||
def delete_load_balancer_service(self):
|
||||
try:
|
||||
self._get_load_balancer()
|
||||
if self.hcloud_load_balancer_service is not None:
|
||||
if not self.module.check_mode:
|
||||
self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service).wait_until_finished(
|
||||
max_retries=1000)
|
||||
self._mark_as_changed()
|
||||
self.hcloud_load_balancer_service = None
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
@staticmethod
|
||||
def define_module():
|
||||
return AnsibleModule(
|
||||
argument_spec=dict(
|
||||
load_balancer={"type": "str", "required": True},
|
||||
listen_port={"type": "int", "required": True},
|
||||
destination_port={"type": "int"},
|
||||
protocol={
|
||||
"type": "str",
|
||||
"choices": ["http", "https", "tcp"],
|
||||
},
|
||||
proxyprotocol={"type": "bool", "default": False},
|
||||
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"
|
||||
},
|
||||
|
||||
)
|
||||
},
|
||||
health_check={
|
||||
"type": "dict",
|
||||
"options": dict(
|
||||
protocol={
|
||||
"type": "str",
|
||||
"choices": ["http", "https", "tcp"],
|
||||
},
|
||||
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
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
},
|
||||
state={
|
||||
"choices": ["absent", "present"],
|
||||
"default": "present",
|
||||
},
|
||||
**Hcloud.base_module_arguments()
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleHcloudLoadBalancerService.define_module()
|
||||
|
||||
hcloud = AnsibleHcloudLoadBalancerService(module)
|
||||
state = module.params.get("state")
|
||||
if state == "absent":
|
||||
hcloud.delete_load_balancer_service()
|
||||
elif state == "present":
|
||||
hcloud.present_load_balancer_service()
|
||||
|
||||
module.exit_json(**hcloud.get_result())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
213
plugins/modules/hcloud_load_balancer_target.py
Normal file
213
plugins/modules/hcloud_load_balancer_target.py
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
#!/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_load_balancer_target
|
||||
|
||||
short_description: Manage Hetzner Cloud Load Balancer targets
|
||||
|
||||
|
||||
description:
|
||||
- Create and delete Hetzner Cloud Load Balancer targets
|
||||
|
||||
author:
|
||||
- Lukas Kaemmerling (@lkaemmerling)
|
||||
version_added: 0.1.0
|
||||
options:
|
||||
type:
|
||||
description:
|
||||
- The type of the target.
|
||||
type: str
|
||||
choices: [ server ]
|
||||
required: true
|
||||
load_balancer:
|
||||
description:
|
||||
- The name of the Hetzner Cloud Load Balancer.
|
||||
type: str
|
||||
required: true
|
||||
server:
|
||||
description:
|
||||
- The name of the Hetzner Cloud Server.
|
||||
- Required if I(type) is server
|
||||
type: str
|
||||
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)
|
||||
type: bool
|
||||
state:
|
||||
description:
|
||||
- State of the load_balancer_network.
|
||||
default: present
|
||||
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
|
||||
hcloud_load_balancer_target:
|
||||
type: server
|
||||
load_balancer: my-LoadBalancer
|
||||
server: my-server
|
||||
state: present
|
||||
|
||||
- name: Ensure the Load Balancer target is absent (remove if needed)
|
||||
hcloud_load_balancer_target:
|
||||
type: server
|
||||
load_balancer: my-LoadBalancer
|
||||
server: my-server
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
hcloud_load_balancer_target:
|
||||
description: The relationship between a Load Balancer and a network
|
||||
returned: always
|
||||
type: complex
|
||||
contains:
|
||||
type:
|
||||
description: Type of the Load Balancer Target
|
||||
type: str
|
||||
returned: always
|
||||
sample: server
|
||||
load_balancer:
|
||||
description: Name of the Load Balancer
|
||||
type: str
|
||||
returned: always
|
||||
sample: my-LoadBalancer
|
||||
server:
|
||||
description: Name of the Server
|
||||
type: str
|
||||
returned: if I(type) is server
|
||||
sample: my-server
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
try:
|
||||
from hcloud import APIException
|
||||
from hcloud.load_balancers.domain import LoadBalancerTarget
|
||||
except ImportError:
|
||||
APIException = None
|
||||
|
||||
|
||||
class AnsibleHcloudLoadBalancerTarget(Hcloud):
|
||||
def __init__(self, module):
|
||||
super(AnsibleHcloudLoadBalancerTarget, self).__init__(module, "hcloud_load_balancer_target")
|
||||
self.hcloud_load_balancer = None
|
||||
self.hcloud_load_balancer_target = None
|
||||
self.hcloud_server = None
|
||||
|
||||
def _prepare_result(self):
|
||||
return {
|
||||
"type": to_native(self.hcloud_load_balancer_target.type),
|
||||
"load_balancer": to_native(self.hcloud_load_balancer.name),
|
||||
"server": to_native(self.hcloud_server.name) if self.hcloud_server else None,
|
||||
}
|
||||
|
||||
def _get_load_balancer_and_target(self):
|
||||
try:
|
||||
self.hcloud_load_balancer = self.client.load_balancers.get_by_name(self.module.params.get("load_balancer"))
|
||||
if self.module.params.get("type") == "server":
|
||||
self.hcloud_server = self.client.servers.get_by_name(self.module.params.get("server"))
|
||||
self.hcloud_load_balancer_target = None
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
def _get_load_balancer_target(self):
|
||||
for target in self.hcloud_load_balancer.targets:
|
||||
if self.module.params.get("type") == "server":
|
||||
if target.server.id == self.hcloud_server.id:
|
||||
self.hcloud_load_balancer_target = target
|
||||
|
||||
def _create_load_balancer_target(self):
|
||||
params = {
|
||||
"target": None
|
||||
}
|
||||
|
||||
if self.module.params.get("type") == "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"))
|
||||
if not self.module.check_mode:
|
||||
try:
|
||||
self.hcloud_load_balancer.add_target(**params).wait_until_finished()
|
||||
except APIException as e:
|
||||
self.module.fail_json(msg=e.message)
|
||||
|
||||
self._mark_as_changed()
|
||||
self._get_load_balancer_and_target()
|
||||
self._get_load_balancer_target()
|
||||
|
||||
def present_load_balancer_target(self):
|
||||
self._get_load_balancer_and_target()
|
||||
self._get_load_balancer_target()
|
||||
if self.hcloud_load_balancer_target is None:
|
||||
self._create_load_balancer_target()
|
||||
|
||||
def delete_load_balancer_target(self):
|
||||
self._get_load_balancer_and_target()
|
||||
self._get_load_balancer_target()
|
||||
if self.hcloud_load_balancer_target is not None and self.hcloud_load_balancer is not None:
|
||||
if not self.module.check_mode:
|
||||
target = None
|
||||
if self.module.params.get("type") == "server":
|
||||
target = LoadBalancerTarget(type=self.module.params.get("type"),
|
||||
server=self.hcloud_server,
|
||||
use_private_ip=self.module.params.get("use_private_ip"))
|
||||
self.hcloud_load_balancer.remove_target(target).wait_until_finished()
|
||||
self._mark_as_changed()
|
||||
self.hcloud_load_balancer_target = None
|
||||
|
||||
@staticmethod
|
||||
def define_module():
|
||||
return AnsibleModule(
|
||||
argument_spec=dict(
|
||||
type={"type": "str", "required": True, "choices": ["server"]},
|
||||
load_balancer={"type": "str", "required": True},
|
||||
server={"type": "str"},
|
||||
use_private_ip={"type": "bool", "default": False},
|
||||
state={
|
||||
"choices": ["absent", "present"],
|
||||
"default": "present",
|
||||
},
|
||||
**Hcloud.base_module_arguments()
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleHcloudLoadBalancerTarget.define_module()
|
||||
|
||||
hcloud = AnsibleHcloudLoadBalancerTarget(module)
|
||||
state = module.params["state"]
|
||||
if state == "absent":
|
||||
hcloud.delete_load_balancer_target()
|
||||
elif state == "present":
|
||||
hcloud.present_load_balancer_target()
|
||||
|
||||
module.exit_json(**hcloud.get_result())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
163
plugins/modules/hcloud_load_balancer_type_info.py
Normal file
163
plugins/modules/hcloud_load_balancer_type_info.py
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#!/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_load_balancer_type_info
|
||||
|
||||
short_description: Gather infos about the Hetzner Cloud Load Balancer types.
|
||||
|
||||
|
||||
description:
|
||||
- Gather infos about your Hetzner Cloud Load Balancer types.
|
||||
|
||||
author:
|
||||
- Lukas Kaemmerling (@LKaemmerling)
|
||||
version_added: 0.1.0
|
||||
options:
|
||||
id:
|
||||
description:
|
||||
- The ID of the Load Balancer type you want to get.
|
||||
type: int
|
||||
name:
|
||||
description:
|
||||
- The name of the Load Balancer type you want to get.
|
||||
type: str
|
||||
extends_documentation_fragment:
|
||||
- hetzner.hcloud.hcloud
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Gather hcloud Load Balancer type infos
|
||||
hcloud_load_balancer_type_info:
|
||||
register: output
|
||||
|
||||
- name: Print the gathered infos
|
||||
debug:
|
||||
var: output.hcloud_load_balancer_type_info
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
hcloud_load_balancer_type_info:
|
||||
description: The Load Balancer type infos as list
|
||||
returned: always
|
||||
type: complex
|
||||
contains:
|
||||
id:
|
||||
description: Numeric identifier of the Load Balancer type
|
||||
returned: always
|
||||
type: int
|
||||
sample: 1937415
|
||||
name:
|
||||
description: Name of the Load Balancer type
|
||||
returned: always
|
||||
type: str
|
||||
sample: lb11
|
||||
description:
|
||||
description: Description of the Load Balancer type
|
||||
returned: always
|
||||
type: str
|
||||
sample: LB11
|
||||
max_connections:
|
||||
description: Number of maximum simultaneous open connections
|
||||
returned: always
|
||||
type: int
|
||||
sample: 1
|
||||
max_services:
|
||||
description: Number of services a Load Balancer of this type can have
|
||||
returned: always
|
||||
type: int
|
||||
sample: 1
|
||||
max_targets:
|
||||
description: Number of targets a single Load Balancer can have
|
||||
returned: always
|
||||
type: int
|
||||
sample: 25
|
||||
max_assigned_certificates:
|
||||
description: Number of SSL Certificates that can be assigned to a single Load Balancer
|
||||
returned: always
|
||||
type: int
|
||||
sample: 5
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
try:
|
||||
from hcloud import APIException
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class AnsibleHcloudLoadBalancerTypeInfo(Hcloud):
|
||||
def __init__(self, module):
|
||||
Hcloud.__init__(self, module, "hcloud_load_balancer_type_info")
|
||||
self.hcloud_load_balancer_type_info = 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
|
||||
})
|
||||
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")
|
||||
)]
|
||||
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")
|
||||
)]
|
||||
else:
|
||||
self.hcloud_load_balancer_type_info = self.client.load_balancer_types.get_all()
|
||||
|
||||
except APIException 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 = AnsibleHcloudLoadBalancerTypeInfo.define_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']
|
||||
}
|
||||
module.exit_json(**ansible_info)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -100,7 +100,7 @@ hcloud_network:
|
|||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
labels:
|
||||
description: User-defined labels (key-value pairs)
|
||||
type: dict
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ hcloud_network_info:
|
|||
description: True if the network is protected for deletion
|
||||
returned: always
|
||||
type: bool
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
labels:
|
||||
description: Labels of the network
|
||||
returned: always
|
||||
|
|
|
|||
|
|
@ -238,13 +238,13 @@ hcloud_server:
|
|||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
rebuild_protection:
|
||||
description: True if server is protected for rebuild
|
||||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
|
|
|||
|
|
@ -116,13 +116,13 @@ hcloud_server_info:
|
|||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
rebuild_protection:
|
||||
description: True if server is protected for rebuild
|
||||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ options:
|
|||
network:
|
||||
description:
|
||||
- The name of the Hetzner Cloud Networks.
|
||||
|
||||
type: str
|
||||
required: true
|
||||
server:
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ options:
|
|||
network:
|
||||
description:
|
||||
- The ID or Name of the Hetzner Cloud Networks.
|
||||
|
||||
type: str
|
||||
required: true
|
||||
ip_range:
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ hcloud_volume:
|
|||
returned: always
|
||||
type: str
|
||||
sample: /dev/disk/by-id/scsi-0HC_Volume_12345
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
location:
|
||||
description: Location name where the Volume is located at
|
||||
type: str
|
||||
|
|
@ -157,7 +157,7 @@ hcloud_volume:
|
|||
type: bool
|
||||
returned: always
|
||||
sample: false
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ hcloud_volume_info:
|
|||
returned: always
|
||||
type: str
|
||||
sample: /dev/disk/by-id/scsi-0HC_Volume_12345
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
location:
|
||||
description: Name of the location where the Volume resides in
|
||||
returned: always
|
||||
|
|
@ -88,7 +88,7 @@ hcloud_volume_info:
|
|||
description: True if the Volume is protected for deletion
|
||||
returned: always
|
||||
type: bool
|
||||
version_added: "1.0.0"
|
||||
version_added: "0.1.0"
|
||||
labels:
|
||||
description: User-defined labels (key-value pairs)
|
||||
returned: always
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue