1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-02-04 07:51:50 +00:00
community.general/plugins/modules/ovh_ip_loadbalancing_backend.py
2025-11-01 13:46:53 +01:00

295 lines
10 KiB
Python

#!/usr/bin/python
# Copyright Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
DOCUMENTATION = r"""
module: ovh_ip_loadbalancing_backend
short_description: Manage OVH IP LoadBalancing backends
description:
- Manage OVH (French European hosting provider) LoadBalancing IP backends.
author: Pascal Heraud (@pascalheraud)
notes:
- Uses the Python OVH API U(https://github.com/ovh/python-ovh). You have to create an application (a key and secret) with
a consumer key as described into U(https://docs.ovh.com/gb/en/customer/first-steps-with-ovh-api/).
requirements:
- ovh > 0.3.5
extends_documentation_fragment:
- community.general.attributes
attributes:
check_mode:
support: none
diff_mode:
support: none
options:
name:
required: true
description:
- Name of the LoadBalancing internal name (V(ip-X.X.X.X)).
type: str
backend:
required: true
description:
- The IP address of the backend to update / modify / delete.
type: str
state:
default: present
choices: ['present', 'absent']
description:
- Determines whether the backend is to be created/modified or deleted.
type: str
probe:
default: 'none'
choices: ['none', 'http', 'icmp', 'oco']
description:
- Determines the type of probe to use for this backend.
type: str
weight:
default: 8
description:
- Determines the weight for this backend.
type: int
endpoint:
required: true
description:
- The endpoint to use (for instance V(ovh-eu)).
type: str
application_key:
required: true
description:
- The applicationKey to use.
type: str
application_secret:
required: true
description:
- The application secret to use.
type: str
consumer_key:
required: true
description:
- The consumer key to use.
type: str
timeout:
default: 120
description:
- The timeout in seconds used to wait for a task to be completed.
type: int
"""
EXAMPLES = r"""
- name: Adds or modify the backend '212.1.1.1' to a loadbalancing 'ip-1.1.1.1'
ovh_ip_loadbalancing:
name: ip-1.1.1.1
backend: 212.1.1.1
state: present
probe: none
weight: 8
endpoint: ovh-eu
application_key: yourkey
application_secret: yoursecret
consumer_key: yourconsumerkey
- name: Removes a backend '212.1.1.1' from a loadbalancing 'ip-1.1.1.1'
ovh_ip_loadbalancing:
name: ip-1.1.1.1
backend: 212.1.1.1
state: absent
endpoint: ovh-eu
application_key: yourkey
application_secret: yoursecret
consumer_key: yourconsumerkey
"""
import time
try:
import ovh
import ovh.exceptions
from ovh.exceptions import APIError
HAS_OVH = True
except ImportError:
HAS_OVH = False
from ansible.module_utils.basic import AnsibleModule
def getOvhClient(ansibleModule):
endpoint = ansibleModule.params.get("endpoint")
application_key = ansibleModule.params.get("application_key")
application_secret = ansibleModule.params.get("application_secret")
consumer_key = ansibleModule.params.get("consumer_key")
return ovh.Client(
endpoint=endpoint,
application_key=application_key,
application_secret=application_secret,
consumer_key=consumer_key,
)
def waitForNoTask(client, name, timeout):
currentTimeout = timeout
while len(client.get(f"/ip/loadBalancing/{name}/task")) > 0:
time.sleep(1) # Delay for 1 sec
currentTimeout -= 1
if currentTimeout < 0:
return False
return True
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
backend=dict(required=True),
weight=dict(default=8, type="int"),
probe=dict(default="none", choices=["none", "http", "icmp", "oco"]),
state=dict(default="present", choices=["present", "absent"]),
endpoint=dict(required=True),
application_key=dict(required=True, no_log=True),
application_secret=dict(required=True, no_log=True),
consumer_key=dict(required=True, no_log=True),
timeout=dict(default=120, type="int"),
)
)
if not HAS_OVH:
module.fail_json(msg="ovh-api python module is required to run this module")
# Get parameters
name = module.params.get("name")
state = module.params.get("state")
backend = module.params.get("backend")
weight = module.params.get("weight")
probe = module.params.get("probe")
timeout = module.params.get("timeout")
# Connect to OVH API
client = getOvhClient(module)
# Check that the load balancing exists
try:
loadBalancings = client.get("/ip/loadBalancing")
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for getting the list of loadBalancing, check application key, secret, consumerkey and parameters. "
f"Error returned by OVH API was : {apiError}"
)
if name not in loadBalancings:
module.fail_json(msg=f"IP LoadBalancing {name} does not exist")
# Check that no task is pending before going on
try:
if not waitForNoTask(client, name, timeout):
module.fail_json(
msg=f"Timeout of {timeout} seconds while waiting for no pending tasks before executing the module "
)
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for getting the list of pending tasks of the loadBalancing, check application key, secret, consumerkey and "
f"parameters. Error returned by OVH API was : {apiError}"
)
try:
backends = client.get(f"/ip/loadBalancing/{name}/backend")
except APIError as apiError:
module.fail_json(
msg=(
"Unable to call OVH API for getting the list of backends "
"of the loadBalancing, check application key, secret, consumerkey "
f"and parameters. Error returned by OVH API was : {apiError}"
)
)
backendExists = backend in backends
moduleChanged = False
if state == "absent":
if backendExists:
# Remove backend
try:
client.delete(f"/ip/loadBalancing/{name}/backend/{backend}")
if not waitForNoTask(client, name, timeout):
module.fail_json(
msg=f"Timeout of {timeout} seconds while waiting for completion of removing backend task"
)
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for deleting the backend, check application key, secret, consumerkey and parameters. "
f"Error returned by OVH API was : {apiError}"
)
moduleChanged = True
else:
if backendExists:
# Get properties
try:
backendProperties = client.get(f"/ip/loadBalancing/{name}/backend/{backend}")
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for getting the backend properties, check application key, secret, consumerkey and parameters. "
f"Error returned by OVH API was : {apiError}"
)
if backendProperties["weight"] != weight:
# Change weight
try:
client.post(f"/ip/loadBalancing/{name}/backend/{backend}/setWeight", weight=weight)
if not waitForNoTask(client, name, timeout):
module.fail_json(
msg=f"Timeout of {timeout} seconds while waiting for completion of setWeight to backend task"
)
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for updating the weight of the backend, check application key, secret, consumerkey and parameters. "
f"Error returned by OVH API was : {apiError}"
)
moduleChanged = True
if backendProperties["probe"] != probe:
# Change probe
backendProperties["probe"] = probe
try:
client.put(f"/ip/loadBalancing/{name}/backend/{backend}", probe=probe)
if not waitForNoTask(client, name, timeout):
module.fail_json(
msg=f"Timeout of {timeout} seconds while waiting for completion of setProbe to backend task"
)
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for updating the probe of the backend, check application key, secret, consumerkey and parameters. "
f"Error returned by OVH API was : {apiError}"
)
moduleChanged = True
else:
# Creates backend
try:
try:
client.post(f"/ip/loadBalancing/{name}/backend", ipBackend=backend, probe=probe, weight=weight)
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for creating the backend, check application key, secret, consumerkey and parameters. "
f"Error returned by OVH API was : {apiError}"
)
if not waitForNoTask(client, name, timeout):
module.fail_json(
msg=f"Timeout of {timeout} seconds while waiting for completion of backend creation task"
)
except APIError as apiError:
module.fail_json(
msg=f"Unable to call OVH API for creating the backend, check application key, secret, consumerkey and parameters. "
f"Error returned by OVH API was : {apiError}"
)
moduleChanged = True
module.exit_json(changed=moduleChanged)
if __name__ == "__main__":
main()