mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
Merge pull request #8022 from sean-m-sullivan/wait_function
Add wait function and update collection modules
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
https://github.com/beeankha
This commit is contained in:
commit
30616c1fce
@ -7,6 +7,7 @@ from ansible.module_utils.six import PY2
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
||||
from ansible.module_utils.six.moves.http_cookiejar import CookieJar
|
||||
import time
|
||||
import re
|
||||
from json import loads, dumps
|
||||
|
||||
@ -588,3 +589,42 @@ class TowerAPIModule(TowerModule):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def wait_on_url(self, url, object_name, object_type, timeout=30, interval=10):
|
||||
# Grab our start time to compare against for the timeout
|
||||
start = time.time()
|
||||
result = self.get_endpoint(url)
|
||||
while not result['json']['finished']:
|
||||
# If we are past our time out fail with a message
|
||||
if timeout and timeout < time.time() - start:
|
||||
# Account for Legacy messages
|
||||
if object_type is 'legacy_job_wait':
|
||||
self.json_output['msg'] = 'Monitoring of Job - {0} aborted due to timeout'.format(object_name)
|
||||
else:
|
||||
self.json_output['msg'] = 'Monitoring of {0} - {1} aborted due to timeout'.format(object_type, object_name)
|
||||
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)
|
||||
self.json_output['status'] = result['json']['status']
|
||||
|
||||
# If the job has failed, we want to raise a task failure for that so we get a non-zero response.
|
||||
if result['json']['failed']:
|
||||
# Account for Legacy messages
|
||||
if object_type is 'legacy_job_wait':
|
||||
self.json_output['msg'] = 'Job with id {0} failed'.format(object_name)
|
||||
else:
|
||||
self.json_output['msg'] = 'The {0} - {1}, failed'.format(object_type, object_name)
|
||||
self.wait_output(result)
|
||||
self.fail_json(**self.json_output)
|
||||
|
||||
self.wait_output(result)
|
||||
|
||||
return result
|
||||
|
||||
def wait_output(self, response):
|
||||
for k in ('id', 'status', 'elapsed', 'started', 'finished'):
|
||||
self.json_output[k] = response['json'].get(k)
|
||||
|
||||
@ -81,6 +81,22 @@ options:
|
||||
description:
|
||||
- Passwords for credentials which are set to prompt on launch
|
||||
type: dict
|
||||
wait:
|
||||
description:
|
||||
- Wait for the job to complete.
|
||||
default: False
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval to request an update from Tower.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
timeout:
|
||||
description:
|
||||
- If waiting for the job to complete this will abort after this
|
||||
amount of seconds
|
||||
type: int
|
||||
extends_documentation_fragment: awx.awx.auth
|
||||
'''
|
||||
|
||||
@ -143,6 +159,9 @@ def main():
|
||||
verbosity=dict(type='int', choices=[0, 1, 2, 3, 4, 5]),
|
||||
diff_mode=dict(type='bool'),
|
||||
credential_passwords=dict(type='dict'),
|
||||
wait=dict(default=False, type='bool'),
|
||||
interval=dict(default=1.0, type='float'),
|
||||
timeout=dict(default=None, type='int'),
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
@ -162,6 +181,9 @@ def main():
|
||||
optional_args['verbosity'] = module.params.get('verbosity')
|
||||
optional_args['diff_mode'] = module.params.get('diff_mode')
|
||||
optional_args['credential_passwords'] = module.params.get('credential_passwords')
|
||||
wait = module.params.get('wait')
|
||||
interval = module.params.get('interval')
|
||||
timeout = module.params.get('timeout')
|
||||
|
||||
# Create a datastructure to pass into our job launch
|
||||
post_data = {}
|
||||
@ -216,6 +238,21 @@ def main():
|
||||
if results['status_code'] != 201:
|
||||
module.fail_json(msg="Failed to launch job, see response for details", **{'response': results})
|
||||
|
||||
if not wait:
|
||||
module.exit_json(**{
|
||||
'changed': True,
|
||||
'id': results['json']['id'],
|
||||
'status': results['json']['status'],
|
||||
})
|
||||
|
||||
# Invoke wait function
|
||||
results = module.wait_on_url(
|
||||
url=results['json']['url'],
|
||||
object_name=name,
|
||||
object_type='Job',
|
||||
timeout=timeout, interval=interval
|
||||
)
|
||||
|
||||
module.exit_json(**{
|
||||
'changed': True,
|
||||
'id': results['json']['id'],
|
||||
|
||||
@ -55,7 +55,7 @@ EXAMPLES = '''
|
||||
- name: Launch a job
|
||||
tower_job_launch:
|
||||
job_template: "My Job Template"
|
||||
register: job
|
||||
register: job
|
||||
|
||||
- name: Wait for job max 120s
|
||||
tower_job_wait:
|
||||
@ -93,20 +93,6 @@ status:
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
import time
|
||||
|
||||
|
||||
def check_job(module, job_url):
|
||||
response = module.get_endpoint(job_url)
|
||||
if response['status_code'] != 200:
|
||||
module.fail_json(msg="Unable to read job from Tower {0}: {1}".format(response['status_code'], module.extract_errors_from_response(response)))
|
||||
|
||||
# Since we were successful, extract the fields we want to return
|
||||
for k in ('id', 'status', 'elapsed', 'started', 'finished'):
|
||||
module.json_output[k] = response['json'].get(k)
|
||||
|
||||
# And finally return the payload
|
||||
return response['json']
|
||||
|
||||
|
||||
def main():
|
||||
@ -153,31 +139,13 @@ def main():
|
||||
if job is None:
|
||||
module.fail_json(msg='Unable to wait on job {0}; that ID does not exist in Tower.'.format(job_id))
|
||||
|
||||
job_url = job['url']
|
||||
|
||||
# Grab our start time to compare against for the timeout
|
||||
start = time.time()
|
||||
|
||||
# Get the initial job status from Tower, this will exit if there are any issues with the HTTP call
|
||||
result = check_job(module, job_url)
|
||||
|
||||
# Loop while the job is not yet completed
|
||||
while not result['finished']:
|
||||
# If we are past our time out fail with a message
|
||||
if timeout and timeout < time.time() - start:
|
||||
module.json_output['msg'] = "Monitoring aborted due to timeout"
|
||||
module.fail_json(**module.json_output)
|
||||
|
||||
# Put the process to sleep for our interval
|
||||
time.sleep(interval)
|
||||
|
||||
# Check the job again
|
||||
result = check_job(module, job_url)
|
||||
|
||||
# If the job has failed, we want to raise an Exception for that so we get a non-zero response.
|
||||
if result['failed']:
|
||||
module.json_output['msg'] = 'Job with id {0} failed'.format(job_id)
|
||||
module.fail_json(**module.json_output)
|
||||
# Invoke wait function
|
||||
result = module.wait_on_url(
|
||||
url=job['url'],
|
||||
object_name=job_id,
|
||||
object_type='legacy_job_wait',
|
||||
timeout=timeout, interval=interval
|
||||
)
|
||||
|
||||
module.exit_json(**module.json_output)
|
||||
|
||||
|
||||
@ -93,7 +93,6 @@ EXAMPLES = '''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
import json
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
@ -178,26 +177,13 @@ def main():
|
||||
if not wait:
|
||||
module.exit_json(**module.json_output)
|
||||
|
||||
# Grab our start time to compare against for the timeout
|
||||
start = time.time()
|
||||
|
||||
job_url = result['json']['url']
|
||||
while not result['json']['finished']:
|
||||
# If we are past our time out fail with a message
|
||||
if timeout and timeout < time.time() - start:
|
||||
module.json_output['msg'] = "Monitoring aborted due to timeout"
|
||||
module.fail_json(**module.json_output)
|
||||
|
||||
# Put the process to sleep for our interval
|
||||
time.sleep(interval)
|
||||
|
||||
result = module.get_endpoint(job_url)
|
||||
module.json_output['status'] = result['json']['status']
|
||||
|
||||
# If the job has failed, we want to raise a task failure for that so we get a non-zero response.
|
||||
if result['json']['failed']:
|
||||
module.json_output['msg'] = 'The workflow "{0}" failed'.format(name)
|
||||
module.fail_json(**module.json_output)
|
||||
# Invoke wait function
|
||||
module.wait_on_url(
|
||||
url=result['json']['url'],
|
||||
object_name=name,
|
||||
object_type='Workflow Job',
|
||||
timeout=timeout, interval=interval
|
||||
)
|
||||
|
||||
module.exit_json(**module.json_output)
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
- assert:
|
||||
that:
|
||||
- result is failed
|
||||
- "'Monitoring aborted due to timeout' in result.msg"
|
||||
- "'Monitoring of Workflow Job - {{ wfjt_name1 }} aborted due to timeout' in result.msg"
|
||||
|
||||
- name: Kick off a workflow and wait for it
|
||||
tower_workflow_launch:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user