def load_callbacks(self): ''' Loads all available callbacks, with the exception of those which utilize the CALLBACK_TYPE option. When CALLBACK_TYPE is set to 'stdout', only one such callback plugin will be loaded. ''' if self._callbacks_loaded: return stdout_callback_loaded = False if self._stdout_callback is None: self._stdout_callback = C.DEFAULT_STDOUT_CALLBACK if isinstance(self._stdout_callback, CallbackBase): stdout_callback_loaded = True elif isinstance(self._stdout_callback, string_types): if self._stdout_callback not in callback_loader: raise AnsibleError("Invalid callback for stdout specified: %s" % self._stdout_callback) else: self._stdout_callback = callback_loader.get(self._stdout_callback) try: self._stdout_callback.set_options() except AttributeError: display.deprecated("%s stdout callback, does not support setting 'options', it will work for now, " " but this will be required in the future and should be updated," " see the 2.4 porting guide for details." % self._stdout_callback._load_name, version="2.9") stdout_callback_loaded = True else: raise AnsibleError("callback must be an instance of CallbackBase or the name of a callback plugin") for callback_plugin in callback_loader.all(class_only=True): callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '') callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False) (callback_name, _) = os.path.splitext(os.path.basename(callback_plugin._original_path)) if callback_type == 'stdout': # we only allow one callback of type 'stdout' to be loaded, if callback_name != self._stdout_callback or stdout_callback_loaded: continue stdout_callback_loaded = True elif callback_name == 'tree' and self._run_tree: # special case for ansible cli option pass elif not self._run_additional_callbacks or (callback_needs_whitelist and ( C.DEFAULT_CALLBACK_WHITELIST is None or callback_name not in C.DEFAULT_CALLBACK_WHITELIST)): # 2.x plugins shipped with ansible should require whitelisting, older or non shipped should load automatically continue callback_obj = callback_plugin() try: callback_obj.set_options() except AttributeError: display.deprecated("%s callback, does not support setting 'options', it will work for now, " " but this will be required in the future and should be updated, " " see the 2.4 porting guide for details." % callback_obj._load_name, version="2.9") self._callback_plugins.append(callback_obj) self._callbacks_loaded = True
def load_callbacks(self): ''' Loads all available callbacks, with the exception of those which utilize the CALLBACK_TYPE option. When CALLBACK_TYPE is set to 'stdout', only one such callback plugin will be loaded. ''' if self._callbacks_loaded: return stdout_callback_loaded = False if self._stdout_callback is None: self._stdout_callback = C.DEFAULT_STDOUT_CALLBACK if isinstance(self._stdout_callback, CallbackBase): stdout_callback_loaded = True elif isinstance(self._stdout_callback, string_types): if self._stdout_callback not in callback_loader: raise AnsibleError("Invalid callback for stdout specified: %s" % self._stdout_callback) else: self._stdout_callback = callback_loader.get(self._stdout_callback) try: self._stdout_callback.set_options() except AttributeError: display.deprecated("%s stdout callback, does not support setting 'options', it will work for now, " " but this will be required in the future and should be updated," " see the 2.4 porting guide for details." % self._stdout_callback._load_name, version="2.9") stdout_callback_loaded = True else: raise AnsibleError("callback must be an instance of CallbackBase or the name of a callback plugin") for callback_plugin in callback_loader.all(class_only=True): callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '') callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False) (callback_name, _) = os.path.splitext(os.path.basename(callback_plugin._original_path)) if callback_type == 'stdout': # we only allow one callback of type 'stdout' to be loaded, if callback_name != self._stdout_callback or stdout_callback_loaded: continue stdout_callback_loaded = True elif callback_name == 'tree' and self._run_tree: # special case for ansible cli option pass elif not self._run_additional_callbacks or (callback_needs_whitelist and ( C.DEFAULT_CALLBACK_WHITELIST is None or callback_name not in C.DEFAULT_CALLBACK_WHITELIST)): # 2.x plugins shipped with ansible should require whitelisting, older or non shipped should load automatically continue callback_obj = callback_plugin() try: callback_obj.set_options() except AttributeError: display.deprecated("%s callback, does not support setting 'options', it will work for now, " " but this will be required in the future and should be updated, " " see the 2.4 porting guide for details." % self.callback_obj._load_name, version="2.9") self._callback_plugins.append(callback_obj) self._callbacks_loaded = True
def load_callbacks(self): ''' Loads all available callbacks, with the exception of those which utilize the CALLBACK_TYPE option. When CALLBACK_TYPE is set to 'stdout', only one such callback plugin will be loaded. ''' if self._callbacks_loaded: return stdout_callback_loaded = False if self._stdout_callback is None: self._stdout_callback = C.DEFAULT_STDOUT_CALLBACK if isinstance(self._stdout_callback, CallbackBase): stdout_callback_loaded = True elif isinstance(self._stdout_callback, string_types): if self._stdout_callback not in callback_loader: raise AnsibleError( "Invalid callback for stdout specified: %s" % self._stdout_callback) else: self._stdout_callback = callback_loader.get( self._stdout_callback) stdout_callback_loaded = True else: raise AnsibleError( "callback must be an instance of CallbackBase or the name of a callback plugin" ) for callback_plugin in callback_loader.all(class_only=True): if hasattr(callback_plugin, 'CALLBACK_VERSION' ) and callback_plugin.CALLBACK_VERSION >= 2.0: # we only allow one callback of type 'stdout' to be loaded, so check # the name of the current plugin and type to see if we need to skip # loading this callback plugin callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', None) callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False) (callback_name, _) = os.path.splitext( os.path.basename(callback_plugin._original_path)) if callback_type == 'stdout': if callback_name != self._stdout_callback or stdout_callback_loaded: continue stdout_callback_loaded = True elif callback_name == 'tree' and self._run_tree: pass elif not self._run_additional_callbacks or ( callback_needs_whitelist and (C.DEFAULT_CALLBACK_WHITELIST is None or callback_name not in C.DEFAULT_CALLBACK_WHITELIST)): continue self._callback_plugins.append(callback_plugin()) self._callbacks_loaded = True
def load_callbacks(self): ''' Loads all available callbacks, with the exception of those which utilize the CALLBACK_TYPE option. When CALLBACK_TYPE is set to 'stdout', only one such callback plugin will be loaded. ''' if self._callbacks_loaded: return stdout_callback_loaded = False if self._stdout_callback is None: self._stdout_callback = C.DEFAULT_STDOUT_CALLBACK if isinstance(self._stdout_callback, CallbackBase): stdout_callback_loaded = True elif isinstance(self._stdout_callback, string_types): if self._stdout_callback not in callback_loader: raise AnsibleError("Invalid callback for stdout specified: %s" % self._stdout_callback) else: self._stdout_callback = callback_loader.get(self._stdout_callback) self._stdout_callback.set_options() stdout_callback_loaded = True else: raise AnsibleError("callback must be an instance of CallbackBase or the name of a callback plugin") for callback_plugin in callback_loader.all(class_only=True): callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '') callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False) (callback_name, _) = os.path.splitext(os.path.basename(callback_plugin._original_path)) if callback_type == 'stdout': # we only allow one callback of type 'stdout' to be loaded, if callback_name != self._stdout_callback or stdout_callback_loaded: continue stdout_callback_loaded = True elif callback_name == 'tree' and self._run_tree: # special case for ansible cli option pass elif not self._run_additional_callbacks or (callback_needs_whitelist and ( C.DEFAULT_CALLBACK_WHITELIST is None or callback_name not in C.DEFAULT_CALLBACK_WHITELIST)): # 2.x plugins shipped with ansible should require whitelisting, older or non shipped should load automatically continue callback_obj = callback_plugin() callback_obj.set_options() self._callback_plugins.append(callback_obj) for callback_plugin_name in (c for c in C.DEFAULT_CALLBACK_WHITELIST if AnsibleCollectionRef.is_valid_fqcr(c)): # TODO: need to extend/duplicate the stdout callback check here (and possible move this ahead of the old way callback_obj = callback_loader.get(callback_plugin_name) self._callback_plugins.append(callback_obj) self._callbacks_loaded = True
def load_callbacks(self): ''' Loads all available callbacks, with the exception of those which utilize the CALLBACK_TYPE option. When CALLBACK_TYPE is set to 'stdout', only one such callback plugin will be loaded. ''' if self._callbacks_loaded: return stdout_callback_loaded = False if self._stdout_callback is None: self._stdout_callback = C.DEFAULT_STDOUT_CALLBACK if isinstance(self._stdout_callback, CallbackBase): stdout_callback_loaded = True elif isinstance(self._stdout_callback, string_types): if self._stdout_callback not in callback_loader: raise AnsibleError( "Invalid callback for stdout specified: %s" % self._stdout_callback) else: self._stdout_callback = callback_loader.get( self._stdout_callback) self._stdout_callback.set_options() stdout_callback_loaded = True else: raise AnsibleError( "callback must be an instance of CallbackBase or the name of a callback plugin" ) # get all configured loadable callbacks (adjacent, builtin) callback_list = list(callback_loader.all(class_only=True)) # add whitelisted callbacks that refer to collections, which might not appear in normal listing for c in C.DEFAULT_CALLBACK_WHITELIST: # load all, as collection ones might be using short/redirected names and not a fqcn plugin = callback_loader.get(c, class_only=True) # TODO: check if this skip is redundant, loader should handle bad file/plugin cases already if plugin: # avoids incorrect and dupes possible due to collections if plugin not in callback_list: callback_list.append(plugin) else: display.warning( "Skipping callback plugin '%s', unable to load" % c) # for each callback in the list see if we should add it to 'active callbacks' used in the play for callback_plugin in callback_list: callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '') callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False) # try to get collection world name first cnames = getattr(callback_plugin, '_redirected_names', []) if cnames: # store the name the plugin was loaded as, as that's what we'll need to compare to the configured callback list later callback_name = cnames[0] else: # fallback to 'old loader name' (callback_name, _) = os.path.splitext( os.path.basename(callback_plugin._original_path)) display.vvvvv("Attempting to use '%s' callback." % (callback_name)) if callback_type == 'stdout': # we only allow one callback of type 'stdout' to be loaded, if callback_name != self._stdout_callback or stdout_callback_loaded: display.vv( "Skipping callback '%s', as we already have a stdout callback." % (callback_name)) continue stdout_callback_loaded = True elif callback_name == 'tree' and self._run_tree: # TODO: remove special case for tree, which is an adhoc cli option --tree pass elif not self._run_additional_callbacks or ( callback_needs_whitelist and ( # only run if not adhoc, or adhoc was specifically configured to run + check enabled list C.DEFAULT_CALLBACK_WHITELIST is None or callback_name not in C.DEFAULT_CALLBACK_WHITELIST)): # 2.x plugins shipped with ansible should require whitelisting, older or non shipped should load automatically continue try: callback_obj = callback_plugin() # avoid bad plugin not returning an object, only needed cause we do class_only load and bypass loader checks, # really a bug in the plugin itself which we ignore as callback errors are not supposed to be fatal. if callback_obj: # skip initializing if we already did the work for the same plugin (even with diff names) if callback_obj not in self._callback_plugins: callback_obj.set_options() self._callback_plugins.append(callback_obj) else: display.vv( "Skipping callback '%s', already loaded as '%s'." % (callback_plugin, callback_name)) else: display.warning( "Skipping callback '%s', as it does not create a valid plugin instance." % callback_name) continue except Exception as e: display.warning( "Skipping callback '%s', unable to load due to: %s" % (callback_name, to_native(e))) continue self._callbacks_loaded = True
def load_callbacks(self): ''' Loads all available callbacks, with the exception of those which utilize the CALLBACK_TYPE option. When CALLBACK_TYPE is set to 'stdout', only one such callback plugin will be loaded. ''' if self._callbacks_loaded: return stdout_callback_loaded = False if self._stdout_callback is None: self._stdout_callback = C.DEFAULT_STDOUT_CALLBACK if isinstance(self._stdout_callback, CallbackBase): stdout_callback_loaded = True elif isinstance(self._stdout_callback, string_types): if self._stdout_callback not in callback_loader: raise AnsibleError( "Invalid callback for stdout specified: %s" % self._stdout_callback) else: self._stdout_callback = callback_loader.get( self._stdout_callback) self._stdout_callback.set_options() stdout_callback_loaded = True else: raise AnsibleError( "callback must be an instance of CallbackBase or the name of a callback plugin" ) loaded_callbacks = set() # first, load callbacks in the core distribution and configured callback paths for callback_plugin in callback_loader.all(class_only=True): callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '') callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False) (callback_name, _) = os.path.splitext( os.path.basename(callback_plugin._original_path)) if callback_type == 'stdout': # we only allow one callback of type 'stdout' to be loaded, if callback_name != self._stdout_callback or stdout_callback_loaded: continue stdout_callback_loaded = True elif callback_name == 'tree' and self._run_tree: # special case for ansible cli option pass # eg, ad-hoc doesn't allow non-default callbacks elif not self._run_additional_callbacks or ( callback_needs_whitelist and (C.DEFAULT_CALLBACK_WHITELIST is None or callback_name not in C.DEFAULT_CALLBACK_WHITELIST)): # 2.x plugins shipped with ansible should require whitelisting, older or non shipped should load automatically continue callback_obj = callback_plugin() loaded_callbacks.add( callback_name) # mark as loaded so we skip in second pass callback_obj.set_options() self._callback_plugins.append(callback_obj) # eg, ad-hoc doesn't allow non-default callbacks if self._run_additional_callbacks: # Second pass over everything in the whitelist we haven't already loaded, try to explicitly load. This will catch # collection-hosted callbacks, as well as formerly-core callbacks that have been redirected to collections. for callback_plugin_name in (c for c in C.DEFAULT_CALLBACK_WHITELIST if c not in loaded_callbacks): # TODO: need to extend/duplicate the stdout callback check here (and possible move this ahead of the old way callback_obj, plugin_load_context = callback_loader.get_with_context( callback_plugin_name) if callback_obj: loaded_as_name = callback_obj._redirected_names[-1] if loaded_as_name in loaded_callbacks: display.warning( "Skipping callback '%s', already loaded as '%s'." % (callback_plugin_name, loaded_as_name)) continue loaded_callbacks.add(loaded_as_name) callback_obj.set_options() self._callback_plugins.append(callback_obj) else: display.warning( "Skipping '%s', unable to load or use as a callback" % callback_plugin_name) self._callbacks_loaded = True