Repository: ansible/ansible

Issue:
set_options on a callback gets called even when not whitelisted
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
Always add information AFTER of these html comments.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.6.0 (devel ac9dbdeb10) last updated 2018/04/04 12:23:06 (GMT +200)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/administrator/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/administrator/ansible-devel/lib/ansible
  executable location = /home/administrator/ansible-devel/bin/ansible
  python version = 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
RETRY_FILES_ENABLED(/etc/ansible/ansible.cfg) = False

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
N/A

##### SUMMARY
There's this warning with each run of `ansible-playbook`:

```
 [WARNING]: Grafana URL was not provided. The Grafana URL can be provided using the `GRAFANA_URL` environment variable.

[DEPRECATION WARNING]: default 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.. This feature will be removed in version 2.9. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/monitoring/grafana_plugin.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/monitoring/grafana_plugin.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @tsalle
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Files identified in the description:
None

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
Files identified in the description:
* [lib/ansible/plugins/callback/grafana_annotations.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/callback/grafana_annotations.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @rrey
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
the warning is fine, the problem is we are calling `set_options` when the callback is not whitelisted
I saw two warnings (about Grafana URL and callback doesn't support setting 'options'), but didn't know they are related. I'll update the description to include them both.
@sm4rk0 the warning is in the `set_options` method ...

the deprecation warning is for the 'default' callback, which confuses me as it was first one to support it
Yes, I saw that and even wanted to report that as another issue, but the last commit for task_queue_manager.py was on Nov 16, 2017, so I ruled that out and didn't want to make noise.
found it, the 'name' used was incorrect (always stdout plugin), so there is another error in the plugin. I updated my PR to use the correct name, but still need to trace what the exception is.
@bcoca should we close this?
it will close once i merge the fix for the underlying problem, not just the specific plugin fix (which was already merged)
Ah, yes - the `fixes` keyword in PR.

Resolving patch:
diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py
--- a/lib/ansible/executor/task_queue_manager.py
+++ b/lib/ansible/executor/task_queue_manager.py
@@ -188,22 +188,21 @@ def load_callbacks(self):
             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)):
+            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:
@@ -211,7 +210,7 @@ def load_callbacks(self):
             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._stdout_callback._load_name, version="2.9")
+                                       " 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


Test patch: