diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py index c109f28b65..b390043765 100644 --- a/awx/main/models/credential/__init__.py +++ b/awx/main/models/credential/__init__.py @@ -632,7 +632,7 @@ class CredentialType(CommonModelNameNotUnique): data = Template(file_tmpl).render(**namespace) _, path = tempfile.mkstemp(dir=private_data_dir) with open(path, 'w') as f: - f.write(data) + f.write(data.encode('utf-8')) os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) # determine if filename indicates single file or many diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index 90023d9076..9a17a12239 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from contextlib import contextmanager from datetime import datetime from functools import partial @@ -12,6 +14,7 @@ from backports.tempfile import TemporaryDirectory import fcntl import mock import pytest +import six import yaml from django.conf import settings @@ -1319,6 +1322,33 @@ class TestJobCredentials(TestJobExecution): self.run_pexpect.side_effect = run_pexpect_side_effect self.task.run(self.pk) + def test_custom_environment_injectors_with_unicode_content(self): + value = six.u('Iñtërnâtiônàlizætiøn') + some_cloud = CredentialType( + kind='cloud', + name='SomeCloud', + managed_by_tower=False, + inputs={'fields': []}, + injectors={ + 'file': {'template': value}, + 'env': {'MY_CLOUD_INI_FILE': '{{tower.filename}}'} + } + ) + credential = Credential( + pk=1, + credential_type=some_cloud, + ) + self.instance.credentials.add(credential) + self.task.run(self.pk) + + def run_pexpect_side_effect(*args, **kwargs): + args, cwd, env, stdout = args + assert open(env['MY_CLOUD_INI_FILE'], 'rb').read() == value.encode('utf-8') + return ['successful', 0] + + self.run_pexpect.side_effect = run_pexpect_side_effect + self.task.run(self.pk) + def test_custom_environment_injectors_with_files(self): some_cloud = CredentialType( kind='cloud',