mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-25 13:34:01 -07:00 
			
		
		
		
	s[a-c]*: normalize docs (#9353)
* s[a-c]*: normalize docs
* Apply suggestions from code review
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 70b62ed745)
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
		
	
			
		
			
				
	
	
		
			699 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			699 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| #
 | |
| # Scaleway Compute management module
 | |
| #
 | |
| # Copyright (C) 2018 Online SAS.
 | |
| # https://www.scaleway.com
 | |
| #
 | |
| # 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 = r"""
 | |
| module: scaleway_compute
 | |
| short_description: Scaleway compute management module
 | |
| author: Remy Leone (@remyleone)
 | |
| description:
 | |
|   - This module manages compute instances on Scaleway.
 | |
| extends_documentation_fragment:
 | |
|   - community.general.scaleway
 | |
|   - community.general.attributes
 | |
| 
 | |
| attributes:
 | |
|   check_mode:
 | |
|     support: full
 | |
|   diff_mode:
 | |
|     support: none
 | |
| 
 | |
| options:
 | |
| 
 | |
|   public_ip:
 | |
|     type: str
 | |
|     description:
 | |
|       - Manage public IP on a Scaleway server.
 | |
|       - Could be Scaleway IP address UUID.
 | |
|       - V(dynamic) Means that IP is destroyed at the same time the host is destroyed.
 | |
|       - V(absent) Means no public IP at all.
 | |
|     default: absent
 | |
| 
 | |
|   enable_ipv6:
 | |
|     description:
 | |
|       - Enable public IPv6 connectivity on the instance.
 | |
|     default: false
 | |
|     type: bool
 | |
| 
 | |
|   image:
 | |
|     type: str
 | |
|     description:
 | |
|       - Image identifier used to start the instance with.
 | |
|     required: true
 | |
| 
 | |
|   name:
 | |
|     type: str
 | |
|     description:
 | |
|       - Name of the instance.
 | |
|   organization:
 | |
|     type: str
 | |
|     description:
 | |
|       - Organization identifier.
 | |
|       - Exactly one of O(project) and O(organization) must be specified.
 | |
|   project:
 | |
|     type: str
 | |
|     description:
 | |
|       - Project identifier.
 | |
|       - Exactly one of O(project) and O(organization) must be specified.
 | |
|     version_added: 4.3.0
 | |
| 
 | |
|   state:
 | |
|     type: str
 | |
|     description:
 | |
|       - Indicate desired state of the instance.
 | |
|     default: present
 | |
|     choices:
 | |
|       - present
 | |
|       - absent
 | |
|       - running
 | |
|       - restarted
 | |
|       - stopped
 | |
| 
 | |
|   tags:
 | |
|     type: list
 | |
|     elements: str
 | |
|     description:
 | |
|       - List of tags to apply to the instance (5 max).
 | |
|     required: false
 | |
|     default: []
 | |
| 
 | |
|   region:
 | |
|     type: str
 | |
|     description:
 | |
|       - Scaleway compute zone.
 | |
|     required: true
 | |
|     choices:
 | |
|       - ams1
 | |
|       - EMEA-NL-EVS
 | |
|       - par1
 | |
|       - EMEA-FR-PAR1
 | |
|       - par2
 | |
|       - EMEA-FR-PAR2
 | |
|       - waw1
 | |
|       - EMEA-PL-WAW1
 | |
| 
 | |
|   commercial_type:
 | |
|     type: str
 | |
|     description:
 | |
|       - Commercial name of the compute node.
 | |
|     required: true
 | |
| 
 | |
|   wait:
 | |
|     description:
 | |
|       - Wait for the instance to reach its desired state before returning.
 | |
|     type: bool
 | |
|     default: false
 | |
| 
 | |
|   wait_timeout:
 | |
|     type: int
 | |
|     description:
 | |
|       - Time to wait for the server to reach the expected state.
 | |
|     required: false
 | |
|     default: 300
 | |
