Add exception to allow relaunching callback jobs

allows for execute_role level users to directly
relaunch callback-type jobs, even though limit
has changed from JT, it is a down-selection
This commit is contained in:
AlanCoding 2018-05-11 09:05:25 -04:00
parent 46add35f98
commit db6cc7c50b
No known key found for this signature in database
GPG Key ID: FD2C3C012A72926B
5 changed files with 22 additions and 7 deletions

View File

@ -1507,7 +1507,7 @@ class JobAccess(BaseAccess):
elif not jt_access:
return False
org_access = obj.inventory and self.user in obj.inventory.organization.inventory_admin_role
org_access = bool(obj.inventory) and self.user in obj.inventory.organization.inventory_admin_role
project_access = obj.project is None or self.user in obj.project.admin_role
credential_access = all([self.user in cred.use_role for cred in obj.credentials.all()])

View File

@ -975,6 +975,8 @@ class JobLaunchConfig(LaunchTimeConfig):
return True
for field_name, ask_field_name in ask_mapping.items():
if field_name in prompts and not getattr(template, ask_field_name):
if field_name == 'limit' and self.job and self.job.launch_type == 'callback':
continue # exception for relaunching callbacks
return True
else:
return False

View File

@ -814,7 +814,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
# Done.
return result
def copy_unified_job(self, limit=None):
def copy_unified_job(self, _eager_fields=None, **new_prompts):
'''
Returns saved object, including related fields.
Create a copy of this unified job for the purpose of relaunch
@ -824,12 +824,14 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
parent_field_name = unified_job_class._get_parent_field_name()
fields = unified_jt_class._get_unified_job_field_names() | set([parent_field_name])
create_data = {"launch_type": "relaunch"}
if limit:
create_data["limit"] = limit
create_data = {}
if _eager_fields:
create_data = _eager_fields.copy()
create_data["launch_type"] = "relaunch"
prompts = self.launch_prompts()
if self.unified_job_template and prompts:
if self.unified_job_template and (prompts is not None):
prompts.update(new_prompts)
prompts['_eager_fields'] = create_data
unified_job = self.unified_job_template.create_unified_job(**prompts)
else:

View File

@ -75,7 +75,7 @@ def test_job_relaunch_on_failed_hosts(post, inventory, project, machine_credenti
project=project
)
jt.credentials.add(machine_credential)
job = jt.create_unified_job(_eager_fields={'status': 'failed', 'limit': 'host1,host2,host3'})
job = jt.create_unified_job(_eager_fields={'status': 'failed'}, limit='host1,host2,host3')
job.job_events.create(event='playbook_on_stats')
job.job_host_summaries.create(host=h1, failed=False, ok=1, changed=0, failures=0, host_name=h1.name)
job.job_host_summaries.create(host=h2, failed=False, ok=0, changed=1, failures=0, host_name=h2.name)

View File

@ -223,6 +223,17 @@ class TestJobRelaunchAccess:
job.credentials.add(net_credential)
assert not rando.can_access(Job, 'start', job, validate_license=False)
@pytest.mark.job_runtime_vars
def test_callback_relaunchable_by_user(self, job_template, rando):
job = job_template.create_unified_job(
_eager_fields={'launch_type': 'callback'},
limit='host2'
)
assert 'limit' in job.launch_config.prompts_dict() # sanity assertion
job_template.execute_role.members.add(rando)
can_access, messages = rando.can_access_with_errors(Job, 'start', job, validate_license=False)
assert can_access, messages
@pytest.mark.django_db
class TestJobAndUpdateCancels: