mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-23 05:10:22 -07:00
Initial commit for Scaleway Compute (#38285)
This commit is contained in:
parent
72120c3cac
commit
eccccfe77f
4 changed files with 1113 additions and 81 deletions
78
lib/ansible/module_utils/scaleway.py
Normal file
78
lib/ansible/module_utils/scaleway.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
from ansible.module_utils.urls import fetch_url
|
||||||
|
|
||||||
|
|
||||||
|
class Response(object):
|
||||||
|
|
||||||
|
def __init__(self, resp, info):
|
||||||
|
self.body = None
|
||||||
|
if resp:
|
||||||
|
self.body = resp.read()
|
||||||
|
self.info = info
|
||||||
|
|
||||||
|
@property
|
||||||
|
def json(self):
|
||||||
|
if not self.body:
|
||||||
|
if "body" in self.info:
|
||||||
|
return json.loads(self.info["body"])
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return json.loads(self.body)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def status_code(self):
|
||||||
|
return self.info["status"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ok(self):
|
||||||
|
return self.status_code in (200, 201, 202, 204)
|
||||||
|
|
||||||
|
|
||||||
|
class ScalewayAPI(object):
|
||||||
|
|
||||||
|
def __init__(self, module, headers, base_url):
|
||||||
|
self.module = module
|
||||||
|
self.headers = headers
|
||||||
|
self.base_url = base_url
|
||||||
|
|
||||||
|
def _url_builder(self, path):
|
||||||
|
if path[0] == '/':
|
||||||
|
path = path[1:]
|
||||||
|
return '%s/%s' % (self.base_url, path)
|
||||||
|
|
||||||
|
def send(self, method, path, data=None, headers=None):
|
||||||
|
url = self._url_builder(path)
|
||||||
|
data = self.module.jsonify(data)
|
||||||
|
timeout = self.module.params['timeout']
|
||||||
|
|
||||||
|
if headers is not None:
|
||||||
|
self.headers.update(headers)
|
||||||
|
|
||||||
|
resp, info = fetch_url(self.module, url, data=data, headers=self.headers, method=method, timeout=timeout)
|
||||||
|
|
||||||
|
# Exceptions in fetch_url may result in a status -1, the ensures a proper error to the user in all cases
|
||||||
|
if info['status'] == -1:
|
||||||
|
self.module.fail_json(msg=info['msg'])
|
||||||
|
|
||||||
|
return Response(resp, info)
|
||||||
|
|
||||||
|
def get(self, path, data=None, headers=None):
|
||||||
|
return self.send('GET', path, data, headers)
|
||||||
|
|
||||||
|
def put(self, path, data=None, headers=None):
|
||||||
|
return self.send('PUT', path, data, headers)
|
||||||
|
|
||||||
|
def post(self, path, data=None, headers=None):
|
||||||
|
return self.send('POST', path, data, headers)
|
||||||
|
|
||||||
|
def delete(self, path, data=None, headers=None):
|
||||||
|
return self.send('DELETE', path, data, headers)
|
||||||
|
|
||||||
|
def patch(self, path, data=None, headers=None):
|
||||||
|
return self.send("PATCH", path, data, headers)
|
||||||
|
|
||||||
|
def update(self, path, data=None, headers=None):
|
||||||
|
return self.send("UPDATE", path, data, headers)
|
631
lib/ansible/modules/cloud/scaleway/scaleway_compute.py
Normal file
631
lib/ansible/modules/cloud/scaleway/scaleway_compute.py
Normal file
|
@ -0,0 +1,631 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
#
|
||||||
|
# Scaleway Compute management module
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 Online SAS.
|
||||||
|
# https://www.scaleway.com
|
||||||
|
#
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {
|
||||||
|
'metadata_version': '1.1',
|
||||||
|
'status': ['preview'],
|
||||||
|
'supported_by': 'community'
|
||||||
|
}
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
---
|
||||||
|
module: scaleway_compute
|
||||||
|
short_description: Scaleway compute management module
|
||||||
|
version_added: "2.6"
|
||||||
|
author: Remy Leone (@sieben)
|
||||||
|
description:
|
||||||
|
- "This module manages compute instances on Scaleway."
|
||||||
|
options:
|
||||||
|
|
||||||
|
enable_ipv6:
|
||||||
|
description:
|
||||||
|
- Enable public IPv6 connectivity on the instance
|
||||||
|
default: false
|
||||||
|
type: bool
|
||||||
|
|
||||||
|
image:
|
||||||
|
description:
|
||||||
|
- Image identifier used to start the instance with
|
||||||
|
required: true
|
||||||
|
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the instance
|
||||||
|
|
||||||
|
organization:
|
||||||
|
description:
|
||||||
|
- Organization identifier
|
||||||
|
required: true
|
||||||
|
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- Indicate desired state of the instance.
|
||||||
|
default: present
|
||||||
|
choices:
|
||||||
|
- present
|
||||||
|
- absent
|
||||||
|
- running
|
||||||
|
- restarted
|
||||||
|
- stopped
|
||||||
|
|
||||||
|
tags:
|
||||||
|
description:
|
||||||
|
- List of tags to apply to the instance (5 max)
|
||||||
|
required: false
|
||||||
|
default: []
|
||||||
|
|
||||||
|
oauth_token:
|
||||||
|
description:
|
||||||
|
- Scaleway OAuth token.
|
||||||
|
required: true
|
||||||
|
|
||||||
|
region:
|
||||||
|
description:
|
||||||
|
- Scaleway compute zone
|
||||||
|
required: true
|
||||||
|
choices:
|
||||||
|
- ams1
|
||||||
|
- EMEA-NL-EVS
|
||||||
|
- par1
|
||||||
|
- EMEA-FR-PAR1
|
||||||
|
|
||||||
|
commercial_type:
|
||||||
|
description:
|
||||||
|
- Commercial name of the compute node
|
||||||
|
required: true
|
||||||
|
choices:
|
||||||
|
- ARM64-2GB
|
||||||
|
- ARM64-4GB
|
||||||
|
- ARM64-8GB
|
||||||
|
- ARM64-16GB
|
||||||
|
- ARM64-32GB
|
||||||
|
- ARM64-64GB
|
||||||
|
- ARM64-128GB
|
||||||
|
- C1
|
||||||
|
- C2S
|
||||||
|
- C2M
|
||||||
|
- C2L
|
||||||
|
- VC1S
|
||||||
|
- VC1M
|
||||||
|
- VC1L
|
||||||
|
- X64-15GB
|
||||||
|
- X64-30GB
|
||||||
|
- X64-60GB
|
||||||
|
- X64-120GB
|
||||||
|
|
||||||
|
timeout:
|
||||||
|
description:
|
||||||
|
- Timeout for API calls
|
||||||
|
required: false
|
||||||
|
default: 30
|
||||||
|
|
||||||
|
wait:
|
||||||
|
description:
|
||||||
|
- Wait for the instance to reach its desired state before returning.
|
||||||
|
type: bool
|
||||||
|
default: 'no'
|
||||||
|
|
||||||
|
wait_timeout:
|
||||||
|
description:
|
||||||
|
- Time to wait for the server to reach the expected state
|
||||||
|
required: false
|
||||||
|
default: 300
|
||||||
|
|
||||||
|
wait_sleep_time:
|
||||||
|
description:
|
||||||
|
- Time to wait before every attempt to check the state of the server
|
||||||
|
required: false
|
||||||
|
default: 3
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
- name: Create a server
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
|
||||||
|
- name: Destroy it right after
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: absent
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = '''
|
||||||
|
'''
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.basic import env_fallback
|
||||||
|
from ansible.module_utils.six.moves.urllib.parse import quote as urlquote
|
||||||
|
from ansible.module_utils.scaleway import ScalewayAPI
|
||||||
|
|
||||||
|
SCALEWAY_COMMERCIAL_TYPES = [
|
||||||
|
|
||||||
|
# Virtual ARM64 compute instance
|
||||||
|
'ARM64-2GB',
|
||||||
|
'ARM64-4GB',
|
||||||
|
'ARM64-8GB',
|
||||||
|
'ARM64-16GB',
|
||||||
|
'ARM64-32GB',
|
||||||
|
'ARM64-64GB',
|
||||||
|
'ARM64-128GB',
|
||||||
|
|
||||||
|
# Baremetal
|
||||||
|
'C1', # ARM64 (4 cores) - 2GB
|
||||||
|
'C2S', # X86-64 (4 cores) - 8GB
|
||||||
|
'C2M', # X86-64 (8 cores) - 16GB
|
||||||
|
'C2L', # x86-64 (8 cores) - 32 GB
|
||||||
|
|
||||||
|
# Virtual X86-64 compute instance
|
||||||
|
'VC1S', # Starter X86-64 (2 cores) - 2GB
|
||||||
|
'VC1M', # Starter X86-64 (4 cores) - 4GB
|
||||||
|
'VC1L', # Starter X86-64 (6 cores) - 8GB
|
||||||
|
'X64-15GB',
|
||||||
|
'X64-30GB',
|
||||||
|
'X64-60GB',
|
||||||
|
'X64-120GB',
|
||||||
|
]
|
||||||
|
|
||||||
|
SCALEWAY_LOCATION = {
|
||||||
|
'par1': {'name': 'Paris 1', 'country': 'FR', "api_endpoint": 'https://cp-par1.scaleway.com'},
|
||||||
|
'EMEA-FR-PAR1': {'name': 'Paris 1', 'country': 'FR', "api_endpoint": 'https://cp-par1.scaleway.com'},
|
||||||
|
'ams1': {'name': 'Amsterdam 1', 'country': 'NL', "api_endpoint": 'https://cp-ams1.scaleway.com'},
|
||||||
|
'EMEA-NL-EVS': {'name': 'Amsterdam 1', 'country': 'NL', "api_endpoint": 'https://cp-ams1.scaleway.com'},
|
||||||
|
}
|
||||||
|
|
||||||
|
SCALEWAY_SERVER_STATES = (
|
||||||
|
'stopped',
|
||||||
|
'stopping',
|
||||||
|
'starting',
|
||||||
|
'running',
|
||||||
|
'locked'
|
||||||
|
)
|
||||||
|
|
||||||
|
SCALEWAY_TRANSITIONS_STATES = (
|
||||||
|
"stopping",
|
||||||
|
"starting",
|
||||||
|
"pending"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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 = 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 = datetime.datetime.utcnow()
|
||||||
|
end = start + datetime.timedelta(seconds=wait_timeout)
|
||||||
|
while datetime.datetime.utcnow() < 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 create_server(compute_api, server):
|
||||||
|
compute_api.module.debug("Starting a create_server")
|
||||||
|
target_server = None
|
||||||
|
response = compute_api.post(path="servers",
|
||||||
|
data={"enable_ipv6": server["enable_ipv6"],
|
||||||
|
"tags": server["tags"],
|
||||||
|
"commercial_type": server["commercial_type"],
|
||||||
|
"image": server["image"],
|
||||||
|
"name": server["name"],
|
||||||
|
"organization": server["organization"]})
|
||||||
|
|
||||||
|
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"]}
|
||||||
|
|
||||||
|
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 not fetch_state(compute_api=compute_api, server=target_server) == "stopped":
|
||||||
|
wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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"]}
|
||||||
|
|
||||||
|
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"]}
|
||||||
|
|
||||||
|
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"]}
|
||||||
|
|
||||||
|
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
|
||||||
|
url = 'servers?name=%s&per_page=%d' % (urlquote(wished_server["name"]), per_page)
|
||||||
|
response = compute_api.get(url)
|
||||||
|
|
||||||
|
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",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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 = 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:
|
||||||
|
return any([target_server[x] != wished_server[x]
|
||||||
|
for x in PATCH_MUTABLE_SERVER_ATTRIBUTES
|
||||||
|
if x in target_server and x in wished_server])
|
||||||
|
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((x, wished_server[x])
|
||||||
|
for x in PATCH_MUTABLE_SERVER_ATTRIBUTES
|
||||||
|
if x in wished_server and x in target_server)
|
||||||
|
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)
|
||||||
|
|
||||||
|
wait_to_complete_state_transition(compute_api=compute_api, server=target_server)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def core(module):
|
||||||
|
api_token = module.params['oauth_token']
|
||||||
|
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"]
|
||||||
|
}
|
||||||
|
|
||||||
|
compute_api = ScalewayAPI(module=module,
|
||||||
|
headers={'X-Auth-Token': api_token,
|
||||||
|
'Content-type': 'application/json'},
|
||||||
|
base_url=SCALEWAY_LOCATION[region]["api_endpoint"])
|
||||||
|
|
||||||
|
changed, summary = state_strategy[wished_server["state"]](compute_api=compute_api, wished_server=wished_server)
|
||||||
|
module.exit_json(changed=changed, msg=summary)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
module = AnsibleModule(
|
||||||
|
argument_spec=dict(
|
||||||
|
oauth_token=dict(
|
||||||
|
no_log=True,
|
||||||
|
# Support environment variable for Scaleway OAuth Token
|
||||||
|
fallback=(env_fallback, ['SCW_TOKEN', 'SCW_API_KEY', 'SCW_OAUTH_TOKEN']),
|
||||||
|
required=True,
|
||||||
|
),
|
||||||
|
image=dict(required=True),
|
||||||
|
name=dict(),
|
||||||
|
region=dict(required=True, choices=SCALEWAY_LOCATION.keys()),
|
||||||
|
commercial_type=dict(required=True, choices=SCALEWAY_COMMERCIAL_TYPES),
|
||||||
|
enable_ipv6=dict(default=False, type="bool"),
|
||||||
|
state=dict(choices=state_strategy.keys(), default='present'),
|
||||||
|
tags=dict(type="list", default=[]),
|
||||||
|
organization=dict(required=True),
|
||||||
|
timeout=dict(type="int", default=30),
|
||||||
|
wait=dict(type="bool", default=False),
|
||||||
|
wait_timeout=dict(type="int", default=300),
|
||||||
|
wait_sleep_time=dict(type="int", default=3),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
core(module)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -83,82 +83,9 @@ data:
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.basic import env_fallback
|
from ansible.module_utils.basic import env_fallback
|
||||||
from ansible.module_utils.urls import fetch_url
|
from ansible.module_utils.scaleway import ScalewayAPI
|
||||||
|
|
||||||
|
|
||||||
class Response(object):
|
|
||||||
|
|
||||||
def __init__(self, resp, info):
|
|
||||||
self.body = None
|
|
||||||
if resp:
|
|
||||||
self.body = resp.read()
|
|
||||||
self.info = info
|
|
||||||
|
|
||||||
@property
|
|
||||||
def json(self):
|
|
||||||
if not self.body:
|
|
||||||
if "body" in self.info:
|
|
||||||
return json.loads(self.info["body"])
|
|
||||||
return None
|
|
||||||
try:
|
|
||||||
return json.loads(self.body)
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def status_code(self):
|
|
||||||
return self.info["status"]
|
|
||||||
|
|
||||||
|
|
||||||
class AccountAPI(object):
|
|
||||||
|
|
||||||
def __init__(self, module, headers, base_url):
|
|
||||||
self.module = module
|
|
||||||
self.headers = headers
|
|
||||||
self.base_url = base_url
|
|
||||||
|
|
||||||
def _url_builder(self, path):
|
|
||||||
if path[0] == '/':
|
|
||||||
path = path[1:]
|
|
||||||
return '%s/%s' % (self.base_url, path)
|
|
||||||
|
|
||||||
def send(self, method, path, data=None, headers=None):
|
|
||||||
url = self._url_builder(path)
|
|
||||||
data = self.module.jsonify(data)
|
|
||||||
timeout = self.module.params['timeout']
|
|
||||||
|
|
||||||
if headers is not None:
|
|
||||||
self.headers.update(headers)
|
|
||||||
|
|
||||||
resp, info = fetch_url(self.module, url, data=data, headers=self.headers, method=method, timeout=timeout)
|
|
||||||
|
|
||||||
# Exceptions in fetch_url may result in a status -1, the ensures a proper error to the user in all cases
|
|
||||||
if info['status'] == -1:
|
|
||||||
self.module.fail_json(msg=info['msg'])
|
|
||||||
|
|
||||||
return Response(resp, info)
|
|
||||||
|
|
||||||
def get(self, path, data=None, headers=None):
|
|
||||||
return self.send('GET', path, data, headers)
|
|
||||||
|
|
||||||
def put(self, path, data=None, headers=None):
|
|
||||||
return self.send('PUT', path, data, headers)
|
|
||||||
|
|
||||||
def post(self, path, data=None, headers=None):
|
|
||||||
return self.send('POST', path, data, headers)
|
|
||||||
|
|
||||||
def delete(self, path, data=None, headers=None):
|
|
||||||
return self.send('DELETE', path, data, headers)
|
|
||||||
|
|
||||||
def patch(self, path, data=None, headers=None):
|
|
||||||
return self.send("PATCH", path, data, headers)
|
|
||||||
|
|
||||||
def update(self, path, data=None, headers=None):
|
|
||||||
return self.send("UPDATE", path, data, headers)
|
|
||||||
|
|
||||||
|
|
||||||
def extract_present_sshkeys(raw_organization_dict):
|
def extract_present_sshkeys(raw_organization_dict):
|
||||||
|
@ -181,16 +108,16 @@ def core(module):
|
||||||
api_token = module.params['oauth_token']
|
api_token = module.params['oauth_token']
|
||||||
ssh_pub_key = module.params['ssh_pub_key']
|
ssh_pub_key = module.params['ssh_pub_key']
|
||||||
state = module.params["state"]
|
state = module.params["state"]
|
||||||
account_api = AccountAPI(module,
|
account_api = ScalewayAPI(module,
|
||||||
headers={'X-Auth-Token': api_token,
|
headers={'X-Auth-Token': api_token,
|
||||||
'Content-type': 'application/json'},
|
'Content-type': 'application/json'},
|
||||||
base_url=module.params["base_url"])
|
base_url=module.params["base_url"])
|
||||||
response = account_api.get('organizations')
|
response = account_api.get('organizations')
|
||||||
|
|
||||||
status_code = response.status_code
|
status_code = response.status_code
|
||||||
organization_json = response.json
|
organization_json = response.json
|
||||||
|
|
||||||
if status_code not in (200, 404):
|
if not response.ok:
|
||||||
module.fail_json(msg='Error getting ssh key [{0}: {1}]'.format(
|
module.fail_json(msg='Error getting ssh key [{0}: {1}]'.format(
|
||||||
status_code, response.json['message']))
|
status_code, response.json['message']))
|
||||||
|
|
||||||
|
@ -214,7 +141,7 @@ def core(module):
|
||||||
|
|
||||||
response = account_api.patch('/users/%s' % user_id, data=payload)
|
response = account_api.patch('/users/%s' % user_id, data=payload)
|
||||||
|
|
||||||
if response.status_code in (200, 201):
|
if response.ok:
|
||||||
module.exit_json(changed=True, data=response.json)
|
module.exit_json(changed=True, data=response.json)
|
||||||
|
|
||||||
module.fail_json(msg='Error creating ssh key [{0}: {1}]'.format(
|
module.fail_json(msg='Error creating ssh key [{0}: {1}]'.format(
|
||||||
|
@ -232,7 +159,7 @@ def core(module):
|
||||||
|
|
||||||
response = account_api.patch('/users/%s' % user_id, data=payload)
|
response = account_api.patch('/users/%s' % user_id, data=payload)
|
||||||
|
|
||||||
if response.status_code in (200, 201, 204):
|
if response.ok:
|
||||||
module.exit_json(changed=True, data=response.json)
|
module.exit_json(changed=True, data=response.json)
|
||||||
|
|
||||||
module.fail_json(msg='Error deleting ssh key [{0}: {1}]'.format(
|
module.fail_json(msg='Error deleting ssh key [{0}: {1}]'.format(
|
||||||
|
|
396
test/legacy/scaleway_compute.yml
Normal file
396
test/legacy/scaleway_compute.yml
Normal file
|
@ -0,0 +1,396 @@
|
||||||
|
# SCW_API_KEY='XXX' ansible-playbook ./test/legacy/scaleway_compute.yml
|
||||||
|
|
||||||
|
- name: Test compute instance lifecyle on a Scaleway account
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: no
|
||||||
|
environment:
|
||||||
|
SCW_API_KEY: "{{ lookup('env', 'SCW_API_KEY') }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
- name: Create a server (Check)
|
||||||
|
check_mode: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
|
||||||
|
register: server_creation_check_task
|
||||||
|
|
||||||
|
- debug: var=server_creation_check_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_creation_check_task is success
|
||||||
|
- server_creation_check_task is changed
|
||||||
|
|
||||||
|
- name: Create a server
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
|
||||||
|
register: server_creation_task
|
||||||
|
|
||||||
|
- debug: var=server_creation_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_creation_task is success
|
||||||
|
- server_creation_task is changed
|
||||||
|
|
||||||
|
- name: Create a server (Confirmation)
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
|
||||||
|
register: server_creation_confirmation_task
|
||||||
|
|
||||||
|
- debug: var=server_creation_confirmation_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_creation_confirmation_task is success
|
||||||
|
- server_creation_confirmation_task is not changed
|
||||||
|
|
||||||
|
- name: Patch server tags (Check)
|
||||||
|
check_mode: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_patching_check_task
|
||||||
|
|
||||||
|
- debug: var=server_patching_check_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_patching_check_task is success
|
||||||
|
- server_patching_check_task is changed
|
||||||
|
|
||||||
|
- name: Patch server tags
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_patching_task
|
||||||
|
|
||||||
|
- debug: var=server_patching_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_patching_task is success
|
||||||
|
- server_patching_task is changed
|
||||||
|
|
||||||
|
- name: Patch server tags (Confirmation)
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_patching_confirmation_task
|
||||||
|
|
||||||
|
- debug: var=server_patching_confirmation_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_patching_confirmation_task is success
|
||||||
|
- server_patching_confirmation_task is not changed
|
||||||
|
|
||||||
|
- name: Run it (Check mode)
|
||||||
|
check_mode: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: running
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_run_check_task
|
||||||
|
|
||||||
|
- debug: var=server_run_check_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_run_check_task is success
|
||||||
|
- server_run_check_task is changed
|
||||||
|
|
||||||
|
- name: Run it
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: running
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_run_task
|
||||||
|
|
||||||
|
- debug: var=server_run_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_run_task is success
|
||||||
|
- server_run_task is changed
|
||||||
|
|
||||||
|
- name: Run it
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: running
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_run_confirmation_task
|
||||||
|
|
||||||
|
- debug: var=server_run_confirmation_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_run_confirmation_task is success
|
||||||
|
- server_run_confirmation_task is not changed
|
||||||
|
|
||||||
|
- name: Reboot it (Check mode)
|
||||||
|
check_mode: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: restarted
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_reboot_check_task
|
||||||
|
|
||||||
|
- debug: var=server_reboot_check_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_reboot_check_task is success
|
||||||
|
- server_reboot_check_task is changed
|
||||||
|
|
||||||
|
- name: Reboot it
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: restarted
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_reboot_task
|
||||||
|
|
||||||
|
- debug: var=server_reboot_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_reboot_task is success
|
||||||
|
- server_reboot_task is changed
|
||||||
|
|
||||||
|
- name: Stop it (Check mode)
|
||||||
|
check_mode: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: stopped
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_stop_check_task
|
||||||
|
|
||||||
|
- debug: var=server_stop_check_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_stop_check_task is success
|
||||||
|
- server_stop_check_task is changed
|
||||||
|
|
||||||
|
- name: Stop it
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: stopped
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_stop_task
|
||||||
|
|
||||||
|
- debug: var=server_stop_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_stop_task is success
|
||||||
|
- server_stop_task is changed
|
||||||
|
|
||||||
|
- name: Stop it (Confirmation)
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: stopped
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_stop_confirmation_task
|
||||||
|
|
||||||
|
- debug: var=server_stop_confirmation_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_stop_confirmation_task is success
|
||||||
|
- server_stop_confirmation_task is not changed
|
||||||
|
|
||||||
|
- name: Destroy it (Check mode)
|
||||||
|
check_mode: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: absent
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_destroy_check_task
|
||||||
|
|
||||||
|
- debug: var=server_destroy_check_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_destroy_check_task is success
|
||||||
|
- server_destroy_check_task is changed
|
||||||
|
|
||||||
|
- name: Destroy it
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: absent
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_destroy_task
|
||||||
|
|
||||||
|
- debug: var=server_destroy_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_destroy_task is success
|
||||||
|
- server_destroy_task is changed
|
||||||
|
|
||||||
|
- name: Destroy it (Confirmation)
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: absent
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
wait: true
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
- www
|
||||||
|
register: server_destroy_confirmation_task
|
||||||
|
|
||||||
|
- debug: var=server_destroy_confirmation_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- server_destroy_confirmation_task is success
|
||||||
|
- server_destroy_confirmation_task is not changed
|
||||||
|
|
||||||
|
- name: Testing for unauthorized organization
|
||||||
|
ignore_errors: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
|
||||||
|
organization: this-organization-does-not-exists
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
register: unauthorized_organization_task
|
||||||
|
|
||||||
|
- debug: var=unauthorized_organization_task
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- unauthorized_organization_task is not success
|
||||||
|
- unauthorized_organization_task is not changed
|
||||||
|
|
||||||
|
- name: Testing for unexisting image
|
||||||
|
ignore_errors: yes
|
||||||
|
scaleway_compute:
|
||||||
|
name: foobar
|
||||||
|
state: present
|
||||||
|
image: this-image-does-not-exists
|
||||||
|
organization: 951df375-e094-4d26-97c1-ba548eeb9c42
|
||||||
|
region: ams1
|
||||||
|
commercial_type: VC1S
|
||||||
|
register: unexisting_image_check
|
||||||
|
|
||||||
|
- debug: var=unexisting_image_check
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- unexisting_image_check is not success
|
||||||
|
- unexisting_image_check is not changed
|
Loading…
Add table
Add a link
Reference in a new issue