Add support for multi-file injection in custom creds

This commit is contained in:
Jim Ladd
2017-11-14 17:26:58 -05:00
parent 87365e5969
commit 286a70f2ca
3 changed files with 14 additions and 10 deletions

View File

@@ -695,11 +695,10 @@ class CredentialTypeInjectorField(JSONSchemaField):
'properties': { 'properties': {
'file': { 'file': {
'type': 'object', 'type': 'object',
'properties': { 'patternProperties': {
'template': {'type': 'string'}, '^template\.[a-zA-Z_]+$': {'type': 'string'},
}, },
'additionalProperties': False, 'additionalProperties': False,
'required': ['template'],
}, },
'env': { 'env': {
'type': 'object', 'type': 'object',

View File

@@ -594,9 +594,11 @@ class CredentialType(CommonModelNameNotUnique):
return return
class TowerNamespace: class TowerNamespace:
filename = None pass
tower_namespace = TowerNamespace() tower_namespace = TowerNamespace()
filename_namespace = TowerNamespace()
tower_namespace.filename = filename_namespace
# maintain a normal namespace for building the ansible-playbook arguments (env and args) # maintain a normal namespace for building the ansible-playbook arguments (env and args)
namespace = {'tower': tower_namespace} namespace = {'tower': tower_namespace}
@@ -622,17 +624,18 @@ class CredentialType(CommonModelNameNotUnique):
if len(value): if len(value):
namespace[field_name] = value namespace[field_name] = value
file_tmpl = self.injectors.get('file', {}).get('template') file_tmpls = self.injectors.get('file', {})
if file_tmpl is not None: # If any file templates are provided, render the files and update the
# If a file template is provided, render the file and update the # special `tower` template namespace so the filename can be
# special `tower` template namespace so the filename can be # referenced in other injectors
# referenced in other injectors for file_label, file_tmpl in file_tmpls.items():
data = Template(file_tmpl).render(**namespace) data = Template(file_tmpl).render(**namespace)
_, path = tempfile.mkstemp(dir=private_data_dir) _, path = tempfile.mkstemp(dir=private_data_dir)
with open(path, 'w') as f: with open(path, 'w') as f:
f.write(data) f.write(data)
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
namespace['tower'].filename = path file_label = file_label.split('.')[1]
setattr(namespace['tower'].filename, file_label, path)
for env_var, tmpl in self.injectors.get('env', {}).items(): for env_var, tmpl in self.injectors.get('env', {}).items():
if env_var.startswith('ANSIBLE_') or env_var in self.ENV_BLACKLIST: if env_var.startswith('ANSIBLE_') or env_var in self.ENV_BLACKLIST:

View File

@@ -109,6 +109,8 @@ def test_cred_type_input_schema_validity(input_, valid):
({'file': 123}, False), ({'file': 123}, False),
({'file': {}}, False), ({'file': {}}, False),
({'file': {'template': '{{username}}'}}, True), ({'file': {'template': '{{username}}'}}, True),
({'file': {'template.username': '{{username}}'}}, True),
({'file': {'template.username': '{{username}}', 'template.password': '{{pass}}'}}, True),
({'file': {'foo': 'bar'}}, False), ({'file': {'foo': 'bar'}}, False),
({'env': 123}, False), ({'env': 123}, False),
({'env': {}}, True), ({'env': {}}, True),