diff --git a/galaxy.yml b/galaxy.yml index 996d68e65..5a7a1c4d1 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 91fc657f8..de3ff9c89 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 000000000..61a18477a --- /dev/null +++ b/plugins/modules/wait_for_task.py @@ -0,0 +1,92 @@ +#!/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 . + +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 __future__ import absolute_import, division, print_function +from ansible_collections.theforeman.foreman.plugins.module_utils.foreman_helper import ForemanAnsibleModule + +__metaclass__ = type + +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 000000000..f9e401512 --- /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 000000000..203d68edf --- /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 000000000..cfd2598c4 --- /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