mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-25 05:23:58 -07:00 
			
		
		
		
	Moving over all lookup plugins to v2
This commit is contained in:
		
					parent
					
						
							
								45f8e6f3b0
							
						
					
				
			
			
				commit
				
					
						1544dde932
					
				
			
		
					 54 changed files with 1650 additions and 37 deletions
				
			
		|  | @ -60,6 +60,7 @@ class PlayState: | |||
|         (rescue/always) | ||||
|         ''' | ||||
| 
 | ||||
|         self._parent_iterator = parent_iterator | ||||
|         self._run_state       = ITERATING_SETUP | ||||
|         self._failed_state    = FAILED_NONE | ||||
|         self._task_list       = parent_iterator._play.compile() | ||||
|  | @ -104,6 +105,8 @@ class PlayState: | |||
|                     if self._gather_facts == 'smart' and not self._host.gathered_facts or boolean(self._gather_facts): | ||||
|                         self._host.set_gathered_facts(True) | ||||
|                         task = Task() | ||||
|                         # FIXME: this is not the best way to get this... | ||||
|                         task.set_loader(self._parent_iterator._play._loader) | ||||
|                         task.action = 'setup' | ||||
|                         break | ||||
|             elif run_state == ITERATING_TASKS: | ||||
|  |  | |||
|  | @ -97,9 +97,23 @@ class WorkerProcess(multiprocessing.Process): | |||
|             try: | ||||
|                 if not self._main_q.empty(): | ||||
|                     debug("there's work to be done!") | ||||
|                     (host, task, job_vars, connection_info) = self._main_q.get(block=False) | ||||
|                     (host, task, basedir, job_vars, connection_info) = self._main_q.get(block=False) | ||||
|                     debug("got a task/handler to work on: %s" % task) | ||||
| 
 | ||||
|                     # because the task queue manager starts workers (forks) before the | ||||
|                     # playbook is loaded, set the basedir of the loader inherted by | ||||
|                     # this fork now so that we can find files correctly | ||||
|                     self._loader.set_basedir(basedir) | ||||
| 
 | ||||
|                     # Serializing/deserializing tasks does not preserve the loader attribute, | ||||
|                     # since it is passed to the worker during the forking of the process and | ||||
|                     # would be wasteful to serialize. So we set it here on the task now, and | ||||
|                     # the task handles updating parent/child objects as needed. | ||||
|                     task.set_loader(self._loader) | ||||
| 
 | ||||
|                     # apply the given task's information to the connection info, | ||||
|                     # which may override some fields already set by the play or | ||||
|                     # the options specified on the command line | ||||
|                     new_connection_info = connection_info.set_task_override(task) | ||||
| 
 | ||||
|                     # execute the task and build a TaskResult from the result | ||||
|  |  | |||
|  | @ -58,7 +58,7 @@ class TaskExecutor: | |||
| 
 | ||||
|         try: | ||||
|             items = self._get_loop_items() | ||||
|             if items: | ||||
|             if items is not None: | ||||
|                 if len(items) > 0: | ||||
|                     item_results = self._run_loop(items) | ||||
|                     res = dict(results=item_results) | ||||
|  | @ -84,7 +84,7 @@ class TaskExecutor: | |||
| 
 | ||||
|         items = None | ||||
|         if self._task.loop and self._task.loop in lookup_loader: | ||||
|             items = lookup_loader.get(self._task.loop).run(terms=self._task.loop_args, variables=self._job_vars) | ||||
|             items = lookup_loader.get(self._task.loop, loader=self._loader).run(terms=self._task.loop_args, variables=self._job_vars) | ||||
| 
 | ||||
|         return items | ||||
| 
 | ||||
|  |  | |||
|  | @ -204,18 +204,3 @@ class DataLoader(): | |||
|         self.set_basedir(cur_basedir) | ||||
|         return source2 # which does not exist | ||||
| 
 | ||||
|     #def __getstate__(self): | ||||
|     #    data = dict( | ||||
|     #        basedir = self._basedir, | ||||
|     #        vault_password = self._vault_password, | ||||
|     #        FILE_CACHE = self._FILE_CACHE, | ||||
|     #    ) | ||||
|     #    return data | ||||
| 
 | ||||
|     #def __setstate__(self, data): | ||||
|     #    self._basedir = data.get('basedir', '.') | ||||
|     #    self._FILE_CACHE = data.get('FILE_CACHE', dict()) | ||||
|     #    self._vault_password = data.get('vault_password', '') | ||||
|     # | ||||
|     #    self._vault = VaultLib(password=self._vault_password) | ||||
|          | ||||
|  |  | |||
|  | @ -178,7 +178,7 @@ class Base: | |||
|         if self._loader is not None: | ||||
|             basedir = self._loader.get_basedir() | ||||
| 
 | ||||
|         templar = Templar(basedir=basedir, variables=all_vars, fail_on_undefined=fail_on_undefined) | ||||
|         templar = Templar(loader=self._loader, variables=all_vars, fail_on_undefined=fail_on_undefined) | ||||
| 
 | ||||
|         for (name, attribute) in iteritems(self._get_base_attributes()): | ||||
| 
 | ||||
|  |  | |||
|  | @ -162,3 +162,10 @@ class Block(Base, Conditional, Taggable): | |||
|                 return False | ||||
|         return super(Block, self).evaluate_tags(only_tags=only_tags, skip_tags=skip_tags) | ||||
| 
 | ||||
|     def set_loader(self, loader): | ||||
|         self._loader = loader | ||||
|         if self._parent_block: | ||||
|             self._parent_block.set_loader(loader) | ||||
|         elif self._role: | ||||
|             self._role.set_loader(loader) | ||||
| 
 | ||||
|  |  | |||
|  | @ -45,7 +45,7 @@ class Conditional: | |||
|         False if any of them evaluate as such. | ||||
|         ''' | ||||
| 
 | ||||
|         templar = Templar(variables=all_vars) | ||||
|         templar = Templar(loader=self._loader, variables=all_vars) | ||||
|         for conditional in self.when: | ||||
|             if not self._check_conditional(conditional, templar): | ||||
|                 return False | ||||
|  |  | |||
|  | @ -358,3 +358,10 @@ class Role(Base, Conditional, Taggable): | |||
| 
 | ||||
|         super(Role, self).deserialize(data) | ||||
| 
 | ||||
|     def set_loader(self, loader): | ||||
|         self._loader = loader | ||||
|         for parent in self._parents: | ||||
|             parent.set_loader(loader) | ||||
|         for dep in self.get_direct_dependencies(): | ||||
|             dep.set_loader(loader) | ||||
| 
 | ||||
|  |  | |||
|  | @ -200,7 +200,7 @@ class Task(Base, Conditional, Taggable): | |||
|         super(Task, self).post_validate(all_vars=all_vars, fail_on_undefined=fail_on_undefined) | ||||
| 
 | ||||
|     def _post_validate_loop_args(self, attr, value, all_vars, fail_on_undefined): | ||||
|         return listify_lookup_plugin_terms(value, all_vars) | ||||
|         return listify_lookup_plugin_terms(value, all_vars, loader=self._loader) | ||||
| 
 | ||||
|     def get_vars(self): | ||||
|         return self.serialize() | ||||
|  | @ -283,3 +283,18 @@ class Task(Base, Conditional, Taggable): | |||
|                 return False | ||||
|         return super(Task, self).evaluate_tags(only_tags=only_tags, skip_tags=skip_tags) | ||||
| 
 | ||||
| 
 | ||||
|     def set_loader(self, loader): | ||||
|         ''' | ||||
|         Sets the loader on this object and recursively on parent, child objects. | ||||
|         This is used primarily after the Task has been serialized/deserialized, which | ||||
|         does not preserve the loader. | ||||
|         ''' | ||||
| 
 | ||||
|         self._loader = loader | ||||
| 
 | ||||
|         if self._block: | ||||
|             self._block.set_loader(loader) | ||||
| 
 | ||||
|         for dep in self._dep_chain: | ||||
|             dep.set_loader(loader) | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ class ActionModule(ActionBase): | |||
|                 result = dict(msg=self._task.args['msg']) | ||||
|         # FIXME: move the LOOKUP_REGEX somewhere else | ||||
|         elif 'var' in self._task.args: # and not utils.LOOKUP_REGEX.search(self._task.args['var']): | ||||
|             templar = Templar(variables=task_vars) | ||||
|             templar = Templar(loader=self._loader, variables=task_vars) | ||||
|             results = templar.template(self._task.args['var'], convert_bare=True) | ||||
|             result = dict() | ||||
|             result[self._task.args['var']] = results | ||||
|  |  | |||
|  | @ -77,7 +77,7 @@ class ActionModule(ActionBase): | |||
|             dest = os.path.join(dest, base) | ||||
| 
 | ||||
|         # template the source data locally & get ready to transfer | ||||
|         templar = Templar(basedir=self._loader.get_basedir(), variables=task_vars) | ||||
|         templar = Templar(loader=self._loader, variables=task_vars) | ||||
|         try: | ||||
|             with open(source, 'r') as f: | ||||
|                 template_data = f.read() | ||||
|  |  | |||
|  | @ -22,8 +22,8 @@ __metaclass__ = type | |||
| __all__ = ['LookupBase'] | ||||
| 
 | ||||
| class LookupBase: | ||||
|     def __init__(self, **kwargs): | ||||
|         pass | ||||
|     def __init__(self, loader=None, **kwargs): | ||||
|         self._loader = loader | ||||
| 
 | ||||
|     def _flatten(self, terms): | ||||
|         ret = [] | ||||
|  | @ -41,3 +41,9 @@ class LookupBase: | |||
|                 results.append(self._flatten([x,y])) | ||||
|         return results | ||||
| 
 | ||||
|     def _flatten_hash_to_list(self, terms): | ||||
|         ret = [] | ||||
|         for key in terms: | ||||
|             ret.append({'key': key, 'value': terms[key]}) | ||||
|         return ret | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										79
									
								
								v2/ansible/plugins/lookup/csvfile.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								v2/ansible/plugins/lookup/csvfile.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,79 @@ | |||
| # (c) 2013, Jan-Piet Mens <jpmens(at)gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| import codecs | ||||
| import csv | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def read_csv(self, filename, key, delimiter, dflt=None, col=1): | ||||
| 
 | ||||
|         try: | ||||
|             f = codecs.open(filename, 'r', encoding='utf-8') | ||||
|             creader = csv.reader(f, delimiter=delimiter) | ||||
| 
 | ||||
|             for row in creader: | ||||
|                 if row[0] == key: | ||||
|                     return row[int(col)] | ||||
|         except Exception, e: | ||||
|             raise AnsibleError("csvfile: %s" % str(e)) | ||||
| 
 | ||||
|         return dflt | ||||
| 
 | ||||
|     def run(self, terms, variables=None, **kwargs): | ||||
| 
 | ||||
|         if isinstance(terms, basestring): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             params = term.split() | ||||
|             key = params[0] | ||||
| 
 | ||||
|             paramvals = { | ||||
|                 'file' : 'ansible.csv', | ||||
|                 'default' : None, | ||||
|                 'delimiter' : "TAB", | ||||
|                 'col' : "1",          # column to return | ||||
|             } | ||||
| 
 | ||||
|             # parameters specified? | ||||
|             try: | ||||
|                 for param in params[1:]: | ||||
|                     name, value = param.split('=') | ||||
|                     assert(name in paramvals) | ||||
|                     paramvals[name] = value | ||||
|             except (ValueError, AssertionError), e: | ||||
|                 raise AnsibleError(e) | ||||
| 
 | ||||
|             if paramvals['delimiter'] == 'TAB': | ||||
|                 paramvals['delimiter'] = "\t" | ||||
| 
 | ||||
|             path = self._loader.path_dwim(paramvals['file']) | ||||
| 
 | ||||
|             var = self.read_csv(path, key, paramvals['delimiter'], paramvals['default'], paramvals['col']) | ||||
|             if var is not None: | ||||
|                 if type(var) is list: | ||||
|                     for v in var: | ||||
|                         ret.append(v) | ||||
|                 else: | ||||
|                     ret.append(var) | ||||
|         return ret | ||||
							
								
								
									
										27
									
								
								v2/ansible/plugins/lookup/dict.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								v2/ansible/plugins/lookup/dict.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| # (c) 2014, Kent R. Spillner <kspillner@acm.org> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, varibles=None, **kwargs): | ||||
| 
 | ||||
|         if not isinstance(terms, dict): | ||||
|             raise errors.AnsibleError("with_dict expects a dict") | ||||
| 
 | ||||
|         return self._flatten_hash_to_list(terms) | ||||
							
								
								
									
										68
									
								
								v2/ansible/plugins/lookup/dnstxt.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								v2/ansible/plugins/lookup/dnstxt.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,68 @@ | |||
| # (c) 2012, Jan-Piet Mens <jpmens(at)gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| HAVE_DNS=False | ||||
| try: | ||||
|     import dns.resolver | ||||
|     from dns.exception import DNSException | ||||
|     HAVE_DNS=True | ||||
| except ImportError: | ||||
|     pass | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| # ============================================================== | ||||
| # DNSTXT: DNS TXT records | ||||
| # | ||||
| #       key=domainname | ||||
| # TODO: configurable resolver IPs | ||||
| # -------------------------------------------------------------- | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables=None, **kwargs): | ||||
| 
 | ||||
|         if HAVE_DNS == False: | ||||
|             raise AnsibleError("Can't LOOKUP(dnstxt): module dns.resolver is not installed") | ||||
| 
 | ||||
|         if isinstance(terms, basestring): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             domain = term.split()[0] | ||||
|             string = [] | ||||
|             try: | ||||
|                 answers = dns.resolver.query(domain, 'TXT') | ||||
|                 for rdata in answers: | ||||
|                     s = rdata.to_text() | ||||
|                     string.append(s[1:-1])  # Strip outside quotes on TXT rdata | ||||
| 
 | ||||
|             except dns.resolver.NXDOMAIN: | ||||
|                 string = 'NXDOMAIN' | ||||
|             except dns.resolver.Timeout: | ||||
|                 string = '' | ||||
|             except dns.exception.DNSException, e: | ||||
|                 raise AnsibleError("dns.resolver unhandled exception", e) | ||||
| 
 | ||||
|             ret.append(''.join(string)) | ||||
| 
 | ||||
|         return ret | ||||
| 
 | ||||
							
								
								
									
										34
									
								
								v2/ansible/plugins/lookup/env.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								v2/ansible/plugins/lookup/env.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| # (c) 2012, Jan-Piet Mens <jpmens(at)gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         if isinstance(terms, basestring): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             var = term.split()[0] | ||||
|             ret.append(os.getenv(var, '')) | ||||
| 
 | ||||
|         return ret | ||||
							
								
								
									
										75
									
								
								v2/ansible/plugins/lookup/etcd.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								v2/ansible/plugins/lookup/etcd.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,75 @@ | |||
| # (c) 2013, Jan-Piet Mens <jpmens(at)gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| import urllib2 | ||||
| try: | ||||
|     import json | ||||
| except ImportError: | ||||
|     import simplejson as json | ||||
| 
 | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| # this can be made configurable, not should not use ansible.cfg | ||||
| ANSIBLE_ETCD_URL = 'http://127.0.0.1:4001' | ||||
| if os.getenv('ANSIBLE_ETCD_URL') is not None: | ||||
|     ANSIBLE_ETCD_URL = os.environ['ANSIBLE_ETCD_URL'] | ||||
| 
 | ||||
| class etcd(): | ||||
|     def __init__(self, url=ANSIBLE_ETCD_URL): | ||||
|         self.url = url | ||||
|         self.baseurl = '%s/v1/keys' % (self.url) | ||||
| 
 | ||||
|     def get(self, key): | ||||
|         url = "%s/%s" % (self.baseurl, key) | ||||
| 
 | ||||
|         data = None | ||||
|         value = "" | ||||
|         try: | ||||
|             r = urllib2.urlopen(url) | ||||
|             data = r.read() | ||||
|         except: | ||||
|             return value | ||||
| 
 | ||||
|         try: | ||||
|             # {"action":"get","key":"/name","value":"Jane Jolie","index":5} | ||||
|             item = json.loads(data) | ||||
|             if 'value' in item: | ||||
|                 value = item['value'] | ||||
|             if 'errorCode' in item: | ||||
|                 value = "ENOENT" | ||||
|         except: | ||||
|             raise | ||||
|             pass | ||||
| 
 | ||||
|         return value | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         if isinstance(terms, basestring): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         etcd = etcd() | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             key = term.split()[0] | ||||
|             value = etcd.get(key) | ||||
|             ret.append(value) | ||||
|         return ret | ||||
							
								
								
									
										58
									
								
								v2/ansible/plugins/lookup/file.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								v2/ansible/plugins/lookup/file.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| # (c) 2012, Daniel Hokka Zakrisson <daniel@hozac.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| import codecs | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables=None, **kwargs): | ||||
| 
 | ||||
|         if not isinstance(terms, list): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             basedir_path  = self._loader.path_dwim(term) | ||||
|             relative_path = None | ||||
|             playbook_path = None | ||||
| 
 | ||||
|             # Special handling of the file lookup, used primarily when the | ||||
|             # lookup is done from a role. If the file isn't found in the | ||||
|             # basedir of the current file, use dwim_relative to look in the | ||||
|             # role/files/ directory, and finally the playbook directory | ||||
|             # itself (which will be relative to the current working dir) | ||||
| 
 | ||||
|             # FIXME: the original file stuff still needs to be worked out, but the | ||||
|             #        playbook_dir stuff should be able to be removed as it should | ||||
|             #        be covered by the fact that the loader contains that info | ||||
|             #if '_original_file' in variables: | ||||
|             #    relative_path = self._loader.path_dwim_relative(variables['_original_file'], 'files', term, self.basedir, check=False) | ||||
|             #if 'playbook_dir' in variables: | ||||
|             #    playbook_path = os.path.join(variables['playbook_dir'], term) | ||||
| 
 | ||||
|             for path in (basedir_path, relative_path, playbook_path): | ||||
|                 if path and os.path.exists(path): | ||||
|                     ret.append(codecs.open(path, encoding="utf8").read().rstrip()) | ||||
|                     break | ||||
|             else: | ||||
|                 raise AnsibleError("could not locate file in lookup: %s" % term) | ||||
| 
 | ||||
|         return ret | ||||
							
								
								
									
										32
									
								
								v2/ansible/plugins/lookup/fileglob.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								v2/ansible/plugins/lookup/fileglob.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| import glob | ||||
| 
 | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables=None, **kwargs): | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             dwimmed = self._loader.path_dwim(term) | ||||
|             globbed = glob.glob(dwimmed) | ||||
|             ret.extend(g for g in globbed if os.path.isfile(g)) | ||||
|         return ret | ||||
							
								
								
									
										191
									
								
								v2/ansible/plugins/lookup/first_found.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								v2/ansible/plugins/lookup/first_found.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,191 @@ | |||
| # (c) 2013, seth vidal <skvidal@fedoraproject.org> red hat, inc | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| # take a list of files and (optionally) a list of paths | ||||
| # return the first existing file found in the paths | ||||
| # [file1, file2, file3], [path1, path2, path3] | ||||
| # search order is: | ||||
| # path1/file1 | ||||
| # path1/file2 | ||||
| # path1/file3 | ||||
| # path2/file1 | ||||
| # path2/file2 | ||||
| # path2/file3 | ||||
| # path3/file1 | ||||
| # path3/file2 | ||||
| # path3/file3 | ||||
| 
 | ||||
| # first file found with os.path.exists() is returned | ||||
| # no file matches raises ansibleerror | ||||
| # EXAMPLES | ||||
| #  - name: copy first existing file found to /some/file | ||||
| #    action: copy src=$item dest=/some/file | ||||
| #    with_first_found:  | ||||
| #     - files: foo ${inventory_hostname} bar | ||||
| #       paths: /tmp/production /tmp/staging | ||||
| 
 | ||||
| # that will look for files in this order: | ||||
| # /tmp/production/foo | ||||
| #                 ${inventory_hostname} | ||||
| #                 bar | ||||
| # /tmp/staging/foo | ||||
| #              ${inventory_hostname} | ||||
| #              bar | ||||
|                    | ||||
| #  - name: copy first existing file found to /some/file | ||||
| #    action: copy src=$item dest=/some/file | ||||
| #    with_first_found:  | ||||
| #     - files: /some/place/foo ${inventory_hostname} /some/place/else | ||||
| 
 | ||||
| #  that will look for files in this order: | ||||
| #  /some/place/foo | ||||
| #  $relative_path/${inventory_hostname} | ||||
| #  /some/place/else | ||||
| 
 | ||||
| # example - including tasks: | ||||
| #  tasks: | ||||
| #  - include: $item | ||||
| #    with_first_found: | ||||
| #     - files: generic | ||||
| #       paths: tasks/staging tasks/production | ||||
| # this will include the tasks in the file generic where it is found first (staging or production) | ||||
| 
 | ||||
| # example simple file lists | ||||
| #tasks: | ||||
| #- name: first found file | ||||
| #  action: copy src=$item dest=/etc/file.cfg | ||||
| #  with_first_found: | ||||
| #  - files: foo.${inventory_hostname} foo | ||||
| 
 | ||||
| 
 | ||||
| # example skipping if no matched files | ||||
| # First_found also offers the ability to control whether or not failing | ||||
| # to find a file returns an error or not | ||||
| # | ||||
| #- name: first found file - or skip | ||||
| #  action: copy src=$item dest=/etc/file.cfg | ||||
| #  with_first_found: | ||||
| #  - files: foo.${inventory_hostname} | ||||
| #    skip: true | ||||
| 
 | ||||
| # example a role with default configuration and configuration per host | ||||
| # you can set multiple terms with their own files and paths to look through. | ||||
| # consider a role that sets some configuration per host falling back on a default config. | ||||
| # | ||||
| #- name: some configuration template | ||||
| #  template: src={{ item }} dest=/etc/file.cfg mode=0444 owner=root group=root | ||||
| #  with_first_found: | ||||
| #   - files: | ||||
| #      - ${inventory_hostname}/etc/file.cfg | ||||
| #     paths: | ||||
| #      - ../../../templates.overwrites | ||||
| #      - ../../../templates | ||||
| #   - files: | ||||
| #      - etc/file.cfg | ||||
| #     paths: | ||||
| #      - templates | ||||
| 
 | ||||
| # the above will return an empty list if the files cannot be found at all | ||||
| # if skip is unspecificed or if it is set to false then it will return a list  | ||||
| # error which can be caught bye ignore_errors: true for that action. | ||||
| 
 | ||||
| # finally - if you want you can use it, in place to replace first_available_file: | ||||
| # you simply cannot use the - files, path or skip options. simply replace | ||||
| # first_available_file with with_first_found and leave the file listing in place | ||||
| # | ||||
| # | ||||
| #  - name: with_first_found like first_available_file | ||||
| #    action: copy src=$item dest=/tmp/faftest | ||||
| #    with_first_found: | ||||
| #     - ../files/foo | ||||
| #     - ../files/bar | ||||
| #     - ../files/baz | ||||
| #    ignore_errors: true | ||||
| 
 | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         result = None | ||||
|         anydict = False | ||||
|         skip = False | ||||
| 
 | ||||
|         for term in terms: | ||||
|             if isinstance(term, dict): | ||||
|                 anydict = True | ||||
| 
 | ||||
|         total_search = [] | ||||
|         if anydict: | ||||
|             for term in terms: | ||||
|                 if isinstance(term, dict): | ||||
|                     files = term.get('files', []) | ||||
|                     paths = term.get('paths', []) | ||||
|                     skip  = boolean(term.get('skip', False)) | ||||
| 
 | ||||
|                     filelist = files | ||||
|                     if isinstance(files, basestring): | ||||
|                         files = files.replace(',', ' ') | ||||
|                         files = files.replace(';', ' ') | ||||
|                         filelist = files.split(' ') | ||||
| 
 | ||||
|                     pathlist = paths | ||||
|                     if paths: | ||||
|                         if isinstance(paths, basestring): | ||||
|                             paths = paths.replace(',', ' ') | ||||
|                             paths = paths.replace(':', ' ') | ||||
|                             paths = paths.replace(';', ' ') | ||||
|                             pathlist = paths.split(' ') | ||||
| 
 | ||||
|                     if not pathlist: | ||||
|                         total_search = filelist | ||||
|                     else: | ||||
|                         for path in pathlist: | ||||
|                             for fn in filelist: | ||||
|                                 f = os.path.join(path, fn) | ||||
|                                 total_search.append(f) | ||||
|                 else: | ||||
|                     total_search.append(term) | ||||
|         else: | ||||
|             total_search = terms | ||||
| 
 | ||||
|         for fn in total_search: | ||||
|             # FIXME: the original file stuff needs to be fixed/implemented | ||||
|             #if variables and '_original_file' in variables: | ||||
|             #    # check the templates and vars directories too, | ||||
|             #    # if they exist | ||||
|             #    for roledir in ('templates', 'vars'): | ||||
|             #        path = self._loader.path_dwim(os.path.join(self.basedir, '..', roledir), fn) | ||||
|             #        if os.path.exists(path): | ||||
|             #            return [path] | ||||
| 
 | ||||
|             # if none of the above were found, just check the | ||||
|             # current filename against the basedir (this will already | ||||
|             # have ../files from runner, if it's a role task | ||||
|             path = self._loader.path_dwim(fn) | ||||
|             if os.path.exists(path): | ||||
|                 return [path] | ||||
|         else: | ||||
|             if skip: | ||||
|                 return [] | ||||
|             else: | ||||
|                 return [None] | ||||
| 
 | ||||
							
								
								
									
										69
									
								
								v2/ansible/plugins/lookup/flattened.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								v2/ansible/plugins/lookup/flattened.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | |||
| # (c) 2013, Serge van Ginderachter <serge@vanginderachter.be> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| from ansible.utils.listify import listify_lookup_plugin_terms | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def _check_list_of_one_list(self, term): | ||||
|         # make sure term is not a list of one (list of one..) item | ||||
|         # return the final non list item if so | ||||
| 
 | ||||
|         if isinstance(term,list) and len(term) == 1: | ||||
|             term = term[0] | ||||
|             if isinstance(term,list): | ||||
|                 term = self._check_list_of_one_list(term) | ||||
| 
 | ||||
|         return term | ||||
| 
 | ||||
|     def _do_flatten(self, terms, variables): | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             term = self._check_list_of_one_list(term) | ||||
| 
 | ||||
|             if term == 'None' or term == 'null': | ||||
|                 # ignore undefined items | ||||
|                 break | ||||
| 
 | ||||
|             if isinstance(term, basestring): | ||||
|                 # convert a variable to a list | ||||
|                 term2 = listify_lookup_plugin_terms(term, variables, loader=self._loader) | ||||
|                 # but avoid converting a plain string to a list of one string | ||||
|                 if term2 != [ term ]: | ||||
|                     term = term2 | ||||
| 
 | ||||
|             if isinstance(term, list): | ||||
|                 # if it's a list, check recursively for items that are a list | ||||
|                 term = self._do_flatten(term, variables) | ||||
|                 ret.extend(term) | ||||
|             else: | ||||
|                 ret.append(term) | ||||
| 
 | ||||
|         return ret | ||||
| 
 | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         if not isinstance(terms, list): | ||||
|             raise AnsibleError("with_flattened expects a list") | ||||
| 
 | ||||
|         return self._do_flatten(terms, variables) | ||||
| 
 | ||||
							
								
								
									
										32
									
								
								v2/ansible/plugins/lookup/indexed_items.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								v2/ansible/plugins/lookup/indexed_items.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def __init__(self, basedir=None, **kwargs): | ||||
|         self.basedir = basedir | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         if not isinstance(terms, list): | ||||
|             raise errors.AnsibleError("with_indexed_items expects a list") | ||||
| 
 | ||||
|         items = self._flatten(terms) | ||||
|         return zip(range(len(items)), items) | ||||
| 
 | ||||
							
								
								
									
										34
									
								
								v2/ansible/plugins/lookup/inventory_hostnames.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								v2/ansible/plugins/lookup/inventory_hostnames.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com> | ||||
| # (c) 2013, Steven Dossett <sdossett@panath.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, inject=None, **kwargs): | ||||
|         if not isinstance(terms, list): | ||||
|             raise AnsibleError("with_inventory_hostnames expects a list") | ||||
| 
 | ||||
|         # FIXME: the inventory is no longer available this way, so we may have | ||||
|         #        to dump the host list into the list of variables and read it back | ||||
|         #        in here (or the inventory sources, so we can recreate the list | ||||
|         #        of hosts) | ||||
|         #return self._flatten(inventory.Inventory(self.host_list).list_hosts(terms)) | ||||
|         return terms | ||||
| 
 | ||||
							
								
								
									
										35
									
								
								v2/ansible/plugins/lookup/lines.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								v2/ansible/plugins/lookup/lines.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| # (c) 2012, Daniel Hokka Zakrisson <daniel@hozac.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import subprocess | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             p = subprocess.Popen(term, cwd=self._loader.get_basedir(), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) | ||||
|             (stdout, stderr) = p.communicate() | ||||
|             if p.returncode == 0: | ||||
|                 ret.extend(stdout.splitlines()) | ||||
|             else: | ||||
|                 raise AnsibleError("lookup_plugin.lines(%s) returned %d" % (term, p.returncode)) | ||||
|         return ret | ||||
|  | @ -24,7 +24,7 @@ class LookupModule(LookupBase): | |||
|     def __lookup_variabless(self, terms, variables): | ||||
|         results = [] | ||||
|         for x in terms: | ||||
|             intermediate = listify_lookup_plugin_terms(x, variables) | ||||
|             intermediate = listify_lookup_plugin_terms(x, variables, loader=self._loader) | ||||
|             results.append(intermediate) | ||||
|         return results | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										146
									
								
								v2/ansible/plugins/lookup/password.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								v2/ansible/plugins/lookup/password.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,146 @@ | |||
| # (c) 2012, Daniel Hokka Zakrisson <daniel@hozac.com> | ||||
| # (c) 2013, Javier Candeira <javier@candeira.com> | ||||
| # (c) 2013, Maykel Moya <mmoya@speedyrails.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| import errno | ||||
| import string | ||||
| import random | ||||
| 
 | ||||
| from string import ascii_letters, digits | ||||
| 
 | ||||
| from ansible import constants as C | ||||
| from ansible.errors import AnsibleError | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| from ansible.utils.encrypt import do_encrypt | ||||
| 
 | ||||
| DEFAULT_LENGTH = 20 | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def random_password(self, length=DEFAULT_LENGTH, chars=C.DEFAULT_PASSWORD_CHARS): | ||||
|         ''' | ||||
|         Return a random password string of length containing only chars. | ||||
|         NOTE: this was moved from the old ansible utils code, as nothing | ||||
|               else appeared to use it. | ||||
|         ''' | ||||
| 
 | ||||
|         password = [] | ||||
|         while len(password) < length: | ||||
|             new_char = os.urandom(1) | ||||
|             if new_char in chars: | ||||
|                 password.append(new_char) | ||||
| 
 | ||||
|         return ''.join(password) | ||||
| 
 | ||||
|     def random_salt(self): | ||||
|         salt_chars = ascii_letters + digits + './' | ||||
|         return self.random_password(length=8, chars=salt_chars) | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         ret = [] | ||||
| 
 | ||||
|         if not isinstance(terms, list): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         for term in terms: | ||||
|             # you can't have escaped spaces in yor pathname | ||||
|             params = term.split() | ||||
|             relpath = params[0] | ||||
| 
 | ||||
|             paramvals = { | ||||
|                 'length': DEFAULT_LENGTH, | ||||
|                 'encrypt': None, | ||||
|                 'chars': ['ascii_letters','digits',".,:-_"], | ||||
|             } | ||||
| 
 | ||||
|             # get non-default parameters if specified | ||||
|             try: | ||||
|                 for param in params[1:]: | ||||
|                     name, value = param.split('=') | ||||
|                     assert(name in paramvals) | ||||
|                     if name == 'length': | ||||
|                         paramvals[name] = int(value) | ||||
|                     elif name == 'chars': | ||||
|                         use_chars=[] | ||||
|                         if ",," in value:  | ||||
|                             use_chars.append(',') | ||||
|                         use_chars.extend(value.replace(',,',',').split(',')) | ||||
|                         paramvals['chars'] = use_chars | ||||
|                     else: | ||||
|                         paramvals[name] = value | ||||
|             except (ValueError, AssertionError), e: | ||||
|                 raise AnsibleError(e) | ||||
| 
 | ||||
|             length  = paramvals['length'] | ||||
|             encrypt = paramvals['encrypt'] | ||||
|             use_chars = paramvals['chars'] | ||||
| 
 | ||||
|             # get password or create it if file doesn't exist | ||||
|             path = self._loader.path_dwim(relpath) | ||||
|             if not os.path.exists(path): | ||||
|                 pathdir = os.path.dirname(path) | ||||
|                 if not os.path.isdir(pathdir): | ||||
|                     try: | ||||
|                         os.makedirs(pathdir, mode=0700) | ||||
|                     except OSError, e: | ||||
|                         raise AnsibleError("cannot create the path for the password lookup: %s (error was %s)" % (pathdir, str(e))) | ||||
| 
 | ||||
|                 chars = "".join([getattr(string,c,c) for c in use_chars]).replace('"','').replace("'",'') | ||||
|                 password = ''.join(random.choice(chars) for _ in range(length)) | ||||
| 
 | ||||
|                 if encrypt is not None: | ||||
|                     salt = self.random_salt() | ||||
|                     content = '%s salt=%s' % (password, salt) | ||||
|                 else: | ||||
|                     content = password | ||||
|                 with open(path, 'w') as f: | ||||
|                     os.chmod(path, 0600) | ||||
|                     f.write(content + '\n') | ||||
|             else: | ||||
|                 content = open(path).read().rstrip() | ||||
|                 sep = content.find(' ') | ||||
| 
 | ||||
|                 if sep >= 0: | ||||
|                     password = content[:sep] | ||||
|                     salt = content[sep+1:].split('=')[1] | ||||
|                 else: | ||||
|                     password = content | ||||
|                     salt = None | ||||
| 
 | ||||
|                 # crypt requested, add salt if missing | ||||
|                 if (encrypt is not None and not salt): | ||||
|                     salt = self.random_salt() | ||||
|                     content = '%s salt=%s' % (password, salt) | ||||
|                     with open(path, 'w') as f: | ||||
|                         os.chmod(path, 0600) | ||||
|                         f.write(content + '\n') | ||||
|                 # crypt not requested, remove salt if present | ||||
|                 elif (encrypt is None and salt): | ||||
|                     with open(path, 'w') as f: | ||||
|                         os.chmod(path, 0600) | ||||
|                         f.write(password + '\n') | ||||
| 
 | ||||
|             if encrypt: | ||||
|                 password = do_encrypt(password, encrypt, salt=salt) | ||||
| 
 | ||||
|             ret.append(password) | ||||
| 
 | ||||
|         return ret | ||||
| 
 | ||||
							
								
								
									
										49
									
								
								v2/ansible/plugins/lookup/pipe.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								v2/ansible/plugins/lookup/pipe.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| # (c) 2012, Daniel Hokka Zakrisson <daniel@hozac.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import subprocess | ||||
| 
 | ||||
| from ansible.errors import AnsibleError | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         if isinstance(terms, basestring): | ||||
|             terms = [ terms ]  | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             ''' | ||||
|             http://docs.python.org/2/library/subprocess.html#popen-constructor | ||||
| 
 | ||||
|             The shell argument (which defaults to False) specifies whether to use the  | ||||
|             shell as the program to execute. If shell is True, it is recommended to pass  | ||||
|             args as a string rather than as a sequence | ||||
| 
 | ||||
|             https://github.com/ansible/ansible/issues/6550 | ||||
|             ''' | ||||
|             term = str(term) | ||||
| 
 | ||||
|             p = subprocess.Popen(term, cwd=self._loader.get_basedir(), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) | ||||
|             (stdout, stderr) = p.communicate() | ||||
|             if p.returncode == 0: | ||||
|                 ret.append(stdout.decode("utf-8").rstrip()) | ||||
|             else: | ||||
|                 raise AnsibleError("lookup_plugin.pipe(%s) returned %d" % (term, p.returncode)) | ||||
|         return ret | ||||
							
								
								
									
										37
									
								
								v2/ansible/plugins/lookup/random_choice.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								v2/ansible/plugins/lookup/random_choice.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| # (c) 2013, Michael DeHaan <michael.dehaan@gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import random | ||||
| 
 | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| # useful for introducing chaos ... or just somewhat reasonably fair selection | ||||
| # amongst available mirrors | ||||
| # | ||||
| #    tasks: | ||||
| #        - debug: msg=$item | ||||
| #          with_random_choice: | ||||
| #             - one | ||||
| #             - two  | ||||
| #             - three | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, inject=None, **kwargs): | ||||
| 
 | ||||
|         return [ random.choice(terms) ] | ||||
| 
 | ||||
							
								
								
									
										73
									
								
								v2/ansible/plugins/lookup/redis_kv.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								v2/ansible/plugins/lookup/redis_kv.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| # (c) 2012, Jan-Piet Mens <jpmens(at)gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| import re | ||||
| 
 | ||||
| HAVE_REDIS=False | ||||
| try: | ||||
|     import redis        # https://github.com/andymccurdy/redis-py/ | ||||
|     HAVE_REDIS=True | ||||
| except ImportError: | ||||
|     pass | ||||
| 
 | ||||
| from ansible.errors import AnsibleError | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| # ============================================================== | ||||
| # REDISGET: Obtain value from a GET on a Redis key. Terms | ||||
| # expected: 0 = URL, 1 = Key | ||||
| # URL may be empty, in which case redis://localhost:6379 assumed | ||||
| # -------------------------------------------------------------- | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         if not HAVE_REDIS: | ||||
|             raise AnsibleError("Can't LOOKUP(redis_kv): module redis is not installed") | ||||
| 
 | ||||
|         if not isinstance(terms, list): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             (url,key) = term.split(',') | ||||
|             if url == "": | ||||
|                 url = 'redis://localhost:6379' | ||||
| 
 | ||||
|             # urlsplit on Python 2.6.1 is broken. Hmm. Probably also the reason | ||||
|             # Redis' from_url() doesn't work here. | ||||
| 
 | ||||
|             p = '(?P<scheme>[^:]+)://?(?P<host>[^:/ ]+).?(?P<port>[0-9]*).*' | ||||
| 
 | ||||
|             try: | ||||
|                 m = re.search(p, url) | ||||
|                 host = m.group('host') | ||||
|                 port = int(m.group('port')) | ||||
|             except AttributeError: | ||||
|                 raise AnsibleError("Bad URI in redis lookup") | ||||
| 
 | ||||
|             try: | ||||
|                 conn = redis.Redis(host=host, port=port) | ||||
|                 res = conn.get(key) | ||||
|                 if res is None: | ||||
|                     res = "" | ||||
|                 ret.append(res) | ||||
|             except: | ||||
|                 ret.append("")  # connection failed or key not found | ||||
|         return ret | ||||
							
								
								
									
										197
									
								
								v2/ansible/plugins/lookup/sequence.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								v2/ansible/plugins/lookup/sequence.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,197 @@ | |||
| # (c) 2013, Jayson Vantuyl <jayson@aggressive.ly> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| from re import compile as re_compile, IGNORECASE | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.parsing.splitter import parse_kv | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| 
 | ||||
| # shortcut format | ||||
| NUM = "(0?x?[0-9a-f]+)" | ||||
| SHORTCUT = re_compile( | ||||
|     "^(" +        # Group 0 | ||||
|     NUM +         # Group 1: Start | ||||
|     "-)?" + | ||||
|     NUM +         # Group 2: End | ||||
|     "(/" +        # Group 3 | ||||
|     NUM +         # Group 4: Stride | ||||
|     ")?" + | ||||
|     "(:(.+))?$",  # Group 5, Group 6: Format String | ||||
|     IGNORECASE | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
|     """ | ||||
|     sequence lookup module | ||||
| 
 | ||||
|     Used to generate some sequence of items. Takes arguments in two forms. | ||||
| 
 | ||||
|     The simple / shortcut form is: | ||||
| 
 | ||||
|       [start-]end[/stride][:format] | ||||
| 
 | ||||
|     As indicated by the brackets: start, stride, and format string are all | ||||
|     optional.  The format string is in the style of printf.  This can be used | ||||
|     to pad with zeros, format in hexadecimal, etc.  All of the numerical values | ||||
|     can be specified in octal (i.e. 0664) or hexadecimal (i.e. 0x3f8). | ||||
|     Negative numbers are not supported. | ||||
| 
 | ||||
|     Some examples: | ||||
| 
 | ||||
|       5 -> ["1","2","3","4","5"] | ||||
|       5-8 -> ["5", "6", "7", "8"] | ||||
|       2-10/2 -> ["2", "4", "6", "8", "10"] | ||||
|       4:host%02d -> ["host01","host02","host03","host04"] | ||||
| 
 | ||||
|     The standard Ansible key-value form is accepted as well.  For example: | ||||
| 
 | ||||
|       start=5 end=11 stride=2 format=0x%02x -> ["0x05","0x07","0x09","0x0a"] | ||||
| 
 | ||||
|     This format takes an alternate form of "end" called "count", which counts | ||||
|     some number from the starting value.  For example: | ||||
| 
 | ||||
|       count=5 -> ["1", "2", "3", "4", "5"] | ||||
|       start=0x0f00 count=4 format=%04x -> ["0f00", "0f01", "0f02", "0f03"] | ||||
|       start=0 count=5 stride=2 -> ["0", "2", "4", "6", "8"] | ||||
|       start=1 count=5 stride=2 -> ["1", "3", "5", "7", "9"] | ||||
| 
 | ||||
|     The count option is mostly useful for avoiding off-by-one errors and errors | ||||
|     calculating the number of entries in a sequence when a stride is specified. | ||||
|     """ | ||||
| 
 | ||||
|     def reset(self): | ||||
|         """set sensible defaults""" | ||||
|         self.start = 1 | ||||
|         self.count = None | ||||
|         self.end = None | ||||
|         self.stride = 1 | ||||
|         self.format = "%d" | ||||
| 
 | ||||
|     def parse_kv_args(self, args): | ||||
|         """parse key-value style arguments""" | ||||
|         for arg in ["start", "end", "count", "stride"]: | ||||
|             try: | ||||
|                 arg_raw = args.pop(arg, None) | ||||
|                 if arg_raw is None: | ||||
|                     continue | ||||
|                 arg_cooked = int(arg_raw, 0) | ||||
|                 setattr(self, arg, arg_cooked) | ||||
|             except ValueError: | ||||
|                 raise AnsibleError( | ||||
|                     "can't parse arg %s=%r as integer" | ||||
|                         % (arg, arg_raw) | ||||
|                 ) | ||||
|             if 'format' in args: | ||||
|                 self.format = args.pop("format") | ||||
|         if args: | ||||
|             raise AnsibleError( | ||||
|                 "unrecognized arguments to with_sequence: %r" | ||||
|                 % args.keys() | ||||
|             ) | ||||
| 
 | ||||
|     def parse_simple_args(self, term): | ||||
|         """parse the shortcut forms, return True/False""" | ||||
|         match = SHORTCUT.match(term) | ||||
|         if not match: | ||||
|             return False | ||||
| 
 | ||||
|         _, start, end, _, stride, _, format = match.groups() | ||||
| 
 | ||||
|         if start is not None: | ||||
|             try: | ||||
|                 start = int(start, 0) | ||||
|             except ValueError: | ||||
|                 raise AnsibleError("can't parse start=%s as integer" % start) | ||||
|         if end is not None: | ||||
|             try: | ||||
|                 end = int(end, 0) | ||||
|             except ValueError: | ||||
|                 raise AnsibleError("can't parse end=%s as integer" % end) | ||||
|         if stride is not None: | ||||
|             try: | ||||
|                 stride = int(stride, 0) | ||||
|             except ValueError: | ||||
|                 raise AnsibleError("can't parse stride=%s as integer" % stride) | ||||
| 
 | ||||
|         if start is not None: | ||||
|             self.start = start | ||||
|         if end is not None: | ||||
|             self.end = end | ||||
|         if stride is not None: | ||||
|             self.stride = stride | ||||
|         if format is not None: | ||||
|             self.format = format | ||||
| 
 | ||||
|     def sanity_check(self): | ||||
|         if self.count is None and self.end is None: | ||||
|             raise AnsibleError( | ||||
|                 "must specify count or end in with_sequence" | ||||
|             ) | ||||
|         elif self.count is not None and self.end is not None: | ||||
|             raise AnsibleError( | ||||
|                 "can't specify both count and end in with_sequence" | ||||
|             ) | ||||
|         elif self.count is not None: | ||||
|             # convert count to end | ||||
|             self.end = self.start + self.count * self.stride - 1 | ||||
|             del self.count | ||||
|         if self.end < self.start: | ||||
|             raise AnsibleError("can't count backwards") | ||||
|         if self.format.count('%') != 1: | ||||
|             raise AnsibleError("bad formatting string: %s" % self.format) | ||||
| 
 | ||||
|     def generate_sequence(self): | ||||
|         numbers = xrange(self.start, self.end + 1, self.stride) | ||||
| 
 | ||||
|         for i in numbers: | ||||
|             try: | ||||
|                 formatted = self.format % i | ||||
|                 yield formatted | ||||
|             except (ValueError, TypeError): | ||||
|                 raise AnsibleError( | ||||
|                     "problem formatting %r with %r" % self.format | ||||
|                 ) | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
|         results = [] | ||||
| 
 | ||||
|         if isinstance(terms, basestring): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         for term in terms: | ||||
|             try: | ||||
|                 self.reset()  # clear out things for this iteration | ||||
| 
 | ||||
|                 try: | ||||
|                     if not self.parse_simple_args(term): | ||||
|                         self.parse_kv_args(parse_kv(term)) | ||||
|                 except Exception, e: | ||||
|                     raise AnsibleError("unknown error parsing with_sequence arguments: %r" % term) | ||||
| 
 | ||||
|                 self.sanity_check() | ||||
| 
 | ||||
|                 results.extend(self.generate_sequence()) | ||||
|             except AnsibleError: | ||||
|                 raise | ||||
|             except Exception: | ||||
|                 raise AnsibleError( | ||||
|                     "unknown error generating sequence" | ||||
|                 ) | ||||
| 
 | ||||
|         return results | ||||
							
								
								
									
										59
									
								
								v2/ansible/plugins/lookup/subelements.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								v2/ansible/plugins/lookup/subelements.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| # (c) 2013, Serge van Ginderachter <serge@vanginderachter.be> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| from ansible.utils.listify import listify_lookup_plugin_terms | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         terms[0] = listify_lookup_plugin_terms(terms[0], variables, loader=self._loader) | ||||
| 
 | ||||
|         if not isinstance(terms, list) or not len(terms) == 2: | ||||
|             raise AnsibleError("subelements lookup expects a list of two items, first a dict or a list, and second a string") | ||||
| 
 | ||||
|         if isinstance(terms[0], dict): # convert to list: | ||||
|             if terms[0].get('skipped',False) != False: | ||||
|                 # the registered result was completely skipped | ||||
|                 return [] | ||||
|             elementlist = [] | ||||
|             for key in terms[0].iterkeys(): | ||||
|                 elementlist.append(terms[0][key]) | ||||
|         else:  | ||||
|             elementlist = terms[0] | ||||
| 
 | ||||
|         subelement = terms[1] | ||||
| 
 | ||||
|         ret = [] | ||||
|         for item0 in elementlist: | ||||
|             if not isinstance(item0, dict): | ||||
|                 raise AnsibleError("subelements lookup expects a dictionary, got '%s'" %item0) | ||||
|             if item0.get('skipped', False) != False: | ||||
|                 # this particular item is to be skipped | ||||
|                 continue  | ||||
|             if not subelement in item0: | ||||
|                 raise AnsibleError("could not find '%s' key in iterated item '%s'" % (subelement, item0)) | ||||
|             if not isinstance(item0[subelement], list): | ||||
|                 raise AnsibleError("the key %s should point to a list, got '%s'" % (subelement, item0[subelement])) | ||||
|             sublist = item0.pop(subelement, []) | ||||
|             for item1 in sublist: | ||||
|                 ret.append((item0, item1)) | ||||
| 
 | ||||
|         return ret | ||||
| 
 | ||||
							
								
								
									
										43
									
								
								v2/ansible/plugins/lookup/template.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								v2/ansible/plugins/lookup/template.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| from ansible.errors import AnsibleError | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| from ansible.template import Templar | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
| 
 | ||||
|     def run(self, terms, variables, **kwargs): | ||||
| 
 | ||||
|         if not isinstance(terms, list): | ||||
|             terms = [ terms ] | ||||
| 
 | ||||
|         templar = Templar(loader=self._loader, variables=variables) | ||||
| 
 | ||||
|         ret = [] | ||||
|         for term in terms: | ||||
|             path = self._loader.path_dwim(term) | ||||
|             if os.path.exists(path): | ||||
|                 with open(path, 'r') as f: | ||||
|                     template_data = f.read() | ||||
|                     res = templar.template(template_data, preserve_trailing_newlines=True) | ||||
|                     ret.append(res) | ||||
|             else: | ||||
|                 raise AnsibleError("the template file %s could not be found for the lookup" % term) | ||||
|         return ret | ||||
							
								
								
									
										48
									
								
								v2/ansible/plugins/lookup/together.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								v2/ansible/plugins/lookup/together.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| # (c) 2013, Bradley Young <young.bradley@gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| from itertools import izip_longest | ||||
| 
 | ||||
| from ansible.errors import * | ||||
| from ansible.plugins.lookup import LookupBase | ||||
| from ansible.utils.listify import listify_lookup_plugin_terms | ||||
| 
 | ||||
| class LookupModule(LookupBase): | ||||
|     """ | ||||
|     Transpose a list of arrays: | ||||
|     [1, 2, 3], [4, 5, 6] -> [1, 4], [2, 5], [3, 6] | ||||
|     Replace any empty spots in 2nd array with None: | ||||
|     [1, 2], [3] -> [1, 3], [2, None] | ||||
|     """ | ||||
| 
 | ||||
|     def __lookup_variabless(self, terms, variables): | ||||
|         results = [] | ||||
|         for x in terms: | ||||
|             intermediate = listify_lookup_plugin_terms(x, variables) | ||||
|             results.append(intermediate) | ||||
|         return results | ||||
| 
 | ||||
|     def run(self, terms, variables=None, **kwargs): | ||||
| 
 | ||||
|         terms = self.__lookup_variabless(terms, variables) | ||||
| 
 | ||||
|         my_list = terms[:] | ||||
|         if len(my_list) == 0: | ||||
|             raise errors.AnsibleError("with_together requires at least one element in each list") | ||||
| 
 | ||||
|         return [self._flatten(x) for x in izip_longest(*my_list, fillvalue=None)] | ||||
| 
 | ||||
|  | @ -116,7 +116,7 @@ class StrategyBase: | |||
|                 self._cur_worker = 0 | ||||
| 
 | ||||
|             self._pending_results += 1 | ||||
|             main_q.put((host, new_task, task_vars, connection_info), block=False) | ||||
|             main_q.put((host, new_task, self._loader.get_basedir(), task_vars, connection_info), block=False) | ||||
|         except (EOFError, IOError, AssertionError), e: | ||||
|             # most likely an abort | ||||
|             debug("got an error while queuing: %s" % e) | ||||
|  |  | |||
|  | @ -41,8 +41,9 @@ class Templar: | |||
|     The main class for templating, with the main entry-point of template(). | ||||
|     ''' | ||||
| 
 | ||||
|     def __init__(self, basedir=None, variables=dict(), fail_on_undefined=C.DEFAULT_UNDEFINED_VAR_BEHAVIOR): | ||||
|         self._basedir             = basedir | ||||
|     def __init__(self, loader, variables=dict(), fail_on_undefined=C.DEFAULT_UNDEFINED_VAR_BEHAVIOR): | ||||
|         self._loader              = loader | ||||
|         self._basedir             = loader.get_basedir() | ||||
|         self._filters             = None | ||||
|         self._available_variables = variables | ||||
| 
 | ||||
|  | @ -180,15 +181,17 @@ class Templar: | |||
|         return thing if thing is not None else '' | ||||
| 
 | ||||
|     def _lookup(self, name, *args, **kwargs): | ||||
|         instance = lookup_loader.get(name.lower(), basedir=kwargs.get('basedir',None)) | ||||
|         instance = lookup_loader.get(name.lower(), loader=self._loader) | ||||
| 
 | ||||
|         if instance is not None: | ||||
|             # safely catch run failures per #5059 | ||||
|             try: | ||||
|                 ran = instance.run(*args, inject=self._available_vars, **kwargs) | ||||
|                 ran = instance.run(*args, variables=self._available_variables, **kwargs) | ||||
|             except AnsibleUndefinedVariable: | ||||
|                 raise | ||||
|             except Exception, e: | ||||
|                 if self._fail_on_lookup_errors: | ||||
|                     raise | ||||
|                 ran = None | ||||
|             if ran: | ||||
|                 ran = ",".join(ran) | ||||
|  |  | |||
							
								
								
									
										46
									
								
								v2/ansible/utils/encrypt.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								v2/ansible/utils/encrypt.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| # (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com> | ||||
| # | ||||
| # This file is part of Ansible | ||||
| # | ||||
| # Ansible is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # Ansible is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with Ansible.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| PASSLIB_AVAILABLE = False | ||||
| try: | ||||
|     import passlib.hash | ||||
|     PASSLIB_AVAILABLE = True | ||||
| except: | ||||
|     pass | ||||
| 
 | ||||
| from ansible.errors import AnsibleError | ||||
| 
 | ||||
| __all__ = ['do_encrypt'] | ||||
| 
 | ||||
| def do_encrypt(result, encrypt, salt_size=None, salt=None): | ||||
|     if PASSLIB_AVAILABLE: | ||||
|         try: | ||||
|             crypt = getattr(passlib.hash, encrypt) | ||||
|         except: | ||||
|             raise AnsibleError("passlib does not support '%s' algorithm" % encrypt) | ||||
| 
 | ||||
|         if salt_size: | ||||
|             result = crypt.encrypt(result, salt_size=salt_size) | ||||
|         elif salt: | ||||
|             result = crypt.encrypt(result, salt=salt) | ||||
|         else: | ||||
|             result = crypt.encrypt(result) | ||||
|     else: | ||||
|         raise AnsibleError("passlib must be installed to encrypt vars_prompt values") | ||||
| 
 | ||||
|     return result | ||||
| 
 | ||||
|  | @ -30,7 +30,7 @@ __all__ = ['listify_lookup_plugin_terms'] | |||
| 
 | ||||
| LOOKUP_REGEX = re.compile(r'lookup\s*\(') | ||||
| 
 | ||||
| def listify_lookup_plugin_terms(terms, variables): | ||||
| def listify_lookup_plugin_terms(terms, variables, loader): | ||||
| 
 | ||||
|     if isinstance(terms, basestring): | ||||
|         # someone did: | ||||
|  | @ -46,7 +46,7 @@ def listify_lookup_plugin_terms(terms, variables): | |||
|             # if not already a list, get ready to evaluate with Jinja2 | ||||
|             # not sure why the "/" is in above code :) | ||||
|             try: | ||||
|                 templar = Templar(variables=variables) | ||||
|                 templar = Templar(loader=loader, variables=variables) | ||||
|                 new_terms = templar.template("{{ %s }}" % terms) | ||||
|                 if isinstance(new_terms, basestring) and "{{" in new_terms: | ||||
|                     pass | ||||
|  |  | |||
|  | @ -41,8 +41,6 @@ class VariableManager: | |||
|         self._host_vars_files  = defaultdict(dict) | ||||
|         self._group_vars_files = defaultdict(dict) | ||||
| 
 | ||||
|         self._templar = Templar() | ||||
| 
 | ||||
|     def _get_cache_entry(self, play=None, host=None, task=None): | ||||
|         play_id = "NONE" | ||||
|         if play: | ||||
|  | @ -156,10 +154,10 @@ class VariableManager: | |||
| 
 | ||||
|         if play: | ||||
|             all_vars = self._merge_dicts(all_vars, play.get_vars()) | ||||
|             templar = Templar(loader=loader, variables=all_vars) | ||||
|             for vars_file in play.get_vars_files(): | ||||
|                 self._templar.set_available_variables(all_vars) | ||||
|                 try: | ||||
|                     vars_file = self._templar.template(vars_file) | ||||
|                     vars_file = templar.template(vars_file) | ||||
|                     data = loader.load_from_file(vars_file) | ||||
|                     all_vars = self._merge_dicts(all_vars, data) | ||||
|                 except: | ||||
|  |  | |||
							
								
								
									
										5
									
								
								v2/samples/lookup_file.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								v2/samples/lookup_file.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|   - debug: msg="the pubkey is {{lookup('file', '~/.ssh/id_rsa.pub')}}" | ||||
							
								
								
									
										7
									
								
								v2/samples/lookup_password.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								v2/samples/lookup_password.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| - hosts: localhost | ||||
|   gather_facts: no | ||||
|   #vars: | ||||
|   #  my_password: "{{ lookup('password', '/tmp/test_lookup_password length=15') }}" | ||||
|   tasks: | ||||
|   #- debug: msg="the password is {{my_password}}" | ||||
|   - debug: msg="the password is {{ lookup('password', '/tmp/test_lookup_password length=15') }}" | ||||
							
								
								
									
										4
									
								
								v2/samples/lookup_pipe.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								v2/samples/lookup_pipe.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| - hosts: localhost | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|   - debug: msg="the date is {{ lookup('pipe', 'date') }}" | ||||
							
								
								
									
										7
									
								
								v2/samples/lookup_template.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								v2/samples/lookup_template.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| - hosts: localhost | ||||
|   gather_facts: no | ||||
|   vars: | ||||
|     my_var: "Bazinga!" | ||||
|   tasks: | ||||
|   - debug: msg="the rendered template is {{ lookup('template', 'template.j2') }}" | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								v2/samples/template.j2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								v2/samples/template.j2
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| the variable is {{my_var}} | ||||
							
								
								
									
										15
									
								
								v2/samples/with_dict.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								v2/samples/with_dict.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   vars: | ||||
|     users: | ||||
|       alice: | ||||
|         name: Alice Appleworth | ||||
|         telephone: 123-456-7890 | ||||
|       bob: | ||||
|         name: Bob Bananarama | ||||
|         telephone: 987-654-3210 | ||||
|   tasks: | ||||
|   - name: Print phone records | ||||
|     debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" | ||||
|     with_dict: users | ||||
							
								
								
									
										5
									
								
								v2/samples/with_env.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								v2/samples/with_env.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|   - debug: msg="{{ lookup('env','HOME') }} is an environment variable" | ||||
							
								
								
									
										7
									
								
								v2/samples/with_fileglob.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								v2/samples/with_fileglob.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|   - debug: msg="file is {{item}}" | ||||
|     with_fileglob: | ||||
|     - "*.yml" | ||||
							
								
								
									
										10
									
								
								v2/samples/with_first_found.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								v2/samples/with_first_found.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|   - debug: msg="file is {{item}}" | ||||
|     with_first_found: | ||||
|     - /etc/foo | ||||
|     - /etc/bar | ||||
|     - /etc/passwd | ||||
|     - /etc/shadow | ||||
							
								
								
									
										13
									
								
								v2/samples/with_flattened.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								v2/samples/with_flattened.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: | ||||
|   vars: | ||||
|     list_a: | ||||
|     - ['foo', 'bar'] | ||||
|     list_b: | ||||
|     - [['bam', 'baz']] | ||||
|   tasks: | ||||
|   - debug: msg="item is {{item}}" | ||||
|     with_flattened: | ||||
|     - list_a | ||||
|     - list_b | ||||
							
								
								
									
										11
									
								
								v2/samples/with_indexed_items.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								v2/samples/with_indexed_items.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   vars: | ||||
|     some_list: | ||||
|     - a | ||||
|     - b | ||||
|     - c | ||||
|   tasks: | ||||
|   - debug: msg="at array position {{ item.0 }} there is a value {{ item.1 }}" | ||||
|     with_indexed_items: some_list | ||||
							
								
								
									
										6
									
								
								v2/samples/with_lines.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								v2/samples/with_lines.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| - hosts: localhost | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|   - debug: msg="line is {{item}}" | ||||
|     with_lines: | ||||
|     - "cat /etc/hosts" | ||||
							
								
								
									
										10
									
								
								v2/samples/with_random_choice.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								v2/samples/with_random_choice.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|   - debug: msg={{ item }} | ||||
|     with_random_choice: | ||||
|     - "go through the door" | ||||
|     - "drink from the goblet" | ||||
|     - "press the red button" | ||||
|     - "do nothing" | ||||
							
								
								
									
										13
									
								
								v2/samples/with_sequence.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								v2/samples/with_sequence.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
| 
 | ||||
|     - debug: msg="name={{ item }} state=present groups=evens" | ||||
|       with_sequence: start=0 end=32 format=testuser%02x | ||||
| 
 | ||||
|     - debug: msg="dest=/var/stuff/{{ item }} state=directory" | ||||
|       with_sequence: start=4 end=16 stride=2 | ||||
| 
 | ||||
|     - debug: msg="name=group{{ item }} state=present" | ||||
|       with_sequence: count=4 | ||||
							
								
								
									
										18
									
								
								v2/samples/with_subelements.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								v2/samples/with_subelements.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   vars: | ||||
|     users: | ||||
|       - name: alice | ||||
|         authorized: | ||||
|           - /tmp/alice/onekey.pub | ||||
|           - /tmp/alice/twokey.pub | ||||
|       - name: bob | ||||
|         authorized: | ||||
|           - /tmp/bob/id_rsa.pub | ||||
| 
 | ||||
|   tasks: | ||||
|   - debug: msg="user={{ item.0.name }} key='{{ item.1 }}'" | ||||
|     with_subelements: | ||||
|     - users | ||||
|     - authorized | ||||
							
								
								
									
										11
									
								
								v2/samples/with_together.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								v2/samples/with_together.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| - hosts: localhost | ||||
|   connection: local | ||||
|   gather_facts: no | ||||
|   vars: | ||||
|     alpha: [ 'a', 'b', 'c', 'd' ] | ||||
|     numbers:  [ 1, 2, 3, 4 ] | ||||
|   tasks: | ||||
|   - debug: msg="{{ item.0 }} and {{ item.1 }}" | ||||
|     with_together: | ||||
|     - alpha | ||||
|     - numbers | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue