diff options
author | Tobias Henkel <tobias.henkel@bmw.de> | 2020-07-20 18:12:07 +0200 |
---|---|---|
committer | Tobias Henkel <tobias.henkel@bmw.de> | 2020-07-21 19:20:24 +0200 |
commit | 49fe527edb2c27f67c074be72e3fb6d665400de7 (patch) | |
tree | 2e851a40b29cbe15ca9a36b92f6cfe728d0eb3d8 /tests/remote/test_remote_zuul_stream.py | |
parent | 6161ad75a83cd8e8c3bd347ea7f40b0e2d6b5c33 (diff) | |
download | zuul-49fe527edb2c27f67c074be72e3fb6d665400de7.tar.gz |
Block localhost shell tasks in untrusted playbooks
Zuul was designed to block local code execution in untrusted
environments to not only rely on bwrap to contain a job. This got
broken since the creation of a command plugin that injects the
zuul_job_id which is required for log streaming. However this plugin
doesn't do a check if the task is a localhost task. Further it is
required in trusted and untrusted environments due to log
streaming. Thus we need to fork this plugin and restrict the variant
that is used in untrusted environments.
We do this by moving actiongeneral/command.py back to action/*. We
further introduce a new catecory actiontrusted which gets the
unrestricted version of this plugin.
Change-Id: If81cc46bcae466f4c071badf09a8a88469ae6779
Story: 2007935
Task: 40391
Diffstat (limited to 'tests/remote/test_remote_zuul_stream.py')
-rw-r--r-- | tests/remote/test_remote_zuul_stream.py | 90 |
1 files changed, 58 insertions, 32 deletions
diff --git a/tests/remote/test_remote_zuul_stream.py b/tests/remote/test_remote_zuul_stream.py index 026fd1e7f..9fef472b5 100644 --- a/tests/remote/test_remote_zuul_stream.py +++ b/tests/remote/test_remote_zuul_stream.py @@ -32,7 +32,7 @@ class FunctionalZuulStreamMixIn: ansible_remote = os.environ.get('ZUUL_REMOTE_IPV4') self.assertIsNotNone(ansible_remote) - def _run_job(self, job_name): + def _run_job(self, job_name, create=True): # Keep the jobdir around so we can inspect contents if an # assert fails. It will be cleaned up anyway as it is contained # in a tmp dir which gets cleaned up after the test. @@ -40,32 +40,40 @@ class FunctionalZuulStreamMixIn: # Output extra ansible info so we might see errors. self.executor_server.verbose = True - conf = textwrap.dedent( - """ - - job: - name: {job_name} - run: playbooks/{job_name}.yaml - ansible-version: {version} - vars: - test_console_port: {console_port} - roles: - - zuul: org/common-config - nodeset: - nodes: - - name: compute1 - label: whatever - - name: controller - label: whatever - - - project: - check: - jobs: - - {job_name} - """.format( - job_name=job_name, - version=self.ansible_version, - console_port=self.log_console_port)) + if create: + conf = textwrap.dedent( + """ + - job: + name: {job_name} + run: playbooks/{job_name}.yaml + ansible-version: {version} + vars: + test_console_port: {console_port} + roles: + - zuul: org/common-config + nodeset: + nodes: + - name: compute1 + label: whatever + - name: controller + label: whatever + - project: + check: + jobs: + - {job_name} + """.format( + job_name=job_name, + version=self.ansible_version, + console_port=self.log_console_port)) + else: + conf = textwrap.dedent( + """ + - project: + check: + jobs: + - {job_name} + """.format(job_name=job_name)) file_dict = {'zuul.yaml': conf} A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A', files=file_dict) @@ -141,9 +149,6 @@ class FunctionalZuulStreamMixIn: self.assertLogLine(r'compute1 \| failed_in_loop2', text) self.assertLogLine(r'compute1 \| ok: Item: failed_in_loop2 ' r'Result: 1', text) - self.assertLogLine(r'localhost \| .*No such file or directory: .*' - r'\'/local-shelltask/somewhere/' - r'that/does/not/exist\'', text) self.assertLogLine(r'compute1 \| .*No such file or directory: .*' r'\'/remote-shelltask/somewhere/' r'that/does/not/exist\'', text) @@ -160,6 +165,18 @@ class FunctionalZuulStreamMixIn: r'RUN END RESULT_NORMAL: \[untrusted : review.example.com/' r'org/project/playbooks/command.yaml@master]', text) + # Run a pre-defined job that is defined in a trusted repo to test + # localhost tasks. + job = self._run_job('command-localhost', create=False) + with self.jobLog(job): + build = self.history[-1] + self.assertEqual(build.result, 'SUCCESS') + + text = self._get_job_output(build) + self.assertLogLine(r'localhost \| .*No such file or directory: .*' + r'\'/local-shelltask/somewhere/' + r'that/does/not/exist\'', text) + def test_module_exception(self): job = self._run_job('module_failure_exception') with self.jobLog(job): @@ -260,9 +277,6 @@ class TestZuulStream28(AnsibleZuulTestCase, FunctionalZuulStreamMixIn): self.assertLogLine(r'compute1 \| failed_in_loop2', text) self.assertLogLine(r'compute1 \| ok: Item: failed_in_loop2 ' r'Result: 1', text) - self.assertLogLine(r'localhost \| .*No such file or directory: .*' - r'\'/local-shelltask/somewhere/' - r'that/does/not/exist\'', text) self.assertLogLine(r'compute1 \| .*No such file or directory: .*' r'\'/remote-shelltask/somewhere/' r'that/does/not/exist\'', text) @@ -281,6 +295,18 @@ class TestZuulStream28(AnsibleZuulTestCase, FunctionalZuulStreamMixIn): r'RUN END RESULT_NORMAL: \[untrusted : review.example.com/' r'org/project/playbooks/command.yaml@master]', text) + # Run a pre-defined job that is defined in a trusted repo to test + # localhost tasks. + job = self._run_job('command-localhost', create=False) + with self.jobLog(job): + build = self.history[-1] + self.assertEqual(build.result, 'SUCCESS') + + text = self._get_job_output(build) + self.assertLogLine(r'localhost \| .*No such file or directory: .*' + r'\'/local-shelltask/somewhere/' + r'that/does/not/exist\'', text) + class TestZuulStream29(TestZuulStream28): ansible_version = '2.9' |