From fc2a2e538f0e756fa69effae83ed46822466fbc0 Mon Sep 17 00:00:00 2001 From: Will Haines Date: Thu, 10 Dec 2020 18:01:20 -0700 Subject: [PATCH 1/4] Enabled jinja2.ChainableUndefined for custom webhook notifications Signed-off-by: Will Haines --- awx/main/models/notifications.py | 4 ++-- requirements/requirements_ansible.in | 2 +- requirements/requirements_ansible.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/awx/main/models/notifications.py b/awx/main/models/notifications.py index 11d97c7690..33562e7fca 100644 --- a/awx/main/models/notifications.py +++ b/awx/main/models/notifications.py @@ -12,7 +12,7 @@ from django.core.mail.message import EmailMessage from django.db import connection from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_str, force_text -from jinja2 import sandbox +from jinja2 import sandbox, ChainableUndefined from jinja2.exceptions import TemplateSyntaxError, UndefinedError, SecurityError # AWX @@ -429,7 +429,7 @@ class JobNotificationMixin(object): raise RuntimeError("Define me") def build_notification_message(self, nt, status): - env = sandbox.ImmutableSandboxedEnvironment() + env = sandbox.ImmutableSandboxedEnvironment(undefined=ChainableUndefined) from awx.api.serializers import UnifiedJobSerializer job_serialization = UnifiedJobSerializer(self).to_representation(self) diff --git a/requirements/requirements_ansible.in b/requirements/requirements_ansible.in index ec3c2984f5..c36e22bcb6 100644 --- a/requirements/requirements_ansible.in +++ b/requirements/requirements_ansible.in @@ -43,7 +43,7 @@ azure-mgmt-iothub==0.7.0 # AWS boto==2.47.0 # last which does not break ec2 scripts boto3==1.9.223 -jinja2==2.10.1 # required for native jinja2 types for inventory compat mode +jinja2==2.11.2 # required for ChainableUndefined # netconf for network modules ncclient==0.6.3 # netaddr filter diff --git a/requirements/requirements_ansible.txt b/requirements/requirements_ansible.txt index 05355fb8b8..cf945c462f 100644 --- a/requirements/requirements_ansible.txt +++ b/requirements/requirements_ansible.txt @@ -58,7 +58,7 @@ idna==2.8 # via requests ipaddress==1.0.23; python_version < "3" # via cryptography, kubernetes, openstacksdk iso8601==0.1.12 # via keystoneauth1, openstacksdk isodate==0.6.0 # via msrest -jinja2==2.10.1 # via -r /awx_devel/requirements/requirements_ansible.in, openshift +jinja2==2.11.2 # via -r /awx_devel/requirements/requirements_ansible.in, openshift jmespath==0.9.4 # via azure-cli-core, boto3, botocore, knack, openstacksdk jsonpatch==1.24 # via openstacksdk jsonpointer==2.0 # via jsonpatch From 9ec958f8396ee9cd1a205291a87e69139c2c8a1b Mon Sep 17 00:00:00 2001 From: Will Haines Date: Thu, 7 Jan 2021 17:24:56 -0700 Subject: [PATCH 2/4] Added test for Chainable Undefined Behavior Signed-off-by: Will Haines --- .../test/awx/test_notification_template.py | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/awx_collection/test/awx/test_notification_template.py b/awx_collection/test/awx/test_notification_template.py index 28f7c4ecee..252aca71e3 100644 --- a/awx_collection/test/awx/test_notification_template.py +++ b/awx_collection/test/awx/test_notification_template.py @@ -3,7 +3,7 @@ __metaclass__ = type import pytest -from awx.main.models import NotificationTemplate +from awx.main.models import NotificationTemplate, Job def compare_with_encrypted(model_config, param_config): @@ -109,3 +109,32 @@ def test_deprecated_to_modern_no_op(run_module, admin_user, organization): ), admin_user) assert not result.get('failed', False), result.get('msg', result) assert not result.pop('changed', None), result + + +@pytest.mark.django_db +def test_build_notification_message_undefined(run_module, admin_user, organization): + """Job notification templates may encounter undefined values in the context when they are + rendered. Make sure that accessing attributes or items of an undefined value returns another + instance of Undefined, rather than raising an UndefinedError. This enables the use of expressions + like "{{ job.created_by.first_name | default('unknown') }}".""" + job = Job.objects.create(name='foobar') + + nt_config = { + 'url': 'http://www.example.com/hook', + 'headers': { + 'X-Custom-Header': 'value123' + } + } + custom_start_template = {'body': '{"started_by": "{{ job.summary_fields.created_by.username | default(\'My Placeholder\') }}"}'} + messages = {'started': custom_start_template, 'success': None, 'error': None, 'workflow_approval': None} + result = run_module('tower_notification_template', dict( + name='foo-notification-template', + organization=organization.name, + notification_type='webhook', + notification_configuration=nt_config, + messages=messages, + ), admin_user) + nt = NotificationTemplate.objects.get(id=result['id']) + + _, body = job.build_notification_message(nt, 'running') + assert '{"started_by": "My Placeholder"}' in body \ No newline at end of file From d59e172f535dd080b9a422c2886473b3188e77cb Mon Sep 17 00:00:00 2001 From: Will Haines Date: Mon, 11 Jan 2021 11:56:04 -0700 Subject: [PATCH 3/4] Pinned Jinja2 to ensure ChainableUndefined is present Signed-off-by: Will Haines --- awx_collection/test/awx/test_notification_template.py | 2 +- requirements/requirements.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/awx_collection/test/awx/test_notification_template.py b/awx_collection/test/awx/test_notification_template.py index 252aca71e3..96fbd5e56c 100644 --- a/awx_collection/test/awx/test_notification_template.py +++ b/awx_collection/test/awx/test_notification_template.py @@ -137,4 +137,4 @@ def test_build_notification_message_undefined(run_module, admin_user, organizati nt = NotificationTemplate.objects.get(id=result['id']) _, body = job.build_notification_message(nt, 'running') - assert '{"started_by": "My Placeholder"}' in body \ No newline at end of file + assert '{"started_by": "My Placeholder"}' in body diff --git a/requirements/requirements.in b/requirements/requirements.in index c4466dedc1..cb53e02f8f 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -25,7 +25,7 @@ djangorestframework>=3.12.1 djangorestframework-yaml GitPython>=3.1.1 # minimum to fix https://github.com/ansible/awx/issues/6119 irc -jinja2 +jinja2>=2.11.0 # required for ChainableUndefined jsonschema Markdown # used for formatting API help openshift>=0.11.0 # minimum version to pull in new pyyaml for CVE-2017-18342 From 60dee83481baf6b396c3eff3d9702ec0b478c67c Mon Sep 17 00:00:00 2001 From: Jim Ladd Date: Mon, 11 Jan 2021 11:48:39 -0800 Subject: [PATCH 4/4] revert jinja2 dep changes for ansible venv --- requirements/requirements_ansible.in | 2 +- requirements/requirements_ansible.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/requirements_ansible.in b/requirements/requirements_ansible.in index c36e22bcb6..ec3c2984f5 100644 --- a/requirements/requirements_ansible.in +++ b/requirements/requirements_ansible.in @@ -43,7 +43,7 @@ azure-mgmt-iothub==0.7.0 # AWS boto==2.47.0 # last which does not break ec2 scripts boto3==1.9.223 -jinja2==2.11.2 # required for ChainableUndefined +jinja2==2.10.1 # required for native jinja2 types for inventory compat mode # netconf for network modules ncclient==0.6.3 # netaddr filter diff --git a/requirements/requirements_ansible.txt b/requirements/requirements_ansible.txt index cf945c462f..05355fb8b8 100644 --- a/requirements/requirements_ansible.txt +++ b/requirements/requirements_ansible.txt @@ -58,7 +58,7 @@ idna==2.8 # via requests ipaddress==1.0.23; python_version < "3" # via cryptography, kubernetes, openstacksdk iso8601==0.1.12 # via keystoneauth1, openstacksdk isodate==0.6.0 # via msrest -jinja2==2.11.2 # via -r /awx_devel/requirements/requirements_ansible.in, openshift +jinja2==2.10.1 # via -r /awx_devel/requirements/requirements_ansible.in, openshift jmespath==0.9.4 # via azure-cli-core, boto3, botocore, knack, openstacksdk jsonpatch==1.24 # via openstacksdk jsonpointer==2.0 # via jsonpatch