mirror of
https://github.com/ansible/awx.git
synced 2026-03-20 18:37:39 -02:30
Enforce extra_vars override hierachy
This commit is contained in:
@@ -111,20 +111,29 @@ class SurveyJobTemplateMixin(models.Model):
|
|||||||
vars.append(survey_element['variable'])
|
vars.append(survey_element['variable'])
|
||||||
return vars
|
return vars
|
||||||
|
|
||||||
def _update_unified_job_kwargs(self, **kwargs):
|
def _update_unified_job_kwargs(self, create_kwargs, kwargs):
|
||||||
'''
|
'''
|
||||||
Combine extra_vars with variable precedence order:
|
Combine extra_vars with variable precedence order:
|
||||||
JT extra_vars -> JT survey defaults -> runtime extra_vars
|
JT extra_vars -> JT survey defaults -> runtime extra_vars
|
||||||
|
|
||||||
|
:param create_kwargs: key-worded arguments to be updated and later used for creating unified job.
|
||||||
|
:type create_kwargs: dict
|
||||||
|
:param kwargs: request parameters used to override unified job template fields with runtime values.
|
||||||
|
:type kwargs: dict
|
||||||
|
:return: modified create_kwargs.
|
||||||
|
:rtype: dict
|
||||||
'''
|
'''
|
||||||
# Job Template extra_vars
|
# Job Template extra_vars
|
||||||
extra_vars = self.extra_vars_dict
|
extra_vars = self.extra_vars_dict
|
||||||
|
|
||||||
|
survey_defaults = {}
|
||||||
|
|
||||||
# transform to dict
|
# transform to dict
|
||||||
if 'extra_vars' in kwargs:
|
if 'extra_vars' in kwargs:
|
||||||
kwargs_extra_vars = kwargs['extra_vars']
|
runtime_extra_vars = kwargs['extra_vars']
|
||||||
kwargs_extra_vars = parse_yaml_or_json(kwargs_extra_vars)
|
runtime_extra_vars = parse_yaml_or_json(runtime_extra_vars)
|
||||||
else:
|
else:
|
||||||
kwargs_extra_vars = {}
|
runtime_extra_vars = {}
|
||||||
|
|
||||||
# Overwrite with job template extra vars with survey default vars
|
# Overwrite with job template extra vars with survey default vars
|
||||||
if self.survey_enabled and 'spec' in self.survey_spec:
|
if self.survey_enabled and 'spec' in self.survey_spec:
|
||||||
@@ -133,22 +142,23 @@ class SurveyJobTemplateMixin(models.Model):
|
|||||||
variable_key = survey_element.get('variable')
|
variable_key = survey_element.get('variable')
|
||||||
|
|
||||||
if survey_element.get('type') == 'password':
|
if survey_element.get('type') == 'password':
|
||||||
if variable_key in kwargs_extra_vars and default:
|
if variable_key in runtime_extra_vars and default:
|
||||||
kw_value = kwargs_extra_vars[variable_key]
|
kw_value = runtime_extra_vars[variable_key]
|
||||||
if kw_value.startswith('$encrypted$') and kw_value != default:
|
if kw_value.startswith('$encrypted$') and kw_value != default:
|
||||||
kwargs_extra_vars[variable_key] = default
|
runtime_extra_vars[variable_key] = default
|
||||||
|
|
||||||
if default is not None:
|
if default is not None:
|
||||||
data = {variable_key: default}
|
data = {variable_key: default}
|
||||||
errors = self._survey_element_validation(survey_element, data)
|
errors = self._survey_element_validation(survey_element, data)
|
||||||
if not errors:
|
if not errors:
|
||||||
extra_vars[variable_key] = default
|
survey_defaults[variable_key] = default
|
||||||
|
extra_vars.update(survey_defaults)
|
||||||
|
|
||||||
# Overwrite job template extra vars with explicit job extra vars
|
# Overwrite job template extra vars with explicit job extra vars
|
||||||
# and add on job extra vars
|
# and add on job extra vars
|
||||||
extra_vars.update(kwargs_extra_vars)
|
extra_vars.update(runtime_extra_vars)
|
||||||
kwargs['extra_vars'] = json.dumps(extra_vars)
|
create_kwargs['extra_vars'] = json.dumps(extra_vars)
|
||||||
return kwargs
|
return create_kwargs
|
||||||
|
|
||||||
def _survey_element_validation(self, survey_element, data):
|
def _survey_element_validation(self, survey_element, data):
|
||||||
errors = []
|
errors = []
|
||||||
@@ -291,5 +301,3 @@ class TaskManagerProjectUpdateMixin(TaskManagerUpdateOnLaunchMixin):
|
|||||||
class TaskManagerInventoryUpdateMixin(TaskManagerUpdateOnLaunchMixin):
|
class TaskManagerInventoryUpdateMixin(TaskManagerUpdateOnLaunchMixin):
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -377,10 +377,18 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin):
|
|||||||
def _can_update(self):
|
def _can_update(self):
|
||||||
return bool(self.scm_type)
|
return bool(self.scm_type)
|
||||||
|
|
||||||
def _update_unified_job_kwargs(self, **kwargs):
|
def _update_unified_job_kwargs(self, create_kwargs, kwargs):
|
||||||
|
'''
|
||||||
|
:param create_kwargs: key-worded arguments to be updated and later used for creating unified job.
|
||||||
|
:type create_kwargs: dict
|
||||||
|
:param kwargs: request parameters used to override unified job template fields with runtime values.
|
||||||
|
:type kwargs: dict
|
||||||
|
:return: modified create_kwargs.
|
||||||
|
:rtype: dict
|
||||||
|
'''
|
||||||
if self.scm_delete_on_next_update:
|
if self.scm_delete_on_next_update:
|
||||||
kwargs['scm_delete_on_update'] = True
|
create_kwargs['scm_delete_on_update'] = True
|
||||||
return kwargs
|
return create_kwargs
|
||||||
|
|
||||||
def create_project_update(self, **kwargs):
|
def create_project_update(self, **kwargs):
|
||||||
return self.create_unified_job(**kwargs)
|
return self.create_unified_job(**kwargs)
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ def test_job_template_survey_mixin(job_template_factory):
|
|||||||
obj = objects.job_template
|
obj = objects.job_template
|
||||||
obj.survey_enabled = True
|
obj.survey_enabled = True
|
||||||
obj.survey_spec = {'spec': [{'default':'my_default', 'type':'password', 'variable':'my_variable'}]}
|
obj.survey_spec = {'spec': [{'default':'my_default', 'type':'password', 'variable':'my_variable'}]}
|
||||||
kwargs = obj._update_unified_job_kwargs(extra_vars={'my_variable':'$encrypted$'})
|
kwargs = obj._update_unified_job_kwargs({}, {'extra_vars': {'my_variable':'$encrypted$'}})
|
||||||
assert kwargs['extra_vars'] == '{"my_variable": "my_default"}'
|
assert kwargs['extra_vars'] == '{"my_variable": "my_default"}'
|
||||||
|
|
||||||
|
|
||||||
@@ -113,10 +113,25 @@ def test_job_template_survey_mixin_length(job_template_factory):
|
|||||||
obj.survey_enabled = True
|
obj.survey_enabled = True
|
||||||
obj.survey_spec = {'spec': [{'default':'my_default', 'type':'password', 'variable':'my_variable'},
|
obj.survey_spec = {'spec': [{'default':'my_default', 'type':'password', 'variable':'my_variable'},
|
||||||
{'type':'password', 'variable':'my_other_variable'}]}
|
{'type':'password', 'variable':'my_other_variable'}]}
|
||||||
kwargs = obj._update_unified_job_kwargs(extra_vars={'my_variable':'$encrypted$'})
|
kwargs = obj._update_unified_job_kwargs({}, {'extra_vars': {'my_variable':'$encrypted$'}})
|
||||||
assert kwargs['extra_vars'] == '{"my_variable": "my_default"}'
|
assert kwargs['extra_vars'] == '{"my_variable": "my_default"}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_job_template_survey_mixin_survey_runtime_has_highest_priority(job_template_factory):
|
||||||
|
objects = job_template_factory(
|
||||||
|
'survey_mixin_test',
|
||||||
|
organization='org1',
|
||||||
|
inventory='inventory1',
|
||||||
|
credential='cred1',
|
||||||
|
persisted=False,
|
||||||
|
)
|
||||||
|
obj = objects.job_template
|
||||||
|
obj.survey_enabled = True
|
||||||
|
obj.survey_spec = {'spec': [{'default':'foo', 'type':'password', 'variable':'my_variable'}]}
|
||||||
|
kwargs = obj._update_unified_job_kwargs({}, {'extra_vars': {'my_variable': 'bar'}})
|
||||||
|
assert kwargs['extra_vars'] == '{"my_variable": "bar"}'
|
||||||
|
|
||||||
|
|
||||||
def test_job_template_can_start_with_callback_extra_vars_provided(job_template_factory):
|
def test_job_template_can_start_with_callback_extra_vars_provided(job_template_factory):
|
||||||
objects = job_template_factory(
|
objects = job_template_factory(
|
||||||
'callback_extra_vars_test',
|
'callback_extra_vars_test',
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ def test_update_kwargs_survey_invalid_default(survey_spec_factory):
|
|||||||
spec['spec'][0]['min'] = 3
|
spec['spec'][0]['min'] = 3
|
||||||
spec['spec'][0]['default'] = 1
|
spec['spec'][0]['default'] = 1
|
||||||
jt = JobTemplate(name="test-jt", survey_spec=spec, survey_enabled=True, extra_vars="var2: 2")
|
jt = JobTemplate(name="test-jt", survey_spec=spec, survey_enabled=True, extra_vars="var2: 2")
|
||||||
defaulted_extra_vars = jt._update_unified_job_kwargs()
|
defaulted_extra_vars = jt._update_unified_job_kwargs({}, {})
|
||||||
assert 'extra_vars' in defaulted_extra_vars
|
assert 'extra_vars' in defaulted_extra_vars
|
||||||
# Make sure we did not set the invalid default of 1
|
# Make sure we did not set the invalid default of 1
|
||||||
assert json.loads(defaulted_extra_vars['extra_vars'])['var2'] == 2
|
assert json.loads(defaulted_extra_vars['extra_vars'])['var2'] == 2
|
||||||
@@ -115,7 +115,7 @@ def test_optional_survey_question_defaults(
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
jt = JobTemplate(name="test-jt", survey_spec=spec, survey_enabled=True)
|
jt = JobTemplate(name="test-jt", survey_spec=spec, survey_enabled=True)
|
||||||
defaulted_extra_vars = jt._update_unified_job_kwargs()
|
defaulted_extra_vars = jt._update_unified_job_kwargs({}, {})
|
||||||
element = spec['spec'][0]
|
element = spec['spec'][0]
|
||||||
if expect_use:
|
if expect_use:
|
||||||
assert jt._survey_element_validation(element, {element['variable']: element['default']}) == []
|
assert jt._survey_element_validation(element, {element['variable']: element['default']}) == []
|
||||||
@@ -140,7 +140,7 @@ class TestWorkflowSurveys:
|
|||||||
survey_enabled=True,
|
survey_enabled=True,
|
||||||
extra_vars="var1: 5"
|
extra_vars="var1: 5"
|
||||||
)
|
)
|
||||||
updated_extra_vars = wfjt._update_unified_job_kwargs()
|
updated_extra_vars = wfjt._update_unified_job_kwargs({}, {})
|
||||||
assert 'extra_vars' in updated_extra_vars
|
assert 'extra_vars' in updated_extra_vars
|
||||||
assert json.loads(updated_extra_vars['extra_vars'])['var1'] == 3
|
assert json.loads(updated_extra_vars['extra_vars'])['var1'] == 3
|
||||||
assert wfjt.can_start_without_user_input()
|
assert wfjt.can_start_without_user_input()
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ def copy_model_by_class(obj1, Class2, fields, kwargs):
|
|||||||
|
|
||||||
# Apply class-specific extra processing for origination of unified jobs
|
# Apply class-specific extra processing for origination of unified jobs
|
||||||
if hasattr(obj1, '_update_unified_job_kwargs') and obj1.__class__ != Class2:
|
if hasattr(obj1, '_update_unified_job_kwargs') and obj1.__class__ != Class2:
|
||||||
new_kwargs = obj1._update_unified_job_kwargs(**create_kwargs)
|
new_kwargs = obj1._update_unified_job_kwargs(create_kwargs, kwargs)
|
||||||
else:
|
else:
|
||||||
new_kwargs = create_kwargs
|
new_kwargs = create_kwargs
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user