Skip to content

Commit

Permalink
allow for environment driven env settings
Browse files Browse the repository at this point in the history
expose ANSIBLE_RUNNER_{PASSWORDS,SETTINGS,ENVVARS,SSH_KEY} as an
alternative means of driving ansible runner inputs vs serializing to
file.
  • Loading branch information
mattp- committed Oct 7, 2020
1 parent 1194519 commit f36c662
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 13 deletions.
79 changes: 70 additions & 9 deletions ansible_runner/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,85 @@ def load_file(self, path, objtype=None, encoding='utf-8'):

try:
debug('cache miss, attempting to load file from disk: %s' % path)
contents = parsed_data = self.get_contents(path)
if encoding:
parsed_data = contents.encode(encoding)
contents = self.get_contents(path)
except ConfigurationError as exc:
debug(exc)
raise
except UnicodeEncodeError:
raise ConfigurationError('unable to encode file contents')

return self.deserialize(contents, objtype, encoding, key=path)


def load_env(self, key, objtype=None, encoding='utf-8'):
'''
Load the object specified by env key
This method will try to load object contents from environment
Args:
key (string): the key that contains the serialized data
encoding (string): The file contents text encoding
objtype (object): The object type of the file contents. This
is used to type check the deserialized content against the
contents loaded from disk.
Ignore serializing if objtype is string_types
Returns:
object: The deserialized file contents which could be either a
string object or a dict object
Raises:
ConfigurationError:
'''
try:
debug('cache miss, attempting to key from env %s' % key)
contents = os.environ[key]
except KeyError as exc:
debug(exc)
raise ConfigurationError('key %s is not in environment' % key)

return self.deserialize(contents, objtype, encoding)


def deserialize(self, data, objtype=None, encoding='utf-8', key=None):
'''
deserialize and type check data
Args:
data (string): The possibly encoded data to be deserialized
key (string): if specified, a key to use to memoize/cache deserialized contents
encoding (string): The data text encoding
objtype (object): The object type of the deserialized data. This
is used to type check the deserialized content is as expected.
Ignore serializing if objtype is string_types
Returns:
object: The deserialized data which could be either a
string object or a dict object
Raises:
ConfigurationError:
'''
if encoding:
try:
parsed_data = data.encode(encoding)
except UnicodeEncodeError:
raise ConfigurationError('unable to encode file contents')

if objtype is not string_types:
for deserializer in (self._load_json, self._load_yaml):
parsed_data = deserializer(contents)
parsed_data = deserializer(data)
if parsed_data:
break

if objtype and not isinstance(parsed_data, objtype):
debug('specified file %s is not of type %s' % (path, objtype))
raise ConfigurationError('invalid file serialization type for contents')
debug('specified data %s is not of type %s' % (data, objtype))
raise ConfigurationError('invalid file serialization type for data')

self._cache[path] = parsed_data
if key:
self._cache[key] = parsed_data
return parsed_data
20 changes: 16 additions & 4 deletions ansible_runner/runner_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,10 @@ def prepare_env(self):
with existing values so the :py:class:`ansible_runner.runner.Runner` object can read and use them easily
"""
try:
passwords = self.loader.load_file('env/passwords', Mapping)
if 'ANSIBLE_RUNNER_PASSWORDS' in os.environ:
passwords = self.loader.load_env('ANSIBLE_RUNNER_PASSWORDS', Mapping)
else:
passwords = self.loader.load_file('env/passwords', Mapping)
self.expect_passwords = {
re.compile(pattern, re.M): password
for pattern, password in iteritems(passwords)
Expand All @@ -318,7 +321,10 @@ def prepare_env(self):
self.expect_passwords[pexpect.EOF] = None

try:
self.settings = self.loader.load_file('env/settings', Mapping)
if 'ANSIBLE_RUNNER_SETTINGS' in os.environ:
self.settings = self.loader.load_env('ANSIBLE_RUNNER_SETTINGS', Mapping)
else:
self.settings = self.loader.load_file('env/settings', Mapping)
except ConfigurationError:
output.debug("Not loading settings")
self.settings = dict()
Expand All @@ -343,7 +349,10 @@ def prepare_env(self):
self.env.update(self.envvars)

try:
envvars = self.loader.load_file('env/envvars', Mapping)
if 'ANSIBLE_RUNNER_ENVVARS' in os.environ:
envvars = self.loader.load_env('ANSIBLE_RUNNER_ENVVARS', Mapping)
else:
envvars = self.loader.load_file('env/envvars', Mapping)
if envvars:
self.env.update({str(k):str(v) for k, v in envvars.items()})
except ConfigurationError:
Expand All @@ -352,7 +361,10 @@ def prepare_env(self):

try:
if self.ssh_key_data is None:
self.ssh_key_data = self.loader.load_file('env/ssh_key', string_types)
if 'ANSIBLE_RUNNER_SSH_KEY' in os.environ:
self.ssh_key_data = self.loader.load_env('ANSIBLE_RUNNER_SSH_KEY', Mapping)
else:
self.ssh_key_data = self.loader.load_file('env/ssh_key', string_types)
except ConfigurationError:
output.debug("Not loading ssh key")
self.ssh_key_data = None
Expand Down

0 comments on commit f36c662

Please sign in to comment.