| 
 | |
|   wait_sleep_time:
 | |
|     type: int
 | |
|     description:
 | |
|       - Time to wait before every attempt to check the state of the server.
 | |
|     required: false
 | |
|     default: 3
 | |
| 
 | |
|   security_group:
 | |
|     type: str
 | |
|     description:
 | |
|       - Security group unique identifier.
 | |
|       - If no value provided, the default security group or current security group will be used.
 | |
|     required: false
 | |
| """
 | |
| 
 | |
| EXAMPLES = r"""
 | |
| - name: Create a server
 | |
|   community.general.scaleway_compute:
 | |
|     name: foobar
 | |
|     state: present
 | |
|     image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
 | |
|     project: 951df375-e094-4d26-97c1-ba548eeb9c42
 | |
|     region: ams1
 | |
|     commercial_type: VC1S
 | |
|     tags:
 | |
|       - test
 | |
|       - www
 | |
| 
 | |
| - name: Create a server attached to a security group
 | |
|   community.general.scaleway_compute:
 | |
|     name: foobar
 | |
|     state: present
 | |
|     image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
 | |
|     project: 951df375-e094-4d26-97c1-ba548eeb9c42
 | |
|     region: ams1
 | |
|     commercial_type: VC1S
 | |
|     security_group: 4a31b633-118e-4900-bd52-facf1085fc8d
 | |
|     tags:
 | |
|       - test
 | |
|       - www
 | |
| 
 | |
| - name: Destroy it right after
 | |
|   community.general.scaleway_compute:
 | |
|     name: foobar
 | |
|     state: absent
 | |
|     image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
 | |
|     project: 951df375-e094-4d26-97c1-ba548eeb9c42
 | |
|     region: ams1
 | |
|     commercial_type: VC1S
 | |
| """
 | |
| 
 | |
| RETURN = r"""
 | |
