feat: allow selecting a resource using its ID (#361)

##### SUMMARY

Allow referring to resources using their IDs for:
- hcloud_load_balancer_network
- hcloud_load_balancer_service
- hcloud_load_balancer_target
- hcloud_rdns
- hcloud_route
- hcloud_server_network
- hcloud_subnetwork


##### ISSUE TYPE

- Feature Pull Request


##### COMPONENT NAME
- hcloud_load_balancer_network
- hcloud_load_balancer_service
- hcloud_load_balancer_target
- hcloud_rdns
- hcloud_route
- hcloud_server_network
- hcloud_subnetwork
This commit is contained in:
Jonas L 2023-10-18 10:28:42 +02:00 committed by GitHub
parent bd93d2caf8
commit 5e425c56c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 101 additions and 58 deletions

View file

@ -0,0 +1,8 @@
minor_changes:
- hcloud_load_balancer_network - Allow selecting a `load_balancer` or `network` using its ID.
- hcloud_load_balancer_service - Allow selecting a `load_balancer` using its ID.
- hcloud_load_balancer_target - Allow selecting a `load_balancer` or `server` using its ID.
- hcloud_rdns - Allow selecting a `server`, `floating_ip`, `primary_ip` or `load_balancer` using its ID.
- hcloud_route - Allow selecting a `network` using its ID.
- hcloud_server_network - Allow selecting a `network` or `server` using its ID.
- hcloud_subnetwork - Allow selecting to a `network` using its ID.

View file

@ -4,7 +4,7 @@
import traceback import traceback
from typing import Any, Dict, Optional from typing import Any, Dict, Optional, Union
from ansible.module_utils.basic import ( from ansible.module_utils.basic import (
AnsibleModule as AnsibleModuleBase, AnsibleModule as AnsibleModuleBase,
@ -91,6 +91,27 @@ class AnsibleHCloud:
application_version=version, application_version=version,
) )
def _client_get_by_name_or_id(self, resource: str, param: Union[str, int]):
"""
Get a resource by name, and if not found by its ID.
:param resource: Name of the resource client that implements both `get_by_name` and `get_by_id` methods
:param param: Name or ID of the resource to query
"""
resource_client = getattr(self.client, resource)
result = resource_client.get_by_name(param)
if result is not None:
return result
# If the param is not a valid ID, prevent an unnecessary call to the API.
try:
int(param)
except ValueError:
self.module.fail_json(msg=f"resource ({resource.rstrip('s')}) does not exist: {param}")
return resource_client.get_by_id(param)
def _mark_as_changed(self) -> None: def _mark_as_changed(self) -> None:
self.result["changed"] = True self.result["changed"] = True

View file

@ -20,12 +20,12 @@ version_added: 0.1.0
options: options:
network: network:
description: description:
- The name of the Hetzner Cloud Networks. - Name or ID of the Hetzner Cloud Networks.
type: str type: str
required: true required: true
load_balancer: load_balancer:
description: description:
- The name of the Hetzner Cloud Load Balancer. - Name or ID of the Hetzner Cloud Load Balancer.
type: str type: str
required: true required: true
ip: ip:
@ -118,15 +118,14 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud):
def _get_load_balancer_and_network(self): def _get_load_balancer_and_network(self):
try: try:
network = self.module.params.get("network") self.hcloud_network = self._client_get_by_name_or_id(
self.hcloud_network = self.client.networks.get_by_name(network) "networks",
if not self.hcloud_network: self.module.params.get("network"),
self.module.fail_json(msg=f"Network does not exist: {network}") )
self.hcloud_load_balancer = self._client_get_by_name_or_id(
load_balancer_name = self.module.params.get("load_balancer") "load_balancers",
self.hcloud_load_balancer = self.client.load_balancers.get_by_name(load_balancer_name) self.module.params.get("load_balancer"),
if not self.hcloud_load_balancer: )
self.module.fail_json(msg=f"Load balancer does not exist: {load_balancer_name}")
self.hcloud_load_balancer_network = None self.hcloud_load_balancer_network = None
except HCloudException as exception: except HCloudException as exception:

View file

@ -20,7 +20,7 @@ version_added: 0.1.0
options: options:
load_balancer: load_balancer:
description: 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 type: str
required: true required: true
listen_port: listen_port:
@ -343,11 +343,10 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud):
def _get_load_balancer(self): def _get_load_balancer(self):
try: try:
load_balancer_name = self.module.params.get("load_balancer") self.hcloud_load_balancer = self._client_get_by_name_or_id(
self.hcloud_load_balancer = self.client.load_balancers.get_by_name(load_balancer_name) "load_balancers",
if not self.hcloud_load_balancer: self.module.params.get("load_balancer"),
self.module.fail_json(msg=f"Load balancer does not exist: {load_balancer_name}") )
self._get_load_balancer_service() self._get_load_balancer_service()
except HCloudException as exception: except HCloudException as exception:
self.fail_json_hcloud(exception) self.fail_json_hcloud(exception)

View file

@ -26,12 +26,12 @@ options:
required: true required: true
load_balancer: load_balancer:
description: description:
- The name of the Hetzner Cloud Load Balancer. - Name or ID of the Hetzner Cloud Load Balancer.
type: str type: str
required: true required: true
server: server:
description: description:
- The name of the Hetzner Cloud Server. - Name or ID of the Hetzner Cloud Server.
- Required if I(type) is server - Required if I(type) is server
type: str type: str
label_selector: label_selector:
@ -175,16 +175,16 @@ class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud):
def _get_load_balancer_and_target(self): def _get_load_balancer_and_target(self):
try: try:
load_balancer_name = self.module.params.get("load_balancer") self.hcloud_load_balancer = self._client_get_by_name_or_id(
self.hcloud_load_balancer = self.client.load_balancers.get_by_name(load_balancer_name) "load_balancers",
if not self.hcloud_load_balancer: self.module.params.get("load_balancer"),
self.module.fail_json(msg=f"Load balancer does not exist: {load_balancer_name}") )
if self.module.params.get("type") == "server": if self.module.params.get("type") == "server":
server_name = self.module.params.get("server") self.hcloud_server = self._client_get_by_name_or_id(
self.hcloud_server = self.client.servers.get_by_name(server_name) "servers",
if not self.hcloud_server: self.module.params.get("server"),
self.module.fail_json(msg=f"Server not found: {server_name}") )
self.hcloud_load_balancer_target = None self.hcloud_load_balancer_target = None
except HCloudException as exception: except HCloudException as exception:

View file

@ -20,19 +20,19 @@ author:
options: options:
server: server:
description: 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 type: str
floating_ip: floating_ip:
description: 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 type: str
primary_ip: primary_ip:
description: 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 type: str
load_balancer: load_balancer:
description: 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 type: str
ip_address: ip_address:
description: description:
@ -178,21 +178,25 @@ class AnsibleHCloudReverseDNS(AnsibleHCloud):
def _get_resource(self): def _get_resource(self):
try: try:
if self.module.params.get("server"): 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(
if self.hcloud_resource is None: "servers",
self.module.fail_json(msg="The selected server does not exist") self.module.params.get("server"),
)
elif self.module.params.get("floating_ip"): 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(
if self.hcloud_resource is None: "floating_ips",
self.module.fail_json(msg="The selected Floating IP does not exist") self.module.params.get("floating_ip"),
)
elif self.module.params.get("primary_ip"): 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(
if self.hcloud_resource is None: "primary_ips",
self.module.fail_json(msg="The selected Floating IP does not exist") self.module.params.get("primary_ip"),
)
elif self.module.params.get("load_balancer"): 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(
if self.hcloud_resource is None: "load_balancers",
self.module.fail_json(msg="The selected Load Balancer does not exist") self.module.params.get("load_balancer"),
)
except HCloudException as exception: except HCloudException as exception:
self.fail_json_hcloud(exception) self.fail_json_hcloud(exception)

View file

@ -20,7 +20,7 @@ author:
options: options:
network: network:
description: description:
- The name of the Hetzner Cloud Network. - Name or ID of the Hetzner Cloud Network.
type: str type: str
required: true required: true
destination: destination:
@ -112,7 +112,10 @@ class AnsibleHCloudRoute(AnsibleHCloud):
def _get_network(self): def _get_network(self):
try: 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 self.hcloud_route = None
except HCloudException as exception: except HCloudException as exception:
self.fail_json_hcloud(exception) self.fail_json_hcloud(exception)

View file

@ -20,12 +20,12 @@ author:
options: options:
network: network:
description: description:
- The name of the Hetzner Cloud Networks. - Name or ID of the Hetzner Cloud Networks.
type: str type: str
required: true required: true
server: server:
description: description:
- The name of the Hetzner Cloud server. - Name or ID of the Hetzner Cloud server.
type: str type: str
required: true required: true
ip: ip:
@ -140,8 +140,14 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud):
def _get_server_and_network(self): def _get_server_and_network(self):
try: 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(
self.hcloud_server = self.client.servers.get_by_name(self.module.params.get("server")) "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 self.hcloud_server_network = None
except HCloudException as exception: except HCloudException as exception:
self.fail_json_hcloud(exception) self.fail_json_hcloud(exception)

View file

@ -20,7 +20,7 @@ author:
options: options:
network: network:
description: description:
- The ID or Name of the Hetzner Cloud Networks. - The name or ID of the Hetzner Cloud Networks.
type: str type: str
required: true required: true
ip_range: ip_range:
@ -152,7 +152,10 @@ class AnsibleHCloudSubnetwork(AnsibleHCloud):
def _get_network(self): def _get_network(self):
try: 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 self.hcloud_subnetwork = None
except HCloudException as exception: except HCloudException as exception:
self.fail_json_hcloud(exception) self.fail_json_hcloud(exception)

View file

@ -59,7 +59,7 @@
assert: assert:
that: that:
- result is failed - result is failed
- "result.msg == 'Load balancer does not exist: does-not-exist'" - "result.msg == 'resource (load_balancer) does not exist: does-not-exist'"
- name: test fail network does not exist - name: test fail network does not exist
hetzner.hcloud.hcloud_load_balancer_network: hetzner.hcloud.hcloud_load_balancer_network:
@ -72,7 +72,7 @@
assert: assert:
that: that:
- result is failed - result is failed
- "result.msg == 'Network does not exist: does-not-exist'" - "result.msg == 'resource (network) does not exist: does-not-exist'"
- name: test create load_balancer network with checkmode - name: test create load_balancer network with checkmode
hetzner.hcloud.hcloud_load_balancer_network: hetzner.hcloud.hcloud_load_balancer_network:

View file

@ -25,7 +25,7 @@
assert: assert:
that: that:
- result is failed - result is failed
- "result.msg == 'Load balancer does not exist: does-not-exist'" - "result.msg == 'resource (load_balancer) does not exist: does-not-exist'"
- name: test create load_balancer service with checkmode - name: test create load_balancer service with checkmode
hetzner.hcloud.hcloud_load_balancer_service: hetzner.hcloud.hcloud_load_balancer_service:

View file

@ -37,7 +37,7 @@
assert: assert:
that: that:
- result is failed - result is failed
- "result.msg == 'Load balancer does not exist: does-not-exist'" - "result.msg == 'resource (load_balancer) does not exist: does-not-exist'"
- name: test fail server does not exist - name: test fail server does not exist
hetzner.hcloud.hcloud_load_balancer_target: hetzner.hcloud.hcloud_load_balancer_target:
@ -50,7 +50,7 @@
assert: assert:
that: that:
- result is failed - result is failed
- "result.msg == 'Server not found: does-not-exist'" - "result.msg == 'resource (server) does not exist: does-not-exist'"
- name: test create load_balancer target with checkmode - name: test create load_balancer target with checkmode
hetzner.hcloud.hcloud_load_balancer_target: hetzner.hcloud.hcloud_load_balancer_target:

View file

@ -70,7 +70,7 @@
assert: assert:
that: that:
- result is failed - result is failed
- 'result.msg == "The selected server does not exist"' - 'result.msg == "resource (server) does not exist: not-existing"'
- name: test create rdns - name: test create rdns
hetzner.hcloud.hcloud_rdns: hetzner.hcloud.hcloud_rdns:
server: "{{ hcloud_server_name }}" server: "{{ hcloud_server_name }}"