Merge "Ensure valid Ansible variable names in config"

This commit is contained in:
Zuul 2019-03-27 15:45:36 +00:00 committed by Gerrit Code Review
commit 33fb2dbdd3
2 changed files with 136 additions and 7 deletions

View File

@ -1469,6 +1469,123 @@ class TestInRepoConfig(ZuulTestCase):
self.assertIn('not recognized', A.messages[0],
"A should have a syntax error reported")
def test_invalid_job_secret_var_name(self):
in_repo_conf = textwrap.dedent(
"""
- secret:
name: foo-bar
data:
dummy: value
- job:
name: foobar
secrets:
- name: foo-bar
secret: foo-bar
""")
file_dict = {".zuul.yaml": in_repo_conf}
A = self.fake_gerrit.addFakeChange("org/project", "master", "A",
files=file_dict)
A.addApproval("Code-Review", 2)
self.fake_gerrit.addEvent(A.addApproval("Approved", 1))
self.waitUntilSettled()
self.assertEqual(A.data["status"], "NEW")
self.assertEqual(A.reported, 1,
"A should report failure")
self.assertIn("Ansible variable name 'foo-bar'", A.messages[0],
"A should have a syntax error reported")
def test_invalid_job_vars(self):
in_repo_conf = textwrap.dedent(
"""
- job:
name: foobar
vars:
foo-bar: value
""")
file_dict = {".zuul.yaml": in_repo_conf}
A = self.fake_gerrit.addFakeChange("org/project", "master", "A",
files=file_dict)
A.addApproval("Code-Review", 2)
self.fake_gerrit.addEvent(A.addApproval("Approved", 1))
self.waitUntilSettled()
self.assertEqual(A.data["status"], "NEW")
self.assertEqual(A.reported, 1,
"A should report failure")
self.assertIn("Ansible variable name 'foo-bar'", A.messages[0],
"A should have a syntax error reported")
def test_invalid_job_extra_vars(self):
in_repo_conf = textwrap.dedent(
"""
- job:
name: foobar
extra-vars:
foo-bar: value
""")
file_dict = {".zuul.yaml": in_repo_conf}
A = self.fake_gerrit.addFakeChange("org/project", "master", "A",
files=file_dict)
A.addApproval("Code-Review", 2)
self.fake_gerrit.addEvent(A.addApproval("Approved", 1))
self.waitUntilSettled()
self.assertEqual(A.data["status"], "NEW")
self.assertEqual(A.reported, 1,
"A should report failure")
self.assertIn("Ansible variable name 'foo-bar'", A.messages[0],
"A should have a syntax error reported")
def test_invalid_job_host_vars(self):
in_repo_conf = textwrap.dedent(
"""
- job:
name: foobar
host-vars:
host-name:
foo-bar: value
""")
file_dict = {".zuul.yaml": in_repo_conf}
A = self.fake_gerrit.addFakeChange("org/project", "master", "A",
files=file_dict)
A.addApproval("Code-Review", 2)
self.fake_gerrit.addEvent(A.addApproval("Approved", 1))
self.waitUntilSettled()
self.assertEqual(A.data["status"], "NEW")
self.assertEqual(A.reported, 1,
"A should report failure")
self.assertIn("Ansible variable name 'foo-bar'", A.messages[0],
"A should have a syntax error reported")
def test_invalid_job_group_vars(self):
in_repo_conf = textwrap.dedent(
"""
- job:
name: foobar
group-vars:
group-name:
foo-bar: value
""")
file_dict = {".zuul.yaml": in_repo_conf}
A = self.fake_gerrit.addFakeChange("org/project", "master", "A",
files=file_dict)
A.addApproval("Code-Review", 2)
self.fake_gerrit.addEvent(A.addApproval("Approved", 1))
self.waitUntilSettled()
self.assertEqual(A.data["status"], "NEW")
self.assertEqual(A.reported, 1,
"A should report failure")
self.assertIn("Ansible variable name 'foo-bar'", A.messages[0],
"A should have a syntax error reported")
def test_untrusted_syntax_error(self):
in_repo_conf = textwrap.dedent(
"""

View File

@ -400,6 +400,18 @@ class EncryptedPKCS1_OAEP(yaml.YAMLObject):
private_key).decode('utf8')
def ansible_var_name(value):
vs.Schema(str)(value)
if not re.fullmatch(r"[a-zA-Z][a-zA-Z0-9_]*", value):
raise vs.Invalid("Invalid Ansible variable name '{}'".format(value))
def ansible_vars_dict(value):
vs.Schema(dict)(value)
for key in value:
ansible_var_name(key)
class PragmaParser(object):
pragma = {
'implied-branch-matchers': bool,
@ -536,7 +548,7 @@ class JobParser(object):
job_dependency = {vs.Required('name'): str,
'soft': bool}
secret = {vs.Required('name'): str,
secret = {vs.Required('name'): ansible_var_name,
vs.Required('secret'): str,
'pass-to-parent': bool}
@ -575,10 +587,10 @@ class JobParser(object):
'_start_mark': ZuulMark,
'roles': to_list(role),
'required-projects': to_list(vs.Any(job_project, str)),
'vars': dict,
'extra-vars': dict,
'host-vars': {str: dict},
'group-vars': {str: dict},
'vars': ansible_vars_dict,
'extra-vars': ansible_vars_dict,
'host-vars': {str: ansible_vars_dict},
'group-vars': {str: ansible_vars_dict},
'dependencies': to_list(vs.Any(job_dependency, str)),
'allowed-projects': to_list(str),
'override-branch': str,
@ -897,7 +909,7 @@ class ProjectTemplateParser(object):
project = {
'name': str,
'description': str,
'vars': dict,
'vars': ansible_vars_dict,
str: pipeline_contents,
'_source_context': model.SourceContext,
'_start_mark': ZuulMark,
@ -978,7 +990,7 @@ class ProjectParser(object):
project = {
'name': str,
'description': str,
'vars': dict,
'vars': ansible_vars_dict,
'templates': [str],
'merge-mode': vs.Any('merge', 'merge-resolve',
'cherry-pick'),