From 268073915349c8975a9ba753b9aa7b022db73abd Mon Sep 17 00:00:00 2001 From: Guillaume MARTINEZ Date: Sun, 23 Oct 2022 17:18:06 +0200 Subject: [PATCH] [Scaleway] Add module to manage container registries (#5399) * [Scaleway] Add module to manage container registries Signed-off-by: Lunik * first review Signed-off-by: Lunik * lint documentation on return value Signed-off-by: Lunik * second review Signed-off-by: Lunik * second review *bis Signed-off-by: Lunik * second review *ter Signed-off-by: Lunik * Fix typo. Signed-off-by: Lunik Co-authored-by: Felix Fontein --- .github/BOTMETA.yml | 4 + .gitignore | 3 + meta/runtime.yml | 4 + .../scaleway_waitable_resource.py | 33 +++ plugins/module_utils/scaleway.py | 101 +++++++ .../scaleway/scaleway_container_registry.py | 265 ++++++++++++++++++ .../scaleway_container_registry_info.py | 146 ++++++++++ .../scaleway_container_registry/aliases | 6 + .../defaults/main.yml | 9 + .../tasks/main.yml | 178 ++++++++++++ .../scaleway_container_registry_info/aliases | 6 + .../defaults/main.yml | 9 + .../tasks/main.yml | 41 +++ 13 files changed, 805 insertions(+) create mode 100644 plugins/doc_fragments/scaleway_waitable_resource.py create mode 100644 plugins/modules/cloud/scaleway/scaleway_container_registry.py create mode 100644 plugins/modules/cloud/scaleway/scaleway_container_registry_info.py create mode 100644 tests/integration/targets/scaleway_container_registry/aliases create mode 100644 tests/integration/targets/scaleway_container_registry/defaults/main.yml create mode 100644 tests/integration/targets/scaleway_container_registry/tasks/main.yml create mode 100644 tests/integration/targets/scaleway_container_registry_info/aliases create mode 100644 tests/integration/targets/scaleway_container_registry_info/defaults/main.yml create mode 100644 tests/integration/targets/scaleway_container_registry_info/tasks/main.yml diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index fa9a5f355f..53fa9ad257 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -461,6 +461,10 @@ files: maintainers: $team_scaleway $modules/cloud/scaleway/scaleway_compute_private_network.py: maintainers: pastral + $modules/cloud/scaleway/scaleway_container_registry.py: + maintainers: Lunik + $modules/cloud/scaleway/scaleway_container_registry_info.py: + maintainers: Lunik $modules/cloud/scaleway/scaleway_database_backup.py: maintainers: guillaume_ro_fr $modules/cloud/scaleway/scaleway_image_info.py: diff --git a/.gitignore b/.gitignore index c39969326d..b7868a9e41 100644 --- a/.gitignore +++ b/.gitignore @@ -509,3 +509,6 @@ $RECYCLE.BIN/ *.lnk # End of https://www.toptal.com/developers/gitignore/api/vim,git,macos,linux,pydev,emacs,dotenv,python,windows,webstorm,pycharm+all,jupyternotebooks + +# Integration tests cloud configs +tests/integration/cloud-config-*.ini diff --git a/meta/runtime.yml b/meta/runtime.yml index 8444d0b6f8..350edaee11 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1379,6 +1379,10 @@ plugin_routing: redirect: community.general.cloud.scaleway.scaleway_compute scaleway_compute_private_network: redirect: community.general.cloud.scaleway.scaleway_compute_private_network + scaleway_container_registry: + redirect: community.general.cloud.scaleway.scaleway_container_registry + scaleway_container_registry_info: + redirect: community.general.cloud.scaleway.scaleway_container_registry_info scaleway_database_backup: redirect: community.general.cloud.scaleway.scaleway_database_backup scaleway_image_facts: diff --git a/plugins/doc_fragments/scaleway_waitable_resource.py b/plugins/doc_fragments/scaleway_waitable_resource.py new file mode 100644 index 0000000000..3ab5c7d6f4 --- /dev/null +++ b/plugins/doc_fragments/scaleway_waitable_resource.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Guillaume MARTINEZ +# 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 + + +class ModuleDocFragment(object): + + # Standard documentation fragment + DOCUMENTATION = r''' +options: + wait: + description: + - Wait for the resource to reach its desired state before returning. + type: bool + default: true + wait_timeout: + type: int + description: + - Time to wait for the resource 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 resource. + required: false + default: 3 +''' diff --git a/plugins/module_utils/scaleway.py b/plugins/module_utils/scaleway.py index 4c1a475689..ee22d0f183 100644 --- a/plugins/module_utils/scaleway.py +++ b/plugins/module_utils/scaleway.py @@ -9,6 +9,8 @@ __metaclass__ = type import json import re import sys +import datetime +import time from ansible.module_utils.basic import env_fallback from ansible.module_utils.urls import fetch_url @@ -26,6 +28,14 @@ def scaleway_argument_spec(): ) +def scaleway_waitable_resource_argument_spec(): + return dict( + wait=dict(type="bool", default=True), + wait_timeout=dict(type="int", default=300), + wait_sleep_time=dict(type="int", default=3), + ) + + def payload_from_object(scw_object): return dict( (k, v) @@ -63,6 +73,25 @@ def parse_pagination_link(header): return parsed_relations +def filter_sensitive_attributes(container, attributes): + for attr in attributes: + container[attr] = "SENSITIVE_VALUE" + + return container + + +def resource_attributes_should_be_changed(target, wished, verifiable_mutable_attributes, mutable_attributes): + diff = dict() + for attr in verifiable_mutable_attributes: + if wished[attr] is not None and target[attr] != wished[attr]: + diff[attr] = wished[attr] + + if diff: + return dict((attr, wished[attr]) for attr in mutable_attributes) + else: + return diff + + class Response(object): def __init__(self, resp, info): @@ -169,6 +198,78 @@ class Scaleway(object): def warn(self, x): self.module.warn(str(x)) + def fetch_state(self, resource): + self.module.debug("fetch_state of resource: %s" % resource["id"]) + response = self.get(path=self.api_path + "/%s" % resource["id"]) + + if response.status_code == 404: + return "absent" + + if not response.ok: + msg = 'Error during state fetching: (%s) %s' % (response.status_code, response.json) + self.module.fail_json(msg=msg) + + try: + self.module.debug("Resource %s in state: %s" % (resource["id"], response.json["status"])) + return response.json["status"] + except KeyError: + self.module.fail_json(msg="Could not fetch state in %s" % response.json) + + def fetch_paginated_resources(self, resource_key, **pagination_kwargs): + response = self.get( + path=self.api_path, + params=pagination_kwargs) + + status_code = response.status_code + if not response.ok: + self.module.fail_json(msg='Error getting {0} [{1}: {2}]'.format( + resource_key, + response.status_code, response.json['message'])) + + return response.json[resource_key] + + def fetch_all_resources(self, resource_key, **pagination_kwargs): + resources = [] + + result = [None] + while len(result) != 0: + result = self.fetch_paginated_resources(resource_key, **pagination_kwargs) + resources += result + if 'page' in pagination_kwargs: + pagination_kwargs['page'] += 1 + else: + pagination_kwargs['page'] = 2 + + return resources + + def wait_to_complete_state_transition(self, resource, stable_states, force_wait=False): + wait = self.module.params["wait"] + + if not (wait or force_wait): + return + + wait_timeout = self.module.params["wait_timeout"] + wait_sleep_time = self.module.params["wait_sleep_time"] + + # Prevent requesting the ressource status too soon + time.sleep(wait_sleep_time) + + start = datetime.datetime.utcnow() + end = start + datetime.timedelta(seconds=wait_timeout) + + while datetime.datetime.utcnow() < end: + self.module.debug("We are going to wait for the resource to finish its transition") + + state = self.fetch_state(resource) + if state in stable_states: + self.module.debug("It seems that the resource is not in transition anymore.") + self.module.debug("load-balancer in state: %s" % self.fetch_state(resource)) + break + + time.sleep(wait_sleep_time) + else: + self.module.fail_json(msg="Server takes too long to finish its transition") + SCALEWAY_LOCATION = { 'par1': { diff --git a/plugins/modules/cloud/scaleway/scaleway_container_registry.py b/plugins/modules/cloud/scaleway/scaleway_container_registry.py new file mode 100644 index 0000000000..ed10ddf292 --- /dev/null +++ b/plugins/modules/cloud/scaleway/scaleway_container_registry.py @@ -0,0 +1,265 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Scaleway Container registry management module +# +# Copyright (c) 2022, Guillaume MARTINEZ +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: scaleway_container_registry +short_description: Scaleway Container registry management module +version_added: 5.8.0 +author: Guillaume MARTINEZ (@Lunik) +description: + - This module manages container registries on Scaleway account. +extends_documentation_fragment: + - community.general.scaleway + - community.general.scaleway_waitable_resource + + +options: + state: + type: str + description: + - Indicate desired state of the container regitry. + default: present + choices: + - present + - absent + + project_id: + type: str + description: + - Project identifier. + required: true + + region: + type: str + description: + - Scaleway region to use (for example C(fr-par)). + required: true + choices: + - fr-par + - nl-ams + - pl-waw + + name: + type: str + description: + - Name of the container registry. + required: true + + description: + description: + - Description of the container registry. + type: str + + privacy_policy: + type: str + description: + - Default visibility policy. + - Everyone will be able to pull images from a C(public) registry. + choices: + - public + - private + default: private +''' + +EXAMPLES = ''' +- name: Create a container registry + community.general.scaleway_container_registry: + project_id: '{{ scw_project }}' + state: present + region: fr-par + name: my-awesome-container-registry + register: container_registry_creation_task + +- name: Make sure container registry is deleted + community.general.scaleway_container_registry: + project_id: '{{ scw_project }}' + state: absent + region: fr-par + name: my-awesome-container-registry +''' + +RETURN = ''' +container_registry: + description: The container registry information. + returned: when I(state=present) + type: dict + sample: + created_at: "2022-10-14T09:51:07.949716Z" + description: Managed by Ansible + endpoint: rg.fr-par.scw.cloud/my-awesome-registry + id: 0d7d5270-7864-49c2-920b-9fd6731f3589 + image_count: 0 + is_public: false + name: my-awesome-registry + organization_id: 10697b59-5c34-4d24-8d15-9ff2d3b89f58 + project_id: 3da4f0b2-06be-4773-8ec4-5dfa435381be + region: fr-par + size: 0 + status: ready + status_message: "" + updated_at: "2022-10-14T09:51:07.949716Z" +''' + +from ansible_collections.community.general.plugins.module_utils.scaleway import ( + SCALEWAY_ENDPOINT, SCALEWAY_REGIONS, scaleway_argument_spec, Scaleway, + scaleway_waitable_resource_argument_spec, resource_attributes_should_be_changed +) +from ansible.module_utils.basic import AnsibleModule + +STABLE_STATES = ( + "ready", + "absent" +) + +MUTABLE_ATTRIBUTES = ( + "description", + "is_public" +) + + +def payload_from_wished_cr(wished_cr): + payload = { + "project_id": wished_cr["project_id"], + "name": wished_cr["name"], + "description": wished_cr["description"], + "is_public": wished_cr["privacy_policy"] == "public" + } + + return payload + + +def absent_strategy(api, wished_cr): + changed = False + + cr_list = api.fetch_all_resources("namespaces") + cr_lookup = dict((cr["name"], cr) + for cr in cr_list) + + if wished_cr["name"] not in cr_lookup: + return changed, {} + + target_cr = cr_lookup[wished_cr["name"]] + changed = True + if api.module.check_mode: + return changed, {"status": "Container registry would be destroyed"} + + api.wait_to_complete_state_transition(resource=target_cr, stable_states=STABLE_STATES, force_wait=True) + response = api.delete(path=api.api_path + "/%s" % target_cr["id"]) + if not response.ok: + api.module.fail_json(msg='Error deleting container registry [{0}: {1}]'.format( + response.status_code, response.json)) + + api.wait_to_complete_state_transition(resource=target_cr, stable_states=STABLE_STATES) + return changed, response.json + + +def present_strategy(api, wished_cr): + changed = False + + cr_list = api.fetch_all_resources("namespaces") + cr_lookup = dict((cr["name"], cr) + for cr in cr_list) + + payload_cr = payload_from_wished_cr(wished_cr) + + if wished_cr["name"] not in cr_lookup: + changed = True + if api.module.check_mode: + return changed, {"status": "A container registry would be created."} + + # Create container registry + api.warn(payload_cr) + creation_response = api.post(path=api.api_path, + data=payload_cr) + + if not creation_response.ok: + msg = "Error during container registry creation: %s: '%s' (%s)" % (creation_response.info['msg'], + creation_response.json['message'], + creation_response.json) + api.module.fail_json(msg=msg) + + api.wait_to_complete_state_transition(resource=creation_response.json, stable_states=STABLE_STATES) + response = api.get(path=api.api_path + "/%s" % creation_response.json["id"]) + return changed, response.json + + target_cr = cr_lookup[wished_cr["name"]] + patch_payload = resource_attributes_should_be_changed(target=target_cr, + wished=payload_cr, + verifiable_mutable_attributes=MUTABLE_ATTRIBUTES, + mutable_attributes=MUTABLE_ATTRIBUTES) + + if not patch_payload: + return changed, target_cr + + changed = True + if api.module.check_mode: + return changed, {"status": "Container registry attributes would be changed."} + + cr_patch_response = api.patch(path=api.api_path + "/%s" % target_cr["id"], + data=patch_payload) + + if not cr_patch_response.ok: + api.module.fail_json(msg='Error during container registry attributes update: [{0}: {1}]'.format( + cr_patch_response.status_code, cr_patch_response.json['message'])) + + api.wait_to_complete_state_transition(resource=target_cr, stable_states=STABLE_STATES) + response = api.get(path=api.api_path + "/%s" % target_cr["id"]) + return changed, response.json + + +state_strategy = { + "present": present_strategy, + "absent": absent_strategy +} + + +def core(module): + region = module.params["region"] + wished_container_registry = { + "state": module.params["state"], + "project_id": module.params["project_id"], + "name": module.params["name"], + "description": module.params['description'], + "privacy_policy": module.params['privacy_policy'] + } + + api = Scaleway(module=module) + api.api_path = "registry/v1/regions/%s/namespaces" % region + + changed, summary = state_strategy[wished_container_registry["state"]](api=api, wished_cr=wished_container_registry) + + module.exit_json(changed=changed, container_registry=summary) + + +def main(): + argument_spec = scaleway_argument_spec() + argument_spec.update(scaleway_waitable_resource_argument_spec()) + argument_spec.update(dict( + state=dict(type='str', default='present', choices=['absent', 'present']), + project_id=dict(type='str', required=True), + region=dict(type='str', required=True, choices=SCALEWAY_REGIONS), + name=dict(type='str', required=True), + description=dict(type='str', default=''), + privacy_policy=dict(type='str', default='private', choices=['public', 'private']) + )) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + core(module) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/cloud/scaleway/scaleway_container_registry_info.py b/plugins/modules/cloud/scaleway/scaleway_container_registry_info.py new file mode 100644 index 0000000000..c53e405780 --- /dev/null +++ b/plugins/modules/cloud/scaleway/scaleway_container_registry_info.py @@ -0,0 +1,146 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Scaleway Serverless container registry info module +# +# Copyright (c) 2022, Guillaume MARTINEZ +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: scaleway_container_registry_info +short_description: Scaleway Container registry info module +version_added: 5.8.0 +author: Guillaume MARTINEZ (@Lunik) +description: + - This module return information about a container registry on Scaleway account. +extends_documentation_fragment: + - community.general.scaleway + + +options: + project_id: + type: str + description: + - Project identifier. + required: true + + region: + type: str + description: + - Scaleway region to use (for example C(fr-par)). + required: true + choices: + - fr-par + - nl-ams + - pl-waw + + name: + type: str + description: + - Name of the container registry. + required: true +''' + +EXAMPLES = ''' +- name: Get a container registry info + community.general.scaleway_container_registry_info: + project_id: '{{ scw_project }}' + region: fr-par + name: my-awesome-container-registry + register: container_registry_info_task +''' + +RETURN = ''' +container_registry: + description: The container registry information. + returned: always + type: dict + sample: + created_at: "2022-10-14T09:51:07.949716Z" + description: Managed by Ansible + endpoint: rg.fr-par.scw.cloud/my-awesome-registry + id: 0d7d5270-7864-49c2-920b-9fd6731f3589 + image_count: 0 + is_public: false + name: my-awesome-registry + organization_id: 10697b59-5c34-4d24-8d15-9ff2d3b89f58 + project_id: 3da4f0b2-06be-4773-8ec4-5dfa435381be + region: fr-par + size: 0 + status: ready + status_message: "" + updated_at: "2022-10-14T09:51:07.949716Z" +''' + +from ansible_collections.community.general.plugins.module_utils.scaleway import ( + SCALEWAY_ENDPOINT, SCALEWAY_REGIONS, scaleway_argument_spec, Scaleway, + filter_sensitive_attributes +) +from ansible.module_utils.basic import AnsibleModule + +SENSITIVE_ATTRIBUTES = ( + "secret_environment_variables", +) + + +def info_strategy(api, wished_cn): + cn_list = api.fetch_all_resources("namespaces") + cn_lookup = dict((fn["name"], fn) + for fn in cn_list) + + if wished_cn["name"] not in cn_lookup: + msg = "Error during container registries lookup: Unable to find container registry named '%s' in project '%s'" % (wished_cn["name"], + wished_cn["project_id"]) + + api.module.fail_json(msg=msg) + + target_cn = cn_lookup[wished_cn["name"]] + + response = api.get(path=api.api_path + "/%s" % target_cn["id"]) + if not response.ok: + msg = "Error during container registry lookup: %s: '%s' (%s)" % (response.info['msg'], + response.json['message'], + response.json) + api.module.fail_json(msg=msg) + + return response.json + + +def core(module): + region = module.params["region"] + wished_container_namespace = { + "project_id": module.params["project_id"], + "name": module.params["name"] + } + + api = Scaleway(module=module) + api.api_path = "registry/v1/regions/%s/namespaces" % region + + summary = info_strategy(api=api, wished_cn=wished_container_namespace) + + module.exit_json(changed=False, container_registry=filter_sensitive_attributes(summary, SENSITIVE_ATTRIBUTES)) + + +def main(): + argument_spec = scaleway_argument_spec() + argument_spec.update(dict( + project_id=dict(type='str', required=True), + region=dict(type='str', required=True, choices=SCALEWAY_REGIONS), + name=dict(type='str', required=True) + )) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + core(module) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/scaleway_container_registry/aliases b/tests/integration/targets/scaleway_container_registry/aliases new file mode 100644 index 0000000000..a5ac5181f0 --- /dev/null +++ b/tests/integration/targets/scaleway_container_registry/aliases @@ -0,0 +1,6 @@ +# Copyright (c) 2022, Guillaume MARTINEZ +# 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 + +cloud/scaleway +unsupported diff --git a/tests/integration/targets/scaleway_container_registry/defaults/main.yml b/tests/integration/targets/scaleway_container_registry/defaults/main.yml new file mode 100644 index 0000000000..73b31423f7 --- /dev/null +++ b/tests/integration/targets/scaleway_container_registry/defaults/main.yml @@ -0,0 +1,9 @@ +--- +# Copyright (c) 2022, Guillaume MARTINEZ +# 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 + +scaleway_region: fr-par +name: cr_ansible_test +description: Container registry used for testing scaleway_container_registry ansible module +updated_description: Container registry used for testing scaleway_container_registry ansible module (Updated description) diff --git a/tests/integration/targets/scaleway_container_registry/tasks/main.yml b/tests/integration/targets/scaleway_container_registry/tasks/main.yml new file mode 100644 index 0000000000..24b1f0cbc9 --- /dev/null +++ b/tests/integration/targets/scaleway_container_registry/tasks/main.yml @@ -0,0 +1,178 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +# Copyright (c) 2022, Guillaume MARTINEZ +# 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 + +- name: Create a container registry (Check) + check_mode: yes + community.general.scaleway_container_registry: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ description }}' + register: cr_creation_check_task + +- ansible.builtin.debug: + var: cr_creation_check_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_creation_check_task is success + - cr_creation_check_task is changed + +- name: Create container_registry + community.general.scaleway_container_registry: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ description }}' + register: cr_creation_task + +- ansible.builtin.debug: + var: cr_creation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_creation_task is success + - cr_creation_task is changed + - cr_creation_task.container_registry.status == "ready" + +- name: Create container registry (Confirmation) + community.general.scaleway_container_registry: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ description }}' + register: cr_creation_confirmation_task + +- ansible.builtin.debug: + var: cr_creation_confirmation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_creation_confirmation_task is success + - cr_creation_confirmation_task is not changed + - cr_creation_confirmation_task.container_registry.status == "ready" + +- name: Update container registry (Check) + check_mode: yes + community.general.scaleway_container_registry: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ updated_description }}' + register: cr_update_check_task + +- ansible.builtin.debug: + var: cr_update_check_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_update_check_task is success + - cr_update_check_task is changed + +- name: Update container registry + community.general.scaleway_container_registry: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ updated_description }}' + register: cr_update_task + +- ansible.builtin.debug: + var: cr_update_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_update_task is success + - cr_update_task is changed + - cr_update_task.container_registry.status == "ready" + +- name: Update container registry (Confirmation) + community.general.scaleway_container_registry: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ updated_description }}' + register: cr_update_confirmation_task + +- ansible.builtin.debug: + var: cr_update_confirmation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_update_confirmation_task is success + - cr_update_confirmation_task is not changed + - cr_update_confirmation_task.container_registry.status == "ready" + +- name: Delete container registry (Check) + check_mode: yes + community.general.scaleway_container_registry: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + project_id: '{{ scw_project }}' + register: cr_deletion_check_task + +- ansible.builtin.debug: + var: cr_deletion_check_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_deletion_check_task is success + - cr_deletion_check_task is changed + +- name: Delete container registry + community.general.scaleway_container_registry: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + project_id: '{{ scw_project }}' + register: cr_deletion_task + +- ansible.builtin.debug: + var: cr_deletion_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_deletion_task is success + - cr_deletion_task is changed + +- name: Delete container regitry (Confirmation) + community.general.scaleway_container_registry: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + project_id: '{{ scw_project }}' + register: cr_deletion_confirmation_task + +- ansible.builtin.debug: + var: cr_deletion_confirmation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_deletion_confirmation_task is success + - cr_deletion_confirmation_task is not changed diff --git a/tests/integration/targets/scaleway_container_registry_info/aliases b/tests/integration/targets/scaleway_container_registry_info/aliases new file mode 100644 index 0000000000..a5ac5181f0 --- /dev/null +++ b/tests/integration/targets/scaleway_container_registry_info/aliases @@ -0,0 +1,6 @@ +# Copyright (c) 2022, Guillaume MARTINEZ +# 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 + +cloud/scaleway +unsupported diff --git a/tests/integration/targets/scaleway_container_registry_info/defaults/main.yml b/tests/integration/targets/scaleway_container_registry_info/defaults/main.yml new file mode 100644 index 0000000000..8c53a31e7d --- /dev/null +++ b/tests/integration/targets/scaleway_container_registry_info/defaults/main.yml @@ -0,0 +1,9 @@ +--- +# Copyright (c) 2022, Guillaume MARTINEZ +# 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 + +scaleway_region: fr-par +name: cr_ansible_test +description: Container registry used for testing scaleway_container_registry_info ansible module +updated_description: Container registry used for testing scaleway_container_registry_info ansible module (Updated description) diff --git a/tests/integration/targets/scaleway_container_registry_info/tasks/main.yml b/tests/integration/targets/scaleway_container_registry_info/tasks/main.yml new file mode 100644 index 0000000000..7de4d245ad --- /dev/null +++ b/tests/integration/targets/scaleway_container_registry_info/tasks/main.yml @@ -0,0 +1,41 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +# Copyright (c) 2022, Guillaume MARTINEZ +# 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 + +- name: Create container_registry + community.general.scaleway_container_registry: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ description }}' + +- name: Get container registry info + community.general.scaleway_container_registry_info: + name: '{{ name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + register: cr_info_task + +- ansible.builtin.debug: + var: cr_info_task + +- name: Check module call result + ansible.builtin.assert: + that: + - cr_info_task is success + - cr_info_task is not changed + +- name: Delete container registry + community.general.scaleway_container_registry: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + project_id: '{{ scw_project }}'