mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-02-03 23:41:51 +00:00
294 lines
10 KiB
Python
294 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()
|