| """
 | |
| 
 | |
| import datetime
 | |
| import time
 | |
| 
 | |
| from ansible.module_utils.basic import AnsibleModule
 | |
| from ansible_collections.community.general.plugins.module_utils.datetime import now
 | |
| from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, scaleway_argument_spec, Scaleway
 | |
| 
 | |
| SCALEWAY_SERVER_STATES = (
 | |
|     'stopped',
 | |
|     'stopping',
 | |
|     'starting',
 | |
|     'running',
 | |
|     'locked'
 | |
| )
 | |
| 
 | |
| SCALEWAY_TRANSITIONS_STATES = (
 | |
|     "stopping",
 | |
|     "starting",
 | |
|     "pending"
 | |
| )
 | |
| 
 | |
| 
 | |
| def check_image_id(compute_api, image_id):
 | |
|     response = compute_api.get(path="images/%s" % image_id)
 | |
| 
 | |
|     if not response.ok:
 | |
|         msg = 'Error in getting image %s on %s : %s' % (image_id, compute_api.module.params.get('api_url'), response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
| 
 | |
| def fetch_state(compute_api, server):
 | |
|     compute_api.module.debug("fetch_state of server: %s" % server["id"])
 | |
|     response = compute_api.get(path="servers/%s" % server["id"])
 | |
| 
 | |
|     if response.status_code == 404:
 | |
|         return "absent"
 | |
| 
 | |
|     if not response.ok:
 | |
|         msg = 'Error during state fetching: (%s) %s' % (response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     try:
 | |
|         compute_api.module.debug("Server %s in state: %s" % (server["id"], response.json["server"]["state"]))
 | |
|         return response.json["server"]["state"]
 | |
|     except KeyError:
 | |
|         compute_api.module.fail_json(msg="Could not fetch state in %s" % response.json)
 | |
| 
 | |
| 
 | |
| def wait_to_complete_state_transition(compute_api, server, wait=None):
 | |
|     if wait is None:
 | |
|         wait = compute_api.module.params["wait"]
 | |
|     if not wait:
 | |
|         return
 | |
| 
 | |
|     wait_timeout = compute_api.module.params["wait_timeout"]
 | |
|     wait_sleep_time = compute_api.module.params["wait_sleep_time"]
 | |
| 
 | |
|     start = now()
 | |
|     end = start + datetime.timedelta(seconds=wait_timeout)
 | |
|     while now() < end:
 | |
|         compute_api.module.debug("We are going to wait for the server to finish its transition")
 | |
|         if fetch_state(compute_api, server) not in SCALEWAY_TRANSITIONS_STATES:
 | |
|             compute_api.module.debug("It seems that the server is not in transition anymore.")
 | |
|             compute_api.module.debug("Server in state: %s" % fetch_state(compute_api, server))
 | |
|             break
 | |
|         time.sleep(wait_sleep_time)
 | |
|     else:
 | |
|         compute_api.module.fail_json(msg="Server takes too long to finish its transition")
 | |
| 
 | |
| 
 | |
| def public_ip_payload(compute_api, public_ip):
 | |
|     # We don't want a public ip
 | |
|     if public_ip in ("absent",):
 | |
|         return {"dynamic_ip_required": False}
 | |
| 
 | |
|     # IP is only attached to the instance and is released as soon as the instance terminates
 | |
|     if public_ip in ("dynamic", "allocated"):
 | |
|         return {"dynamic_ip_required": True}
 | |
| 
 | |
|     # We check that the IP we want to attach exists, if so its ID is returned
 | |
|     response = compute_api.get("ips")
 | |
|     if not response.ok:
 | |
|         msg = 'Error during public IP validation: (%s) %s' % (response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     ip_list = []
 | |
|     try:
 | |
|         ip_list = response.json["ips"]
 | |
|     except KeyError:
 | |
|         compute_api.module.fail_json(msg="Error in getting the IP information from: %s" % response.json)
 | |
| 
 | |
|     lookup = [ip["id"] for ip in ip_list]
 | |
|     if public_ip in lookup:
 | |
|         return {"public_ip": public_ip}
 | |
| 
 | |
| 
 | |
| def create_server(compute_api, server):
 | |
|     compute_api.module.debug("Starting a create_server")
 | |
|     target_server = None
 | |
|     data = {"enable_ipv6": server["enable_ipv6"],
 | |
|             "tags": server["tags"],
 | |
|             "commercial_type": server["commercial_type"],
 | |
|             "image": server["image"],
 | |
|             "dynamic_ip_required": server["dynamic_ip_required"],
 | |
|             "name": server["name"]
 | |
|             }
 | |
| 
 | |
|     if server["project"]:
 | |
|         data["project"] = server["project"]
 | |
| 
 | |
|     if server["organization"]:
 | |
|         data["organization"] = server["organization"]
 | |
| 
 | |
|     if server["security_group"]:
 | |
|         data["security_group"] = server["security_group"]
 | |
| 
 | |
|     response = compute_api.post(path="servers", data=data)
 | |
| 
 | |
|     if not response.ok:
 | |
|         msg = 'Error during server creation: (%s) %s' % (response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     try:
 | |
|         target_server = response.json["server"]
 | |
|     except KeyError:
 | |
|         compute_api.module.fail_json(msg="Error in getting the server information from: %s" % response.json)
 | |
| 
 | |
|     wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
 | |
| 
 | |
|     return target_server
 | |
| 
 | |
| 
 | |
| def restart_server(compute_api, server):
 | |
|     return perform_action(compute_api=compute_api, server=server, action="reboot")
 | |
| 
 | |
| 
 | |
| def stop_server(compute_api, server):
 | |
|     return perform_action(compute_api=compute_api, server=server, action="poweroff")
 | |
| 
 | |
| 
 | |
| def start_server(compute_api, server):
 | |
|     return perform_action(compute_api=compute_api, server=server, action="poweron")
 | |
| 
 | |
| 
 | |
| def perform_action(compute_api, server, action):
 | |
|     response = compute_api.post(path="servers/%s/action" % server["id"],
 | |
|                                 data={"action": action})
 | |
|     if not response.ok:
 | |
|         msg = 'Error during server %s: (%s) %s' % (action, response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     wait_to_complete_state_transition(compute_api=compute_api, server=server)
 | |
| 
 | |
|     return response
 | |
| 
 | |
| 
 | |
| def remove_server(compute_api, server):
 | |
|     compute_api.module.debug("Starting remove server strategy")
 | |
|     response = compute_api.delete(path="servers/%s" % server["id"])
 | |
|     if not response.ok:
 | |
|         msg = 'Error during server deletion: (%s) %s' % (response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     wait_to_complete_state_transition(compute_api=compute_api, server=server)
 | |
| 
 | |
|     return response
 | |
| 
 | |
| 
 | |
| def present_strategy(compute_api, wished_server):
 | |
|     compute_api.module.debug("Starting present strategy")
 | |
|     changed = False
 | |
|     query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1)
 | |
| 
 | |
|     if not query_results:
 | |
|         changed = True
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "A server would be created."}
 | |
| 
 | |
|         target_server = create_server(compute_api=compute_api, server=wished_server)
 | |
|     else:
 | |
|         target_server = query_results[0]
 | |
| 
 | |
|     if server_attributes_should_be_changed(compute_api=compute_api, target_server=target_server,
 | |
|                                            wished_server=wished_server):
 | |
|         changed = True
 | |
| 
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "Server %s attributes would be changed." % target_server["id"]}
 | |
| 
 | |
|         target_server = server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server)
 | |
| 
 | |
|     return changed, target_server
 | |
| 
 | |
| 
 | |
| def absent_strategy(compute_api, wished_server):
 | |
|     compute_api.module.debug("Starting absent strategy")
 | |
|     changed = False
 | |
|     target_server = None
 | |
|     query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1)
 | |
| 
 | |
|     if not query_results:
 | |
|         return changed, {"status": "Server already absent."}
 | |
|     else:
 | |
|         target_server = query_results[0]
 | |
| 
 | |
|     changed = True
 | |
| 
 | |
|     if compute_api.module.check_mode:
 | |
|         return changed, {"status": "Server %s would be made absent." % target_server["id"]}
 | |
| 
 | |
|     # A server MUST be stopped to be deleted.
 | |
|     while fetch_state(compute_api=compute_api, server=target_server) != "stopped":
 | |
|         wait_to_complete_state_transition(compute_api=compute_api, server=target_server, wait=True)
 | |
|         response = stop_server(compute_api=compute_api, server=target_server)
 | |
| 
 | |
|         if not response.ok:
 | |
|             err_msg = 'Error while stopping a server before removing it [{0}: {1}]'.format(response.status_code,
 | |
|                                                                                            response.json)
 | |
|             compute_api.module.fail_json(msg=err_msg)
 | |
| 
 | |
|         wait_to_complete_state_transition(compute_api=compute_api, server=target_server, wait=True)
 | |
| 
 | |
|     response = remove_server(compute_api=compute_api, server=target_server)
 | |
| 
 | |
|     if not response.ok:
 | |
|         err_msg = 'Error while removing server [{0}: {1}]'.format(response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=err_msg)
 | |
| 
 | |
|     return changed, {"status": "Server %s deleted" % target_server["id"]}
 | |
| 
 | |
| 
 | |
| def running_strategy(compute_api, wished_server):
 | |
|     compute_api.module.debug("Starting running strategy")
 | |
|     changed = False
 | |
|     query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1)
 | |
| 
 | |
|     if not query_results:
 | |
|         changed = True
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "A server would be created before being run."}
 | |
| 
 | |
|         target_server = create_server(compute_api=compute_api, server=wished_server)
 | |
|     else:
 | |
|         target_server = query_results[0]
 | |
| 
 | |
|     if server_attributes_should_be_changed(compute_api=compute_api, target_server=target_server,
 | |
|                                            wished_server=wished_server):
 | |
|         changed = True
 | |
| 
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "Server %s attributes would be changed before running it." % target_server["id"]}
 | |
| 
 | |
|         target_server = server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server)
 | |
| 
 | |
|     current_state = fetch_state(compute_api=compute_api, server=target_server)
 | |
|     if current_state not in ("running", "starting"):
 | |
|         compute_api.module.debug("running_strategy: Server in state: %s" % current_state)
 | |
|         changed = True
 | |
| 
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "Server %s attributes would be changed." % target_server["id"]}
 | |
| 
 | |
|         response = start_server(compute_api=compute_api, server=target_server)
 | |
|         if not response.ok:
 | |
|             msg = 'Error while running server [{0}: {1}]'.format(response.status_code, response.json)
 | |
|             compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     return changed, target_server
 | |
| 
 | |
| 
 | |
| def stop_strategy(compute_api, wished_server):
 | |
|     compute_api.module.debug("Starting stop strategy")
 | |
|     query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1)
 | |
| 
 | |
|     changed = False
 | |
| 
 | |
|     if not query_results:
 | |
| 
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "A server would be created before being stopped."}
 | |
| 
 | |
|         target_server = create_server(compute_api=compute_api, server=wished_server)
 | |
|         changed = True
 | |
|     else:
 | |
|         target_server = query_results[0]
 | |
| 
 | |
|     compute_api.module.debug("stop_strategy: Servers are found.")
 | |
| 
 | |
|     if server_attributes_should_be_changed(compute_api=compute_api, target_server=target_server,
 | |
|                                            wished_server=wished_server):
 | |
|         changed = True
 | |
| 
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {
 | |
|                 "status": "Server %s attributes would be changed before stopping it." % target_server["id"]}
 | |
| 
 | |
|         target_server = server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server)
 | |
| 
 | |
|     wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
 | |
| 
 | |
|     current_state = fetch_state(compute_api=compute_api, server=target_server)
 | |
|     if current_state not in ("stopped",):
 | |
|         compute_api.module.debug("stop_strategy: Server in state: %s" % current_state)
 | |
| 
 | |
|         changed = True
 | |
| 
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "Server %s would be stopped." % target_server["id"]}
 | |
| 
 | |
|         response = stop_server(compute_api=compute_api, server=target_server)
 | |
|         compute_api.module.debug(response.json)
 | |
|         compute_api.module.debug(response.ok)
 | |
| 
 | |
|         if not response.ok:
 | |
|             msg = 'Error while stopping server [{0}: {1}]'.format(response.status_code, response.json)
 | |
|             compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     return changed, target_server
 | |
| 
 | |
| 
 | |
| def restart_strategy(compute_api, wished_server):
 | |
|     compute_api.module.debug("Starting restart strategy")
 | |
|     changed = False
 | |
|     query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1)
 | |
| 
 | |
|     if not query_results:
 | |
|         changed = True
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {"status": "A server would be created before being rebooted."}
 | |
| 
 | |
|         target_server = create_server(compute_api=compute_api, server=wished_server)
 | |
|     else:
 | |
|         target_server = query_results[0]
 | |
| 
 | |
|     if server_attributes_should_be_changed(compute_api=compute_api,
 | |
|                                            target_server=target_server,
 | |
|                                            wished_server=wished_server):
 | |
|         changed = True
 | |
| 
 | |
|         if compute_api.module.check_mode:
 | |
|             return changed, {
 | |
|                 "status": "Server %s attributes would be changed before rebooting it." % target_server["id"]}
 | |
| 
 | |
|         target_server = server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server)
 | |
| 
 | |
|     changed = True
 | |
|     if compute_api.module.check_mode:
 | |
|         return changed, {"status": "Server %s would be rebooted." % target_server["id"]}
 | |
| 
 | |
|     wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
 | |
| 
 | |
|     if fetch_state(compute_api=compute_api, server=target_server) in ("running",):
 | |
|         response = restart_server(compute_api=compute_api, server=target_server)
 | |
|         wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
 | |
|         if not response.ok:
 | |
|             msg = 'Error while restarting server that was running [{0}: {1}].'.format(response.status_code,
 | |
|                                                                                       response.json)
 | |
|             compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     if fetch_state(compute_api=compute_api, server=target_server) in ("stopped",):
 | |
|         response = restart_server(compute_api=compute_api, server=target_server)
 | |
|         wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
 | |
|         if not response.ok:
 | |
|             msg = 'Error while restarting server that was stopped [{0}: {1}].'.format(response.status_code,
 | |
|                                                                                       response.json)
 | |
|             compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     return changed, target_server
 | |
| 
 | |
| 
 | |
| state_strategy = {
 | |
|     "present": present_strategy,
 | |
|     "restarted": restart_strategy,
 | |
|     "stopped": stop_strategy,
 | |
|     "running": running_strategy,
 | |
|     "absent": absent_strategy
 | |
| }
 | |
| 
 | |
| 
 | |
| def find(compute_api, wished_server, per_page=1):
 | |
|     compute_api.module.debug("Getting inside find")
 | |
|     # Only the name attribute is accepted in the Compute query API
 | |
|     response = compute_api.get("servers", params={"name": wished_server["name"],
 | |
|                                                   "per_page": per_page})
 | |
| 
 | |
|     if not response.ok:
 | |
|         msg = 'Error during server search: (%s) %s' % (response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     search_results = response.json["servers"]
 | |
| 
 | |
|     return search_results
 | |
| 
 | |
| 
 | |
| PATCH_MUTABLE_SERVER_ATTRIBUTES = (
 | |
|     "ipv6",
 | |
|     "tags",
 | |
|     "name",
 | |
|     "dynamic_ip_required",
 | |
|     "security_group",
 | |
| )
 | |
| 
 | |
| 
 | |
| def server_attributes_should_be_changed(compute_api, target_server, wished_server):
 | |
|     compute_api.module.debug("Checking if server attributes should be changed")
 | |
|     compute_api.module.debug("Current Server: %s" % target_server)
 | |
|     compute_api.module.debug("Wished Server: %s" % wished_server)
 | |
|     debug_dict = {
 | |
|         x: (target_server[x], wished_server[x])
 | |
|         for x in PATCH_MUTABLE_SERVER_ATTRIBUTES
 | |
|         if x in target_server and x in wished_server
 | |
|     }
 | |
|     compute_api.module.debug("Debug dict %s" % debug_dict)
 | |
|     try:
 | |
|         for key in PATCH_MUTABLE_SERVER_ATTRIBUTES:
 | |
|             if key in target_server and key in wished_server:
 | |
|                 # When you are working with dict, only ID matter as we ask user to put only the resource ID in the playbook
 | |
|                 if isinstance(target_server[key], dict) and wished_server[key] and "id" in target_server[key].keys(
 | |
|                 ) and target_server[key]["id"] != wished_server[key]:
 | |
|                     return True
 | |
|                 # Handling other structure compare simply the two objects content
 | |
|                 elif not isinstance(target_server[key], dict) and target_server[key] != wished_server[key]:
 | |
|                     return True
 | |
|         return False
 | |
|     except AttributeError:
 | |
|         compute_api.module.fail_json(msg="Error while checking if attributes should be changed")
 | |
| 
 | |
| 
 | |
| def server_change_attributes(compute_api, target_server, wished_server):
 | |
|     compute_api.module.debug("Starting patching server attributes")
 | |
|     patch_payload = dict()
 | |
| 
 | |
|     for key in PATCH_MUTABLE_SERVER_ATTRIBUTES:
 | |
|         if key in target_server and key in wished_server:
 | |
|             # When you are working with dict, only ID matter as we ask user to put only the resource ID in the playbook
 | |
|             if isinstance(target_server[key], dict) and "id" in target_server[key] and wished_server[key]:
 | |
|                 # Setting all key to current value except ID
 | |
|                 key_dict = {x: target_server[key][x] for x in target_server[key].keys() if x != "id"}
 | |
|                 # Setting ID to the user specified ID
 | |
|                 key_dict["id"] = wished_server[key]
 | |
|                 patch_payload[key] = key_dict
 | |
|             elif not isinstance(target_server[key], dict):
 | |
|                 patch_payload[key] = wished_server[key]
 | |
| 
 | |
|     response = compute_api.patch(path="servers/%s" % target_server["id"],
 | |
|                                  data=patch_payload)
 | |
|     if not response.ok:
 | |
|         msg = 'Error during server attributes patching: (%s) %s' % (response.status_code, response.json)
 | |
|         compute_api.module.fail_json(msg=msg)
 | |
| 
 | |
|     try:
 | |
|         target_server = response.json["server"]
 | |
|     except KeyError:
 | |
|         compute_api.module.fail_json(msg="Error in getting the server information from: %s" % response.json)
 | |
| 
 | |
|     wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
 | |
| 
 | |
|     return target_server
 | |
| 
 | |
| 
 | |
| def core(module):
 | |
|     region = module.params["region"]
 | |
|     wished_server = {
 | |
|         "state": module.params["state"],
 | |
|         "image": module.params["image"],
 | |
|         "name": module.params["name"],
 | |
|         "commercial_type": module.params["commercial_type"],
 | |
|         "enable_ipv6": module.params["enable_ipv6"],
 | |
|         "tags": module.params["tags"],
 | |
|         "organization": module.params["organization"],
 | |
|         "project": module.params["project"],
 | |
|         "security_group": module.params["security_group"]
 | |
|     }
 | |
|     module.params['api_url'] = SCALEWAY_LOCATION[region]["api_endpoint"]
 | |
| 
 | |
|     compute_api = Scaleway(module=module)
 | |
| 
 | |
|     check_image_id(compute_api, wished_server["image"])
 | |
| 
 | |
|     # IP parameters of the wished server depends on the configuration
 | |
|     ip_payload = public_ip_payload(compute_api=compute_api, public_ip=module.params["public_ip"])
 | |
|     wished_server.update(ip_payload)
 | |
| 
 | |
|     changed, summary = state_strategy[wished_server["state"]](compute_api=compute_api, wished_server=wished_server)
 | |
|     module.exit_json(changed=changed, msg=summary)
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     argument_spec = scaleway_argument_spec()
 | |
|     argument_spec.update(dict(
 | |
|         image=dict(required=True),
 | |
|         name=dict(),
 | |
|         region=dict(required=True, choices=list(SCALEWAY_LOCATION.keys())),
 | |
|         commercial_type=dict(required=True),
 | |
|         enable_ipv6=dict(default=False, type="bool"),
 | |
|         public_ip=dict(default="absent"),
 | |
|         state=dict(choices=list(state_strategy.keys()), default='present'),
 | |
|         tags=dict(type="list", elements="str", default=[]),
 | |
|         organization=dict(),
 | |
|         project=dict(),
 | |
|         wait=dict(type="bool", default=False),
 | |
|         wait_timeout=dict(type="int", default=300),
 | |
|         wait_sleep_time=dict(type="int", default=3),
 | |
|         security_group=dict(),
 | |
|     ))
 | |
|     module = AnsibleModule(
 | |
|         argument_spec=argument_spec,
 | |
|         supports_check_mode=True,
 | |
|         mutually_exclusive=[
 | |
|             ('organization', 'project'),
 | |
|         ],
 | |
|         required_one_of=[
 | |
|             ('organization', 'project'),
 | |
|         ],
 | |
|     )
 | |
| 
 | |
|     core(module)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |