Skip to content

Commit d8c8ae5

Browse files
committed
allow for environment driven env settings
expose ANSIBLE_RUNNER_{PASSWORDS,SETTINGS,ENVVARS,SSH_KEY} as an alternative means of driving ansible runner inputs vs serializing to file.
1 parent 1194519 commit d8c8ae5

File tree

2 files changed

+87
-13
lines changed

2 files changed

+87
-13
lines changed

ansible_runner/loader.py

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,24 +162,86 @@ def load_file(self, path, objtype=None, encoding='utf-8'):
162162

163163
try:
164164
debug('cache miss, attempting to load file from disk: %s' % path)
165-
contents = parsed_data = self.get_contents(path)
166-
if encoding:
167-
parsed_data = contents.encode(encoding)
165+
contents = self.get_contents(path)
168166
except ConfigurationError as exc:
169167
debug(exc)
170168
raise
171-
except UnicodeEncodeError:
172-
raise ConfigurationError('unable to encode file contents')
169+
170+
return self.deserialize(contents, objtype, encoding, key=path)
171+
172+
173+
def load_env(self, key, objtype=None, encoding='utf-8'):
174+
'''
175+
Load the object specified by env key
176+
177+
This method will try to load object contents from environment
178+
179+
Args:
180+
key (string): the key that contains the serialized data
181+
182+
encoding (string): The file contents text encoding
183+
184+
objtype (object): The object type of the file contents. This
185+
is used to type check the deserialized content against the
186+
contents loaded from disk.
187+
Ignore serializing if objtype is string_types
188+
189+
Returns:
190+
object: The deserialized file contents which could be either a
191+
string object or a dict object
192+
193+
Raises:
194+
ConfigurationError:
195+
'''
196+
try:
197+
debug('cache miss, attempting to key from env %s' % key)
198+
contents = os.environ[key]
199+
except KeyError as exc:
200+
debug(exc)
201+
raise ConfigurationError('key %s is not in environment' % key)
202+
203+
return self.deserialize(contents, objtype, encoding)
204+
205+
206+
def deserialize(self, data, objtype=None, encoding='utf-8', key=None):
207+
'''
208+
deserialize and type check data
209+
210+
Args:
211+
data (string): The possibly encoded data to be deserialized
212+
213+
key (string): if specified, a key to use to memoize/cache deserialized contents
214+
215+
encoding (string): The data text encoding
216+
217+
objtype (object): The object type of the deserialized data. This
218+
is used to type check the deserialized content is as expected.
219+
Ignore serializing if objtype is string_types
220+
221+
Returns:
222+
object: The deserialized data which could be either a
223+
string object or a dict object
224+
225+
Raises:
226+
ConfigurationError:
227+
'''
228+
parsed_data = data
229+
if encoding:
230+
try:
231+
parsed_data = data.encode(encoding)
232+
except UnicodeEncodeError:
233+
raise ConfigurationError('unable to encode file contents')
173234

174235
if objtype is not string_types:
175236
for deserializer in (self._load_json, self._load_yaml):
176-
parsed_data = deserializer(contents)
237+
parsed_data = deserializer(data)
177238
if parsed_data:
178239
break
179240

180241
if objtype and not isinstance(parsed_data, objtype):
181-
debug('specified file %s is not of type %s' % (path, objtype))
182-
raise ConfigurationError('invalid file serialization type for contents')
242+
debug('specified data %s is not of type %s' % (data, objtype))
243+
raise ConfigurationError('invalid file serialization type for data')
183244

184-
self._cache[path] = parsed_data
245+
if key:
246+
self._cache[key] = parsed_data
185247
return parsed_data

ansible_runner/runner_config.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,10 @@ def prepare_env(self):
306306
with existing values so the :py:class:`ansible_runner.runner.Runner` object can read and use them easily
307307
"""
308308
try:
309-
passwords = self.loader.load_file('env/passwords', Mapping)
309+
if 'ANSIBLE_RUNNER_PASSWORDS' in os.environ:
310+
passwords = self.loader.load_env('ANSIBLE_RUNNER_PASSWORDS', Mapping)
311+
else:
312+
passwords = self.loader.load_file('env/passwords', Mapping)
310313
self.expect_passwords = {
311314
re.compile(pattern, re.M): password
312315
for pattern, password in iteritems(passwords)
@@ -318,7 +321,10 @@ def prepare_env(self):
318321
self.expect_passwords[pexpect.EOF] = None
319322

320323
try:
321-
self.settings = self.loader.load_file('env/settings', Mapping)
324+
if 'ANSIBLE_RUNNER_SETTINGS' in os.environ:
325+
self.settings = self.loader.load_env('ANSIBLE_RUNNER_SETTINGS', Mapping)
326+
else:
327+
self.settings = self.loader.load_file('env/settings', Mapping)
322328
except ConfigurationError:
323329
output.debug("Not loading settings")
324330
self.settings = dict()
@@ -343,7 +349,10 @@ def prepare_env(self):
343349
self.env.update(self.envvars)
344350

345351
try:
346-
envvars = self.loader.load_file('env/envvars', Mapping)
352+
if 'ANSIBLE_RUNNER_ENVVARS' in os.environ:
353+
envvars = self.loader.load_env('ANSIBLE_RUNNER_ENVVARS', Mapping)
354+
else:
355+
envvars = self.loader.load_file('env/envvars', Mapping)
347356
if envvars:
348357
self.env.update({str(k):str(v) for k, v in envvars.items()})
349358
except ConfigurationError:
@@ -352,7 +361,10 @@ def prepare_env(self):
352361

353362
try:
354363
if self.ssh_key_data is None:
355-
self.ssh_key_data = self.loader.load_file('env/ssh_key', string_types)
364+
if 'ANSIBLE_RUNNER_SSH_KEY' in os.environ:
365+
self.ssh_key_data = self.loader.load_env('ANSIBLE_RUNNER_SSH_KEY', Mapping)
366+
else:
367+
self.ssh_key_data = self.loader.load_file('env/ssh_key', string_types)
356368
except ConfigurationError:
357369
output.debug("Not loading ssh key")
358370
self.ssh_key_data = None

0 commit comments

Comments
 (0)