Encode zuul.message with base64
Zuul recently added zuul.message which needs to be protected against
interpretation by jinja in ansible. This was initially done by marking
it with the !unsafe tag. However this has the disadvantage that the
inventory is no longer parsable by standard yaml parsers without
teaching them the !unsafe tag.
There is a similar simple possibility that doesn't rely on this tag by
base64 encoding the commit message. Ansible has filters for decoding
this so it is still quite easy to deal with base64 encoded vars in
ansible via '{{ zuul.message | b64decode }}'.
Change-Id: I9628e2770dda120b269612e28bb6217036942b8e
This commit is contained in:
@@ -566,7 +566,18 @@ are available:
|
||||
|
||||
.. var:: message
|
||||
|
||||
The commit or pull request message of the change.
|
||||
The commit or pull request message of the change base64 encoded. Use the
|
||||
`b64decode` filter in ansible when working with it.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- hosts: all
|
||||
tasks:
|
||||
- name: Dump commit message
|
||||
copy:
|
||||
content: "{{ zuul.message | b64decode }}"
|
||||
dest: "{{ zuul.executor.log_root }}/commit-message.txt"
|
||||
|
||||
|
||||
Branch Items
|
||||
~~~~~~~~~~~~
|
||||
|
||||
8
releasenotes/notes/zuul-message-a36f1a6adc7da31c.yaml
Normal file
8
releasenotes/notes/zuul-message-a36f1a6adc7da31c.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
Zuul recently added the job variable :var:`zuul.message`. This can contain
|
||||
jinja tags which can cause problems accessing the zuul variable in the job.
|
||||
Because of this the message is now base64 encoded and any job evaluating
|
||||
this variable needs to be changed from ``{{ zuul.message }}`` to
|
||||
``{{ zuul.message | b64decode }}``.
|
||||
@@ -2,5 +2,5 @@
|
||||
tasks:
|
||||
- name: Dump commit message
|
||||
copy:
|
||||
content: "{{ zuul.message }}"
|
||||
content: "{{ zuul.message | b64decode }}"
|
||||
dest: "{{ zuul.executor.log_root }}/commit-message.txt"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import base64
|
||||
import os
|
||||
|
||||
import yaml
|
||||
@@ -61,7 +62,7 @@ class TestInventory(TestInventoryBase):
|
||||
self.assertIn('src_root', z_vars['executor'])
|
||||
self.assertIn('job', z_vars)
|
||||
self.assertEqual(z_vars['job'], 'single-inventory')
|
||||
self.assertEqual(str(z_vars['message']), 'A')
|
||||
self.assertEqual(z_vars['message'], 'QQ==')
|
||||
|
||||
self.executor_server.release()
|
||||
self.waitUntilSettled()
|
||||
@@ -192,9 +193,9 @@ class TestAnsibleInventory(AnsibleZuulTestCase):
|
||||
inv_path = os.path.join(build.jobdir.root, 'ansible', 'inventory.yaml')
|
||||
inventory = yaml.safe_load(open(inv_path, 'r'))
|
||||
|
||||
self.assertEqual(
|
||||
inventory['all']['vars']['zuul']['message'].unsafe_var,
|
||||
expected_message)
|
||||
decoded_message = base64.b64decode(
|
||||
inventory['all']['vars']['zuul']['message']).decode('utf-8')
|
||||
self.assertEqual(decoded_message, expected_message)
|
||||
|
||||
obtained_message = self._get_file(self.history[0],
|
||||
'work/logs/commit-message.txt')
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import base64
|
||||
import collections
|
||||
import datetime
|
||||
import json
|
||||
@@ -29,7 +30,7 @@ import traceback
|
||||
import git
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from zuul.lib.yamlutil import yaml, UnsafeTag
|
||||
from zuul.lib.yamlutil import yaml
|
||||
from zuul.lib.config import get_default
|
||||
from zuul.lib.statsd import get_statsd
|
||||
from zuul.lib import filecomments
|
||||
@@ -593,7 +594,8 @@ def make_inventory_dict(nodes, args, all_vars):
|
||||
|
||||
zuul_vars = all_vars['zuul']
|
||||
if 'message' in zuul_vars:
|
||||
zuul_vars['message'] = UnsafeTag(zuul_vars['message'])
|
||||
zuul_vars['message'] = base64.b64encode(
|
||||
zuul_vars['message'].encode("utf-8")).decode('utf-8')
|
||||
|
||||
inventory = {
|
||||
'all': {
|
||||
|
||||
@@ -25,26 +25,6 @@ except ImportError:
|
||||
Mark = yaml.Mark
|
||||
|
||||
|
||||
class UnsafeTag(yaml.YAMLObject):
|
||||
yaml_tag = u'!unsafe'
|
||||
yaml_dumper = yaml.SafeDumper
|
||||
yaml_loader = yaml.SafeLoader
|
||||
|
||||
def __init__(self, unsafe_var):
|
||||
self.unsafe_var = unsafe_var
|
||||
|
||||
@classmethod
|
||||
def from_yaml(cls, loader, node):
|
||||
return UnsafeTag(node.value)
|
||||
|
||||
@classmethod
|
||||
def to_yaml(cls, dumper, data):
|
||||
return dumper.represent_scalar(cls.yaml_tag, data.unsafe_var)
|
||||
|
||||
def __str__(self):
|
||||
return self.unsafe_var
|
||||
|
||||
|
||||
def safe_load(stream, *args, **kwargs):
|
||||
return yaml.load(stream, *args, Loader=SafeLoader, **kwargs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user