diff --git a/shippable.yml b/shippable.yml index 86fdbbd8f7a..1b4fcf23a70 100644 --- a/shippable.yml +++ b/shippable.yml @@ -143,7 +143,6 @@ matrix: - env: T=i/cs//1 - env: T=i/tower//1 - env: T=i/cloud//1 - - env: T=i/hcloud//1 branches: except: diff --git a/test/integration/targets/argspec/library/argspec.py b/test/integration/targets/argspec/library/argspec.py index e14df1eac95..751068c5888 100644 --- a/test/integration/targets/argspec/library/argspec.py +++ b/test/integration/targets/argspec/library/argspec.py @@ -50,6 +50,8 @@ def main(): 'default': [], }, 'needed_param': {}, + 'required_together_one': {}, + 'required_together_two': {}, }, required_if=( ('state', 'present', ('path', 'content'), True), @@ -57,6 +59,9 @@ def main(): mutually_exclusive=( ('path', 'content'), ), + required_together=( + ('required_together_one', 'required_together_two'), + ), ) module.fail_on_missing_params(module.params['fail_on_missing_params']) diff --git a/test/integration/targets/argspec/tasks/main.yml b/test/integration/targets/argspec/tasks/main.yml index 50c2855424e..17bbbdbc961 100644 --- a/test/integration/targets/argspec/tasks/main.yml +++ b/test/integration/targets/argspec/tasks/main.yml @@ -112,6 +112,15 @@ register: argspec_fail_on_missing_params_bad ignore_errors: true +- argspec: + required_together_one: foo + required_together_two: bar + +- argspec: + required_together_one: foo + register: argspec_fail_required_together + ignore_errors: true + - assert: that: - argspec_required_if_fail is failed @@ -144,3 +153,5 @@ - argspec_bad_json is failed - argspec_fail_on_missing_params_bad is failed + + - argspec_fail_required_together is failed diff --git a/test/integration/targets/incidental_hcloud_server/aliases b/test/integration/targets/incidental_hcloud_server/aliases deleted file mode 100644 index 6c43c27cf9e..00000000000 --- a/test/integration/targets/incidental_hcloud_server/aliases +++ /dev/null @@ -1,2 +0,0 @@ -cloud/hcloud -shippable/hcloud/incidental diff --git a/test/integration/targets/incidental_hcloud_server/defaults/main.yml b/test/integration/targets/incidental_hcloud_server/defaults/main.yml deleted file mode 100644 index b9a9a8df7b1..00000000000 --- a/test/integration/targets/incidental_hcloud_server/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright: (c) 2019, Hetzner Cloud GmbH -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -hcloud_prefix: "tests" -hcloud_server_name: "{{hcloud_prefix}}-integration" diff --git a/test/integration/targets/incidental_hcloud_server/tasks/main.yml b/test/integration/targets/incidental_hcloud_server/tasks/main.yml deleted file mode 100644 index 31c7ad97e0b..00000000000 --- a/test/integration/targets/incidental_hcloud_server/tasks/main.yml +++ /dev/null @@ -1,517 +0,0 @@ -# Copyright: (c) 2019, Hetzner Cloud GmbH -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ---- -- name: setup - hcloud_server: - name: "{{ hcloud_server_name }}" - state: absent - register: result -- name: verify setup - assert: - that: - - result is success -- name: test missing required parameters on create server - hcloud_server: - name: "{{ hcloud_server_name }}" - register: result - ignore_errors: yes -- name: verify fail test missing required parameters on create server - assert: - that: - - result is failed - - 'result.msg == "missing required arguments: server_type, image"' - -- name: test create server with check mode - hcloud_server: - name: "{{ hcloud_server_name }}" - server_type: cx11 - image: ubuntu-18.04 - state: present - register: result - check_mode: yes -- name: test create server server - assert: - that: - - result is changed - -- name: test create server - hcloud_server: - name: "{{ hcloud_server_name}}" - server_type: cx11 - image: ubuntu-18.04 - state: started - register: main_server -- name: verify create server - assert: - that: - - main_server is changed - - main_server.hcloud_server.name == "{{ hcloud_server_name }}" - - main_server.hcloud_server.server_type == "cx11" - - main_server.hcloud_server.status == "running" - - main_server.root_password != "" - -- name: test create server idempotence - hcloud_server: - name: "{{ hcloud_server_name }}" - state: started - register: result -- name: verify create server idempotence - assert: - that: - - result is not changed - -- name: test stop server with check mode - hcloud_server: - name: "{{ hcloud_server_name }}" - state: stopped - register: result - check_mode: yes -- name: verify stop server with check mode - assert: - that: - - result is changed - - result.hcloud_server.status == "running" - -- name: test stop server - hcloud_server: - name: "{{ hcloud_server_name }}" - state: stopped - register: result -- name: verify stop server - assert: - that: - - result is changed - - result.hcloud_server.status == "off" - -- name: test start server with check mode - hcloud_server: - name: "{{ hcloud_server_name }}" - state: started - register: result - check_mode: true -- name: verify start server with check mode - assert: - that: - - result is changed - -- name: test start server - hcloud_server: - name: "{{ hcloud_server_name }}" - state: started - register: result -- name: verify start server - assert: - that: - - result is changed - - result.hcloud_server.status == "running" - -- name: test start server idempotence - hcloud_server: - name: "{{ hcloud_server_name }}" - state: started - register: result -- name: verify start server idempotence - assert: - that: - - result is not changed - - result.hcloud_server.status == "running" - -- name: test stop server by its id - hcloud_server: - id: "{{ main_server.hcloud_server.id }}" - state: stopped - register: result -- name: verify stop server by its id - assert: - that: - - result is changed - - result.hcloud_server.status == "off" - -- name: test resize server running without force - hcloud_server: - name: "{{ hcloud_server_name }}" - server_type: "cx21" - state: present - register: result - check_mode: true -- name: verify test resize server running without force - assert: - that: - - result is changed - - result.hcloud_server.server_type == "cx11" - -- name: test resize server with check mode - hcloud_server: - name: "{{ hcloud_server_name }}" - server_type: "cx21" - state: stopped - register: result - check_mode: true -- name: verify resize server with check mode - assert: - that: - - result is changed - -- name: test enable backups with check mode - hcloud_server: - name: "{{ hcloud_server_name }}" - backups: true - state: stopped - register: result - check_mode: true -- name: verify enable backups with check mode - assert: - that: - - result is changed - -- name: test enable backups - hcloud_server: - name: "{{ hcloud_server_name }}" - backups: true - state: stopped - register: result -- name: verify enable backups - assert: - that: - - result is changed - - result.hcloud_server.backup_window != "" - -- name: test enable backups idempotence - hcloud_server: - name: "{{ hcloud_server_name }}" - backups: true - state: stopped - register: result -- name: verify enable backups idempotence - assert: - that: - - result is not changed - - result.hcloud_server.backup_window != "" - -- name: test rebuild server - hcloud_server: - name: "{{ hcloud_server_name }}" - image: ubuntu-18.04 - state: rebuild - register: result_after_test -- name: verify rebuild server - assert: - that: - - result_after_test is changed - - result.hcloud_server.id == result_after_test.hcloud_server.id - -- name: test rebuild server with check mode - hcloud_server: - name: "{{ hcloud_server_name }}" - image: ubuntu-18.04 - state: rebuild - register: result_after_test - check_mode: true -- name: verify rebuild server with check mode - assert: - that: - - result_after_test is changed - -- name: test update server protection booth protection arguments are required - hcloud_server: - name: "{{ hcloud_server_name }}" - delete_protection: true - state: present - register: result_after_test - ignore_errors: true -- name: verify update server protection booth protection arguments are required - assert: - that: - - result_after_test is failed - - 'result_after_test.msg == "parameters are required together: delete_protection, rebuild_protection"' - -- name: test update server protection fails if they are not the same - hcloud_server: - name: "{{ hcloud_server_name }}" - delete_protection: true - rebuild_protection: false - state: present - register: result_after_test - ignore_errors: true -- name: verify update server protection fails if they are not the same - assert: - that: - - result_after_test is failed - -- name: test update server protection - hcloud_server: - name: "{{ hcloud_server_name }}" - delete_protection: true - rebuild_protection: true - state: present - register: result_after_test - ignore_errors: true -- name: verify update server protection - assert: - that: - - result_after_test is changed - - result_after_test.hcloud_server.delete_protection is sameas true - - result_after_test.hcloud_server.rebuild_protection is sameas true - -- name: test server without protection set to be idempotent - hcloud_server: - name: "{{hcloud_server_name}}" - register: result_after_test -- name: verify test server without protection set to be idempotent - assert: - that: - - result_after_test is not changed - - result_after_test.hcloud_server.delete_protection is sameas true - - result_after_test.hcloud_server.rebuild_protection is sameas true - -- name: test delete server fails if it is protected - hcloud_server: - name: "{{hcloud_server_name}}" - state: absent - ignore_errors: yes - register: result -- name: verify delete server fails if it is protected - assert: - that: - - result is failed - - 'result.msg == "server deletion is protected"' - -- name: test rebuild server fails if it is protected - hcloud_server: - name: "{{hcloud_server_name}}" - image: ubuntu-18.04 - state: rebuild - ignore_errors: yes - register: result -- name: verify rebuild server fails if it is protected - assert: - that: - - result is failed - - 'result.msg == "server rebuild is protected"' - -- name: test remove server protection - hcloud_server: - name: "{{ hcloud_server_name }}" - delete_protection: false - rebuild_protection: false - state: present - register: result_after_test - ignore_errors: true -- name: verify remove server protection - assert: - that: - - result_after_test is changed - - result_after_test.hcloud_server.delete_protection is sameas false - - result_after_test.hcloud_server.rebuild_protection is sameas false - -- name: absent server - hcloud_server: - name: "{{ hcloud_server_name }}" - state: absent - register: result -- name: verify absent server - assert: - that: - - result is success - -- name: test create server with ssh key - hcloud_server: - name: "{{ hcloud_server_name}}" - server_type: cx11 - image: "ubuntu-18.04" - ssh_keys: - - ci@ansible.hetzner.cloud - state: started - register: main_server -- name: verify create server with ssh key - assert: - that: - - main_server is changed - - main_server.hcloud_server.name == "{{ hcloud_server_name }}" - - main_server.hcloud_server.server_type == "cx11" - - main_server.hcloud_server.status == "running" - - main_server.root_password != "" - -- name: absent server - hcloud_server: - name: "{{ hcloud_server_name }}" - state: absent - register: result -- name: verify absent server - assert: - that: - - result is success - -- name: test create server with rescue_mode - hcloud_server: - name: "{{ hcloud_server_name}}" - server_type: cx11 - image: "ubuntu-18.04" - ssh_keys: - - ci@ansible.hetzner.cloud - rescue_mode: "linux64" - state: started - register: main_server -- name: verify create server with rescue_mode - assert: - that: - - main_server is changed - - main_server.hcloud_server.name == "{{ hcloud_server_name }}" - - main_server.hcloud_server.server_type == "cx11" - - main_server.hcloud_server.status == "running" - - main_server.root_password != "" - - main_server.hcloud_server.rescue_enabled is sameas true - -- name: absent server - hcloud_server: - name: "{{ hcloud_server_name }}" - state: absent - register: result -- name: verify absent server - assert: - that: - - result is success - -- name: setup server - hcloud_server: - name: "{{ hcloud_server_name}}" - server_type: cx11 - image: ubuntu-18.04 - state: started - register: main_server -- name: verify setup server - assert: - that: - - main_server is changed - - main_server.hcloud_server.name == "{{ hcloud_server_name }}" - - main_server.hcloud_server.server_type == "cx11" - - main_server.hcloud_server.status == "running" - - main_server.root_password != "" - -- name: test activate rescue mode with check_mode - hcloud_server: - name: "{{ hcloud_server_name }}" - rescue_mode: "linux64" - ssh_keys: - - ci@ansible.hetzner.cloud - state: present - register: main_server - check_mode: true -- name: verify activate rescue mode - assert: - that: - - main_server is changed - -- name: test activate rescue mode - hcloud_server: - name: "{{ hcloud_server_name }}" - rescue_mode: "linux64" - ssh_keys: - - ci@ansible.hetzner.cloud - state: present - register: main_server -- name: verify activate rescue mode - assert: - that: - - main_server is changed - - main_server.hcloud_server.rescue_enabled is sameas true - -- name: test disable rescue mode - hcloud_server: - name: "{{ hcloud_server_name }}" - ssh_keys: - - ci@ansible.hetzner.cloud - state: present - register: main_server -- name: verify activate rescue mode - assert: - that: - - main_server is changed - - main_server.hcloud_server.rescue_enabled is sameas false - -- name: test activate rescue mode without ssh keys - hcloud_server: - name: "{{ hcloud_server_name }}" - rescue_mode: "linux64" - state: present - register: main_server -- name: verify activate rescue mode without ssh keys - assert: - that: - - main_server is changed - - main_server.hcloud_server.rescue_enabled is sameas true - -- name: cleanup - hcloud_server: - name: "{{ hcloud_server_name }}" - state: absent - register: result -- name: verify cleanup - assert: - that: - - result is success - -- name: test create server with labels - hcloud_server: - name: "{{ hcloud_server_name}}" - server_type: cx11 - image: "ubuntu-18.04" - ssh_keys: - - ci@ansible.hetzner.cloud - labels: - key: value - mylabel: "val123" - state: started - register: main_server -- name: verify create server with labels - assert: - that: - - main_server is changed - - main_server.hcloud_server.labels.key == "value" - - main_server.hcloud_server.labels.mylabel == "val123" - -- name: test update server with labels - hcloud_server: - name: "{{ hcloud_server_name}}" - server_type: cx11 - image: "ubuntu-18.04" - ssh_keys: - - ci@ansible.hetzner.cloud - labels: - key: other - mylabel: "val123" - state: started - register: main_server -- name: verify update server with labels - assert: - that: - - main_server is changed - - main_server.hcloud_server.labels.key == "other" - - main_server.hcloud_server.labels.mylabel == "val123" - -- name: test update server with labels in other order - hcloud_server: - name: "{{ hcloud_server_name}}" - server_type: cx11 - image: "ubuntu-18.04" - ssh_keys: - - ci@ansible.hetzner.cloud - labels: - mylabel: "val123" - key: other - state: started - register: main_server -- name: verify update server with labels in other order - assert: - that: - - main_server is not changed - -- name: cleanup with labels - hcloud_server: - name: "{{ hcloud_server_name }}" - state: absent - register: result -- name: verify cleanup - assert: - that: - - result is success diff --git a/test/support/integration/plugins/module_utils/hcloud.py b/test/support/integration/plugins/module_utils/hcloud.py deleted file mode 100644 index 932b0c5294d..00000000000 --- a/test/support/integration/plugins/module_utils/hcloud.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright: (c) 2019, Hetzner Cloud GmbH - -# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from ansible.module_utils.ansible_release import __version__ -from ansible.module_utils.basic import env_fallback, missing_required_lib - -try: - import hcloud - - HAS_HCLOUD = True -except ImportError: - HAS_HCLOUD = False - - -class Hcloud(object): - def __init__(self, module, represent): - self.module = module - self.represent = represent - self.result = {"changed": False, self.represent: None} - if not HAS_HCLOUD: - module.fail_json(msg=missing_required_lib("hcloud-python")) - self._build_client() - - def _build_client(self): - self.client = hcloud.Client( - token=self.module.params["api_token"], - api_endpoint=self.module.params["endpoint"], - application_name="ansible-module", - application_version=__version__, - ) - - def _mark_as_changed(self): - self.result["changed"] = True - - @staticmethod - def base_module_arguments(): - return { - "api_token": { - "type": "str", - "required": True, - "fallback": (env_fallback, ["HCLOUD_TOKEN"]), - "no_log": True, - }, - "endpoint": {"type": "str", "default": "https://api.hetzner.cloud/v1"}, - } - - def _prepare_result(self): - """Prepare the result for every module - - :return: dict - """ - return {} - - def get_result(self): - if getattr(self, self.represent) is not None: - self.result[self.represent] = self._prepare_result() - return self.result diff --git a/test/support/integration/plugins/modules/hcloud_server.py b/test/support/integration/plugins/modules/hcloud_server.py deleted file mode 100644 index 791c890a296..00000000000 --- a/test/support/integration/plugins/modules/hcloud_server.py +++ /dev/null @@ -1,555 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, Hetzner Cloud GmbH -# 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: hcloud_server - -short_description: Create and manage cloud servers on the Hetzner Cloud. - -version_added: "2.8" - -description: - - Create, update and manage cloud servers on the Hetzner Cloud. - -author: - - Lukas Kaemmerling (@LKaemmerling) - -options: - id: - description: - - The ID of the Hetzner Cloud server to manage. - - Only required if no server I(name) is given - type: int - name: - description: - - The Name of the Hetzner Cloud server to manage. - - Only required if no server I(id) is given or a server does not exists. - type: str - server_type: - description: - - The Server Type of the Hetzner Cloud server to manage. - - Required if server does not exists. - type: str - ssh_keys: - description: - - List of SSH key names - - The key names correspond to the SSH keys configured for your - Hetzner Cloud account access. - type: list - volumes: - description: - - List of Volumes IDs that should be attached to the server on server creation. - type: list - image: - description: - - Image the server should be created from. - - Required if server does not exists. - type: str - location: - description: - - Location of Server. - - Required if no I(datacenter) is given and server does not exists. - type: str - datacenter: - description: - - Datacenter of Server. - - Required of no I(location) is given and server does not exists. - type: str - backups: - description: - - Enable or disable Backups for the given Server. - type: bool - default: no - upgrade_disk: - description: - - Resize the disk size, when resizing a server. - - If you want to downgrade the server later, this value should be False. - type: bool - default: no - force_upgrade: - description: - - Force the upgrade of the server. - - Power off the server if it is running on upgrade. - type: bool - default: no - user_data: - description: - - User Data to be passed to the server on creation. - - Only used if server does not exists. - type: str - rescue_mode: - description: - - Add the Hetzner rescue system type you want the server to be booted into. - type: str - version_added: 2.9 - labels: - description: - - User-defined labels (key-value pairs). - type: dict - delete_protection: - description: - - Protect the Server for deletion. - - Needs to be the same as I(rebuild_protection). - type: bool - version_added: "2.10" - rebuild_protection: - description: - - Protect the Server for rebuild. - - Needs to be the same as I(delete_protection). - type: bool - version_added: "2.10" - state: - description: - - State of the server. - default: present - choices: [ absent, present, restarted, started, stopped, rebuild ] - type: str -extends_documentation_fragment: hcloud -""" - -EXAMPLES = """ -- name: Create a basic server - hcloud_server: - name: my-server - server_type: cx11 - image: ubuntu-18.04 - state: present - -- name: Create a basic server with ssh key - hcloud_server: - name: my-server - server_type: cx11 - image: ubuntu-18.04 - location: fsn1 - ssh_keys: - - me@myorganisation - state: present - -- name: Resize an existing server - hcloud_server: - name: my-server - server_type: cx21 - upgrade_disk: yes - state: present - -- name: Ensure the server is absent (remove if needed) - hcloud_server: - name: my-server - state: absent - -- name: Ensure the server is started - hcloud_server: - name: my-server - state: started - -- name: Ensure the server is stopped - hcloud_server: - name: my-server - state: stopped - -- name: Ensure the server is restarted - hcloud_server: - name: my-server - state: restarted - -- name: Ensure the server is will be booted in rescue mode and therefore restarted - hcloud_server: - name: my-server - rescue_mode: linux64 - state: restarted - -- name: Ensure the server is rebuild - hcloud_server: - name: my-server - image: ubuntu-18.04 - state: rebuild -""" - -RETURN = """ -hcloud_server: - description: The server instance - returned: Always - type: complex - contains: - id: - description: Numeric identifier of the server - returned: always - type: int - sample: 1937415 - name: - description: Name of the server - returned: always - type: str - sample: my-server - status: - description: Status of the server - returned: always - type: str - sample: running - server_type: - description: Name of the server type of the server - returned: always - type: str - sample: cx11 - ipv4_address: - description: Public IPv4 address of the server - returned: always - type: str - sample: 116.203.104.109 - ipv6: - description: IPv6 network of the server - returned: always - type: str - sample: 2a01:4f8:1c1c:c140::/64 - location: - description: Name of the location of the server - returned: always - type: str - sample: fsn1 - datacenter: - description: Name of the datacenter of the server - returned: always - type: str - sample: fsn1-dc14 - rescue_enabled: - description: True if rescue mode is enabled, Server will then boot into rescue system on next reboot - returned: always - type: bool - sample: false - backup_window: - description: Time window (UTC) in which the backup will run, or null if the backups are not enabled - returned: always - type: bool - sample: 22-02 - labels: - description: User-defined labels (key-value pairs) - returned: always - type: dict - delete_protection: - description: True if server is protected for deletion - type: bool - returned: always - sample: false - version_added: "2.10" - rebuild_protection: - description: True if server is protected for rebuild - type: bool - returned: always - sample: false - version_added: "2.10" -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -from ansible.module_utils.hcloud import Hcloud - -try: - from hcloud.volumes.domain import Volume - from hcloud.ssh_keys.domain import SSHKey - from hcloud.servers.domain import Server - from hcloud import APIException -except ImportError: - pass - - -class AnsibleHcloudServer(Hcloud): - def __init__(self, module): - Hcloud.__init__(self, module, "hcloud_server") - self.hcloud_server = None - - def _prepare_result(self): - image = None if self.hcloud_server.image is None else to_native(self.hcloud_server.image.name) - return { - "id": to_native(self.hcloud_server.id), - "name": to_native(self.hcloud_server.name), - "ipv4_address": to_native(self.hcloud_server.public_net.ipv4.ip), - "ipv6": to_native(self.hcloud_server.public_net.ipv6.ip), - "image": image, - "server_type": to_native(self.hcloud_server.server_type.name), - "datacenter": to_native(self.hcloud_server.datacenter.name), - "location": to_native(self.hcloud_server.datacenter.location.name), - "rescue_enabled": self.hcloud_server.rescue_enabled, - "backup_window": to_native(self.hcloud_server.backup_window), - "labels": self.hcloud_server.labels, - "delete_protection": self.hcloud_server.protection["delete"], - "rebuild_protection": self.hcloud_server.protection["rebuild"], - "status": to_native(self.hcloud_server.status), - } - - def _get_server(self): - try: - if self.module.params.get("id") is not None: - self.hcloud_server = self.client.servers.get_by_id( - self.module.params.get("id") - ) - else: - self.hcloud_server = self.client.servers.get_by_name( - self.module.params.get("name") - ) - except APIException as e: - self.module.fail_json(msg=e.message) - - def _create_server(self): - - self.module.fail_on_missing_params( - required_params=["name", "server_type", "image"] - ) - params = { - "name": self.module.params.get("name"), - "server_type": self.client.server_types.get_by_name( - self.module.params.get("server_type") - ), - "user_data": self.module.params.get("user_data"), - "labels": self.module.params.get("labels"), - } - if self.client.images.get_by_name(self.module.params.get("image")) is not None: - # When image name is not available look for id instead - params["image"] = self.client.images.get_by_name(self.module.params.get("image")) - else: - params["image"] = self.client.images.get_by_id(self.module.params.get("image")) - - if self.module.params.get("ssh_keys") is not None: - params["ssh_keys"] = [ - SSHKey(name=ssh_key_name) - for ssh_key_name in self.module.params.get("ssh_keys") - ] - - if self.module.params.get("volumes") is not None: - params["volumes"] = [ - Volume(id=volume_id) for volume_id in self.module.params.get("volumes") - ] - - if self.module.params.get("location") is None and self.module.params.get("datacenter") is None: - # When not given, the API will choose the location. - params["location"] = None - params["datacenter"] = None - elif self.module.params.get("location") is not None and self.module.params.get("datacenter") is None: - params["location"] = self.client.locations.get_by_name( - self.module.params.get("location") - ) - elif self.module.params.get("location") is None and self.module.params.get("datacenter") is not None: - params["datacenter"] = self.client.datacenters.get_by_name( - self.module.params.get("datacenter") - ) - - if not self.module.check_mode: - resp = self.client.servers.create(**params) - self.result["root_password"] = resp.root_password - resp.action.wait_until_finished(max_retries=1000) - [action.wait_until_finished() for action in resp.next_actions] - - rescue_mode = self.module.params.get("rescue_mode") - if rescue_mode: - self._get_server() - self._set_rescue_mode(rescue_mode) - - self._mark_as_changed() - self._get_server() - - def _update_server(self): - try: - rescue_mode = self.module.params.get("rescue_mode") - if rescue_mode and self.hcloud_server.rescue_enabled is False: - if not self.module.check_mode: - self._set_rescue_mode(rescue_mode) - self._mark_as_changed() - elif not rescue_mode and self.hcloud_server.rescue_enabled is True: - if not self.module.check_mode: - self.hcloud_server.disable_rescue().wait_until_finished() - self._mark_as_changed() - - if self.module.params.get("backups") and self.hcloud_server.backup_window is None: - if not self.module.check_mode: - self.hcloud_server.enable_backup().wait_until_finished() - self._mark_as_changed() - elif not self.module.params.get("backups") and self.hcloud_server.backup_window is not None: - if not self.module.check_mode: - self.hcloud_server.disable_backup().wait_until_finished() - self._mark_as_changed() - - labels = self.module.params.get("labels") - if labels is not None and labels != self.hcloud_server.labels: - if not self.module.check_mode: - self.hcloud_server.update(labels=labels) - self._mark_as_changed() - - server_type = self.module.params.get("server_type") - if server_type is not None and self.hcloud_server.server_type.name != server_type: - previous_server_status = self.hcloud_server.status - state = self.module.params.get("state") - if previous_server_status == Server.STATUS_RUNNING: - if not self.module.check_mode: - if self.module.params.get("force_upgrade") or state == "stopped": - self.stop_server() # Only stopped server can be upgraded - else: - self.module.warn( - "You can not upgrade a running instance %s. You need to stop the instance or use force_upgrade=yes." - % self.hcloud_server.name - ) - timeout = 100 - if self.module.params.get("upgrade_disk"): - timeout = ( - 1000 - ) # When we upgrade the disk too the resize progress takes some more time. - if not self.module.check_mode: - self.hcloud_server.change_type( - server_type=self.client.server_types.get_by_name(server_type), - upgrade_disk=self.module.params.get("upgrade_disk"), - ).wait_until_finished(timeout) - if state == "present" and previous_server_status == Server.STATUS_RUNNING or state == "started": - self.start_server() - - self._mark_as_changed() - - delete_protection = self.module.params.get("delete_protection") - rebuild_protection = self.module.params.get("rebuild_protection") - if (delete_protection is not None and rebuild_protection is not None) and ( - delete_protection != self.hcloud_server.protection["delete"] or rebuild_protection != - self.hcloud_server.protection["rebuild"]): - if not self.module.check_mode: - self.hcloud_server.change_protection(delete=delete_protection, - rebuild=rebuild_protection).wait_until_finished() - self._mark_as_changed() - self._get_server() - except APIException as e: - self.module.fail_json(msg=e.message) - - def _set_rescue_mode(self, rescue_mode): - if self.module.params.get("ssh_keys"): - resp = self.hcloud_server.enable_rescue(type=rescue_mode, - ssh_keys=[self.client.ssh_keys.get_by_name(ssh_key_name).id - for - ssh_key_name in - self.module.params.get("ssh_keys")]) - else: - resp = self.hcloud_server.enable_rescue(type=rescue_mode) - resp.action.wait_until_finished() - self.result["root_password"] = resp.root_password - - def start_server(self): - try: - if self.hcloud_server.status != Server.STATUS_RUNNING: - if not self.module.check_mode: - self.client.servers.power_on(self.hcloud_server).wait_until_finished() - self._mark_as_changed() - self._get_server() - except APIException as e: - self.module.fail_json(msg=e.message) - - def stop_server(self): - try: - if self.hcloud_server.status != Server.STATUS_OFF: - if not self.module.check_mode: - self.client.servers.power_off(self.hcloud_server).wait_until_finished() - self._mark_as_changed() - self._get_server() - except APIException as e: - self.module.fail_json(msg=e.message) - - def rebuild_server(self): - self.module.fail_on_missing_params( - required_params=["image"] - ) - try: - if not self.module.check_mode: - self.client.servers.rebuild(self.hcloud_server, self.client.images.get_by_name( - self.module.params.get("image"))).wait_until_finished() - self._mark_as_changed() - - self._get_server() - except APIException as e: - self.module.fail_json(msg=e.message) - - def present_server(self): - self._get_server() - if self.hcloud_server is None: - self._create_server() - else: - self._update_server() - - def delete_server(self): - try: - self._get_server() - if self.hcloud_server is not None: - if not self.module.check_mode: - self.client.servers.delete(self.hcloud_server).wait_until_finished() - self._mark_as_changed() - self.hcloud_server = None - except APIException as e: - self.module.fail_json(msg=e.message) - - @staticmethod - def define_module(): - return AnsibleModule( - argument_spec=dict( - id={"type": "int"}, - name={"type": "str"}, - image={"type": "str"}, - server_type={"type": "str"}, - location={"type": "str"}, - datacenter={"type": "str"}, - user_data={"type": "str"}, - ssh_keys={"type": "list"}, - volumes={"type": "list"}, - labels={"type": "dict"}, - backups={"type": "bool", "default": False}, - upgrade_disk={"type": "bool", "default": False}, - force_upgrade={"type": "bool", "default": False}, - rescue_mode={"type": "str"}, - delete_protection={"type": "bool"}, - rebuild_protection={"type": "bool"}, - state={ - "choices": ["absent", "present", "restarted", "started", "stopped", "rebuild"], - "default": "present", - }, - **Hcloud.base_module_arguments() - ), - required_one_of=[['id', 'name']], - mutually_exclusive=[["location", "datacenter"]], - required_together=[["delete_protection", "rebuild_protection"]], - supports_check_mode=True, - ) - - -def main(): - module = AnsibleHcloudServer.define_module() - - hcloud = AnsibleHcloudServer(module) - state = module.params.get("state") - if state == "absent": - hcloud.delete_server() - elif state == "present": - hcloud.present_server() - elif state == "started": - hcloud.present_server() - hcloud.start_server() - elif state == "stopped": - hcloud.present_server() - hcloud.stop_server() - elif state == "restarted": - hcloud.present_server() - hcloud.stop_server() - hcloud.start_server() - elif state == "rebuild": - hcloud.present_server() - hcloud.rebuild_server() - - module.exit_json(**hcloud.get_result()) - - -if __name__ == "__main__": - main()