mirror of
https://github.com/ansible/awx.git
synced 2026-05-19 23:07:42 -02:30
fix completeness
This commit is contained in:
@@ -740,3 +740,37 @@ class TowerAPIModule(TowerModule):
|
|||||||
def wait_output(self, response):
|
def wait_output(self, response):
|
||||||
for k in ('id', 'status', 'elapsed', 'started', 'finished'):
|
for k in ('id', 'status', 'elapsed', 'started', 'finished'):
|
||||||
self.json_output[k] = response['json'].get(k)
|
self.json_output[k] = response['json'].get(k)
|
||||||
|
|
||||||
|
def wait_on_workflow_node_url(self, url, object_name, object_type, timeout=30, interval=10, **kwargs):
|
||||||
|
# Grab our start time to compare against for the timeout
|
||||||
|
start = time.time()
|
||||||
|
result = self.get_endpoint(url, **kwargs)
|
||||||
|
|
||||||
|
while result["json"]["count"] == 0:
|
||||||
|
# If we are past our time out fail with a message
|
||||||
|
if timeout and timeout < time.time() - start:
|
||||||
|
# Account for Legacy messages
|
||||||
|
self.json_output["msg"] = "Monitoring of {0} - {1} aborted due to timeout, {2}".format(object_type, object_name, url)
|
||||||
|
self.wait_output(result)
|
||||||
|
self.fail_json(**self.json_output)
|
||||||
|
|
||||||
|
# Put the process to sleep for our interval
|
||||||
|
time.sleep(interval)
|
||||||
|
result = self.get_endpoint(url, **kwargs)
|
||||||
|
|
||||||
|
if object_type == "Workflow Approval":
|
||||||
|
# Approval jobs have no elapsed time so return
|
||||||
|
return result["json"]["results"][0]
|
||||||
|
else:
|
||||||
|
# Removed time so far from timeout.
|
||||||
|
revised_timeout = timeout - (time.time() - start)
|
||||||
|
# Now that Job has been found, wait for it to finish
|
||||||
|
result = self.wait_on_url(
|
||||||
|
url=result["json"]["results"][0]["related"]["job"],
|
||||||
|
object_name=object_name,
|
||||||
|
object_type=object_type,
|
||||||
|
timeout=revised_timeout,
|
||||||
|
interval=interval,
|
||||||
|
)
|
||||||
|
self.json_output["job_data"] = result["json"]
|
||||||
|
return result
|
||||||
|
|||||||
125
awx_collection/plugins/modules/tower_workflow_approval.py
Normal file
125
awx_collection/plugins/modules/tower_workflow_approval.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# coding: utf-8 -*-
|
||||||
|
|
||||||
|
# (c) 2021, Sean Sullivan
|
||||||
|
# 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: tower_workflow_approval
|
||||||
|
author: "Sean Sullivan (@sean-m-sullivan)"
|
||||||
|
short_description: Approve an approval node in a workflow job.
|
||||||
|
description:
|
||||||
|
- Approve an approval node in a workflow job. See
|
||||||
|
U(https://www.ansible.com/tower) for an overview.
|
||||||
|
options:
|
||||||
|
workflow_job_id:
|
||||||
|
description:
|
||||||
|
- ID of the workflow job to monitor for approval.
|
||||||
|
required: True
|
||||||
|
type: int
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the Approval node to approve or deny.
|
||||||
|
required: True
|
||||||
|
type: str
|
||||||
|
action:
|
||||||
|
description:
|
||||||
|
- Type of action to take.
|
||||||
|
choices: ["approve", "deny"]
|
||||||
|
default: "approve"
|
||||||
|
type: str
|
||||||
|
interval:
|
||||||
|
description:
|
||||||
|
- The interval in sections, to request an update from Tower.
|
||||||
|
required: False
|
||||||
|
default: 1
|
||||||
|
type: float
|
||||||
|
timeout:
|
||||||
|
description:
|
||||||
|
- Maximum time in seconds to wait for a workflow job to to reach approval node.
|
||||||
|
default: 10
|
||||||
|
type: int
|
||||||
|
extends_documentation_fragment: awx.awx.auth
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLES = """
|
||||||
|
- name: Launch a workflow with a timeout of 10 seconds
|
||||||
|
tower_workflow_launch:
|
||||||
|
workflow_template: "Test Workflow"
|
||||||
|
wait: False
|
||||||
|
register: workflow
|
||||||
|
|
||||||
|
- name: Wait for approval node to activate and approve
|
||||||
|
tower_workflow_approval:
|
||||||
|
workflow_job_id: "{{ workflow.id }}"
|
||||||
|
name: Approve Me
|
||||||
|
interval: 10
|
||||||
|
timeout: 20
|
||||||
|
action: deny
|
||||||
|
"""
|
||||||
|
|
||||||
|
RETURN = """
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from ..module_utils.tower_api import TowerAPIModule
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Any additional arguments that are not fields of the item can be added here
|
||||||
|
argument_spec = dict(
|
||||||
|
workflow_job_id=dict(type="int", required=True),
|
||||||
|
name=dict(required=True),
|
||||||
|
action=dict(choices=["approve", "deny"], default="approve"),
|
||||||
|
timeout=dict(type="int", default=10),
|
||||||
|
interval=dict(type="float", default=1),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a module for ourselves
|
||||||
|
module = TowerAPIModule(argument_spec=argument_spec)
|
||||||
|
|
||||||
|
# Extract our parameters
|
||||||
|
workflow_job_id = module.params.get("workflow_job_id")
|
||||||
|
name = module.params.get("name")
|
||||||
|
action = module.params.get("action")
|
||||||
|
timeout = module.params.get("timeout")
|
||||||
|
interval = module.params.get("interval")
|
||||||
|
|
||||||
|
# Attempt to look up workflow job based on the provided id
|
||||||
|
approval_job = module.wait_on_workflow_node_url(
|
||||||
|
url="workflow_jobs/{0}/workflow_nodes/".format(workflow_job_id),
|
||||||
|
object_name=name,
|
||||||
|
object_type="Workflow Approval",
|
||||||
|
timeout=timeout,
|
||||||
|
interval=interval,
|
||||||
|
**{
|
||||||
|
"data": {
|
||||||
|
"job__name": name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
response = module.post_endpoint("{0}{1}".format(approval_job["related"]["job"], action))
|
||||||
|
if response["status_code"] == 204:
|
||||||
|
module.json_output["changed"] = True
|
||||||
|
|
||||||
|
# Attempt to look up jobs based on the status
|
||||||
|
module.exit_json(**module.json_output)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
115
awx_collection/plugins/modules/tower_workflow_node_wait.py
Normal file
115
awx_collection/plugins/modules/tower_workflow_node_wait.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# coding: utf-8 -*-
|
||||||
|
|
||||||
|
# (c) 2021, Sean Sullivan
|
||||||
|
# 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: tower_workflow_node_wait
|
||||||
|
author: "Sean Sullivan (@sean-m-sullivan)"
|
||||||
|
short_description: Approve an approval node in a workflow job.
|
||||||
|
description:
|
||||||
|
- Approve an approval node in a workflow job. See
|
||||||
|
U(https://www.ansible.com/tower) for an overview.
|
||||||
|
options:
|
||||||
|
workflow_job_id:
|
||||||
|
description:
|
||||||
|
- ID of the workflow job to monitor for node.
|
||||||
|
required: True
|
||||||
|
type: int
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the workflow node to wait on.
|
||||||
|
required: True
|
||||||
|
type: str
|
||||||
|
interval:
|
||||||
|
description:
|
||||||
|
- The interval in sections, to request an update from Tower.
|
||||||
|
required: False
|
||||||
|
default: 1
|
||||||
|
type: float
|
||||||
|
timeout:
|
||||||
|
description:
|
||||||
|
- Maximum time in seconds to wait for a workflow job to to reach approval node.
|
||||||
|
default: 10
|
||||||
|
type: int
|
||||||
|
extends_documentation_fragment: awx.awx.auth
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLES = """
|
||||||
|
- name: Launch a workflow with a timeout of 10 seconds
|
||||||
|
tower_workflow_launch:
|
||||||
|
workflow_template: "Test Workflow"
|
||||||
|
wait: False
|
||||||
|
register: workflow
|
||||||
|
|
||||||
|
- name: Wait for a workflow node to finish
|
||||||
|
tower_workflow_node_wait:
|
||||||
|
workflow_job_id: "{{ workflow.id }}"
|
||||||
|
name: Approval Data Step
|
||||||
|
timeout: 120
|
||||||
|
"""
|
||||||
|
|
||||||
|
RETURN = """
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from ..module_utils.tower_api import TowerAPIModule
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Any additional arguments that are not fields of the item can be added here
|
||||||
|
argument_spec = dict(
|
||||||
|
workflow_job_id=dict(type="int", required=True),
|
||||||
|
name=dict(required=True),
|
||||||
|
timeout=dict(type="int", default=10),
|
||||||
|
interval=dict(type="float", default=1),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a module for ourselves
|
||||||
|
module = TowerAPIModule(argument_spec=argument_spec)
|
||||||
|
|
||||||
|
# Extract our parameters
|
||||||
|
workflow_job_id = module.params.get("workflow_job_id")
|
||||||
|
name = module.params.get("name")
|
||||||
|
timeout = module.params.get("timeout")
|
||||||
|
interval = module.params.get("interval")
|
||||||
|
|
||||||
|
node_url = "workflow_jobs/{0}/workflow_nodes/?job__name={1}".format(workflow_job_id, name)
|
||||||
|
# Attempt to look up workflow job node based on the provided id
|
||||||
|
|
||||||
|
result = module.wait_on_workflow_node_url(
|
||||||
|
url="workflow_jobs/{0}/workflow_nodes/".format(workflow_job_id),
|
||||||
|
object_name=name,
|
||||||
|
object_type="Workflow Node",
|
||||||
|
timeout=timeout,
|
||||||
|
interval=interval,
|
||||||
|
**{
|
||||||
|
"data": {
|
||||||
|
"job__name": name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Attempt to look up jobs based on the status
|
||||||
|
module.exit_json(**module.json_output)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -36,6 +36,7 @@ no_endpoint_for_module = [
|
|||||||
'tower_receive',
|
'tower_receive',
|
||||||
'tower_send',
|
'tower_send',
|
||||||
'tower_workflow_launch',
|
'tower_workflow_launch',
|
||||||
|
'tower_workflow_node_wait',
|
||||||
'tower_job_cancel',
|
'tower_job_cancel',
|
||||||
'tower_workflow_template',
|
'tower_workflow_template',
|
||||||
'tower_ad_hoc_command_wait',
|
'tower_ad_hoc_command_wait',
|
||||||
@@ -64,16 +65,17 @@ no_api_parameter_ok = {
|
|||||||
'tower_ad_hoc_command': ['interval', 'timeout', 'wait'],
|
'tower_ad_hoc_command': ['interval', 'timeout', 'wait'],
|
||||||
# tower_group parameters to perserve hosts and children.
|
# tower_group parameters to perserve hosts and children.
|
||||||
'tower_group': ['preserve_existing_children', 'preserve_existing_hosts'],
|
'tower_group': ['preserve_existing_children', 'preserve_existing_hosts'],
|
||||||
|
# tower_workflow_approval parameters that do not apply when approving an approval node.
|
||||||
|
'tower_workflow_approval': ['action', 'interval', 'timeout', 'workflow_job_id'],
|
||||||
}
|
}
|
||||||
|
|
||||||
# When this tool was created we were not feature complete. Adding something in here indicates a module
|
# When this tool was created we were not feature complete. Adding something in here indicates a module
|
||||||
# that needs to be developed. If the module is found on the file system it will auto-detect that the
|
# that needs to be developed. If the module is found on the file system it will auto-detect that the
|
||||||
# work is being done and will bypass this check. At some point this module should be removed from this list.
|
# work is being done and will bypass this check. At some point this module should be removed from this list.
|
||||||
needs_development = [
|
needs_development = ['tower_inventory_script']
|
||||||
'tower_workflow_approval',
|
|
||||||
]
|
|
||||||
needs_param_development = {
|
needs_param_development = {
|
||||||
'tower_host': ['instance_id'],
|
'tower_host': ['instance_id'],
|
||||||
|
'tower_workflow_approval': ['description', 'execution_environment'],
|
||||||
}
|
}
|
||||||
# -----------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -7,146 +7,237 @@
|
|||||||
- name: Generate names
|
- name: Generate names
|
||||||
set_fact:
|
set_fact:
|
||||||
wfjt_name1: "AWX-Collection-tests-tower_workflow_launch--wfjt1-{{ test_id }}"
|
wfjt_name1: "AWX-Collection-tests-tower_workflow_launch--wfjt1-{{ test_id }}"
|
||||||
|
wfjt_name2: "AWX-Collection-tests-tower_workflow_launch--wfjt1-{{ test_id }}-2"
|
||||||
|
approval_node_name: "AWX-Collection-tests-tower_workflow_launch_approval_node-{{ test_id }}"
|
||||||
|
|
||||||
- name: Create our workflow
|
- block:
|
||||||
tower_workflow_job_template:
|
|
||||||
name: "{{ wfjt_name1 }}"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Add a node
|
- name: Create our workflow
|
||||||
tower_workflow_job_template_node:
|
tower_workflow_job_template:
|
||||||
workflow_job_template: "{{ wfjt_name1 }}"
|
name: "{{ wfjt_name1 }}"
|
||||||
unified_job_template: "Demo Job Template"
|
state: present
|
||||||
identifier: leaf
|
|
||||||
register: new_node
|
|
||||||
|
|
||||||
- name: Connect to Tower server but request an invalid workflow
|
- name: Add a node
|
||||||
tower_workflow_launch:
|
tower_workflow_job_template_node:
|
||||||
workflow_template: "Does Not Exist"
|
workflow_job_template: "{{ wfjt_name1 }}"
|
||||||
ignore_errors: true
|
unified_job_template: "Demo Job Template"
|
||||||
register: result
|
identifier: leaf
|
||||||
|
register: new_node
|
||||||
|
|
||||||
- assert:
|
- name: Connect to Tower server but request an invalid workflow
|
||||||
that:
|
tower_workflow_launch:
|
||||||
- result is failed
|
workflow_template: "Does Not Exist"
|
||||||
- "'Unable to find workflow job template' in result.msg"
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
- name: Run the workflow without waiting (this should just give us back a job ID)
|
- assert:
|
||||||
tower_workflow_launch:
|
that:
|
||||||
workflow_template: "{{ wfjt_name1 }}"
|
- result is failed
|
||||||
wait: false
|
- "'Unable to find workflow job template' in result.msg"
|
||||||
ignore_errors: true
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
- name: Run the workflow without waiting (this should just give us back a job ID)
|
||||||
that:
|
tower_workflow_launch:
|
||||||
- result is not failed
|
workflow_template: "{{ wfjt_name1 }}"
|
||||||
- "'id' in result['job_info']"
|
wait: false
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
- name: Kick off a workflow and wait for it, but only for a second
|
- assert:
|
||||||
tower_workflow_launch:
|
that:
|
||||||
workflow_template: "{{ wfjt_name1 }}"
|
- result is not failed
|
||||||
timeout: 1
|
- "'id' in result['job_info']"
|
||||||
ignore_errors: true
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
- name: Kick off a workflow and wait for it, but only for a second
|
||||||
that:
|
tower_workflow_launch:
|
||||||
- result is failed
|
workflow_template: "{{ wfjt_name1 }}"
|
||||||
- "'Monitoring of Workflow Job - {{ wfjt_name1 }} aborted due to timeout' in result.msg"
|
timeout: 1
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
- name: Kick off a workflow and wait for it
|
- assert:
|
||||||
tower_workflow_launch:
|
that:
|
||||||
workflow_template: "{{ wfjt_name1 }}"
|
- result is failed
|
||||||
ignore_errors: true
|
- "'Monitoring of Workflow Job - {{ wfjt_name1 }} aborted due to timeout' in result.msg"
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
- name: Kick off a workflow and wait for it
|
||||||
that:
|
tower_workflow_launch:
|
||||||
- result is not failed
|
workflow_template: "{{ wfjt_name1 }}"
|
||||||
- "'id' in result['job_info']"
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
- name: Kick off a workflow with extra_vars but not enabled
|
- assert:
|
||||||
tower_workflow_launch:
|
that:
|
||||||
workflow_template: "{{ wfjt_name1 }}"
|
- result is not failed
|
||||||
extra_vars:
|
- "'id' in result['job_info']"
|
||||||
var1: My First Variable
|
|
||||||
var2: My Second Variable
|
|
||||||
ignore_errors: true
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
- name: Kick off a workflow with extra_vars but not enabled
|
||||||
that:
|
tower_workflow_launch:
|
||||||
- result is failed
|
workflow_template: "{{ wfjt_name1 }}"
|
||||||
- "'The field extra_vars was specified but the workflow job template does not allow for it to be overridden' in result.errors"
|
extra_vars:
|
||||||
|
var1: My First Variable
|
||||||
|
var2: My Second Variable
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
- name: Prompt the workflow's with survey
|
- assert:
|
||||||
tower_workflow_job_template:
|
that:
|
||||||
name: "{{ wfjt_name1 }}"
|
- result is failed
|
||||||
state: present
|
- "'The field extra_vars was specified but the workflow job template does not allow for it to be overridden' in result.errors"
|
||||||
survey_enabled: true
|
|
||||||
ask_variables_on_launch: false
|
|
||||||
survey:
|
|
||||||
name: ''
|
|
||||||
description: ''
|
|
||||||
spec:
|
|
||||||
- question_name: Basic Name
|
|
||||||
question_description: Name
|
|
||||||
required: true
|
|
||||||
type: text
|
|
||||||
variable: basic_name
|
|
||||||
min: 0
|
|
||||||
max: 1024
|
|
||||||
default: ''
|
|
||||||
choices: ''
|
|
||||||
new_question: true
|
|
||||||
- question_name: Choose yes or no?
|
|
||||||
question_description: Choosing yes or no.
|
|
||||||
required: false
|
|
||||||
type: multiplechoice
|
|
||||||
variable: option_true_false
|
|
||||||
min:
|
|
||||||
max:
|
|
||||||
default: 'yes'
|
|
||||||
choices: |-
|
|
||||||
yes
|
|
||||||
no
|
|
||||||
new_question: true
|
|
||||||
|
|
||||||
- name: Kick off a workflow with survey
|
- name: Prompt the workflow's with survey
|
||||||
tower_workflow_launch:
|
tower_workflow_job_template:
|
||||||
workflow_template: "{{ wfjt_name1 }}"
|
name: "{{ wfjt_name1 }}"
|
||||||
extra_vars:
|
state: present
|
||||||
basic_name: My First Variable
|
survey_enabled: true
|
||||||
option_true_false: 'no'
|
ask_variables_on_launch: false
|
||||||
ignore_errors: true
|
survey:
|
||||||
register: result
|
name: ''
|
||||||
|
description: ''
|
||||||
|
spec:
|
||||||
|
- question_name: Basic Name
|
||||||
|
question_description: Name
|
||||||
|
required: true
|
||||||
|
type: text
|
||||||
|
variable: basic_name
|
||||||
|
min: 0
|
||||||
|
max: 1024
|
||||||
|
default: ''
|
||||||
|
choices: ''
|
||||||
|
new_question: true
|
||||||
|
- question_name: Choose yes or no?
|
||||||
|
question_description: Choosing yes or no.
|
||||||
|
required: false
|
||||||
|
type: multiplechoice
|
||||||
|
variable: option_true_false
|
||||||
|
min:
|
||||||
|
max:
|
||||||
|
default: 'yes'
|
||||||
|
choices: |-
|
||||||
|
yes
|
||||||
|
no
|
||||||
|
new_question: true
|
||||||
|
|
||||||
- assert:
|
- name: Kick off a workflow with survey
|
||||||
that:
|
tower_workflow_launch:
|
||||||
- result is not failed
|
workflow_template: "{{ wfjt_name1 }}"
|
||||||
|
extra_vars:
|
||||||
|
basic_name: My First Variable
|
||||||
|
option_true_false: 'no'
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
- name: Prompt the workflow's extra_vars on launch
|
- assert:
|
||||||
tower_workflow_job_template:
|
that:
|
||||||
name: "{{ wfjt_name1 }}"
|
- result is not failed
|
||||||
state: present
|
|
||||||
ask_variables_on_launch: true
|
|
||||||
|
|
||||||
- name: Kick off a workflow with extra_vars
|
- name: Prompt the workflow's extra_vars on launch
|
||||||
tower_workflow_launch:
|
tower_workflow_job_template:
|
||||||
workflow_template: "{{ wfjt_name1 }}"
|
name: "{{ wfjt_name1 }}"
|
||||||
extra_vars:
|
state: present
|
||||||
basic_name: My First Variable
|
ask_variables_on_launch: true
|
||||||
var1: My First Variable
|
|
||||||
var2: My Second Variable
|
|
||||||
ignore_errors: true
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
- name: Kick off a workflow with extra_vars
|
||||||
that:
|
tower_workflow_launch:
|
||||||
- result is not failed
|
workflow_template: "{{ wfjt_name1 }}"
|
||||||
|
extra_vars:
|
||||||
|
basic_name: My First Variable
|
||||||
|
var1: My First Variable
|
||||||
|
var2: My Second Variable
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
- name: Clean up test workflow
|
- assert:
|
||||||
tower_workflow_job_template:
|
that:
|
||||||
name: "{{ wfjt_name1 }}"
|
- result is not failed
|
||||||
state: absent
|
|
||||||
|
- name: Test waiting for an approval node that doesn't exit on the last workflow for failure.
|
||||||
|
tower_workflow_approval:
|
||||||
|
workflow_job_id: "{{ result.id }}"
|
||||||
|
name: Test workflow approval
|
||||||
|
interval: 1
|
||||||
|
timeout: 2
|
||||||
|
action: deny
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- "'Monitoring of Workflow Approval - Test workflow approval aborted due to timeout' in result.msg"
|
||||||
|
|
||||||
|
- name: Create new Workflow
|
||||||
|
tower_workflow_job_template:
|
||||||
|
name: "{{ wfjt_name2 }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add a job node
|
||||||
|
tower_workflow_job_template_node:
|
||||||
|
workflow_job_template: "{{ wfjt_name2 }}"
|
||||||
|
unified_job_template: "Demo Job Template"
|
||||||
|
identifier: leaf
|
||||||
|
|
||||||
|
# Test tower_workflow_approval and tower_workflow_node_wait
|
||||||
|
- name: Create approval node
|
||||||
|
tower_workflow_job_template_node:
|
||||||
|
identifier: approval_test
|
||||||
|
approval_node:
|
||||||
|
name: "{{ approval_node_name }}"
|
||||||
|
timeout: 900
|
||||||
|
workflow: "{{ wfjt_name2 }}"
|
||||||
|
|
||||||
|
- name: Create link for approval node
|
||||||
|
tower_workflow_job_template_node:
|
||||||
|
identifier: approval_test
|
||||||
|
workflow: "{{ wfjt_name2 }}"
|
||||||
|
always_nodes:
|
||||||
|
- leaf
|
||||||
|
|
||||||
|
- name: Run the workflow without waiting This should pause waiting for approval
|
||||||
|
tower_workflow_launch:
|
||||||
|
workflow_template: "{{ wfjt_name2 }}"
|
||||||
|
wait: false
|
||||||
|
ignore_errors: true
|
||||||
|
register: wfjt_info
|
||||||
|
|
||||||
|
- name: Wait for Job node wait to fail as it is waiting on approval
|
||||||
|
awx.awx.tower_workflow_node_wait:
|
||||||
|
workflow_job_id: "{{ wfjt_info.id }}"
|
||||||
|
name: Demo Job Template
|
||||||
|
interval: 1
|
||||||
|
timeout: 5
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- "'Monitoring of Workflow Node - Demo Job Template aborted due to timeout' in result.msg"
|
||||||
|
|
||||||
|
- name: Wait for approval node to activate and approve
|
||||||
|
awx.awx.tower_workflow_approval:
|
||||||
|
workflow_job_id: "{{ wfjt_info.id }}"
|
||||||
|
name: "{{ approval_node_name }}"
|
||||||
|
interval: 1
|
||||||
|
timeout: 10
|
||||||
|
action: deny
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is not failed
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Wait for workflow job to finish max 120s
|
||||||
|
tower_job_wait:
|
||||||
|
job_id: "{{ wfjt_info.id }}"
|
||||||
|
timeout: 120
|
||||||
|
job_type: "workflow_jobs"
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Clean up test workflow
|
||||||
|
tower_workflow_job_template:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "{{ wfjt_name1 }}"
|
||||||
|
- "{{ wfjt_name2 }}"
|
||||||
|
|||||||
Reference in New Issue
Block a user