diff --git a/ansible_runner/loader.py b/ansible_runner/loader.py index 4b6645e08..2648383e1 100644 --- a/ansible_runner/loader.py +++ b/ansible_runner/loader.py @@ -162,24 +162,86 @@ 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: + ''' + parsed_data = data + 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 diff --git a/ansible_runner/runner_config.py b/ansible_runner/runner_config.py index 0215e9433..1c67303bd 100644 --- a/ansible_runner/runner_config.py +++ b/ansible_runner/runner_config.py @@ -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) @@ -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() @@ -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: @@ -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