From 5bb497635a9fb863d4cd06541ae381847731d769 Mon Sep 17 00:00:00 2001 From: Julien Godin Date: Wed, 19 Jul 2023 12:56:28 +0200 Subject: [PATCH] feat(wait_task): Add a wait_task module. And a new module that simply expose the wait_for_task function Signed-off-by: Julien Godin --- galaxy.yml | 1 + meta/runtime.yml | 1 + plugins/modules/wait_for_task.py | 94 ++++++++++++++++++++ tests/fixtures/apidoc/wait_for_task.json | 1 + tests/test_playbooks/tasks/wait_for_task.yml | 59 ++++++++++++ tests/test_playbooks/wait_for_task.yml | 9 ++ 6 files changed, 165 insertions(+) create mode 100644 plugins/modules/wait_for_task.py create mode 120000 tests/fixtures/apidoc/wait_for_task.json create mode 100644 tests/test_playbooks/tasks/wait_for_task.yml create mode 100644 tests/test_playbooks/wait_for_task.yml diff --git a/galaxy.yml b/galaxy.yml index 996d68e659..5a7a1c4d1d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -93,6 +93,7 @@ authors: - "metalcated " - "russianguppie <46544650+russianguppie@users.noreply.github.com>" - "willtome " + - "Julien Godin " version: "3.13.0-dev" license: - "GPL-3.0-or-later" diff --git a/meta/runtime.yml b/meta/runtime.yml index 91fc657f83..de3ff9c898 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -79,6 +79,7 @@ action_groups: - templates_import - user - usergroup + - wait_for_task plugin_routing: modules: foreman_architecture: diff --git a/plugins/modules/wait_for_task.py b/plugins/modules/wait_for_task.py new file mode 100644 index 0000000000..48cd49476b --- /dev/null +++ b/plugins/modules/wait_for_task.py @@ -0,0 +1,94 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# (c) 2023, Julien Godin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: wait_for_task +version_added: 3.13.0 +short_description: Wait for a task +description: + - Wait for a task to finish +author: + - "Julien Godin (@JGodin-C2C)" +options: + task: + description: + - Task id to wait for. + required: true + type: str + timeout: + description: + - How much time the task should take to be finished + required: false + type: int + default: 60 +extends_documentation_fragment: + - theforeman.foreman.foreman +''' + + +EXAMPLES = ''' +- name: wait for a task to finish in at least 10 seconds + theforeman.foreman.wait_for_task: + server_url: "https://foreman.example.com" + password: changeme + username: admin + task: "{{ item }}" + timeout: 60 + loop: "{{ tasks.resources }}" + +''' + +RETURN = ''' +entity: + description: Designated task is finished + returned: success + type: dict + contains: + task: + description: The finished task + type: dict +''' + + +from ansible_collections.theforeman.foreman.plugins.module_utils.foreman_helper import ForemanAnsibleModule + + +class ForemanWaitForTask(ForemanAnsibleModule): + pass + + +def main(): + module = ForemanWaitForTask( + argument_spec=dict( + task=dict(type="str", required=True), + timeout=dict(type="int", required=False, default=60), + ) + ) + module.task_timeout = module.foreman_params["timeout"] + with module.api_connection(): + + task = module.wait_for_task(module.show_resource( + 'foreman_tasks', module.foreman_params["task"])) + module.exit_json(task=task, task_id=task['id']) + + +if __name__ == "__main__": + main() diff --git a/tests/fixtures/apidoc/wait_for_task.json b/tests/fixtures/apidoc/wait_for_task.json new file mode 120000 index 0000000000..f9e401512c --- /dev/null +++ b/tests/fixtures/apidoc/wait_for_task.json @@ -0,0 +1 @@ +foreman.json \ No newline at end of file diff --git a/tests/test_playbooks/tasks/wait_for_task.yml b/tests/test_playbooks/tasks/wait_for_task.yml new file mode 100644 index 0000000000..203d68edf9 --- /dev/null +++ b/tests/test_playbooks/tasks/wait_for_task.yml @@ -0,0 +1,59 @@ +--- +- name: "Create katello content view version" + vars: + - content_view_name: "Test Content View" + - organization_name: "Test Organization" + - lifecycle_environments: Library + content_view_version: + username: "{{ foreman_username }}" + password: "{{ foreman_password }}" + server_url: "{{ foreman_server_url }}" + validate_certs: "{{ foreman_validate_certs }}" + content_view: "{{ content_view_name }}" + organization: "{{ organization_name }}" + description: "{{ description | default(omit)}}" + version: "{{ version | default(omit)}}" + lifecycle_environments: "{{ lifecycle_environments }}" + force_promote: "{{ force_promote | default(omit) }}" + force_yum_metadata_regeneration: "{{ force_yum_metadata_regeneration | default(omit) }}" + current_lifecycle_environment: "{{ current_lifecycle_environment | default(omit) }}" + state: "{{ state | default(omit) }}" + async: 9999 + +- name: Wait for API to react + ansible.builtin.pause: + seconds: 10 + +- name: "Search for previously created task" + resource_info: + username: "{{ foreman_username }}" + password: "{{ foreman_password }}" + server_url: "{{ foreman_server_url }}" + validate_certs: "{{ foreman_validate_certs }}" + resource: foreman_tasks + search: "(label = Actions::Katello::ContentView::Publish and state = running)" + +- name: wait for the task to finish + wait_for_task: + username: "{{ foreman_username }}" + password: "{{ foreman_password }}" + server_url: "{{ foreman_server_url }}" + validate_certs: "{{ foreman_validate_certs }}" + task: "{{ item }}" + timeout: 900 + loop: "{{ tasks.resources }}" + + +- name: "Search for previously created task" + resource_info: + username: "{{ foreman_username }}" + password: "{{ foreman_password }}" + server_url: "{{ foreman_server_url }}" + validate_certs: "{{ foreman_validate_certs }}" + resource: foreman_tasks + search: "(label = Actions::Katello::ContentView::Publish and state = running)" + register: tasks +- assert: + fail_msg: "Verification that '{{ resource }}' resource is not runing anymore" + that: result.resource | lenght == 0 +... diff --git a/tests/test_playbooks/wait_for_task.yml b/tests/test_playbooks/wait_for_task.yml new file mode 100644 index 0000000000..cfd2598c4e --- /dev/null +++ b/tests/test_playbooks/wait_for_task.yml @@ -0,0 +1,9 @@ +--- +- hosts: localhost + collections: + - theforeman.foreman + gather_facts: false + vars_files: + - vars/server.yml + tasks: + - include_tasks: tasks/wait_task.yml