1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/plugins/modules/scaleway_ip.py
patchback[bot] 186d410f63
[PR #8833/26df6c76 backport][stable-9] use dict comprehension in plugins, part 3 (#8835)
use dict comprehension in plugins, part 3 (#8833)

* use dict comprehension in plugins, part 3

* add changelog frag

(cherry picked from commit 26df6c7657)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2024-09-08 14:46:13 +02:00

268 lines
7.1 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Scaleway IP management module
#
# Copyright (c) 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 absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: scaleway_ip
short_description: Scaleway IP management module
author: Remy Leone (@remyleone)
description:
- This module manages IP on Scaleway account
U(https://developer.scaleway.com)
extends_documentation_fragment:
- community.general.scaleway
- community.general.attributes
attributes:
check_mode:
support: full
diff_mode:
support: none
options:
state:
type: str
description:
- Indicate desired state of the IP.
default: present
choices:
- present
- absent
organization:
type: str
description:
- Scaleway organization identifier
required: true
region:
type: str
description:
- Scaleway region to use (for example par1).
required: true
choices:
- ams1
- EMEA-NL-EVS
- par1
- EMEA-FR-PAR1
- par2
- EMEA-FR-PAR2
- waw1
- EMEA-PL-WAW1
id:
type: str
description:
- id of the Scaleway IP (UUID)
server:
type: str
description:
- id of the server you want to attach an IP to.
- To unattach an IP don't specify this option
reverse:
type: str
description:
- Reverse to assign to the IP
'''
EXAMPLES = '''
- name: Create an IP
community.general.scaleway_ip:
organization: '{{ scw_org }}'
state: present
region: par1
register: ip_creation_task
- name: Make sure IP deleted
community.general.scaleway_ip:
id: '{{ ip_creation_task.scaleway_ip.id }}'
state: absent
region: par1
'''
RETURN = '''
data:
description: This is only present when O(state=present).
returned: when O(state=present)
type: dict
sample: {
"ips": [
{
"organization": "951df375-e094-4d26-97c1-ba548eeb9c42",
"reverse": null,
"id": "dd9e8df6-6775-4863-b517-e0b0ee3d7477",
"server": {
"id": "3f1568ca-b1a2-4e98-b6f7-31a0588157f1",
"name": "ansible_tuto-1"
},
"address": "212.47.232.136"
}
]
}
'''
from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, scaleway_argument_spec, Scaleway
from ansible.module_utils.basic import AnsibleModule
def ip_attributes_should_be_changed(api, target_ip, wished_ip):
patch_payload = {}
if target_ip["reverse"] != wished_ip["reverse"]:
patch_payload["reverse"] = wished_ip["reverse"]
# IP is assigned to a server
if target_ip["server"] is None and wished_ip["server"]:
patch_payload["server"] = wished_ip["server"]
# IP is unassigned to a server
try:
if target_ip["server"]["id"] and wished_ip["server"] is None:
patch_payload["server"] = wished_ip["server"]
except (TypeError, KeyError):
pass
# IP is migrated between 2 different servers
try:
if target_ip["server"]["id"] != wished_ip["server"]:
patch_payload["server"] = wished_ip["server"]
except (TypeError, KeyError):
pass
return patch_payload
def payload_from_wished_ip(wished_ip):
return {
k: v
for k, v in wished_ip.items()
if k != 'id' and v is not None
}
def present_strategy(api, wished_ip):
changed = False
response = api.get('ips')
if not response.ok:
api.module.fail_json(msg='Error getting IPs [{0}: {1}]'.format(
response.status_code, response.json['message']))
ips_list = response.json["ips"]
ip_lookup = {ip["id"]: ip for ip in ips_list}
if wished_ip["id"] not in ip_lookup.keys():
changed = True
if api.module.check_mode:
return changed, {"status": "An IP would be created."}
# Create IP
creation_response = api.post('/ips',
data=payload_from_wished_ip(wished_ip))
if not creation_response.ok:
msg = "Error during ip creation: %s: '%s' (%s)" % (creation_response.info['msg'],
creation_response.json['message'],
creation_response.json)
api.module.fail_json(msg=msg)
return changed, creation_response.json["ip"]
target_ip = ip_lookup[wished_ip["id"]]
patch_payload = ip_attributes_should_be_changed(api=api, target_ip=target_ip, wished_ip=wished_ip)
if not patch_payload:
return changed, target_ip
changed = True
if api.module.check_mode:
return changed, {"status": "IP attributes would be changed."}
ip_patch_response = api.patch(path="ips/%s" % target_ip["id"],
data=patch_payload)
if not ip_patch_response.ok:
api.module.fail_json(msg='Error during IP attributes update: [{0}: {1}]'.format(
ip_patch_response.status_code, ip_patch_response.json['message']))
return changed, ip_patch_response.json["ip"]
def absent_strategy(api, wished_ip):
response = api.get('ips')
changed = False
status_code = response.status_code
ips_json = response.json
ips_list = ips_json["ips"]
if not response.ok:
api.module.fail_json(msg='Error getting IPs [{0}: {1}]'.format(
status_code, response.json['message']))
ip_lookup = {ip["id"]: ip for ip in ips_list}
if wished_ip["id"] not in ip_lookup.keys():
return changed, {}
changed = True
if api.module.check_mode:
return changed, {"status": "IP would be destroyed"}
response = api.delete('/ips/' + wished_ip["id"])
if not response.ok:
api.module.fail_json(msg='Error deleting IP [{0}: {1}]'.format(
response.status_code, response.json))
return changed, response.json
def core(module):
wished_ip = {
"organization": module.params['organization'],
"reverse": module.params["reverse"],
"id": module.params["id"],
"server": module.params["server"]
}
region = module.params["region"]
module.params['api_url'] = SCALEWAY_LOCATION[region]["api_endpoint"]
api = Scaleway(module=module)
if module.params["state"] == "absent":
changed, summary = absent_strategy(api=api, wished_ip=wished_ip)
else:
changed, summary = present_strategy(api=api, wished_ip=wished_ip)
module.exit_json(changed=changed, scaleway_ip=summary)
def main():
argument_spec = scaleway_argument_spec()
argument_spec.update(dict(
state=dict(default='present', choices=['absent', 'present']),
organization=dict(required=True),
server=dict(),
reverse=dict(),
region=dict(required=True, choices=list(SCALEWAY_LOCATION.keys())),
id=dict()
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
core(module)
if __name__ == '__main__':
main()