diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 559689d6fe..2ba562440b 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -472,6 +472,10 @@ files: maintainers: Lunik $modules/scaleway_function_namespace_info.py: maintainers: Lunik + $modules/scaleway_function.py: + maintainers: Lunik + $modules/scaleway_function_info.py: + maintainers: Lunik $modules/scaleway_image_info.py: maintainers: Spredzy $modules/scaleway_ip_info.py: diff --git a/plugins/modules/scaleway_function.py b/plugins/modules/scaleway_function.py new file mode 100644 index 0000000000..b54091c6ab --- /dev/null +++ b/plugins/modules/scaleway_function.py @@ -0,0 +1,387 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Scaleway Serverless function 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_function +short_description: Scaleway Function management +version_added: 6.0.0 +author: Guillaume MARTINEZ (@Lunik) +description: + - This module manages function on Scaleway account. +extends_documentation_fragment: + - community.general.scaleway + - community.general.scaleway_waitable_resource +requirements: + - passlib[argon2] >= 1.7.4 + +options: + state: + type: str + description: + - Indicate desired state of the function. + default: present + choices: + - present + - absent + + namespace_id: + type: str + description: + - Function namespace 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 function. + required: true + + description: + description: + - Description of the function. + type: str + default: '' + + min_scale: + description: + - Minimum number of replicas for the function. + type: int + + max_scale: + description: + - Maximum number of replicas for the function. + type: int + + environment_variables: + description: + - Environment variables of the function. + - Injected in function at runtime. + type: dict + default: {} + + secret_environment_variables: + description: + - Secret environment variables of the function. + - Updating thoses values will not output a C(changed) state in Ansible. + - Injected in function at runtime. + type: dict + default: {} + + runtime: + description: + - Runtime of the function + - See U(https://www.scaleway.com/en/docs/compute/functions/reference-content/functions-lifecycle/) for all available runtimes + type: str + required: true + + memory_limit: + description: + - Resources define performance characteristics of your function. + - They are allocated to your function at runtime. + type: int + + function_timeout: + description: + - The length of time your handler can spend processing a request before being stopped. + type: str + + handler: + description: + - The C(module-name.export) value in your function. + type: str + + privacy: + description: + - Privacy policies define whether a function can be executed anonymously. + - Choose C(public) to enable anonymous execution, or C(private) to protect your function with an authentication mechanism provided by the Scaleway API. + type: str + default: public + choices: + - public + - private + + redeploy: + description: + - Redeploy the function if update is required. + type: bool + default: false +''' + +EXAMPLES = ''' +- name: Create a function + community.general.scaleway_function: + namespace_id: '{{ scw_function_namespace }}' + region: fr-par + state: present + name: my-awesome-function + runtime: python3 + environment_variables: + MY_VAR: my_value + secret_environment_variables: + MY_SECRET_VAR: my_secret_value + register: function_creation_task + +- name: Make sure function is deleted + community.general.scaleway_function: + namespace_id: '{{ scw_function_namespace }}' + region: fr-par + state: absent + name: my-awesome-function +''' + +RETURN = ''' +function: + description: The function information. + returned: when I(state=present) + type: dict + sample: + cpu_limit: 140 + description: Function used for testing scaleway_function ansible module + domain_name: fnansibletestfxamabuc-fn-ansible-test.functions.fnc.fr-par.scw.cloud + environment_variables: + MY_VAR: my_value + error_message: null + handler: handler.handle + http_option: "" + id: ceb64dc4-4464-4196-8e20-ecef705475d3 + max_scale: 5 + memory_limit: 256 + min_scale: 0 + name: fn-ansible-test + namespace_id: 82737d8d-0ebb-4d89-b0ad-625876eca50d + privacy: public + region: fr-par + runtime: python310 + runtime_message: "" + secret_environment_variables: + - key: MY_SECRET_VAR + value: $argon2id$v=19$m=65536,t=1,p=2$tb6UwSPWx/rH5Vyxt9Ujfw$5ZlvaIjWwNDPxD9Rdght3NarJz4IETKjpvAU3mMSmFg + status: created + timeout: 300s +''' + +from copy import deepcopy + +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, + SecretVariables +) +from ansible.module_utils.basic import AnsibleModule + +STABLE_STATES = ( + "ready", + "created", + "absent" +) + +VERIFIABLE_MUTABLE_ATTRIBUTES = ( + "description", + "min_scale", + "max_scale", + "environment_variables", + "runtime", + "memory_limit", + "timeout", + "handler", + "privacy", + "secret_environment_variables" +) + +MUTABLE_ATTRIBUTES = VERIFIABLE_MUTABLE_ATTRIBUTES + ( + "redeploy", +) + + +def payload_from_wished_fn(wished_fn): + payload = { + "namespace_id": wished_fn["namespace_id"], + "name": wished_fn["name"], + "description": wished_fn["description"], + "min_scale": wished_fn["min_scale"], + "max_scale": wished_fn["max_scale"], + "runtime": wished_fn["runtime"], + "memory_limit": wished_fn["memory_limit"], + "timeout": wished_fn["timeout"], + "handler": wished_fn["handler"], + "privacy": wished_fn["privacy"], + "redeploy": wished_fn["redeploy"], + "environment_variables": wished_fn["environment_variables"], + "secret_environment_variables": SecretVariables.dict_to_list(wished_fn["secret_environment_variables"]) + } + + return payload + + +def absent_strategy(api, wished_fn): + changed = False + + fn_list = api.fetch_all_resources("functions") + fn_lookup = dict((fn["name"], fn) + for fn in fn_list) + + if wished_fn["name"] not in fn_lookup: + return changed, {} + + target_fn = fn_lookup[wished_fn["name"]] + changed = True + if api.module.check_mode: + return changed, {"status": "Function would be destroyed"} + + api.wait_to_complete_state_transition(resource=target_fn, stable_states=STABLE_STATES, force_wait=True) + response = api.delete(path=api.api_path + "/%s" % target_fn["id"]) + if not response.ok: + api.module.fail_json(msg='Error deleting function [{0}: {1}]'.format( + response.status_code, response.json)) + + api.wait_to_complete_state_transition(resource=target_fn, stable_states=STABLE_STATES) + return changed, response.json + + +def present_strategy(api, wished_fn): + changed = False + + fn_list = api.fetch_all_resources("functions") + fn_lookup = dict((fn["name"], fn) + for fn in fn_list) + + payload_fn = payload_from_wished_fn(wished_fn) + + if wished_fn["name"] not in fn_lookup: + changed = True + if api.module.check_mode: + return changed, {"status": "A function would be created."} + + # Creation doesn't support `redeploy` parameter + del payload_fn["redeploy"] + + # Create function + api.warn(payload_fn) + creation_response = api.post(path=api.api_path, + data=payload_fn) + + if not creation_response.ok: + msg = "Error during function 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_fn = fn_lookup[wished_fn["name"]] + decoded_target_fn = deepcopy(target_fn) + decoded_target_fn["secret_environment_variables"] = SecretVariables.decode(decoded_target_fn["secret_environment_variables"], + payload_fn["secret_environment_variables"]) + + patch_payload = resource_attributes_should_be_changed(target=decoded_target_fn, + wished=payload_fn, + verifiable_mutable_attributes=VERIFIABLE_MUTABLE_ATTRIBUTES, + mutable_attributes=MUTABLE_ATTRIBUTES) + + if not patch_payload: + return changed, target_fn + + changed = True + if api.module.check_mode: + return changed, {"status": "Function attributes would be changed."} + + fn_patch_response = api.patch(path=api.api_path + "/%s" % target_fn["id"], + data=patch_payload) + + if not fn_patch_response.ok: + api.module.fail_json(msg='Error during function attributes update: [{0}: {1}]'.format( + fn_patch_response.status_code, fn_patch_response.json['message'])) + + api.wait_to_complete_state_transition(resource=target_fn, stable_states=STABLE_STATES) + response = api.get(path=api.api_path + "/%s" % target_fn["id"]) + return changed, response.json + + +state_strategy = { + "present": present_strategy, + "absent": absent_strategy +} + + +def core(module): + SecretVariables.ensure_scaleway_secret_package(module) + + region = module.params["region"] + wished_function = { + "state": module.params["state"], + "namespace_id": module.params["namespace_id"], + "name": module.params["name"], + "description": module.params['description'], + "min_scale": module.params['min_scale'], + "max_scale": module.params['max_scale'], + "runtime": module.params["runtime"], + "memory_limit": module.params["memory_limit"], + "timeout": module.params["function_timeout"], + "handler": module.params["handler"], + "privacy": module.params["privacy"], + "redeploy": module.params["redeploy"], + "environment_variables": module.params['environment_variables'], + "secret_environment_variables": module.params['secret_environment_variables'] + } + + api = Scaleway(module=module) + api.api_path = "functions/v1beta1/regions/%s/functions" % region + + changed, summary = state_strategy[wished_function["state"]](api=api, wished_fn=wished_function) + + module.exit_json(changed=changed, function=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']), + namespace_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=''), + min_scale=dict(type='int'), + max_scale=dict(type='int'), + runtime=dict(type='str', required=True), + memory_limit=dict(type='int'), + function_timeout=dict(type='str'), + handler=dict(type='str'), + privacy=dict(type='str', default='public', choices=['public', 'private']), + redeploy=dict(type='bool', default=False), + environment_variables=dict(type='dict', default={}), + secret_environment_variables=dict(type='dict', default={}, no_log=True) + )) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + core(module) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/scaleway_function_info.py b/plugins/modules/scaleway_function_info.py new file mode 100644 index 0000000000..b6f2eefa71 --- /dev/null +++ b/plugins/modules/scaleway_function_info.py @@ -0,0 +1,153 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Scaleway Serverless function 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_function_info +short_description: Retrieve information on Scaleway Function +version_added: 6.0.0 +author: Guillaume MARTINEZ (@Lunik) +description: + - This module return information about a function on Scaleway account. +extends_documentation_fragment: + - community.general.scaleway + + +options: + namespace_id: + type: str + description: + - Container namespace 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 function. + required: true +''' + +EXAMPLES = ''' +- name: Get a function info + community.general.scaleway_function_info: + namespace_id: '{{ scw_function_namespace }}' + region: fr-par + name: my-awesome-function + register: function_info_task +''' + +RETURN = ''' +function: + description: The function information. + returned: always + type: dict + sample: + cpu_limit: 140 + description: Function used for testing scaleway_function ansible module + domain_name: fnansibletestfxamabuc-fn-ansible-test.functions.fnc.fr-par.scw.cloud + environment_variables: + MY_VAR: my_value + error_message: null + handler: handler.handle + http_option: "" + id: ceb64dc4-4464-4196-8e20-ecef705475d3 + max_scale: 5 + memory_limit: 256 + min_scale: 0 + name: fn-ansible-test + namespace_id: 82737d8d-0ebb-4d89-b0ad-625876eca50d + privacy: public + region: fr-par + runtime: python310 + runtime_message: "" + secret_environment_variables: SENSITIVE_VALUE + status: created + timeout: 300s +''' + +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_fn): + fn_list = api.fetch_all_resources("functions") + fn_lookup = dict((fn["name"], fn) + for fn in fn_list) + + if wished_fn["name"] not in fn_lookup: + msg = "Error during function lookup: Unable to find function named '%s' in namespace '%s'" % (wished_fn["name"], + wished_fn["namespace_id"]) + + api.module.fail_json(msg=msg) + + target_fn = fn_lookup[wished_fn["name"]] + + response = api.get(path=api.api_path + "/%s" % target_fn["id"]) + if not response.ok: + msg = "Error during function 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_function = { + "namespace_id": module.params["namespace_id"], + "name": module.params["name"] + } + + api = Scaleway(module=module) + api.api_path = "functions/v1beta1/regions/%s/functions" % region + + summary = info_strategy(api=api, wished_fn=wished_function) + + module.exit_json(changed=False, function=filter_sensitive_attributes(summary, SENSITIVE_ATTRIBUTES)) + + +def main(): + argument_spec = scaleway_argument_spec() + argument_spec.update(dict( + namespace_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_function/aliases b/tests/integration/targets/scaleway_function/aliases new file mode 100644 index 0000000000..a5ac5181f0 --- /dev/null +++ b/tests/integration/targets/scaleway_function/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_function/defaults/main.yml b/tests/integration/targets/scaleway_function/defaults/main.yml new file mode 100644 index 0000000000..df02a4665f --- /dev/null +++ b/tests/integration/targets/scaleway_function/defaults/main.yml @@ -0,0 +1,17 @@ +--- +# 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 +function_namespace_name: fn-ansible-test +name: fn-ansible-test +description: Function used for testing scaleway_function_infoansible module +updated_description: Function used for testing scaleway_function_info ansible module (Updated description) +environment_variables: + MY_VAR: my_value +secret_environment_variables: + MY_SECRET_VAR: my_secret_value +updated_secret_environment_variables: + MY_SECRET_VAR: my_other_secret_value +runtime: python310 diff --git a/tests/integration/targets/scaleway_function/tasks/main.yml b/tests/integration/targets/scaleway_function/tasks/main.yml new file mode 100644 index 0000000000..92ebfb8f7d --- /dev/null +++ b/tests/integration/targets/scaleway_function/tasks/main.yml @@ -0,0 +1,284 @@ +--- +#################################################################### +# 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 function_namespace + community.general.scaleway_function_namespace: + state: present + name: '{{ function_namespace_name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ description }}' + register: integration_function_namespace + +- name: Create a function (Check) + check_mode: yes + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ secret_environment_variables }}' + register: fn_creation_check_task + +- ansible.builtin.debug: + var: fn_creation_check_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_creation_check_task is success + - fn_creation_check_task is changed + +- name: Create function + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ secret_environment_variables }}' + register: fn_creation_task + +- ansible.builtin.debug: + var: fn_creation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_creation_task is success + - fn_creation_task is changed + - fn_creation_task.function.status in ["created", "ready"] + +- name: Create function (Confirmation) + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ secret_environment_variables }}' + register: fn_creation_confirmation_task + +- ansible.builtin.debug: + var: fn_creation_confirmation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_creation_confirmation_task is success + - fn_creation_confirmation_task is not changed + - fn_creation_confirmation_task.function.status in ["created", "ready"] + +- name: Update function (Check) + check_mode: yes + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ updated_description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ secret_environment_variables }}' + register: fn_update_check_task + +- ansible.builtin.debug: + var: fn_update_check_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_update_check_task is success + - fn_update_check_task is changed + +- name: Update function + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ updated_description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ secret_environment_variables }}' + register: fn_update_task + +- ansible.builtin.debug: + var: fn_update_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_update_task is success + - fn_update_task is changed + - fn_update_task.function.status in ["created", "ready"] + +- name: Update function (Confirmation) + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ updated_description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ secret_environment_variables }}' + register: fn_update_confirmation_task + +- ansible.builtin.debug: + var: fn_update_confirmation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_update_confirmation_task is success + - fn_update_confirmation_task is not changed + - fn_update_confirmation_task.function.status in ["created", "ready"] + +- name: Update function secret variables (Check) + check_mode: yes + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ updated_description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ updated_secret_environment_variables }}' + register: fn_update_secret_check_task + +- ansible.builtin.debug: + var: fn_update_secret_check_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_update_secret_check_task is success + - fn_update_secret_check_task is changed + +- name: Update function secret variables + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ updated_description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ updated_secret_environment_variables }}' + register: fn_update_secret_task + +- ansible.builtin.debug: + var: fn_update_secret_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_update_secret_task is success + - fn_update_secret_task is changed + - fn_update_secret_task.function.status in ["created", "ready"] + - "'hashed_value' in fn_update_secret_task.function.secret_environment_variables[0]" + +- name: Update function secret variables (Confirmation) + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ updated_description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ updated_secret_environment_variables }}' + register: fn_update_secret_confirmation_task + +- ansible.builtin.debug: + var: fn_update_secret_confirmation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_update_secret_confirmation_task is success + - fn_update_secret_confirmation_task is not changed + - fn_update_secret_confirmation_task.function.status in ["created", "ready"] + - "'hashed_value' in fn_update_secret_confirmation_task.function.secret_environment_variables[0]" + +- name: Delete function (Check) + check_mode: yes + community.general.scaleway_function: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + register: fn_deletion_check_task + +- ansible.builtin.debug: + var: fn_deletion_check_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_deletion_check_task is success + - fn_deletion_check_task is changed + +- name: Delete function + community.general.scaleway_function: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + register: fn_deletion_task + +- ansible.builtin.debug: + var: fn_deletion_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_deletion_task is success + - fn_deletion_task is changed + +- name: Delete function (Confirmation) + community.general.scaleway_function: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + register: fn_deletion_confirmation_task + +- ansible.builtin.debug: + var: fn_deletion_confirmation_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_deletion_confirmation_task is success + - fn_deletion_confirmation_task is not changed + +- name: Delete function namespace + community.general.scaleway_function_namespace: + state: absent + name: '{{ function_namespace_name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + project_id: '{{ scw_project }}' diff --git a/tests/integration/targets/scaleway_function_info/aliases b/tests/integration/targets/scaleway_function_info/aliases new file mode 100644 index 0000000000..a5ac5181f0 --- /dev/null +++ b/tests/integration/targets/scaleway_function_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_function_info/defaults/main.yml b/tests/integration/targets/scaleway_function_info/defaults/main.yml new file mode 100644 index 0000000000..71d2fe7803 --- /dev/null +++ b/tests/integration/targets/scaleway_function_info/defaults/main.yml @@ -0,0 +1,15 @@ +--- +# 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 +function_namespace_name: fn-ansible-test +name: fn-ansible-test +description: Container used for testing scaleway_function_info ansible module +updated_description: Container used for testing scaleway_function_info ansible module (Updated description) +environment_variables: + MY_VAR: my_value +secret_environment_variables: + MY_SECRET_VAR: my_secret_value +runtime: python310 diff --git a/tests/integration/targets/scaleway_function_info/tasks/main.yml b/tests/integration/targets/scaleway_function_info/tasks/main.yml new file mode 100644 index 0000000000..17b07f5f97 --- /dev/null +++ b/tests/integration/targets/scaleway_function_info/tasks/main.yml @@ -0,0 +1,62 @@ +--- +#################################################################### +# 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 function_namespace + community.general.scaleway_function_namespace: + state: present + name: '{{ function_namespace_name }}' + region: '{{ scaleway_region }}' + project_id: '{{ scw_project }}' + description: '{{ description }}' + register: integration_function_namespace + +- name: Create function + community.general.scaleway_function: + state: present + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + description: '{{ description }}' + environment_variables: '{{ environment_variables }}' + secret_environment_variables: '{{ secret_environment_variables }}' + +- name: Get function info + community.general.scaleway_function_info: + name: '{{ name }}' + region: '{{ scaleway_region }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + register: fn_info_task + +- ansible.builtin.debug: + var: fn_info_task + +- name: Check module call result + ansible.builtin.assert: + that: + - fn_info_task is success + - fn_info_task is not changed + +- name: Delete function + community.general.scaleway_function: + state: absent + name: '{{ name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + namespace_id: '{{ integration_function_namespace.function_namespace.id }}' + runtime: '{{ runtime }}' + +- name: Delete function namespace + community.general.scaleway_function_namespace: + state: absent + name: '{{ function_namespace_name }}' + region: '{{ scaleway_region }}' + description: '{{ description }}' + project_id: '{{ scw_project }}'