1# (c) 2012, Daniel Hokka Zakrisson <daniel@hozac.com> 2# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com> and others 3# (c) 2017, Toshio Kuratomi <tkuratomi@ansible.com> 4# 5# This file is part of Ansible 6# 7# Ansible is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# Ansible is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 19 20# Make coding more python3-ish 21from __future__ import (absolute_import, division, print_function) 22__metaclass__ = type 23 24from abc import ABCMeta 25 26from ansible import constants as C 27from ansible.errors import AnsibleError 28from ansible.module_utils._text import to_native 29from ansible.module_utils.six import with_metaclass, string_types 30from ansible.utils.display import Display 31 32display = Display() 33 34# Global so that all instances of a PluginLoader will share the caches 35MODULE_CACHE = {} 36PATH_CACHE = {} 37PLUGIN_PATH_CACHE = {} 38 39 40def get_plugin_class(obj): 41 if isinstance(obj, string_types): 42 return obj.lower().replace('module', '') 43 else: 44 return obj.__class__.__name__.lower().replace('module', '') 45 46 47class AnsiblePlugin(with_metaclass(ABCMeta, object)): 48 49 # allow extra passthrough parameters 50 allow_extras = False 51 52 def __init__(self): 53 self._options = {} 54 55 def get_option(self, option, hostvars=None): 56 if option not in self._options: 57 try: 58 option_value = C.config.get_config_value(option, plugin_type=get_plugin_class(self), plugin_name=self._load_name, variables=hostvars) 59 except AnsibleError as e: 60 raise KeyError(to_native(e)) 61 self.set_option(option, option_value) 62 return self._options.get(option) 63 64 def set_option(self, option, value): 65 self._options[option] = value 66 67 def set_options(self, task_keys=None, var_options=None, direct=None): 68 ''' 69 Sets the _options attribute with the configuration/keyword information for this plugin 70 71 :arg task_keys: Dict with playbook keywords that affect this option 72 :arg var_options: Dict with either 'connection variables' 73 :arg direct: Dict with 'direct assignment' 74 ''' 75 self._options = C.config.get_plugin_options(get_plugin_class(self), self._load_name, keys=task_keys, variables=var_options, direct=direct) 76 77 # allow extras/wildcards from vars that are not directly consumed in configuration 78 # this is needed to support things like winrm that can have extended protocol options we don't directly handle 79 if self.allow_extras and var_options and '_extras' in var_options: 80 self.set_option('_extras', var_options['_extras']) 81 82 def has_option(self, option): 83 if not self._options: 84 self.set_options() 85 return option in self._options 86 87 def _check_required(self): 88 # FIXME: standardize required check based on config 89 pass 90