rethink wording (#70028)

* rethink wording
* removed unrequired requirement
* fix tests
* fixed versions
Co-authored-by: Sloane Hertel <shertel@redhat.com>
pull/72427/head
Brian Coca 4 years ago committed by GitHub
parent 4fb336cef1
commit 4b673484f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -77,14 +77,14 @@
#stdout_callback = debug #stdout_callback = debug
# Ansible ships with some plugins that require whitelisting, # Ansible ships with some plugins that require enabling
# this is done to avoid running all of a type by default. # this is done to avoid running all of a type by default.
# These setting lists those that you want enabled for your system. # These setting lists those that you want enabled for your system.
# Custom plugins should not need this unless plugin author disables them # Custom plugins should not need this unless plugin author disables them
# by default. # by default.
# #
# Enable callback plugins, they can output to stdout but cannot be 'stdout' type. # Enable callback plugins, they can output to stdout but cannot be 'stdout' type.
#callback_whitelist = timer, mail #callback_enabled = timer, mail
# Determine whether includes in tasks and handlers are "static" by # Determine whether includes in tasks and handlers are "static" by
# default. As of 2.0, includes are dynamic by default. Setting these # default. As of 2.0, includes are dynamic by default. Setting these
@ -227,7 +227,7 @@
# Set which cowsay stencil you'd like to use by default. When set to 'random', # Set which cowsay stencil you'd like to use by default. When set to 'random',
# a random stencil will be selected for each task. The selection will be filtered # a random stencil will be selected for each task. The selection will be filtered
# against the `cow_whitelist` option below. # against the `cow_enabled` option below.
# #
#cow_selection = default #cow_selection = default
#cow_selection = random #cow_selection = random
@ -237,7 +237,7 @@
# NOTE: line continuations here are for formatting purposes only, as the INI parser # NOTE: line continuations here are for formatting purposes only, as the INI parser
# in python does not support them. # in python does not support them.
# #
#cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\ #cowsay_enabled_stencils=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\
# hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,\ # hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,\
# stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www # stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www

@ -144,7 +144,7 @@ class AdHocCLI(CLI):
run_tree = False run_tree = False
if context.CLIARGS['tree']: if context.CLIARGS['tree']:
C.DEFAULT_CALLBACK_WHITELIST.append('tree') C.CALLBACKS_ENABLED.append('tree')
C.TREE_DIR = context.CLIARGS['tree'] C.TREE_DIR = context.CLIARGS['tree']
run_tree = True run_tree = True

@ -150,7 +150,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
self._find_modules_in_path(module) self._find_modules_in_path(module)
elif module.startswith('__'): elif module.startswith('__'):
continue continue
elif any(module.endswith(x) for x in C.BLACKLIST_EXTS): elif any(module.endswith(x) for x in C.REJECT_EXTS):
continue continue
elif module in C.IGNORE_FILES: elif module in C.IGNORE_FILES:
continue continue

@ -32,7 +32,7 @@ from ansible.utils.collection_loader import AnsibleCollectionConfig
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible.utils.plugin_docs import ( from ansible.utils.plugin_docs import (
BLACKLIST, REJECTLIST,
remove_current_collection_from_versions_and_dates, remove_current_collection_from_versions_and_dates,
get_docstring, get_docstring,
get_versioned_doclink, get_versioned_doclink,
@ -417,7 +417,7 @@ class DocCLI(CLI):
continue continue
elif os.path.isdir(full_path): elif os.path.isdir(full_path):
continue continue
elif any(plugin.endswith(x) for x in C.BLACKLIST_EXTS): elif any(plugin.endswith(x) for x in C.REJECT_EXTS):
continue continue
elif plugin.startswith('__'): elif plugin.startswith('__'):
continue continue
@ -430,7 +430,7 @@ class DocCLI(CLI):
plugin = os.path.splitext(plugin)[0] # removes the extension plugin = os.path.splitext(plugin)[0] # removes the extension
plugin = plugin.lstrip('_') # remove underscore from deprecated plugins plugin = plugin.lstrip('_') # remove underscore from deprecated plugins
if plugin not in BLACKLIST.get(bkey, ()): if plugin not in REJECTLIST.get(bkey, ()):
if collection: if collection:
plugin = '%s.%s' % (collection, plugin) plugin = '%s.%s' % (collection, plugin)

@ -36,15 +36,29 @@ ANSIBLE_COW_SELECTION:
env: [{name: ANSIBLE_COW_SELECTION}] env: [{name: ANSIBLE_COW_SELECTION}]
ini: ini:
- {key: cow_selection, section: defaults} - {key: cow_selection, section: defaults}
ANSIBLE_COW_WHITELIST: ANSIBLE_COW_ACCEPTLIST:
name: Cowsay filter whitelist name: Cowsay filter acceptance list
default: ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep', 'small', 'stegosaurus', 'stimpy', 'supermilker', 'three-eyes', 'turkey', 'turtle', 'tux', 'udder', 'vader-koala', 'vader', 'www'] default: ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep', 'small', 'stegosaurus', 'stimpy', 'supermilker', 'three-eyes', 'turkey', 'turtle', 'tux', 'udder', 'vader-koala', 'vader', 'www']
description: White list of cowsay templates that are 'safe' to use, set to empty list if you want to enable all installed templates. description: White list of cowsay templates that are 'safe' to use, set to empty list if you want to enable all installed templates.
env: [{name: ANSIBLE_COW_WHITELIST}] env:
- name: ANSIBLE_COW_WHITELIST
deprecated:
why: Normalizing names to new standard.
version: "2.15"
alternatives: 'ANSIBLE_COW_ACCEPTLIST'
- name: ANSIBLE_COW_ACCEPTLIST
version_added: '2.11'
ini: ini:
- {key: cow_whitelist, section: defaults} - key: cow_whitelist
section: defaults
deprecated:
why: Normalizing names to new standard.
version: "2.15"
alternatives: 'cowsay_enabled_stencils'
- key: cowsay_enabled_stencils
section: defaults
version_added: '2.11'
type: list type: list
yaml: {key: display.cowsay_whitelist}
ANSIBLE_FORCE_COLOR: ANSIBLE_FORCE_COLOR:
name: Force color output name: Force color output
default: False default: False
@ -382,7 +396,7 @@ COVERAGE_REMOTE_OUTPUT:
- {name: _ansible_coverage_remote_output} - {name: _ansible_coverage_remote_output}
type: str type: str
version_added: '2.9' version_added: '2.9'
COVERAGE_REMOTE_PATH_FILTER: COVERAGE_REMOTE_PATHS:
name: Sets the list of paths to run coverage for. name: Sets the list of paths to run coverage for.
description: description:
- A list of paths for files on the Ansible controller to run coverage for when executing on the remote host. - A list of paths for files on the Ansible controller to run coverage for when executing on the remote host.
@ -392,8 +406,14 @@ COVERAGE_REMOTE_PATH_FILTER:
- This is for internal use only. - This is for internal use only.
default: '*' default: '*'
env: env:
- {name: _ANSIBLE_COVERAGE_REMOTE_PATH_FILTER} - name: _ANSIBLE_COVERAGE_REMOTE_WHITELIST
type: str deprecated:
why: Normalizing names to new standard.
version: "2.15"
alternatives: '_ANSIBLE_COVERAGE_REMOTE_PATHS'
- name: '_ANSIBLE_COVERAGE_REMOTE_PATHS'
version_added: '2.11'
type: pathlist
version_added: '2.9' version_added: '2.9'
ACTION_WARNINGS: ACTION_WARNINGS:
name: Toggle action warnings name: Toggle action warnings
@ -548,13 +568,28 @@ DEFAULT_CACHE_PLUGIN_PATH:
ini: ini:
- {key: cache_plugins, section: defaults} - {key: cache_plugins, section: defaults}
type: pathspec type: pathspec
DEFAULT_CALLABLE_WHITELIST: CALLABLE_ACCEPT_LIST:
name: Template 'callable' whitelist name: Template 'callable' accept list
default: [] default: []
description: Whitelist of callable methods to be made available to template evaluation description: Whitelist of callable methods to be made available to template evaluation
env: [{name: ANSIBLE_CALLABLE_WHITELIST}] env:
- name: ANSIBLE_CALLABLE_WHITELIST
deprecated:
why: Normalizing names to new standard.
version: "2.15"
alternatives: 'ANSIBLE_CALLABLE_ENABLED'
- name: ANSIBLE_CALLABLE_ENABLED
version_added: '2.11'
ini: ini:
- {key: callable_whitelist, section: defaults} - key: callable_whitelist
section: defaults
deprecated:
why: Normalizing names to new standard.
version: "2.15"
alternatives: 'callable_enabled'
- key: callable_enabled
section: defaults
version_added: '2.11'
type: list type: list
DEFAULT_CALLBACK_PLUGIN_PATH: DEFAULT_CALLBACK_PLUGIN_PATH:
name: Callback Plugins Path name: Callback Plugins Path
@ -565,17 +600,31 @@ DEFAULT_CALLBACK_PLUGIN_PATH:
- {key: callback_plugins, section: defaults} - {key: callback_plugins, section: defaults}
type: pathspec type: pathspec
yaml: {key: plugins.callback.path} yaml: {key: plugins.callback.path}
DEFAULT_CALLBACK_WHITELIST: CALLBACKS_ENABLED:
name: Callback Whitelist name: Enable callback plugins that require it.
default: [] default: []
description: description:
- "List of whitelisted callbacks, not all callbacks need whitelisting, - "List of enabled callbacks, not all callbacks need enabling,
but many of those shipped with Ansible do as we don't want them activated by default." but many of those shipped with Ansible do as we don't want them activated by default."
env: [{name: ANSIBLE_CALLBACK_WHITELIST}] env:
- name: ANSIBLE_CALLBACK_WHITELIST
deprecated:
why: Normalizing names to new standard.
version: "2.15"
alternatives: 'ANSIBLE_CALLBACKS_ENABLED'
- name: ANSIBLE_CALLBACKS_ENABLED
version_added: '2.11'
ini: ini:
- {key: callback_whitelist, section: defaults} - key: callback_whitelist
section: defaults
deprecated:
why: Normalizing names to new standard.
version: "2.15"
alternatives: 'callback_enabled'
- key: callbacks_enabled
section: defaults
version_added: '2.11'
type: list type: list
yaml: {key: plugins.callback.whitelist}
DEFAULT_CLICONF_PLUGIN_PATH: DEFAULT_CLICONF_PLUGIN_PATH:
name: Cliconf Plugins Path name: Cliconf Plugins Path
default: ~/.ansible/plugins/cliconf:/usr/share/ansible/plugins/cliconf default: ~/.ansible/plugins/cliconf:/usr/share/ansible/plugins/cliconf
@ -1610,7 +1659,7 @@ INVENTORY_EXPORT:
type: bool type: bool
INVENTORY_IGNORE_EXTS: INVENTORY_IGNORE_EXTS:
name: Inventory ignore extensions name: Inventory ignore extensions
default: "{{(BLACKLIST_EXTS + ('.orig', '.ini', '.cfg', '.retry'))}}" default: "{{(REJECT_EXTS + ('.orig', '.ini', '.cfg', '.retry'))}}"
description: List of extensions to ignore when using a directory as an inventory source description: List of extensions to ignore when using a directory as an inventory source
env: [{name: ANSIBLE_INVENTORY_IGNORE}] env: [{name: ANSIBLE_INVENTORY_IGNORE}]
ini: ini:
@ -1672,10 +1721,10 @@ INJECT_FACTS_AS_VARS:
version_added: "2.5" version_added: "2.5"
MODULE_IGNORE_EXTS: MODULE_IGNORE_EXTS:
name: Module ignore extensions name: Module ignore extensions
default: "{{(BLACKLIST_EXTS + ('.yaml', '.yml', '.ini'))}}" default: "{{(REJECT_EXTS + ('.yaml', '.yml', '.ini'))}}"
description: description:
- List of extensions to ignore when looking for modules to load - List of extensions to ignore when looking for modules to load
- This is for blacklisting script and binary module fallback extensions - This is for rejecting script and binary module fallback extensions
env: [{name: ANSIBLE_MODULE_IGNORE_EXTS}] env: [{name: ANSIBLE_MODULE_IGNORE_EXTS}]
ini: ini:
- {key: module_ignore_exts, section: defaults} - {key: module_ignore_exts, section: defaults}
@ -1905,7 +1954,7 @@ USE_PERSISTENT_CONNECTIONS:
- {key: use_persistent_connections, section: defaults} - {key: use_persistent_connections, section: defaults}
type: boolean type: boolean
VARIABLE_PLUGINS_ENABLED: VARIABLE_PLUGINS_ENABLED:
name: Vars plugin whitelist name: Vars plugin enabled list
default: ['host_group_vars'] default: ['host_group_vars']
description: Whitelist for variable plugins that require it. description: Whitelist for variable plugins that require it.
env: [{name: ANSIBLE_VARS_ENABLED}] env: [{name: ANSIBLE_VARS_ENABLED}]

@ -60,7 +60,7 @@ class _DeprecatedSequenceConstant(Sequence):
# CONSTANTS ### yes, actual ones # CONSTANTS ### yes, actual ones
BLACKLIST_EXTS = ('.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt', '.rst') REJECT_EXTS = ('.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt', '.rst')
BOOL_TRUE = BOOLEANS_TRUE BOOL_TRUE = BOOLEANS_TRUE
COLLECTION_PTYPE_COMPAT = {'module': 'modules'} COLLECTION_PTYPE_COMPAT = {'module': 'modules'}
DEFAULT_BECOME_PASS = None DEFAULT_BECOME_PASS = None

@ -340,8 +340,8 @@ def _create_powershell_wrapper(b_module_data, module_path, module_args,
finder.scan_exec_script('coverage_wrapper') finder.scan_exec_script('coverage_wrapper')
coverage_manifest['output'] = coverage_output coverage_manifest['output'] = coverage_output
coverage_path_filter = C.config.get_config_value('COVERAGE_REMOTE_PATH_FILTER', variables=task_vars) coverage_enabled = C.config.get_config_value('COVERAGE_REMOTE_PATHS', variables=task_vars)
coverage_manifest['path_filter'] = coverage_path_filter coverage_manifest['path_filter'] = coverage_enabled
# make sure Ansible.ModuleUtils.AddType is added if any C# utils are used # make sure Ansible.ModuleUtils.AddType is added if any C# utils are used
if len(finder.cs_utils_wrapper) > 0 or len(finder.cs_utils_module) > 0: if len(finder.cs_utils_wrapper) > 0 or len(finder.cs_utils_module) > 0:

@ -174,8 +174,8 @@ class TaskQueueManager:
# get all configured loadable callbacks (adjacent, builtin) # get all configured loadable callbacks (adjacent, builtin)
callback_list = list(callback_loader.all(class_only=True)) callback_list = list(callback_loader.all(class_only=True))
# add whitelisted callbacks that refer to collections, which might not appear in normal listing # add enabled callbacks that refer to collections, which might not appear in normal listing
for c in C.DEFAULT_CALLBACK_WHITELIST: for c in C.CALLBACKS_ENABLED:
# load all, as collection ones might be using short/redirected names and not a fqcn # load all, as collection ones might be using short/redirected names and not a fqcn
plugin = callback_loader.get(c, class_only=True) plugin = callback_loader.get(c, class_only=True)
@ -191,7 +191,7 @@ class TaskQueueManager:
for callback_plugin in callback_list: for callback_plugin in callback_list:
callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '') callback_type = getattr(callback_plugin, 'CALLBACK_TYPE', '')
callback_needs_whitelist = getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False) callback_needs_enabled = getattr(callback_plugin, 'CALLBACK_NEEDS_ENABLED', getattr(callback_plugin, 'CALLBACK_NEEDS_WHITELIST', False))
# try to get colleciotn world name first # try to get colleciotn world name first
cnames = getattr(callback_plugin, '_redirected_names', []) cnames = getattr(callback_plugin, '_redirected_names', [])
@ -212,10 +212,10 @@ class TaskQueueManager:
elif callback_name == 'tree' and self._run_tree: elif callback_name == 'tree' and self._run_tree:
# TODO: remove special case for tree, which is an adhoc cli option --tree # TODO: remove special case for tree, which is an adhoc cli option --tree
pass pass
elif not self._run_additional_callbacks or (callback_needs_whitelist and ( elif not self._run_additional_callbacks or (callback_needs_enabled and (
# only run if not adhoc, or adhoc was specifically configured to run + check enabled list # 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)): C.CALLBACKS_ENABLED is None or callback_name not in C.CALLBACKS_ENABLED)):
# 2.x plugins shipped with ansible should require whitelisting, older or non shipped should load automatically # 2.x plugins shipped with ansible should require enabling, older or non shipped should load automatically
continue continue
try: try:

@ -86,8 +86,8 @@ options:
remote_src: remote_src:
description: description:
- Influence whether C(src) needs to be transferred or already is present remotely. - Influence whether C(src) needs to be transferred or already is present remotely.
- If C(no), it will search for C(src) at originating/master machine. - If C(no), it will search for C(src) on the controller node.
- If C(yes) it will go to the remote/target machine for the C(src). - If C(yes) it will search for C(src) on the managed (remote) node.
- C(remote_src) supports recursive copying as of version 2.8. - C(remote_src) supports recursive copying as of version 2.8.
- C(remote_src) only works with C(mode=preserve) as of version 2.6. - C(remote_src) only works with C(mode=preserve) as of version 2.6.
type: bool type: bool

@ -39,7 +39,7 @@ options:
required: true required: true
copy: copy:
description: description:
- If true, the file is copied from local 'master' to the target machine, otherwise, the plugin will look for src archive at the target machine. - If true, the file is copied from local controller to the managed (remote) node, otherwise, the plugin will look for src archive on the managed machine.
- This option has been deprecated in favor of C(remote_src). - This option has been deprecated in favor of C(remote_src).
- This option is mutually exclusive with C(remote_src). - This option is mutually exclusive with C(remote_src).
type: bool type: bool

@ -149,8 +149,8 @@ options:
version_added: '2.7' version_added: '2.7'
remote_src: remote_src:
description: description:
- If C(no), the module will search for src on originating/master machine. - If C(no), the module will search for the C(src) on the controller node.
- If C(yes) the module will use the C(src) path on the remote/target machine. - If C(yes), the module will search for the C(src) on the managed (remote) node.
type: bool type: bool
default: no default: no
version_added: '2.7' version_added: '2.7'

@ -150,7 +150,7 @@ class CallbackModule(CallbackBase):
CALLBACK_VERSION = 2.0 CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'aggregate' CALLBACK_TYPE = 'aggregate'
CALLBACK_NAME = 'junit' CALLBACK_NAME = 'junit'
CALLBACK_NEEDS_WHITELIST = True CALLBACK_NEEDS_ENABLED = True
def __init__(self): def __init__(self):
super(CallbackModule, self).__init__() super(CallbackModule, self).__init__()

@ -44,7 +44,7 @@ class CallbackModule(CallbackBase):
CALLBACK_VERSION = 2.0 CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'aggregate' CALLBACK_TYPE = 'aggregate'
CALLBACK_NAME = 'tree' CALLBACK_NAME = 'tree'
CALLBACK_NEEDS_WHITELIST = True CALLBACK_NEEDS_ENABLED = True
def set_options(self, task_keys=None, var_options=None, direct=None): def set_options(self, task_keys=None, var_options=None, direct=None):
''' override to set self.tree ''' ''' override to set self.tree '''

@ -112,7 +112,7 @@ def safe_eval(expr, locals=None, include_exceptions=False):
for test in test_loader.all(): for test in test_loader.all():
test_list.extend(test.tests().keys()) test_list.extend(test.tests().keys())
CALL_WHITELIST = C.DEFAULT_CALLABLE_WHITELIST + filter_list + test_list CALL_ENABLED = C.CALLABLE_ACCEPT_LIST + filter_list + test_list
class CleansingNodeVisitor(ast.NodeVisitor): class CleansingNodeVisitor(ast.NodeVisitor):
def generic_visit(self, node, inside_call=False): def generic_visit(self, node, inside_call=False):
@ -124,7 +124,7 @@ def safe_eval(expr, locals=None, include_exceptions=False):
# Disallow calls to builtin functions that we have not vetted # Disallow calls to builtin functions that we have not vetted
# as safe. Other functions are excluded by setting locals in # as safe. Other functions are excluded by setting locals in
# the call to eval() later on # the call to eval() later on
if hasattr(builtins, node.id) and node.id not in CALL_WHITELIST: if hasattr(builtins, node.id) and node.id not in CALL_ENABLED:
raise Exception("invalid function: %s" % node.id) raise Exception("invalid function: %s" % node.id)
# iterate over all child nodes # iterate over all child nodes
for child_node in ast.iter_child_nodes(node): for child_node in ast.iter_child_nodes(node):

@ -226,8 +226,8 @@ class Display(with_metaclass(Singleton, object)):
cmd = subprocess.Popen([self.b_cowsay, "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) cmd = subprocess.Popen([self.b_cowsay, "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = cmd.communicate() (out, err) = cmd.communicate()
self.cows_available = set([to_text(c) for c in out.split()]) self.cows_available = set([to_text(c) for c in out.split()])
if C.ANSIBLE_COW_WHITELIST and any(C.ANSIBLE_COW_WHITELIST): if C.ANSIBLE_COW_ACCEPTLIST and any(C.ANSIBLE_COW_ACCEPTLIST):
self.cows_available = set(C.ANSIBLE_COW_WHITELIST).intersection(self.cows_available) self.cows_available = set(C.ANSIBLE_COW_ACCEPTLIST).intersection(self.cows_available)
except Exception: except Exception:
# could not execute cowsay for some reason # could not execute cowsay for some reason
self.b_cowsay = False self.b_cowsay = False

@ -18,7 +18,7 @@ display = Display()
# modules that are ok that they do not have documentation strings # modules that are ok that they do not have documentation strings
BLACKLIST = { REJECTLIST = {
'MODULE': frozenset(('async_wrapper',)), 'MODULE': frozenset(('async_wrapper',)),
'CACHE': frozenset(('base',)), 'CACHE': frozenset(('base',)),
} }

@ -16,7 +16,6 @@ class CallbackModule(CallbackBase):
CALLBACK_VERSION = 2.0 CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'aggregate' CALLBACK_TYPE = 'aggregate'
CALLBACK_NAME = 'usercallback' CALLBACK_NAME = 'usercallback'
CALLBACK_NEEDS_WHITELIST = True
def __init__(self): def __init__(self):

@ -1,46 +0,0 @@
# Copyright 2019 RedHat, 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/>.
#############################################
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
vars: vars_req_whitelist
version_added: "2.10"
short_description: load host and group vars
description: test loading host and group vars from a collection
options:
stage:
choices: ['all', 'inventory', 'task']
type: str
ini:
- key: stage
section: vars_req_whitelist
env:
- name: ANSIBLE_VARS_PLUGIN_STAGE
'''
from ansible.plugins.vars import BaseVarsPlugin
class VarsModule(BaseVarsPlugin):
REQUIRES_WHITELIST = True
def get_vars(self, loader, path, entities, cache=True):
super(VarsModule, self).get_vars(loader, path, entities)
return {'whitelisted': True, 'collection': False}

@ -14,22 +14,23 @@ export INVENTORY_PATH="$ipath"
echo "--- validating callbacks" echo "--- validating callbacks"
# validate FQ callbacks in ansible-playbook # validate FQ callbacks in ansible-playbook
ANSIBLE_CALLBACK_WHITELIST=testns.testcoll.usercallback ansible-playbook noop.yml | grep "usercallback says ok" ANSIBLE_CALLBACKS_ENABLED=testns.testcoll.usercallback ansible-playbook noop.yml | grep "usercallback says ok"
# use adhoc for the rest of these tests, must force it to load other callbacks # use adhoc for the rest of these tests, must force it to load other callbacks
export ANSIBLE_LOAD_CALLBACK_PLUGINS=1 export ANSIBLE_LOAD_CALLBACK_PLUGINS=1
# validate redirected callback # validate redirected callback
ANSIBLE_CALLBACK_WHITELIST=formerly_core_callback ansible localhost -m debug 2>&1 | grep -- "usercallback says ok" ANSIBLE_CALLBACKS_ENABLED=formerly_core_callback ansible localhost -m debug 2>&1 | grep -- "usercallback says ok"
## validate missing redirected callback ## validate missing redirected callback
ANSIBLE_CALLBACK_WHITELIST=formerly_core_missing_callback ansible localhost -m debug 2>&1 | grep -- "Skipping callback plugin 'formerly_core_missing_callback'" ANSIBLE_CALLBACKS_ENABLED=formerly_core_missing_callback ansible localhost -m debug 2>&1 | grep -- "Skipping callback plugin 'formerly_core_missing_callback'"
## validate redirected + removed callback (fatal) ## validate redirected + removed callback (fatal)
ANSIBLE_CALLBACK_WHITELIST=formerly_core_removed_callback ansible localhost -m debug 2>&1 | grep -- "testns.testcoll.removedcallback has been removed" ANSIBLE_CALLBACKS_ENABLED=formerly_core_removed_callback ansible localhost -m debug 2>&1 | grep -- "testns.testcoll.removedcallback has been removed"
# validate avoiding duplicate loading of callback, even if using diff names # validate avoiding duplicate loading of callback, even if using diff names
[ "$(ANSIBLE_CALLBACK_WHITELIST=testns.testcoll.usercallback,formerly_core_callback ansible localhost -m debug 2>&1 | grep -c 'usercallback says ok')" = "1" ] [ "$(ANSIBLE_CALLBACKS_ENABLED=testns.testcoll.usercallback,formerly_core_callback ansible localhost -m debug 2>&1 | grep -c 'usercallback says ok')" = "1" ]
# ensure non existing callback does not crash ansible # ensure non existing callback does not crash ansible
ANSIBLE_CALLBACK_WHITELIST=charlie.gomez.notme ansible localhost -m debug 2>&1 | grep -- "Skipping callback plugin 'charlie.gomez.notme'" ANSIBLE_CALLBACKS_ENABLED=charlie.gomez.notme ansible localhost -m debug 2>&1 | grep -- "Skipping callback plugin 'charlie.gomez.notme'"
unset ANSIBLE_LOAD_CALLBACK_PLUGINS unset ANSIBLE_LOAD_CALLBACK_PLUGINS
# adhoc normally shouldn't load non-default plugins- let's be sure # adhoc normally shouldn't load non-default plugins- let's be sure
output=$(ANSIBLE_CALLBACK_WHITELIST=testns.testcoll.usercallback ansible localhost -m debug) output=$(ANSIBLE_CALLBACK_ENABLED=testns.testcoll.usercallback ansible localhost -m debug)
if [[ "${output}" =~ "usercallback says ok" ]]; then echo fail; exit 1; fi if [[ "${output}" =~ "usercallback says ok" ]]; then echo fail; exit 1; fi
echo "--- validating docs" echo "--- validating docs"

@ -2,7 +2,7 @@
set -eux set -eux
# Collections vars plugins must be whitelisted with FQCN because PluginLoader.all() does not search collections # Collections vars plugins must be enabled using the FQCN in the 'enabled' list, because PluginLoader.all() does not search collections
# Let vars plugins run for inventory by using the global setting # Let vars plugins run for inventory by using the global setting
export ANSIBLE_RUN_VARS_PLUGINS=start export ANSIBLE_RUN_VARS_PLUGINS=start
@ -33,7 +33,7 @@ grep '"collection": "collection_root_user"' out.txt
grep '"adj_var": "value"' out.txt grep '"adj_var": "value"' out.txt
grep -v '"collection": "adjacent"' out.txt grep -v '"collection": "adjacent"' out.txt
# Test that 3rd party plugins in plugin_path do not need to require whitelisting by default # Test that 3rd party plugins in plugin_path do not need to require enabling by default
# Plugins shipped with Ansible and in the custom plugin dir should be used first # Plugins shipped with Ansible and in the custom plugin dir should be used first
export ANSIBLE_VARS_PLUGINS=./custom_vars_plugins export ANSIBLE_VARS_PLUGINS=./custom_vars_plugins
@ -42,15 +42,11 @@ ansible-inventory -i a.statichost.yml --list --playbook-dir=./ | tee out.txt
grep '"name": "v2_vars_plugin"' out.txt grep '"name": "v2_vars_plugin"' out.txt
grep '"collection": "collection_root_user"' out.txt grep '"collection": "collection_root_user"' out.txt
grep '"adj_var": "value"' out.txt grep '"adj_var": "value"' out.txt
grep -v '"whitelisted": true' out.txt
# Test plugins in plugin paths that opt-in to require whitelisting # Test plugins in plugin paths that opt-in to require enabling
unset ANSIBLE_VARS_ENABLED unset ANSIBLE_VARS_ENABLED
unset ANSIBLE_COLLECTIONS_PATH unset ANSIBLE_COLLECTIONS_PATH
ANSIBLE_VARS_ENABLED=vars_req_whitelist ansible-inventory -i a.statichost.yml --list --playbook-dir=./ | tee out.txt
grep '"whitelisted": true' out.txt
# Test vars plugins that support the stage setting don't run for inventory when stage is set to 'task' # Test vars plugins that support the stage setting don't run for inventory when stage is set to 'task'
# and that the vars plugins that don't support the stage setting don't run for inventory when the global setting is 'demand' # and that the vars plugins that don't support the stage setting don't run for inventory when the global setting is 'demand'
@ -58,7 +54,6 @@ ANSIBLE_VARS_PLUGIN_STAGE=task ansible-inventory -i a.statichost.yml --list --pl
grep -v '"v1_vars_plugin": true' out.txt grep -v '"v1_vars_plugin": true' out.txt
grep -v '"v2_vars_plugin": true' out.txt grep -v '"v2_vars_plugin": true' out.txt
grep -v '"vars_req_whitelist": true' out.txt
grep -v '"collection": "adjacent"' out.txt grep -v '"collection": "adjacent"' out.txt
grep -v '"collection": "collection_root_user"' out.txt grep -v '"collection": "collection_root_user"' out.txt
grep -v '"adj_var": "value"' out.txt grep -v '"adj_var": "value"' out.txt
@ -66,7 +61,6 @@ grep -v '"adj_var": "value"' out.txt
# Test that the global setting allows v1 and v2 plugins to run after importing inventory # Test that the global setting allows v1 and v2 plugins to run after importing inventory
ANSIBLE_RUN_VARS_PLUGINS=start ansible-inventory -i a.statichost.yml --list --playbook-dir=./ | tee out.txt ANSIBLE_RUN_VARS_PLUGINS=start ansible-inventory -i a.statichost.yml --list --playbook-dir=./ | tee out.txt
grep -v '"vars_req_whitelist": true' out.txt
grep '"v1_vars_plugin": true' out.txt grep '"v1_vars_plugin": true' out.txt
grep '"v2_vars_plugin": true' out.txt grep '"v2_vars_plugin": true' out.txt
grep '"name": "v2_vars_plugin"' out.txt grep '"name": "v2_vars_plugin"' out.txt

@ -42,7 +42,7 @@
- name: Verify lookup_config - name: Verify lookup_config
assert: assert:
that: that:
- '"meow" in lookup("config", "ANSIBLE_COW_WHITELIST")' - '"meow" in lookup("config", "ANSIBLE_COW_ACCEPTLIST")'
- lookup_config_1 is failed - lookup_config_1 is failed
- '"Unable to find setting" in lookup_config_1.msg' - '"Unable to find setting" in lookup_config_1.msg'
- lookup_config_2 is failed - lookup_config_2 is failed

@ -41,10 +41,9 @@ import yaml
from ansible import __version__ as ansible_version from ansible import __version__ as ansible_version
from ansible.executor.module_common import REPLACER_WINDOWS from ansible.executor.module_common import REPLACER_WINDOWS
from ansible.module_utils.common._collections_compat import Mapping from ansible.module_utils.common._collections_compat import Mapping
from ansible.module_utils._text import to_native
from ansible.plugins.loader import fragment_loader from ansible.plugins.loader import fragment_loader
from ansible.utils.collection_loader._collection_finder import _AnsibleCollectionFinder from ansible.utils.collection_loader._collection_finder import _AnsibleCollectionFinder
from ansible.utils.plugin_docs import BLACKLIST, add_collection_to_versions_and_dates, add_fragments, get_docstring from ansible.utils.plugin_docs import REJECTLIST, add_collection_to_versions_and_dates, add_fragments, get_docstring
from ansible.utils.version import SemanticVersion from ansible.utils.version import SemanticVersion
from .module_args import AnsibleModuleImportError, AnsibleModuleNotInitialized, get_argument_spec from .module_args import AnsibleModuleImportError, AnsibleModuleNotInitialized, get_argument_spec
@ -65,11 +64,11 @@ if PY3:
else: else:
TRY_EXCEPT = ast.TryExcept TRY_EXCEPT = ast.TryExcept
BLACKLIST_DIRS = frozenset(('.git', 'test', '.github', '.idea')) REJECTLIST_DIRS = frozenset(('.git', 'test', '.github', '.idea'))
INDENT_REGEX = re.compile(r'([\t]*)') INDENT_REGEX = re.compile(r'([\t]*)')
TYPE_REGEX = re.compile(r'.*(if|or)(\s+[^"\']*|\s+)(?<!_)(?<!str\()type\([^)].*') TYPE_REGEX = re.compile(r'.*(if|or)(\s+[^"\']*|\s+)(?<!_)(?<!str\()type\([^)].*')
SYS_EXIT_REGEX = re.compile(r'[^#]*sys.exit\s*\(.*') SYS_EXIT_REGEX = re.compile(r'[^#]*sys.exit\s*\(.*')
BLACKLIST_IMPORTS = { REJECTLIST_IMPORTS = {
'requests': { 'requests': {
'new_only': True, 'new_only': True,
'error': { 'error': {
@ -236,23 +235,23 @@ class Validator(with_metaclass(abc.ABCMeta, object)):
class ModuleValidator(Validator): class ModuleValidator(Validator):
BLACKLIST_PATTERNS = ('.git*', '*.pyc', '*.pyo', '.*', '*.md', '*.rst', '*.txt') REJECTLIST_PATTERNS = ('.git*', '*.pyc', '*.pyo', '.*', '*.md', '*.rst', '*.txt')
BLACKLIST_FILES = frozenset(('.git', '.gitignore', '.travis.yml', REJECTLIST_FILES = frozenset(('.git', '.gitignore', '.travis.yml',
'shippable.yml', 'shippable.yml',
'.gitattributes', '.gitmodules', 'COPYING', '.gitattributes', '.gitmodules', 'COPYING',
'__init__.py', 'VERSION', 'test-docs.sh')) '__init__.py', 'VERSION', 'test-docs.sh'))
BLACKLIST = BLACKLIST_FILES.union(BLACKLIST['MODULE']) REJECTLIST = REJECTLIST_FILES.union(REJECTLIST['MODULE'])
PS_DOC_BLACKLIST = frozenset(( PS_DOC_REJECTLIST = frozenset((
'async_status.ps1', 'async_status.ps1',
'slurp.ps1', 'slurp.ps1',
'setup.ps1' 'setup.ps1'
)) ))
PS_ARG_VALIDATE_BLACKLIST = frozenset((
'win_dsc.ps1', # win_dsc is a dynamic arg spec, the docs won't ever match
))
WHITELIST_FUTURE_IMPORTS = frozenset(('absolute_import', 'division', 'print_function')) # win_dsc is a dynamic arg spec, the docs won't ever match
PS_ARG_VALIDATE_REJECTLIST = frozenset(('win_dsc.ps1', ))
ACCEPTLIST_FUTURE_IMPORTS = frozenset(('absolute_import', 'division', 'print_function'))
def __init__(self, path, analyze_arg_spec=False, collection=None, collection_version=None, def __init__(self, path, analyze_arg_spec=False, collection=None, collection_version=None,
base_branch=None, git_cache=None, reporter=None, routing=None): base_branch=None, git_cache=None, reporter=None, routing=None):
@ -360,7 +359,7 @@ class ModuleValidator(Validator):
# allowed from __future__ imports # allowed from __future__ imports
if isinstance(child, ast.ImportFrom) and child.module == '__future__': if isinstance(child, ast.ImportFrom) and child.module == '__future__':
for future_import in child.names: for future_import in child.names:
if future_import.name not in self.WHITELIST_FUTURE_IMPORTS: if future_import.name not in self.ACCEPTLIST_FUTURE_IMPORTS:
break break
else: else:
continue continue
@ -509,7 +508,7 @@ class ModuleValidator(Validator):
names.extend(grandchild.names) names.extend(grandchild.names)
for name in names: for name in names:
# TODO: Add line/col # TODO: Add line/col
for blacklist_import, options in BLACKLIST_IMPORTS.items(): for blacklist_import, options in REJECTLIST_IMPORTS.items():
if re.search(blacklist_import, name.name): if re.search(blacklist_import, name.name):
new_only = options['new_only'] new_only = options['new_only']
if self._is_new_module() and new_only: if self._is_new_module() and new_only:
@ -696,12 +695,12 @@ class ModuleValidator(Validator):
if isinstance(child, ast.ImportFrom) and child.module == '__future__': if isinstance(child, ast.ImportFrom) and child.module == '__future__':
# allowed from __future__ imports # allowed from __future__ imports
for future_import in child.names: for future_import in child.names:
if future_import.name not in self.WHITELIST_FUTURE_IMPORTS: if future_import.name not in self.ACCEPTLIST_FUTURE_IMPORTS:
self.reporter.error( self.reporter.error(
path=self.object_path, path=self.object_path,
code='illegal-future-imports', code='illegal-future-imports',
msg=('Only the following from __future__ imports are allowed: %s' msg=('Only the following from __future__ imports are allowed: %s'
% ', '.join(self.WHITELIST_FUTURE_IMPORTS)), % ', '.join(self.ACCEPTLIST_FUTURE_IMPORTS)),
line=child.lineno line=child.lineno
) )
break break
@ -818,7 +817,7 @@ class ModuleValidator(Validator):
) )
def _find_ps_docs_py_file(self): def _find_ps_docs_py_file(self):
if self.object_name in self.PS_DOC_BLACKLIST: if self.object_name in self.PS_DOC_REJECTLIST:
return return
py_path = self.path.replace('.ps1', '.py') py_path = self.path.replace('.ps1', '.py')
if not os.path.isfile(py_path): if not os.path.isfile(py_path):
@ -2104,10 +2103,10 @@ class ModuleValidator(Validator):
if file_name.startswith('_') and os.path.islink(path): if file_name.startswith('_') and os.path.islink(path):
return True return True
if not frozenset((base_name, file_name)).isdisjoint(ModuleValidator.BLACKLIST): if not frozenset((base_name, file_name)).isdisjoint(ModuleValidator.REJECTLIST):
return True return True
for pat in ModuleValidator.BLACKLIST_PATTERNS: for pat in ModuleValidator.REJECTLIST_PATTERNS:
if fnmatch(base_name, pat): if fnmatch(base_name, pat):
return True return True
@ -2200,7 +2199,7 @@ class ModuleValidator(Validator):
self._check_for_os_call() self._check_for_os_call()
if self._powershell_module(): if self._powershell_module():
if self.basename in self.PS_DOC_BLACKLIST: if self.basename in self.PS_DOC_REJECTLIST:
return return
self._validate_ps_replacers() self._validate_ps_replacers()
@ -2208,7 +2207,7 @@ class ModuleValidator(Validator):
# We can only validate PowerShell arg spec if it is using the new Ansible.Basic.AnsibleModule util # We can only validate PowerShell arg spec if it is using the new Ansible.Basic.AnsibleModule util
pattern = r'(?im)^#\s*ansiblerequires\s+\-csharputil\s*Ansible\.Basic' pattern = r'(?im)^#\s*ansiblerequires\s+\-csharputil\s*Ansible\.Basic'
if re.search(pattern, self.text) and self.object_name not in self.PS_ARG_VALIDATE_BLACKLIST: if re.search(pattern, self.text) and self.object_name not in self.PS_ARG_VALIDATE_REJECTLIST:
with ModuleValidator(docs_path, base_branch=self.base_branch, git_cache=self.git_cache) as docs_mv: with ModuleValidator(docs_path, base_branch=self.base_branch, git_cache=self.git_cache) as docs_mv:
docs = docs_mv._validate_docs()[1] docs = docs_mv._validate_docs()[1]
self._validate_ansible_module_call(docs) self._validate_ansible_module_call(docs)
@ -2228,7 +2227,7 @@ class ModuleValidator(Validator):
class PythonPackageValidator(Validator): class PythonPackageValidator(Validator):
BLACKLIST_FILES = frozenset(('__pycache__',)) REJECTLIST_FILES = frozenset(('__pycache__',))
def __init__(self, path, reporter=None): def __init__(self, path, reporter=None):
super(PythonPackageValidator, self).__init__(reporter=reporter or Reporter()) super(PythonPackageValidator, self).__init__(reporter=reporter or Reporter())
@ -2247,7 +2246,7 @@ class PythonPackageValidator(Validator):
def validate(self): def validate(self):
super(PythonPackageValidator, self).validate() super(PythonPackageValidator, self).validate()
if self.basename in self.BLACKLIST_FILES: if self.basename in self.REJECTLIST_FILES:
return return
init_file = os.path.join(self.path, '__init__.py') init_file = os.path.join(self.path, '__init__.py')
@ -2343,10 +2342,10 @@ def run():
for root, dirs, files in os.walk(module): for root, dirs, files in os.walk(module):
basedir = root[len(module) + 1:].split('/', 1)[0] basedir = root[len(module) + 1:].split('/', 1)[0]
if basedir in BLACKLIST_DIRS: if basedir in REJECTLIST_DIRS:
continue continue
for dirname in dirs: for dirname in dirs:
if root == module and dirname in BLACKLIST_DIRS: if root == module and dirname in REJECTLIST_DIRS:
continue continue
path = os.path.join(root, dirname) path = os.path.join(root, dirname)
if args.exclude and args.exclude.search(path): if args.exclude and args.exclude.search(path):

@ -1434,7 +1434,7 @@ def integration_environment(args, target, test_dir, inventory_path, ansible_conf
integration = dict( integration = dict(
JUNIT_OUTPUT_DIR=ResultType.JUNIT.path, JUNIT_OUTPUT_DIR=ResultType.JUNIT.path,
ANSIBLE_CALLBACK_WHITELIST=','.join(sorted(set(callback_plugins))), ANSIBLE_CALLBACK_ENABLED=','.join(sorted(set(callback_plugins))),
ANSIBLE_TEST_CI=args.metadata.ci_provider or get_ci_provider().code, ANSIBLE_TEST_CI=args.metadata.ci_provider or get_ci_provider().code,
ANSIBLE_TEST_COVERAGE='check' if args.coverage_check else ('yes' if args.coverage else ''), ANSIBLE_TEST_COVERAGE='check' if args.coverage_check else ('yes' if args.coverage else ''),
OUTPUT_DIR=test_dir, OUTPUT_DIR=test_dir,

@ -394,7 +394,7 @@ def get_coverage_environment(args, target_name, version, temp_path, module_cover
# is responsible for adding '={language version}=coverage.{hostname}.{pid}.{id}' # is responsible for adding '={language version}=coverage.{hostname}.{pid}.{id}'
env['_ANSIBLE_COVERAGE_REMOTE_OUTPUT'] = os.path.join(remote_temp_path, '%s=%s=%s' % ( env['_ANSIBLE_COVERAGE_REMOTE_OUTPUT'] = os.path.join(remote_temp_path, '%s=%s=%s' % (
args.command, target_name, args.coverage_label or 'remote')) args.command, target_name, args.coverage_label or 'remote'))
env['_ANSIBLE_COVERAGE_REMOTE_PATH_FILTER'] = os.path.join(data_context().content.root, '*') env['_ANSIBLE_COVERAGE_REMOTE_PATHS'] = os.path.join(data_context().content.root, '*')
return env return env

Loading…
Cancel
Save