diff --git a/bin/ansible b/bin/ansible
index 7c1a3ca4f92..dc420f23ca9 100755
--- a/bin/ansible
+++ b/bin/ansible
@@ -127,7 +127,7 @@ if __name__ == '__main__':
exit_code = 99
except Exception as e:
have_cli_options = cli is not None and cli.options is not None
- display.error("Unexpected Exception: %s" % to_text(e), wrap_text=False)
+ display.error("Unexpected Exception, this is probably a bug: %s" % to_text(e), wrap_text=False)
if not have_cli_options or have_cli_options and cli.options.verbosity > 2:
log_only = False
else:
diff --git a/bin/ansible-config b/bin/ansible-config
new file mode 120000
index 00000000000..cabb1f519aa
--- /dev/null
+++ b/bin/ansible-config
@@ -0,0 +1 @@
+ansible
\ No newline at end of file
diff --git a/hacking/conf2yaml.py b/hacking/conf2yaml.py
new file mode 100755
index 00000000000..d8fc8bcc3b9
--- /dev/null
+++ b/hacking/conf2yaml.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+
+import ast
+import yaml
+import os
+import sys
+from ansible.parsing.yaml.dumper import AnsibleDumper
+
+things = {}
+stuff = {}
+
+op_map = {
+ ast.Add: '+',
+ ast.Sub: '-',
+ ast.Mult: '*',
+ ast.Div: '/',
+}
+
+
+
+def get_values(values):
+ if not isinstance(values, list):
+ return get_value(values)
+ ret = []
+ for value in values:
+ ret.append(get_value(value))
+ return ret
+
+
+def get_value(value):
+ if hasattr(value, 'id'):
+ ret = value.id
+ elif hasattr(value, 's'):
+ ret = value.s
+ elif hasattr(value, 'n'):
+ ret = value.n
+ elif hasattr(value, 'left'):
+ operator = op_map[type(value.op)]
+ left = get_values(value.left)
+ right = get_values(value.right)
+ return '%s %s %s' % (left, operator, right)
+ elif hasattr(value, 'value'):
+ ret = value.value
+ elif hasattr(value, 'elts'):
+ ret = get_values(value.elts)
+ elif isinstance(value, ast.Call):
+ func, args, kwargs = get_call(value)
+ args[:] = [repr(arg) for arg in args]
+ for k, v in kwargs.items():
+ args.append('%s=%s' % (k, repr(v)))
+ return '%s(%s)' % (func, ', '.join(args))
+ else:
+ return value
+
+ return get_value(ret)
+
+
+def get_call(value):
+ args = []
+ for arg in value.args:
+ v = get_value(arg)
+ try:
+ v = getattr(C, v, v)
+ except:
+ pass
+ args.append(v)
+ kwargs = {}
+ for keyword in value.keywords:
+ v = get_value(keyword.value)
+ try:
+ v = getattr(C, v, v)
+ except:
+ pass
+ kwargs[keyword.arg] = v
+
+ func = get_value(value.func)
+ try:
+ attr = '.%s' % value.func.attr
+ except:
+ attr = ''
+ return '%s%s' % (func, attr), args, kwargs
+
+
+with open(sys.argv[1]) as f:
+ tree = ast.parse(f.read())
+
+for item in tree.body:
+ if hasattr(item, 'value') and isinstance(item.value, ast.Call):
+ try:
+ if item.value.func.id != 'get_config':
+ continue
+ except AttributeError:
+ continue
+
+ _, args, kwargs = get_call(item.value)
+
+ name = get_value(item.targets[0])
+ section = args[1].lower()
+ config = args[2]
+
+ # new form
+ if name not in stuff:
+ stuff[name] = {}
+ stuff[name] = {
+ 'desc': 'TODO: write it',
+ 'ini': [{'section': section, 'key': config}],
+ 'env': [args[3]],
+ 'default': args[4] if len(args) == 5 else None,
+ 'yaml': {'key': '%s.%s' % (section, config)},
+ 'vars': []
+ }
+ stuff[name].update(kwargs)
+
+ ## ini like
+ #if section not in things:
+ # things[section] = {}
+
+ #things[section][config] = {
+ # 'env_var': args[3],
+ # 'default': args[4] if len(args) == 5 else 'UNKNOWN'
+ #}
+ #things[section][config].update(kwargs)
+print(yaml.dump(stuff, Dumper=AnsibleDumper, indent=2, width=170))
+
diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py
index 3ffc5868eb1..610ea94ec03 100644
--- a/lib/ansible/cli/__init__.py
+++ b/lib/ansible/cli/__init__.py
@@ -269,10 +269,8 @@ class CLI(with_metaclass(ABCMeta, object)):
(op.su or op.su_user) and (op.become or op.become_user) or
(op.sudo or op.sudo_user) and (op.become or op.become_user)):
- self.parser.error("Sudo arguments ('--sudo', '--sudo-user', and '--ask-sudo-pass') "
- "and su arguments ('--su', '--su-user', and '--ask-su-pass') "
- "and become arguments ('--become', '--become-user', and '--ask-become-pass')"
- " are exclusive of each other")
+ self.parser.error("Sudo arguments ('--sudo', '--sudo-user', and '--ask-sudo-pass') and su arguments ('--su', '--su-user', and '--ask-su-pass') "
+ "and become arguments ('--become', '--become-user', and '--ask-become-pass') are exclusive of each other")
if fork_opts:
if op.forks < 1:
@@ -283,20 +281,13 @@ class CLI(with_metaclass(ABCMeta, object)):
setattr(parser.values, option.dest, os.path.expanduser(value))
@staticmethod
- def unfrack_path(option, opt, value, parser):
- setattr(parser.values, option.dest, unfrackpath(value))
+ def unfrack_paths(option, opt, value, parser):
+ if isinstance(value, string_types):
+ setattr(parser.values, option.dest, [unfrackpath(x) for x in value.split(os.sep)])
@staticmethod
- def expand_paths(option, opt, value, parser):
- """optparse action callback to convert a PATH style string arg to a list of path strings.
-
- For ex, cli arg of '-p /blip/foo:/foo/bar' would be split on the
- default os.pathsep and the option value would be set to
- the list ['/blip/foo', '/foo/bar']. Each path string in the list
- will also have '~/' values expand via os.path.expanduser()."""
- path_entries = value.split(os.pathsep)
- expanded_path_entries = [os.path.expanduser(path_entry) for path_entry in path_entries]
- setattr(parser.values, option.dest, expanded_path_entries)
+ def unfrack_path(option, opt, value, parser):
+ setattr(parser.values, option.dest, unfrackpath(value))
@staticmethod
def base_parser(usage="", output_opts=False, runas_opts=False, meta_opts=False, runtask_opts=False, vault_opts=False, module_opts=False,
diff --git a/lib/ansible/cli/config.py b/lib/ansible/cli/config.py
new file mode 100644
index 00000000000..bf365507351
--- /dev/null
+++ b/lib/ansible/cli/config.py
@@ -0,0 +1,181 @@
+# (c) 2017, Ansible by Red Hat, Inc.
+#
+# 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 .
+#
+# ansible-vault is a script that encrypts/decrypts YAML files. See
+# http://docs.ansible.com/playbooks_vault.html for more details.
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import os
+import shlex
+import subprocess
+import sys
+import yaml
+
+from ansible.cli import CLI
+from ansible.config.data import Setting
+from ansible.config.manager import ConfigManager
+from ansible.errors import AnsibleError, AnsibleOptionsError
+from ansible.module_utils._text import to_native, to_text
+from ansible.parsing.yaml.dumper import AnsibleDumper
+from ansible.utils.color import stringc
+from ansible.utils.path import unfrackpath
+
+
+try:
+ from __main__ import display
+except ImportError:
+ from ansible.utils.display import Display
+ display = Display()
+
+
+class ConfigCLI(CLI):
+ """ Config command line class """
+
+ VALID_ACTIONS = ("view", "edit", "update", "dump", "list")
+
+ def __init__(self, args, callback=None):
+
+ self.config_file = None
+ self.config = None
+ super(ConfigCLI, self).__init__(args, callback)
+
+ def parse(self):
+
+ self.parser = CLI.base_parser(
+ usage = "usage: %%prog [%s] [--help] [options] [ansible.cfg]" % "|".join(self.VALID_ACTIONS),
+ epilog = "\nSee '%s --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
+ )
+
+ self.parser.add_option('-c', '--config', dest='config_file', help="path to configuration file, defaults to first file found in precedence.")
+
+ self.set_action()
+
+ # options specific to self.actions
+ if self.action == "list":
+ self.parser.set_usage("usage: %prog list [options] ")
+ if self.action == "dump":
+ self.parser.set_usage("usage: %prog dump [options] [-c ansible.cfg]")
+ elif self.action == "view":
+ self.parser.set_usage("usage: %prog view [options] [-c ansible.cfg] ")
+ elif self.action == "edit":
+ self.parser.set_usage("usage: %prog edit [options] [-c ansible.cfg]")
+ elif self.action == "update":
+ self.parser.add_option('-s', '--setting', dest='setting', help="config setting, the section defaults to 'defaults'")
+ self.parser.set_usage("usage: %prog update [options] [-c ansible.cfg] -s '[section.]setting=value'")
+
+ self.options, self.args = self.parser.parse_args()
+ display.verbosity = self.options.verbosity
+
+ def run(self):
+
+ super(ConfigCLI, self).run()
+
+ if self.options.config_file:
+ self.config_file = unfrackpath(self.options.config_file, follow=False)
+ self.config = ConfigManager(self.config_file)
+ else:
+ self.config = ConfigManager()
+ self.config_file = self.config.data.get_setting('ANSIBLE_CONFIG')
+ try:
+ if not os.path.exists(self.config_file):
+ raise AnsibleOptionsError("%s does not exist or is not accessible" % (self.config_file))
+ elif not os.path.isfile(self.config_file):
+ raise AnsibleOptionsError("%s is not a valid file" % (self.config_file))
+
+ os.environ['ANSIBLE_CONFIG'] = self.config_file
+ except:
+ if self.action in ['view']:
+ raise
+ elif self.action in ['edit', 'update']:
+ display.warning("File does not exist, used empty file: %s" % self.config_file)
+
+ self.execute()
+
+ def execute_update(self):
+ '''
+ Updates a single setting in the specified ansible.cfg
+ '''
+ raise AnsibleError("Option not implemented yet")
+
+ if self.options.setting is None:
+ raise AnsibleOptionsError("update option requries a setting to update")
+
+ (entry, value) = self.options.setting.split('=')
+ if '.' in entry:
+ (section, option) = entry.split('.')
+ else:
+ section = 'defaults'
+ option = entry
+ subprocess.call([
+ 'ansible',
+ '-m','ini_file',
+ 'localhost',
+ '-c','local',
+ '-a','"dest=%s section=%s option=%s value=%s backup=yes"' % (self.config_file, section, option, value)
+ ])
+
+ def execute_view(self):
+ '''
+ Displays the current config file
+ '''
+ try:
+ with open(self.config_file, 'rb') as f:
+ self.pager(to_text(f.read(), errors='surrogate_or_strict'))
+ except Exception as e:
+ raise AnsibleError("Failed to open config file: %s" % to_native(e))
+
+ def execute_edit(self):
+ '''
+ Opens ansible.cfg in the default EDITOR
+ '''
+ raise AnsibleError("Option not implemented yet")
+ try:
+ editor = shlex.split(os.environ.get('EDITOR','vi'))
+ editor.append(self.config_file)
+ subprocess.call(editor)
+ except Exception as e:
+ raise AnsibleError("Failed to open editor: %s" % to_native(e))
+
+ def execute_list(self):
+ '''
+ list all current configs reading lib/constants.py and shows env and config file setting names
+ '''
+ self.pager(to_text(yaml.dump(self.config.initial_defs, Dumper=AnsibleDumper), errors='surrogate_or_strict'))
+
+ def execute_dump(self):
+ '''
+ Shows the current settings, merges ansible.cfg if specified
+ '''
+ text = []
+ defaults = self.config.initial_defs.copy()
+ for setting in self.config.data.get_settings():
+ if setting.name in defaults:
+ defaults[setting.name] = setting
+
+ for setting in sorted(defaults):
+ if isinstance(defaults[setting], Setting):
+ if defaults[setting].origin == 'default':
+ color = 'green'
+ else:
+ color = 'yellow'
+ msg = "%s(%s) = %s" % (setting, defaults[setting].origin, defaults[setting].value)
+ else:
+ color = 'green'
+ msg = "%s(%s) = %s" % (setting, 'default', defaults[setting].get('default'))
+ text.append(stringc(msg, color))
+
+ self.pager(to_text('\n'.join(text), errors='surrogate_or_strict'))
diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py
index a2e6b252a69..4fdcd628672 100644
--- a/lib/ansible/cli/galaxy.py
+++ b/lib/ansible/cli/galaxy.py
@@ -117,11 +117,9 @@ class GalaxyCLI(CLI):
if self.action not in ("delete", "import", "init", "login", "setup"):
# NOTE: while the option type=str, the default is a list, and the
# callback will set the value to a list.
- self.parser.add_option('-p', '--roles-path', dest='roles_path', action="callback", callback=CLI.expand_paths, type=str,
- default=C.DEFAULT_ROLES_PATH,
- help='The path to the directory containing your roles. The default is the roles_path configured in your ansible.cfg '
- 'file (/etc/ansible/roles if not configured)')
-
+ self.parser.add_option('-p', '--roles-path', dest='roles_path', action="callback", callback=CLI.unfrack_paths, default=C.DEFAULT_ROLES_PATH,
+ help='The path to the directory containing your roles. The default is the roles_path configured in your ansible.cfg'
+ 'file (/etc/ansible/roles if not configured)', type="string")
if self.action in ("init", "install"):
self.parser.add_option('-f', '--force', dest='force', action='store_true', default=False, help='Force overwriting an existing role')
@@ -308,16 +306,13 @@ class GalaxyCLI(CLI):
uses the args list of roles to be installed, unless -f was specified. The list of roles
can be a name (which will be downloaded via the galaxy API and github), or it can be a local .tar.gz file.
"""
-
role_file = self.get_opt("role_file", None)
if len(self.args) == 0 and role_file is None:
- # the user needs to specify one of either --role-file
- # or specify a single user/role name
+ # the user needs to specify one of either --role-file or specify a single user/role name
raise AnsibleOptionsError("- you must specify a user/role name or a roles file")
elif len(self.args) == 1 and role_file is not None:
- # using a role file is mutually exclusive of specifying
- # the role name on the command line
+ # using a role file is mutually exclusive of specifying the role name on the command line
raise AnsibleOptionsError("- please specify a user/role name, or a roles file, but not both")
no_deps = self.get_opt("no_deps", False)
diff --git a/lib/ansible/config/__init__.py b/lib/ansible/config/__init__.py
index ae8ccff5952..e69de29bb2d 100644
--- a/lib/ansible/config/__init__.py
+++ b/lib/ansible/config/__init__.py
@@ -1,20 +0,0 @@
-# (c) 2012-2014, Michael DeHaan
-#
-# 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 .
-
-# Make coding more python3-ish
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
diff --git a/lib/ansible/config/data.py b/lib/ansible/config/data.py
new file mode 100644
index 00000000000..9158e2413d3
--- /dev/null
+++ b/lib/ansible/config/data.py
@@ -0,0 +1,63 @@
+# (c) 2017, Ansible by 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 .
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from collections import namedtuple
+
+Setting = namedtuple('Setting','name value origin')
+
+class ConfigData(object):
+
+ BOOL_TRUE = frozenset(["true", "t", "y", "1", "yes", "on"])
+
+ def __init__(self):
+ self._global_settings = {}
+ self._plugins = {}
+
+ def get_setting(self, name, plugin=None):
+
+ setting = None
+ if plugin is None:
+ setting = self._global_settings.get(name)
+ elif plugin.type in self._plugins and plugin.name in self._plugins[plugin.type]:
+ setting = self._plugins[plugin.type][plugin.name].get(name)
+
+ return setting
+
+ def get_settings(self, plugin=None):
+
+ settings = []
+ if plugin is None:
+ settings = [ self._global_settings[k] for k in self._global_settings ]
+ elif plugin.type in self._plugins and plugin.name in self._plugins[plugin.type]:
+ settings = [ self._plugins[plugin.type][plugin.name][k] for k in self._plugins[plugin.type][plugin.name] ]
+
+ return settings
+
+ def update_setting(self, setting, plugin=None):
+
+ if plugin is None:
+ self._global_settings[setting.name] = setting
+ else:
+ if plugin.type not in self._plugins:
+ self._plugins[plugin.type] = {}
+ if plugin.name not in self._plugins[plugin.type]:
+ self._plugins[plugin.type][plugin.name] = {}
+ self._plugins[plugin.type][plugin.name][setting.name] = setting
diff --git a/lib/ansible/config/data/config.yml b/lib/ansible/config/data/config.yml
new file mode 100644
index 00000000000..1eac76a1b79
--- /dev/null
+++ b/lib/ansible/config/data/config.yml
@@ -0,0 +1,1355 @@
+ACCELERATE_CONNECT_TIMEOUT:
+ default: 1.0
+ desc:
+ - This setting controls the timeout for the socket connect call, and should be kept relatively low.
+ The connection to the accelerate_port will be attempted 3 times before Ansible will fall back to ssh or paramiko
+ (depending on your default connection setting) to try and start the accelerate daemon remotely.
+ - Note, this value can be set to less than one second, however it is probably not a good idea to do so
+ unless you’re on a very fast and reliable LAN. If you’re connecting to systems over the internet, it may be necessary to increase this timeout.
+ env: [{name: ACCELERATE_CONNECT_TIMEOUT }]
+ ini:
+ - {key: accelerate_connect_timeout, section: accelerate}
+ value_type: float
+ vars: []
+ yaml: {key: accelerate.accelerate_connect_timeout}
+ version_added: "1.4"
+ACCELERATE_DAEMON_TIMEOUT:
+ default: 30
+ desc:
+ - This setting controls the timeout for the accelerated daemon, as measured in minutes. The default daemon timeout is 30 minutes.
+ - Prior to 1.6, the timeout was hard-coded from the time of the daemon’s launch.
+ - For version 1.6+, the timeout is now based on the last activity to the daemon and is configurable via this option.
+ env: [{name: ACCELERATE_DAEMON_TIMEOUT}]
+ ini:
+ - {key: accelerate_daemon_timeout, section: accelerate}
+ value_type: integer
+ vars: []
+ yaml: {key: accelerate.accelerate_daemon_timeout}
+ version_added: "1.6"
+ACCELERATE_KEYS_DIR:
+ default: ~/.fireball.keys
+ desc: 'TODO: write it'
+ env: [{name: ACCELERATE_KEYS_DIR}]
+ ini:
+ - {key: accelerate_keys_dir, section: accelerate}
+ vars: []
+ yaml: {key: accelerate.accelerate_keys_dir}
+ACCELERATE_KEYS_DIR_PERMS:
+ default: '700'
+ desc: 'TODO: write it'
+ env: [{name: ACCELERATE_KEYS_DIR_PERMS}]
+ ini:
+ - {key: accelerate_keys_dir_perms, section: accelerate}
+ vars: []
+ yaml: {key: accelerate.accelerate_keys_dir_perms}
+ACCELERATE_KEYS_FILE_PERMS:
+ default: '600'
+ desc: 'TODO: write it'
+ env: [{name: ACCELERATE_KEYS_FILE_PERMS}]
+ ini:
+ - {key: accelerate_keys_file_perms, section: accelerate}
+ vars: []
+ yaml: {key: accelerate.accelerate_keys_file_perms}
+ACCELERATE_MULTI_KEY:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ACCELERATE_MULTI_KEY}]
+ ini:
+ - {key: accelerate_multi_key, section: accelerate}
+ value_type: boolean
+ vars: []
+ yaml: {key: accelerate.accelerate_multi_key}
+ACCELERATE_PORT:
+ default: 5099
+ desc: 'TODO: write it'
+ env: [{name: ACCELERATE_PORT}]
+ ini:
+ - {key: accelerate_port, section: accelerate}
+ value_type: integer
+ vars: []
+ yaml: {key: accelerate.accelerate_port}
+ACCELERATE_TIMEOUT:
+ default: 30
+ desc: 'TODO: write it'
+ env: [{name: ACCELERATE_TIMEOUT}]
+ ini:
+ - {key: accelerate_timeout, section: accelerate}
+ value_type: integer
+ vars: []
+ yaml: {key: accelerate.accelerate_timeout}
+ALLOW_WORLD_READABLE_TMPFILES:
+ default: False
+ desc: 'TODO: write it'
+ env: []
+ ini:
+ - {key: allow_world_readable_tmpfiles, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.allow_world_readable_tmpfiles}
+ANSIBLE_COW_SELECTION:
+ default: default
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COW_SELECTION}]
+ ini:
+ - {key: cow_selection, section: defaults}
+ vars: []
+ yaml: {key: defaults.cow_selection}
+ANSIBLE_COW_WHITELIST:
+ 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']
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COW_WHITELIST}]
+ ini:
+ - {key: cow_whitelist, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.cow_whitelist}
+ANSIBLE_FORCE_COLOR:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_FORCE_COLOR}]
+ ini:
+ - {key: force_color, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.force_color}
+ANSIBLE_NOCOLOR:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_NOCOLOR}]
+ ini:
+ - {key: nocolor, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.nocolor}
+ANSIBLE_NOCOWS:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_NOCOWS}]
+ ini:
+ - {key: nocows, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.nocows}
+ANSIBLE_SSH_ARGS:
+ default: -C -o ControlMaster=auto -o ControlPersist=60s
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SSH_ARGS}]
+ ini:
+ - {key: ssh_args, section: ssh_connection}
+ vars: []
+ yaml: {key: ssh_connection.ssh_args}
+ANSIBLE_SSH_CONTROL_PATH:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SSH_CONTROL_PATH}]
+ ini:
+ - {key: control_path, section: ssh_connection}
+ vars: []
+ yaml: {key: ssh_connection.control_path}
+ANSIBLE_SSH_CONTROL_PATH_DIR:
+ default: ~/.ansible/cp
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SSH_CONTROL_PATH_DIR}]
+ ini:
+ - {key: control_path_dir, section: ssh_connection}
+ vars: []
+ yaml: {key: ssh_connection.control_path_dir}
+ANSIBLE_SSH_EXECUTABLE:
+ default: ssh
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SSH_EXECUTABLE}]
+ ini:
+ - {key: ssh_executable, section: ssh_connection}
+ vars: []
+ yaml: {key: ssh_connection.ssh_executable}
+ANSIBLE_SSH_PIPELINING:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SSH_PIPELINING}]
+ ini:
+ - {key: pipelining, section: ssh_connection}
+ value_type: boolean
+ vars: []
+ yaml: {key: ssh_connection.pipelining}
+ANSIBLE_SSH_RETRIES:
+ default: 0
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SSH_RETRIES}]
+ ini:
+ - {key: retries, section: ssh_connection}
+ value_type: integer
+ vars: []
+ yaml: {key: ssh_connection.retries}
+BECOME_ALLOW_SAME_USER:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_BECOME_ALLOW_SAME_USER}]
+ ini:
+ - {key: become_allow_same_user, section: privilege_escalation}
+ value_type: boolean
+ vars: []
+ yaml: {key: privilege_escalation.become_allow_same_user}
+CACHE_PLUGIN:
+ default: memory
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CACHE_PLUGIN}]
+ ini:
+ - {key: fact_caching, section: defaults}
+ vars: []
+ yaml: {key: defaults.fact_caching}
+CACHE_PLUGIN_CONNECTION:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CACHE_PLUGIN_CONNECTION}]
+ ini:
+ - {key: fact_caching_connection, section: defaults}
+ vars: []
+ yaml: {key: defaults.fact_caching_connection}
+CACHE_PLUGIN_PREFIX:
+ default: ansible_facts
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CACHE_PLUGIN_PREFIX}]
+ ini:
+ - {key: fact_caching_prefix, section: defaults}
+ vars: []
+ yaml: {key: defaults.fact_caching_prefix}
+CACHE_PLUGIN_TIMEOUT:
+ default: 86400
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CACHE_PLUGIN_TIMEOUT}]
+ ini:
+ - {key: fact_caching_timeout, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.fact_caching_timeout}
+COLOR_CHANGED:
+ default: yellow
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_CHANGED}]
+ ini:
+ - {key: changed, section: colors}
+ vars: []
+ yaml: {key: colors.changed}
+COLOR_DEBUG:
+ default: dark gray
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_DEBUG}]
+ ini:
+ - {key: debug, section: colors}
+ vars: []
+ yaml: {key: colors.debug}
+COLOR_DEPRECATE:
+ default: purple
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_DEPRECATE}]
+ ini:
+ - {key: deprecate, section: colors}
+ vars: []
+ yaml: {key: colors.deprecate}
+COLOR_DIFF_ADD:
+ default: green
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_DIFF_ADD}]
+ ini:
+ - {key: diff_add, section: colors}
+ vars: []
+ yaml: {key: colors.diff_add}
+COLOR_DIFF_LINES:
+ default: cyan
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_DIFF_LINES}]
+ ini:
+ - {key: diff_lines, section: colors}
+ vars: []
+ yaml: {key: colors.diff_lines}
+COLOR_DIFF_REMOVE:
+ default: red
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_DIFF_REMOVE}]
+ ini:
+ - {key: diff_remove, section: colors}
+ vars: []
+ yaml: {key: colors.diff_remove}
+COLOR_ERROR:
+ default: red
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_ERROR}]
+ ini:
+ - {key: error, section: colors}
+ vars: []
+ yaml: {key: colors.error}
+COLOR_HIGHLIGHT:
+ default: white
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_HIGHLIGHT}]
+ ini:
+ - {key: highlight, section: colors}
+ vars: []
+ yaml: {key: colors.highlight}
+COLOR_OK:
+ default: green
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_OK}]
+ ini:
+ - {key: ok, section: colors}
+ vars: []
+ yaml: {key: colors.ok}
+COLOR_SKIP:
+ default: cyan
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_SKIP}]
+ ini:
+ - {key: skip, section: colors}
+ vars: []
+ yaml: {key: colors.skip}
+COLOR_UNREACHABLE:
+ default: bright red
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_UNREACHABLE}]
+ ini:
+ - {key: unreachable, section: colors}
+ vars: []
+ yaml: {key: colors.unreachable}
+COLOR_VERBOSE:
+ default: blue
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_VERBOSE}]
+ ini:
+ - {key: verbose, section: colors}
+ vars: []
+ yaml: {key: colors.verbose}
+COLOR_WARN:
+ default: bright purple
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COLOR_WARN}]
+ ini:
+ - {key: warn, section: colors}
+ vars: []
+ yaml: {key: colors.warn}
+COMMAND_WARNINGS:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_COMMAND_WARNINGS}]
+ ini:
+ - {key: command_warnings, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.command_warnings}
+DEFAULT_ACTION_PLUGIN_PATH:
+ default: ~/.ansible/plugins/action:/usr/share/ansible/plugins/action
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ACTION_PLUGINS}]
+ ini:
+ - {key: action_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.action_plugins}
+DEFAULT_ALLOW_UNSAFE_LOOKUPS:
+ default: False
+ desc: 'TODO: write it'
+ env: []
+ ini:
+ - {key: allow_unsafe_lookups, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.allow_unsafe_lookups}
+DEFAULT_ASK_PASS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ASK_PASS}]
+ ini:
+ - {key: ask_pass, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.ask_pass}
+DEFAULT_ASK_SUDO_PASS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ASK_SUDO_PASS}]
+ ini:
+ - {key: ask_sudo_pass, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.ask_sudo_pass}
+DEFAULT_ASK_SU_PASS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ASK_SU_PASS}]
+ ini:
+ - {key: ask_su_pass, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.ask_su_pass}
+DEFAULT_ASK_VAULT_PASS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ASK_VAULT_PASS}]
+ ini:
+ - {key: ask_vault_pass, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.ask_vault_pass}
+DEFAULT_BECOME:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_BECOME}]
+ ini:
+ - {key: become, section: privilege_escalation}
+ value_type: boolean
+ vars: []
+ yaml: {key: privilege_escalation.become}
+DEFAULT_BECOME_ASK_PASS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_BECOME_ASK_PASS}]
+ ini:
+ - {key: become_ask_pass, section: privilege_escalation}
+ value_type: boolean
+ vars: []
+ yaml: {key: privilege_escalation.become_ask_pass}
+DEFAULT_BECOME_EXE:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_BECOME_EXE}]
+ ini:
+ - {key: become_exe, section: privilege_escalation}
+ vars: []
+ yaml: {key: privilege_escalation.become_exe}
+DEFAULT_BECOME_FLAGS:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_BECOME_FLAGS}]
+ ini:
+ - {key: become_flags, section: privilege_escalation}
+ vars: []
+ yaml: {key: privilege_escalation.become_flags}
+DEFAULT_BECOME_METHOD:
+ default: 'sudo'
+ desc:
+ env: [{name: ANSIBLE_BECOME_METHOD}]
+ ini:
+ - {section: privilege_escalation, key: become_method}
+ vars: []
+ yaml: {key: privilege_escalation.become_method}
+DEFAULT_BECOME_USER:
+ default: root
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_BECOME_USER}]
+ ini:
+ - {key: become_user, section: privilege_escalation}
+ vars: []
+ yaml: {key: privilege_escalation.become_user}
+DEFAULT_CACHE_PLUGIN_PATH:
+ default: ~/.ansible/plugins/cache:/usr/share/ansible/plugins/cache
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CACHE_PLUGINS}]
+ ini:
+ - {key: cache_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.cache_plugins}
+DEFAULT_CALLABLE_WHITELIST:
+ default: []
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CALLABLE_WHITELIST}]
+ ini:
+ - {key: callable_whitelist, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.callable_whitelist}
+DEFAULT_CALLBACK_PLUGIN_PATH:
+ default: ~/.ansible/plugins/callback:/usr/share/ansible/plugins/callback
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CALLBACK_PLUGINS}]
+ ini:
+ - {key: callback_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.callback_plugins}
+DEFAULT_CALLBACK_WHITELIST:
+ default: []
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CALLBACK_WHITELIST}]
+ ini:
+ - {key: callback_whitelist, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.callback_whitelist}
+DEFAULT_CONNECTION_PLUGIN_PATH:
+ default: ~/.ansible/plugins/connection:/usr/share/ansible/plugins/connection
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_CONNECTION_PLUGINS}]
+ ini:
+ - {key: connection_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.connection_plugins}
+DEFAULT_DEBUG:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_DEBUG}]
+ ini:
+ - {key: debug, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.debug}
+DEFAULT_EXECUTABLE:
+ default: /bin/sh
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_EXECUTABLE}]
+ ini:
+ - {key: executable, section: defaults}
+ vars: []
+ yaml: {key: defaults.executable}
+DEFAULT_FACT_PATH:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_FACT_PATH}]
+ ini:
+ - {key: fact_path, section: defaults}
+ value_type: path
+ vars: []
+ yaml: {key: defaults.fact_path}
+DEFAULT_FILTER_PLUGIN_PATH:
+ default: ~/.ansible/plugins/filter:/usr/share/ansible/plugins/filter
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_FILTER_PLUGINS}]
+ ini:
+ - {key: filter_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.filter_plugins}
+DEFAULT_FORCE_HANDLERS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_FORCE_HANDLERS}]
+ ini:
+ - {key: force_handlers, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.force_handlers}
+DEFAULT_FORKS:
+ default: 5
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_FORKS}]
+ ini:
+ - {key: forks, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.forks}
+DEFAULT_GATHERING:
+ default: 'implicit'
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GATHERING}]
+ ini:
+ - key: gathering
+ section: defaults
+ vars: []
+ yaml: {key: defaults.gathering}
+DEFAULT_GATHER_SUBSET:
+ default: 'all'
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GATHER_SUBSET}]
+ ini:
+ - key: gather_subset
+ section: defaults
+ vars: []
+ yaml: {key: defaults.gather_subset}
+DEFAULT_GATHER_TIMEOUT:
+ default: 10
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GATHER_TIMEOUT}]
+ ini:
+ - {key: gather_timeout, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.gather_timeout}
+DEFAULT_HANDLER_INCLUDES_STATIC:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_HANDLER_INCLUDES_STATIC}]
+ ini:
+ - {key: handler_includes_static, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.handler_includes_static}
+DEFAULT_HASH_BEHAVIOUR:
+ default: replace
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_HASH_BEHAVIOUR}]
+ ini:
+ - {key: hash_behaviour, section: defaults}
+ vars: []
+ yaml: {key: defaults.hash_behaviour}
+DEFAULT_HOST_LIST:
+ default: /etc/ansible/hosts
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_INVENTORY}]
+ expand_relative_paths: True
+ ini:
+ - {key: inventory, section: defaults}
+ value_type: path
+ vars: []
+ yaml: {key: defaults.inventory}
+DEFAULT_INTERNAL_POLL_INTERVAL:
+ default: 0.001
+ desc: 'TODO: write it'
+ env: []
+ ini:
+ - {key: internal_poll_interval, section: defaults}
+ value_type: float
+ vars: []
+ yaml: {key: defaults.internal_poll_interval}
+DEFAULT_INVENTORY_PLUGIN_PATH:
+ default: ~/.ansible/plugins/inventory:/usr/share/ansible/plugins/inventory
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_INVENTORY_PLUGINS}]
+ ini:
+ - {key: inventory_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.inventory_plugins}
+DEFAULT_JINJA2_EXTENSIONS:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_JINJA2_EXTENSIONS}]
+ ini:
+ - {key: jinja2_extensions, section: defaults}
+ vars: []
+ yaml: {key: defaults.jinja2_extensions}
+DEFAULT_KEEP_REMOTE_FILES:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_KEEP_REMOTE_FILES}]
+ ini:
+ - {key: keep_remote_files, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.keep_remote_files}
+DEFAULT_LIBVIRT_LXC_NOSECLABEL:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: LIBVIRT_LXC_NOSECLABEL}]
+ ini:
+ - {key: libvirt_lxc_noseclabel, section: selinux}
+ value_type: boolean
+ vars: []
+ yaml: {key: selinux.libvirt_lxc_noseclabel}
+DEFAULT_LOAD_CALLBACK_PLUGINS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_LOAD_CALLBACK_PLUGINS}]
+ ini:
+ - {key: bin_ansible_callbacks, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.bin_ansible_callbacks}
+DEFAULT_LOCAL_TMP:
+ default: ~/.ansible/tmp
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_LOCAL_TEMP}]
+ ini:
+ - {key: local_tmp, section: defaults}
+ value_type: tmppath
+ vars: []
+ yaml: {key: defaults.local_tmp}
+DEFAULT_LOG_PATH:
+ default: ''
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_LOG_PATH}]
+ ini:
+ - {key: log_path, section: defaults}
+ value_type: path
+ vars: []
+ yaml: {key: defaults.log_path}
+DEFAULT_LOOKUP_PLUGIN_PATH:
+ default: ~/.ansible/plugins/lookup:/usr/share/ansible/plugins/lookup
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_LOOKUP_PLUGINS}]
+ ini:
+ - {key: lookup_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.lookup_plugins}
+DEFAULT_MANAGED_STR:
+ default: Ansible managed
+ desc: 'TODO: write it'
+ env: []
+ ini:
+ - {key: ansible_managed, section: defaults}
+ vars: []
+ yaml: {key: defaults.ansible_managed}
+DEFAULT_MODULE_ARGS:
+ default: ''
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_MODULE_ARGS}]
+ ini:
+ - {key: module_args, section: defaults}
+ vars: []
+ yaml: {key: defaults.module_args}
+DEFAULT_MODULE_COMPRESSION:
+ default: ZIP_DEFLATED
+ desc: 'TODO: write it'
+ env: []
+ ini:
+ - {key: module_compression, section: defaults}
+ vars: []
+ yaml: {key: defaults.module_compression}
+DEFAULT_MODULE_LANG:
+ default: os.getenv('LANG', 'en_US.UTF-8')
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_MODULE_LANG}]
+ ini:
+ - {key: module_lang, section: defaults}
+ vars: []
+ yaml: {key: defaults.module_lang}
+DEFAULT_MODULE_NAME:
+ default: command
+ desc: 'TODO: write it'
+ env: []
+ ini:
+ - {key: module_name, section: defaults}
+ vars: []
+ yaml: {key: defaults.module_name}
+DEFAULT_MODULE_PATH:
+ default: ~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_LIBRARY}]
+ ini:
+ - {key: library, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.library}
+DEFAULT_MODULE_SET_LOCALE:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_MODULE_SET_LOCALE}]
+ ini:
+ - {key: module_set_locale, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.module_set_locale}
+DEFAULT_MODULE_UTILS_PATH:
+ default: ~/.ansible/plugins/module_utils:/usr/share/ansible/plugins/module_utils
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_MODULE_UTILS}]
+ ini:
+ - {key: module_utils, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.module_utils}
+DEFAULT_NO_LOG:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_NO_LOG}]
+ ini:
+ - {key: no_log, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.no_log}
+DEFAULT_NO_TARGET_SYSLOG:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_NO_TARGET_SYSLOG}]
+ ini:
+ - {key: no_target_syslog, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.no_target_syslog}
+DEFAULT_NULL_REPRESENTATION:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_NULL_REPRESENTATION}]
+ ini:
+ - {key: null_representation, section: defaults}
+ value_type: none
+ vars: []
+ yaml: {key: defaults.null_representation}
+DEFAULT_POLL_INTERVAL:
+ default: 15
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_POLL_INTERVAL}]
+ ini:
+ - {key: poll_interval, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.poll_interval}
+DEFAULT_PRIVATE_KEY_FILE:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PRIVATE_KEY_FILE}]
+ ini:
+ - {key: private_key_file, section: defaults}
+ value_type: path
+ vars: []
+ yaml: {key: defaults.private_key_file}
+DEFAULT_PRIVATE_ROLE_VARS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PRIVATE_ROLE_VARS}]
+ ini:
+ - {key: private_role_vars, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.private_role_vars}
+DEFAULT_REMOTE_PORT:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_REMOTE_PORT}]
+ ini:
+ - {key: remote_port, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.remote_port}
+DEFAULT_REMOTE_TMP:
+ default: ~/.ansible/tmp
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_REMOTE_TEMP}]
+ ini:
+ - {key: remote_tmp, section: defaults}
+ vars: []
+ yaml: {key: defaults.remote_tmp}
+DEFAULT_REMOTE_USER:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_REMOTE_USER}]
+ ini:
+ - {key: remote_user, section: defaults}
+ vars: []
+ yaml: {key: defaults.remote_user}
+DEFAULT_ROLES_PATH:
+ default: ~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ROLES_PATH}]
+ expand_relative_paths: True
+ ini:
+ - {key: roles_path, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.roles_path}
+DEFAULT_SCP_IF_SSH:
+ default: smart
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SCP_IF_SSH}]
+ ini:
+ - {key: scp_if_ssh, section: ssh_connection}
+ vars: []
+ yaml: {key: ssh_connection.scp_if_ssh}
+DEFAULT_SELINUX_SPECIAL_FS:
+ default: fuse, nfs, vboxsf, ramfs, 9p
+ desc: 'TODO: write it'
+ env: []
+ ini:
+ - {key: special_context_filesystems, section: selinux}
+ value_type: list
+ vars: []
+ yaml: {key: selinux.special_context_filesystems}
+DEFAULT_SFTP_BATCH_MODE:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SFTP_BATCH_MODE}]
+ ini:
+ - {key: sftp_batch_mode, section: ssh_connection}
+ value_type: boolean
+ vars: []
+ yaml: {key: ssh_connection.sftp_batch_mode}
+DEFAULT_SQUASH_ACTIONS:
+ default: apk, apt, dnf, homebrew, openbsd_pkg, pacman, pkgng, yum, zypper
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SQUASH_ACTIONS}]
+ ini:
+ - {key: squash_actions, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.squash_actions}
+DEFAULT_SSH_TRANSFER_METHOD:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SSH_TRANSFER_METHOD}]
+ ini:
+ - {key: transfer_method, section: ssh_connection}
+ vars: []
+ yaml: {key: ssh_connection.transfer_method}
+DEFAULT_STDOUT_CALLBACK:
+ default: default
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_STDOUT_CALLBACK}]
+ ini:
+ - {key: stdout_callback, section: defaults}
+ vars: []
+ yaml: {key: defaults.stdout_callback}
+DEFAULT_STRATEGY:
+ default: linear
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_STRATEGY}]
+ ini:
+ - {key: strategy, section: defaults}
+ vars: []
+ yaml: {key: defaults.strategy}
+DEFAULT_STRATEGY_PLUGIN_PATH:
+ default: ~/.ansible/plugins/strategy:/usr/share/ansible/plugins/strategy
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_STRATEGY_PLUGINS}]
+ ini:
+ - {key: strategy_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.strategy_plugins}
+DEFAULT_SU:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SU}]
+ ini:
+ - {key: su, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.su}
+DEFAULT_SUDO:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SUDO}]
+ ini:
+ - {key: sudo, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.sudo}
+DEFAULT_SUDO_EXE:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SUDO_EXE}]
+ ini:
+ - {key: sudo_exe, section: defaults}
+ vars: []
+ yaml: {key: defaults.sudo_exe}
+DEFAULT_SUDO_FLAGS:
+ default: -H -S -n
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SUDO_FLAGS}]
+ ini:
+ - {key: sudo_flags, section: defaults}
+ vars: []
+ yaml: {key: defaults.sudo_flags}
+DEFAULT_SUDO_USER:
+ default: root
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SUDO_USER}]
+ ini:
+ - {key: sudo_user, section: defaults}
+ vars: []
+ yaml: {key: defaults.sudo_user}
+DEFAULT_SU_EXE:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SU_EXE}]
+ ini:
+ - {key: su_exe, section: defaults}
+ vars: []
+ yaml: {key: defaults.su_exe}
+DEFAULT_SU_FLAGS:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SU_FLAGS}]
+ ini:
+ - {key: su_flags, section: defaults}
+ vars: []
+ yaml: {key: defaults.su_flags}
+DEFAULT_SU_USER:
+ default: root
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SU_USER}]
+ ini:
+ - {key: su_user, section: defaults}
+ vars: []
+ yaml: {key: defaults.su_user}
+DEFAULT_SYSLOG_FACILITY:
+ default: LOG_USER
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SYSLOG_FACILITY}]
+ ini:
+ - {key: syslog_facility, section: defaults}
+ vars: []
+ yaml: {key: defaults.syslog_facility}
+DEFAULT_TASK_INCLUDES_STATIC:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_TASK_INCLUDES_STATIC}]
+ ini:
+ - {key: task_includes_static, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.task_includes_static}
+DEFAULT_TEST_PLUGIN_PATH:
+ default: ~/.ansible/plugins/test:/usr/share/ansible/plugins/test
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_TEST_PLUGINS}]
+ ini:
+ - {key: test_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.test_plugins}
+DEFAULT_TIMEOUT:
+ default: 10
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_TIMEOUT}]
+ ini:
+ - {key: timeout, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.timeout}
+DEFAULT_TRANSPORT:
+ default: smart
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_TRANSPORT}]
+ ini:
+ - {key: transport, section: defaults}
+ vars: []
+ yaml: {key: defaults.transport}
+DEFAULT_UNDEFINED_VAR_BEHAVIOR:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ERROR_ON_UNDEFINED_VARS}]
+ ini:
+ - {key: error_on_undefined_vars, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.error_on_undefined_vars}
+DEFAULT_VARS_PLUGIN_PATH:
+ default: ~/.ansible/plugins/vars:/usr/share/ansible/plugins/vars
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_VARS_PLUGINS}]
+ ini:
+ - {key: vars_plugins, section: defaults}
+ value_type: pathlist
+ vars: []
+ yaml: {key: defaults.vars_plugins}
+DEFAULT_VAR_COMPRESSION_LEVEL:
+ default: 0
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_VAR_COMPRESSION_LEVEL}]
+ ini:
+ - {key: var_compression_level, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.var_compression_level}
+DEFAULT_VAULT_PASSWORD_FILE:
+ default: ~
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_VAULT_PASSWORD_FILE}]
+ ini:
+ - {key: vault_password_file, section: defaults}
+ value_type: path
+ vars: []
+ yaml: {key: defaults.vault_password_file}
+DEFAULT_VERBOSITY:
+ default: 0
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_VERBOSITY}]
+ ini:
+ - {key: verbosity, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.verbosity}
+DEPRECATION_WARNINGS:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_DEPRECATION_WARNINGS}]
+ ini:
+ - {key: deprecation_warnings, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.deprecation_warnings}
+DIFF_ALWAYS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_DIFF_ALWAYS}]
+ ini:
+ - {key: always, section: diff}
+ value_type: bool
+ vars: []
+ yaml: {key: diff.always}
+DIFF_CONTEXT:
+ default: 3
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_DIFF_CONTEXT}]
+ ini:
+ - {key: context, section: diff}
+ value_type: integer
+ vars: []
+ yaml: {key: diff.context}
+DISPLAY_ARGS_TO_STDOUT:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_DISPLAY_ARGS_TO_STDOUT}]
+ ini:
+ - {key: display_args_to_stdout, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.display_args_to_stdout}
+DISPLAY_SKIPPED_HOSTS:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: DISPLAY_SKIPPED_HOSTS}]
+ ini:
+ - {key: display_skipped_hosts, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.display_skipped_hosts}
+ERROR_ON_MISSING_HANDLER:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_ERROR_ON_MISSING_HANDLER}]
+ ini:
+ - {key: error_on_missing_handler, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.error_on_missing_handler}
+GALAXY_IGNORE_CERTS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GALAXY_IGNORE}]
+ ini:
+ - {key: ignore_certs, section: galaxy}
+ value_type: boolean
+ vars: []
+ yaml: {key: galaxy.ignore_certs}
+GALAXY_ROLE_SKELETON:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GALAXY_ROLE_SKELETON}]
+ ini:
+ - {key: role_skeleton, section: galaxy}
+ value_type: path
+ vars: []
+ yaml: {key: galaxy.role_skeleton}
+GALAXY_ROLE_SKELETON_IGNORE:
+ default: [^.git$, ^.*/.git_keep$]
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GALAXY_ROLE_SKELETON_IGNORE}]
+ ini:
+ - {key: role_skeleton_ignore, section: galaxy}
+ value_type: list
+ vars: []
+ yaml: {key: galaxy.role_skeleton_ignore}
+GALAXY_SCMS:
+ default: git, hg
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GALAXY_SCMS}]
+ ini:
+ - {key: scms, section: galaxy}
+ value_type: list
+ vars: []
+ yaml: {key: galaxy.scms}
+GALAXY_SERVER:
+ default: https://galaxy.ansible.com
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_GALAXY_SERVER}]
+ ini:
+ - {key: server, section: galaxy}
+ vars: []
+ yaml: {key: galaxy.server}
+HOST_KEY_CHECKING:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_HOST_KEY_CHECKING}]
+ ini:
+ - {key: host_key_checking, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.host_key_checking}
+INVENTORY_ENABLED:
+ default: [host_list, script, yaml, ini]
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_INVENTORY_ENABLED}]
+ ini:
+ - {key: inventory_enabled, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.inventory_enabled}
+INVENTORY_IGNORE_EXTS:
+ default: ['.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt', '.orig', '.ini', '.cfg', '.retry']
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_INVENTORY_IGNORE}]
+ ini:
+ - {key: inventory_ignore_extensions, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.inventory_ignore_extensions}
+INVENTORY_IGNORE_PATTERNS:
+ default: []
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_INVENTORY_IGNORE_REGEX}]
+ ini:
+ - {key: inventory_ignore_patterns, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.inventory_ignore_patterns}
+MAX_FILE_SIZE_FOR_DIFF:
+ default: 104448
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_MAX_DIFF_SIZE}]
+ ini:
+ - {key: max_diff_size, section: defaults}
+ value_type: integer
+ vars: []
+ yaml: {key: defaults.max_diff_size}
+MERGE_MULTIPLE_CLI_TAGS:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_MERGE_MULTIPLE_CLI_TAGS}]
+ ini:
+ - {key: merge_multiple_cli_tags, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.merge_multiple_cli_tags}
+NAMESPACE_FACTS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_RESTRICT_FACTS}]
+ ini:
+ - {key: restrict_facts_namespace, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.restrict_facts_namespace}
+NETWORK_GROUP_MODULES:
+ default: [eos, nxos, ios, iosxr, junos, ce, vyos, sros, dellos9, dellos10, dellos6]
+ desc: 'TODO: write it'
+ env: [{name: NETWORK_GROUP_MODULES}]
+ ini:
+ - {key: network_group_modules, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.network_group_modules}
+PARAMIKO_HOST_KEY_AUTO_ADD:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD}]
+ ini:
+ - {key: host_key_auto_add, section: paramiko_connection}
+ value_type: boolean
+ vars: []
+ yaml: {key: paramiko_connection.host_key_auto_add}
+PARAMIKO_LOOK_FOR_KEYS:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PARAMIKO_LOOK_FOR_KEYS}]
+ ini:
+ - {key: look_for_keys, section: paramiko_connection}
+ value_type: boolean
+ vars: []
+ yaml: {key: paramiko_connection.look_for_keys}
+PARAMIKO_PROXY_COMMAND:
+ default:
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PARAMIKO_PROXY_COMMAND}]
+ ini:
+ - {key: proxy_command, section: paramiko_connection}
+ vars: []
+ yaml: {key: paramiko_connection.proxy_command}
+PARAMIKO_PTY:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PARAMIKO_PTY}]
+ ini:
+ - {key: pty, section: paramiko_connection}
+ value_type: boolean
+ vars: []
+ yaml: {key: paramiko_connection.pty}
+PARAMIKO_RECORD_HOST_KEYS:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PARAMIKO_RECORD_HOST_KEYS}]
+ ini:
+ - {key: record_host_keys, section: paramiko_connection}
+ value_type: boolean
+ vars: []
+ yaml: {key: paramiko_connection.record_host_keys}
+PERSISTENT_CONNECT_INTERVAL:
+ default: 1
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PERSISTENT_CONNECT_INTERVAL}]
+ ini:
+ - {key: connect_interval, section: persistent_connection}
+ value_type: integer
+ vars: []
+ yaml: {key: persistent_connection.connect_interval}
+PERSISTENT_CONNECT_RETRIES:
+ default: 30
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PERSISTENT_CONNECT_RETRIES}]
+ ini:
+ - {key: connect_retries, section: persistent_connection}
+ value_type: integer
+ vars: []
+ yaml: {key: persistent_connection.connect_retries}
+PERSISTENT_CONNECT_TIMEOUT:
+ default: 30
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PERSISTENT_CONNECT_TIMEOUT}]
+ ini:
+ - {key: connect_timeout, section: persistent_connection}
+ value_type: integer
+ vars: []
+ yaml: {key: persistent_connection.connect_timeout}
+RETRY_FILES_ENABLED:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_RETRY_FILES_ENABLED}]
+ ini:
+ - {key: retry_files_enabled, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.retry_files_enabled}
+RETRY_FILES_SAVE_PATH:
+ default: ~
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_RETRY_FILES_SAVE_PATH}]
+ ini:
+ - {key: retry_files_save_path, section: defaults}
+ value_type: path
+ vars: []
+ yaml: {key: defaults.retry_files_save_path}
+SHOW_CUSTOM_STATS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SHOW_CUSTOM_STATS}]
+ ini:
+ - {key: show_custom_stats, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.show_custom_stats}
+STRING_TYPE_FILTERS:
+ default: [string, to_json, to_nice_json, to_yaml, ppretty, json]
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_STRING_TYPE_FILTERS}]
+ ini:
+ - {key: dont_type_filters, section: jinja2}
+ value_type: list
+ vars: []
+ yaml: {key: jinja2.dont_type_filters}
+SYSTEM_WARNINGS:
+ default: True
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_SYSTEM_WARNINGS}]
+ ini:
+ - {key: system_warnings, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.system_warnings}
+USE_PERSISTENT_CONNECTIONS:
+ default: False
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_USE_PERSISTENT_CONNECTIONS}]
+ ini:
+ - {key: use_persistent_connections, section: defaults}
+ value_type: boolean
+ vars: []
+ yaml: {key: defaults.use_persistent_connections}
+VARIABLE_PRECEDENCE:
+ default: [all_inventory, groups_inventory, all_plugins_inventory, all_plugins_play, groups_plugins_inventory, groups_plugins_play]
+ desc: 'TODO: write it'
+ env: [{name: ANSIBLE_PRECEDENCE}]
+ ini:
+ - {key: precedence, section: defaults}
+ value_type: list
+ vars: []
+ yaml: {key: defaults.precedence}
diff --git a/lib/ansible/config/manager.py b/lib/ansible/config/manager.py
new file mode 100644
index 00000000000..28a29865e86
--- /dev/null
+++ b/lib/ansible/config/manager.py
@@ -0,0 +1,242 @@
+# (c) 2017, Ansible by 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 .
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import os
+import sys
+import tempfile
+import yaml
+
+from ansible.config.data import ConfigData, Setting
+from ansible.errors import AnsibleOptionsError, AnsibleError
+from ansible.module_utils.six import string_types
+from ansible.module_utils.six.moves import configparser
+from ansible.module_utils._text import to_text, to_bytes, to_native
+from ansible.parsing.quoting import unquote
+from ansible.utils.path import unfrackpath
+from ansible.utils.path import makedirs_safe
+
+
+def resolve_path(path):
+
+ if '{{CWD}}' in path: # allow users to force CWD using 'magic' {{CWD}}
+ path = path.replace('{{CWD}}', os.getcwd())
+
+ return unfrackpath(path, follow=False)
+
+def get_ini_config(p, entries):
+ ''' returns the value of last ini entry found '''
+ value = None
+ if p is not None:
+ for entry in entries:
+ try:
+ value = p.get(entry.get('section','defaults'), entry.get('key',''), raw=True)
+ except:
+ pass
+
+ return value
+
+
+
+class ConfigManager(object):
+
+ def __init__(self, conf_file=None):
+
+ self.data = ConfigData()
+
+ #FIXME: make dynamic?
+ bconfig_def = to_bytes('%s/data/config.yml' % os.path.dirname(__file__))
+ if os.path.exists(bconfig_def):
+ with open(bconfig_def, 'rb') as config_def:
+ self.initial_defs = yaml.safe_load(config_def)
+ else:
+ raise AnsibleError("Missing base configuration definition file (bad install?): %s" % to_native(bconfig_def))
+
+ ftype = None
+ if conf_file is None:
+ # set config using ini
+ conf_file = self.find_ini_config_file()
+ ftype = 'ini'
+ else:
+ ext = os.path.splitext(conf_file)[-1]
+ if ext in ('.ini', '.cfg'):
+ ftype = 'ini'
+ elif ext in ('.yaml', '.yml'):
+ ftype = 'yaml'
+ else:
+ raise AnsibleOptionsError("Unsupported configuration file extension: \n{0}".format(ext))
+
+ self.parse_config(conf_file, ftype)
+
+ def parse_config(self, cfile, ftype):
+ # TODO: take list of files with merge/nomerge
+
+ parser = None
+ if ftype == 'ini':
+ parser = configparser.ConfigParser()
+ try:
+ parser.read(cfile)
+ except configparser.Error as e:
+ raise AnsibleOptionsError("Error reading config file: \n{0}".format(e))
+ elif ftype == 'yaml':
+ with open(cfile, 'rb') as config_stream:
+ parser = yaml.safe_load(config_stream)
+ else:
+ raise AnsibleOptionsError("Unsupported configuration file type: \n{0}".format(ftype))
+
+ self.update_config(cfile, self.initial_defs, parser, ftype)
+
+ def update_config(self, configfile, defs, parser, ftype):
+
+ # update the constant for config file
+ self.data.update_setting(Setting('CONFIG_FILE', configfile, ''))
+
+ origin = None
+ # env and config defs can have several entries, ordered in list from lowest to highest precedence
+ for config in self.initial_defs:
+
+ value = None
+ # env vars are highest precedence
+ if defs[config].get('env'):
+ try:
+ for env_var in defs[config]['env']:
+ env_value = os.environ.get(env_var.get('name'), None)
+ if env_value is not None: # only set if env var is defined
+ value = env_value
+ origin = 'env: %s' % env_var.get('name')
+ except:
+ sys.stderr.write("Error while loading environment configs for %s\n" % config)
+
+ # try config file entries next
+ if value is None and defs[config].get(ftype):
+ if ftype == 'ini':
+ # load from ini config
+ try:
+ value = get_ini_config(parser, defs[config]['ini'])
+ origin = configfile
+ except Exception as e:
+ sys.stderr.write("Error while loading ini config %s: %s" % (configfile, str(e)))
+ elif ftype == 'yaml':
+ # FIXME: break down key from defs (. notation???)
+ key = 'name'
+ value = parser.get(key)
+ origin = configfile
+
+ # set default if we got here w/o a value
+ if value is None:
+ value = defs[config].get('default')
+ origin = 'default'
+
+ # ensure correct type
+ try:
+ value = self.ensure_type(value, defs[config].get('value_type'))
+ except:
+ sys.stderr.write("Unable to set correct type for %s, skipping" % config)
+ continue
+
+ # set the constant
+ self.data.update_setting(Setting(config, value, origin))
+
+
+ def find_ini_config_file(self):
+ ''' Load Config File order(first found is used): ENV, CWD, HOME, /etc/ansible '''
+
+ path0 = os.getenv("ANSIBLE_CONFIG", None)
+ if path0 is not None:
+ path0 = unfrackpath(path0, follow=False)
+ if os.path.isdir(path0):
+ path0 += "/ansible.cfg"
+ try:
+ path1 = os.getcwd() + "/ansible.cfg"
+ except OSError:
+ path1 = None
+ path2 = unfrackpath("~/.ansible.cfg", follow=False)
+ path3 = "/etc/ansible/ansible.cfg"
+
+ for path in [path0, path1, path2, path3]:
+ if path is not None and os.path.exists(path):
+ break
+ else:
+ path = None
+
+ return path
+
+ def make_boolean(self, value):
+ ret = value
+ if not isinstance(value, bool):
+ if value is None:
+ ret = False
+ ret = (to_text(value).lower() in self.data.BOOL_TRUE)
+ return ret
+
+ def ensure_type(self, value, value_type):
+ ''' return a configuration variable with casting
+ :arg value: The value to ensure correct typing of
+ :kwarg value_type: The type of the value. This can be any of the following strings:
+ :boolean: sets the value to a True or False value
+ :integer: Sets the value to an integer or raises a ValueType error
+ :float: Sets the value to a float or raises a ValueType error
+ :list: Treats the value as a comma separated list. Split the value
+ and return it as a python list.
+ :none: Sets the value to None
+ :path: Expands any environment variables and tilde's in the value.
+ :tmp_path: Create a unique temporary directory inside of the directory
+ specified by value and return its path.
+ :pathlist: Treat the value as a typical PATH string. (On POSIX, this
+ means colon separated strings.) Split the value and then expand
+ each part for environment variables and tildes.
+ '''
+ if value_type == 'boolean':
+ value = self.make_boolean(value)
+
+ elif value:
+ if value_type == 'integer':
+ value = int(value)
+
+ elif value_type == 'float':
+ value = float(value)
+
+ elif value_type == 'list':
+ if isinstance(value, string_types):
+ value = [x.strip() for x in value.split(',')]
+
+ elif value_type == 'none':
+ if value == "None":
+ value = None
+
+ elif value_type == 'path':
+ value = resolve_path(value)
+
+ elif value_type == 'tmppath':
+ value = resolve_path(value)
+ if not os.path.exists(value):
+ makedirs_safe(value, 0o700)
+ prefix = 'ansible-local-%s' % os.getpid()
+ value = tempfile.mkdtemp(prefix=prefix, dir=value)
+
+ elif value_type == 'pathlist':
+ if isinstance(value, string_types):
+ value = [resolve_path(x) for x in value.split(os.pathsep)]
+
+ elif isinstance(value, string_types):
+ value = unquote(value)
+
+ return to_text(value, errors='surrogate_or_strict', nonstring='passthru')
+
diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py
index fe01ed6ff79..a9b810712a3 100644
--- a/lib/ansible/constants.py
+++ b/lib/ansible/constants.py
@@ -19,441 +19,40 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
-import os
-import tempfile
from string import ascii_letters, digits
-from ansible.errors import AnsibleOptionsError
-from ansible.module_utils.six import string_types
-from ansible.module_utils.six.moves import configparser
from ansible.module_utils._text import to_text
-from ansible.parsing.quoting import unquote
-from ansible.utils.path import makedirs_safe
+from ansible.config.manager import ConfigManager
-BOOL_TRUE = frozenset(["true", "t", "y", "1", "yes", "on"])
+config = ConfigManager()
+# Generate constants from config
+for setting in config.data.get_settings():
+ vars()[setting.name] = setting.value
def mk_boolean(value):
- ret = value
- if not isinstance(value, bool):
- if value is None:
- ret = False
- ret = (str(value).lower() in BOOL_TRUE)
- return ret
+ ''' moved '''
+ return config.make_boolean(value)
-def shell_expand(path, expand_relative_paths=False):
- '''
- shell_expand is needed as os.path.expanduser does not work
- when path is None, which is the default for ANSIBLE_PRIVATE_KEY_FILE
- '''
- if path:
- path = os.path.expanduser(os.path.expandvars(path))
- if expand_relative_paths and not path.startswith('/'):
- # paths are always 'relative' to the config?
- if 'CONFIG_FILE' in globals():
- CFGDIR = os.path.dirname(CONFIG_FILE)
- path = os.path.join(CFGDIR, path)
- path = os.path.abspath(path)
- return path
+### CONSTANTS ### yes, actual ones
-
-def get_config(p, section, key, env_var, default, value_type=None, expand_relative_paths=False):
- ''' return a configuration variable with casting
-
- :arg p: A ConfigParser object to look for the configuration in
- :arg section: A section of the ini config that should be examined for this section.
- :arg key: The config key to get this config from
- :arg env_var: An Environment variable to check for the config var. If
- this is set to None then no environment variable will be used.
- :arg default: A default value to assign to the config var if nothing else sets it.
- :kwarg value_type: The type of the value. This can be any of the following strings:
- :boolean: sets the value to a True or False value
- :integer: Sets the value to an integer or raises a ValueType error
- :float: Sets the value to a float or raises a ValueType error
- :list: Treats the value as a comma separated list. Split the value
- and return it as a python list.
- :none: Sets the value to None
- :path: Expands any environment variables and tilde's in the value.
- :tmp_path: Create a unique temporary directory inside of the directory
- specified by value and return its path.
- :pathlist: Treat the value as a typical PATH string. (On POSIX, this
- means colon separated strings.) Split the value and then expand
- each part for environment variables and tildes.
- :kwarg expand_relative_paths: for pathlist and path types, if this is set
- to True then also change any relative paths into absolute paths. The
- default is False.
- '''
- value = _get_config(p, section, key, env_var, default)
- if value_type == 'boolean':
- value = mk_boolean(value)
-
- elif value:
- if value_type == 'integer':
- value = int(value)
-
- elif value_type == 'float':
- value = float(value)
-
- elif value_type == 'list':
- if isinstance(value, string_types):
- value = [x.strip() for x in value.split(',')]
-
- elif value_type == 'none':
- if value == "None":
- value = None
-
- elif value_type == 'path':
- value = shell_expand(value, expand_relative_paths=expand_relative_paths)
-
- elif value_type == 'tmppath':
- value = shell_expand(value)
- if not os.path.exists(value):
- makedirs_safe(value, 0o700)
- prefix = 'ansible-local-%s' % os.getpid()
- value = tempfile.mkdtemp(prefix=prefix, dir=value)
-
- elif value_type == 'pathlist':
- if isinstance(value, string_types):
- value = [shell_expand(x, expand_relative_paths=expand_relative_paths) for x in value.split(os.pathsep)]
-
- elif isinstance(value, string_types):
- value = unquote(value)
-
- return to_text(value, errors='surrogate_or_strict', nonstring='passthru')
-
-
-def _get_config(p, section, key, env_var, default):
- ''' helper function for get_config '''
- value = default
-
- if p is not None:
- try:
- value = p.get(section, key, raw=True)
- except:
- pass
-
- if env_var is not None:
- env_value = os.environ.get(env_var, None)
- if env_value is not None:
- value = env_value
-
- return to_text(value, errors='surrogate_or_strict', nonstring='passthru')
-
-
-def load_config_file():
- ''' Load Config File order(first found is used): ENV, CWD, HOME, /etc/ansible '''
-
- p = configparser.ConfigParser()
-
- path0 = os.getenv("ANSIBLE_CONFIG", None)
- if path0 is not None:
- path0 = os.path.expanduser(path0)
- if os.path.isdir(path0):
- path0 += "/ansible.cfg"
- try:
- path1 = os.getcwd() + "/ansible.cfg"
- except OSError:
- path1 = None
- path2 = os.path.expanduser("~/.ansible.cfg")
- path3 = "/etc/ansible/ansible.cfg"
-
- for path in [path0, path1, path2, path3]:
- if path is not None and os.path.exists(path):
- try:
- p.read(path)
- except configparser.Error as e:
- raise AnsibleOptionsError("Error reading config file: \n{0}".format(e))
- return p, path
- return None, ''
-
-
-p, CONFIG_FILE = load_config_file()
-
-# non configurable but used as defaults
BLACKLIST_EXTS = ('.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt')
-# the default whitelist for cow stencils
-DEFAULT_COW_WHITELIST = ['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']
-
-# sections in config file
-DEFAULTS = 'defaults'
-
-# DEPRECATED VARS # FIXME: add deprecation warning when these get set
-# none left now
-
-# DEPRECATED FEATURE TOGGLES: these will eventually be removed as it becomes the standard
-
-# If --tags or --skip-tags is given multiple times on the CLI and this is True, merge the lists of tags together.
-# If False, let the last argument overwrite any previous ones.
-# Behaviour is overwrite through 2.2. 2.3 overwrites but prints deprecation. 2.4 the default is to merge.
-MERGE_MULTIPLE_CLI_TAGS = get_config(p, DEFAULTS, 'merge_multiple_cli_tags', 'ANSIBLE_MERGE_MULTIPLE_CLI_TAGS', True, value_type='boolean')
-
-# Controls which 'precedence path' to take, remove when decide on which!
-SOURCE_OVER_GROUPS = get_config(p, 'vars', 'source_over_groups', 'ANSIBLE_SOURCE_OVER_GROUPS', True, value_type='boolean')
-
-# GENERALLY CONFIGURABLE THINGS ####
-DEFAULT_DEBUG = get_config(p, DEFAULTS, 'debug', 'ANSIBLE_DEBUG', False, value_type='boolean')
-DEFAULT_VERBOSITY = get_config(p, DEFAULTS, 'verbosity', 'ANSIBLE_VERBOSITY', 0, value_type='integer')
-DEFAULT_ROLES_PATH = get_config(p, DEFAULTS, 'roles_path', 'ANSIBLE_ROLES_PATH',
- '~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles', value_type='pathlist', expand_relative_paths=True)
-DEFAULT_REMOTE_TMP = get_config(p, DEFAULTS, 'remote_tmp', 'ANSIBLE_REMOTE_TEMP', '~/.ansible/tmp')
-DEFAULT_LOCAL_TMP = get_config(p, DEFAULTS, 'local_tmp', 'ANSIBLE_LOCAL_TEMP', '~/.ansible/tmp', value_type='tmppath')
-DEFAULT_MODULE_NAME = get_config(p, DEFAULTS, 'module_name', None, 'command')
-DEFAULT_FACT_PATH = get_config(p, DEFAULTS, 'fact_path', 'ANSIBLE_FACT_PATH', None, value_type='path')
-DEFAULT_FORKS = get_config(p, DEFAULTS, 'forks', 'ANSIBLE_FORKS', 5, value_type='integer')
-DEFAULT_MODULE_ARGS = get_config(p, DEFAULTS, 'module_args', 'ANSIBLE_MODULE_ARGS', '')
-DEFAULT_MODULE_LANG = get_config(p, DEFAULTS, 'module_lang', 'ANSIBLE_MODULE_LANG', os.getenv('LANG', 'en_US.UTF-8'))
-DEFAULT_MODULE_SET_LOCALE = get_config(p, DEFAULTS, 'module_set_locale', 'ANSIBLE_MODULE_SET_LOCALE', False, value_type='boolean')
-DEFAULT_MODULE_COMPRESSION = get_config(p, DEFAULTS, 'module_compression', None, 'ZIP_DEFLATED')
-DEFAULT_TIMEOUT = get_config(p, DEFAULTS, 'timeout', 'ANSIBLE_TIMEOUT', 10, value_type='integer')
-DEFAULT_POLL_INTERVAL = get_config(p, DEFAULTS, 'poll_interval', 'ANSIBLE_POLL_INTERVAL', 15, value_type='integer')
-DEFAULT_REMOTE_USER = get_config(p, DEFAULTS, 'remote_user', 'ANSIBLE_REMOTE_USER', None)
-DEFAULT_ASK_PASS = get_config(p, DEFAULTS, 'ask_pass', 'ANSIBLE_ASK_PASS', False, value_type='boolean')
-DEFAULT_PRIVATE_KEY_FILE = get_config(p, DEFAULTS, 'private_key_file', 'ANSIBLE_PRIVATE_KEY_FILE', None, value_type='path')
-DEFAULT_REMOTE_PORT = get_config(p, DEFAULTS, 'remote_port', 'ANSIBLE_REMOTE_PORT', None, value_type='integer')
-DEFAULT_ASK_VAULT_PASS = get_config(p, DEFAULTS, 'ask_vault_pass', 'ANSIBLE_ASK_VAULT_PASS', False, value_type='boolean')
-DEFAULT_VAULT_PASSWORD_FILE = get_config(p, DEFAULTS, 'vault_password_file', 'ANSIBLE_VAULT_PASSWORD_FILE', None, value_type='path')
-DEFAULT_TRANSPORT = get_config(p, DEFAULTS, 'transport', 'ANSIBLE_TRANSPORT', 'smart')
-DEFAULT_SCP_IF_SSH = get_config(p, 'ssh_connection', 'scp_if_ssh', 'ANSIBLE_SCP_IF_SSH', 'smart')
-DEFAULT_SFTP_BATCH_MODE = get_config(p, 'ssh_connection', 'sftp_batch_mode', 'ANSIBLE_SFTP_BATCH_MODE', True, value_type='boolean')
-DEFAULT_SSH_TRANSFER_METHOD = get_config(p, 'ssh_connection', 'transfer_method', 'ANSIBLE_SSH_TRANSFER_METHOD', None)
-DEFAULT_MANAGED_STR = get_config(p, DEFAULTS, 'ansible_managed', None, 'Ansible managed')
-DEFAULT_SYSLOG_FACILITY = get_config(p, DEFAULTS, 'syslog_facility', 'ANSIBLE_SYSLOG_FACILITY', 'LOG_USER')
-DEFAULT_KEEP_REMOTE_FILES = get_config(p, DEFAULTS, 'keep_remote_files', 'ANSIBLE_KEEP_REMOTE_FILES', False, value_type='boolean')
-DEFAULT_HASH_BEHAVIOUR = get_config(p, DEFAULTS, 'hash_behaviour', 'ANSIBLE_HASH_BEHAVIOUR', 'replace')
-DEFAULT_PRIVATE_ROLE_VARS = get_config(p, DEFAULTS, 'private_role_vars', 'ANSIBLE_PRIVATE_ROLE_VARS', False, value_type='boolean')
-DEFAULT_JINJA2_EXTENSIONS = get_config(p, DEFAULTS, 'jinja2_extensions', 'ANSIBLE_JINJA2_EXTENSIONS', None)
-DEFAULT_EXECUTABLE = get_config(p, DEFAULTS, 'executable', 'ANSIBLE_EXECUTABLE', '/bin/sh')
-DEFAULT_GATHERING = get_config(p, DEFAULTS, 'gathering', 'ANSIBLE_GATHERING', 'implicit').lower()
-DEFAULT_GATHER_SUBSET = get_config(p, DEFAULTS, 'gather_subset', 'ANSIBLE_GATHER_SUBSET', 'all').lower()
-DEFAULT_GATHER_TIMEOUT = get_config(p, DEFAULTS, 'gather_timeout', 'ANSIBLE_GATHER_TIMEOUT', 10, value_type='integer')
-DEFAULT_LOG_PATH = get_config(p, DEFAULTS, 'log_path', 'ANSIBLE_LOG_PATH', '', value_type='path')
-DEFAULT_FORCE_HANDLERS = get_config(p, DEFAULTS, 'force_handlers', 'ANSIBLE_FORCE_HANDLERS', False, value_type='boolean')
-DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level', 'ANSIBLE_VAR_COMPRESSION_LEVEL', 0, value_type='integer')
-DEFAULT_INTERNAL_POLL_INTERVAL = get_config(p, DEFAULTS, 'internal_poll_interval', None, 0.001, value_type='float')
-DEFAULT_ALLOW_UNSAFE_LOOKUPS = get_config(p, DEFAULTS, 'allow_unsafe_lookups', None, False, value_type='boolean')
-ERROR_ON_MISSING_HANDLER = get_config(p, DEFAULTS, 'error_on_missing_handler', 'ANSIBLE_ERROR_ON_MISSING_HANDLER', True, value_type='boolean')
-SHOW_CUSTOM_STATS = get_config(p, DEFAULTS, 'show_custom_stats', 'ANSIBLE_SHOW_CUSTOM_STATS', False, value_type='boolean')
-NAMESPACE_FACTS = get_config(p, DEFAULTS, 'restrict_facts_namespace', 'ANSIBLE_RESTRICT_FACTS', False, value_type='boolean')
-
-# Inventory
-DEFAULT_HOST_LIST = get_config(p, DEFAULTS, 'inventory', 'ANSIBLE_INVENTORY', '/etc/ansible/hosts', value_type='path', expand_relative_paths=True)
-INVENTORY_ENABLED = get_config(p, DEFAULTS, 'inventory_enabled', 'ANSIBLE_INVENTORY_ENABLED',
- ['host_list', 'script', 'yaml', 'ini'], value_type='list')
-INVENTORY_IGNORE_EXTS = get_config(p, DEFAULTS, 'inventory_ignore_extensions', 'ANSIBLE_INVENTORY_IGNORE',
- BLACKLIST_EXTS + (".orig", ".ini", ".cfg", ".retry"), value_type='list')
-INVENTORY_IGNORE_PATTERNS = get_config(p, DEFAULTS, 'inventory_ignore_patterns', 'ANSIBLE_INVENTORY_IGNORE_REGEX', [], value_type='list')
-VARIABLE_PRECEDENCE = get_config(p, DEFAULTS, 'precedence', 'ANSIBLE_PRECEDENCE',
- ['all_inventory', 'groups_inventory', 'all_plugins_inventory', 'all_plugins_play',
- 'groups_plugins_inventory', 'groups_plugins_play'],
- value_type='list')
-# Static includes
-DEFAULT_TASK_INCLUDES_STATIC = get_config(p, DEFAULTS, 'task_includes_static', 'ANSIBLE_TASK_INCLUDES_STATIC', False, value_type='boolean')
-DEFAULT_HANDLER_INCLUDES_STATIC = get_config(p, DEFAULTS, 'handler_includes_static', 'ANSIBLE_HANDLER_INCLUDES_STATIC', False, value_type='boolean')
-
-# Disclosure
-DEFAULT_NO_LOG = get_config(p, DEFAULTS, 'no_log', 'ANSIBLE_NO_LOG', False, value_type='boolean')
-DEFAULT_NO_TARGET_SYSLOG = get_config(p, DEFAULTS, 'no_target_syslog', 'ANSIBLE_NO_TARGET_SYSLOG', False, value_type='boolean')
-ALLOW_WORLD_READABLE_TMPFILES = get_config(p, DEFAULTS, 'allow_world_readable_tmpfiles', None, False, value_type='boolean')
-
-# Selinux
-DEFAULT_SELINUX_SPECIAL_FS = get_config(p, 'selinux', 'special_context_filesystems', None, 'fuse, nfs, vboxsf, ramfs, 9p', value_type='list')
-DEFAULT_LIBVIRT_LXC_NOSECLABEL = get_config(p, 'selinux', 'libvirt_lxc_noseclabel', 'LIBVIRT_LXC_NOSECLABEL', False, value_type='boolean')
-
-# PRIVILEGE ESCALATION
-# Backwards Compat
-DEFAULT_SU = get_config(p, DEFAULTS, 'su', 'ANSIBLE_SU', False, value_type='boolean')
-DEFAULT_SU_USER = get_config(p, DEFAULTS, 'su_user', 'ANSIBLE_SU_USER', 'root')
-DEFAULT_SU_EXE = get_config(p, DEFAULTS, 'su_exe', 'ANSIBLE_SU_EXE', None)
-DEFAULT_SU_FLAGS = get_config(p, DEFAULTS, 'su_flags', 'ANSIBLE_SU_FLAGS', None)
-DEFAULT_ASK_SU_PASS = get_config(p, DEFAULTS, 'ask_su_pass', 'ANSIBLE_ASK_SU_PASS', False, value_type='boolean')
-DEFAULT_SUDO = get_config(p, DEFAULTS, 'sudo', 'ANSIBLE_SUDO', False, value_type='boolean')
-DEFAULT_SUDO_USER = get_config(p, DEFAULTS, 'sudo_user', 'ANSIBLE_SUDO_USER', 'root')
-DEFAULT_SUDO_EXE = get_config(p, DEFAULTS, 'sudo_exe', 'ANSIBLE_SUDO_EXE', None)
-DEFAULT_SUDO_FLAGS = get_config(p, DEFAULTS, 'sudo_flags', 'ANSIBLE_SUDO_FLAGS', '-H -S -n')
-DEFAULT_ASK_SUDO_PASS = get_config(p, DEFAULTS, 'ask_sudo_pass', 'ANSIBLE_ASK_SUDO_PASS', False, value_type='boolean')
-
-# Become
-BECOME_ERROR_STRINGS = {
- 'sudo': 'Sorry, try again.',
- 'su': 'Authentication failure',
- 'pbrun': '',
- 'pfexec': '',
- 'doas': 'Permission denied',
- 'dzdo': '',
- 'ksu': 'Password incorrect',
- 'pmrun': 'You are not permitted to run this command'
-} # FIXME: deal with i18n
-BECOME_MISSING_STRINGS = {
- 'sudo': 'sorry, a password is required to run sudo',
- 'su': '',
- 'pbrun': '',
- 'pfexec': '',
- 'doas': 'Authorization required',
- 'dzdo': '',
- 'ksu': 'No password given',
- 'pmrun': ''
-} # FIXME: deal with i18n
BECOME_METHODS = ['sudo', 'su', 'pbrun', 'pfexec', 'doas', 'dzdo', 'ksu', 'runas', 'pmrun']
-BECOME_ALLOW_SAME_USER = get_config(p, 'privilege_escalation', 'become_allow_same_user', 'ANSIBLE_BECOME_ALLOW_SAME_USER', False, value_type='boolean')
-DEFAULT_BECOME_METHOD = get_config(p, 'privilege_escalation', 'become_method', 'ANSIBLE_BECOME_METHOD',
- 'sudo' if DEFAULT_SUDO else 'su' if DEFAULT_SU else 'sudo').lower()
-DEFAULT_BECOME = get_config(p, 'privilege_escalation', 'become', 'ANSIBLE_BECOME', False, value_type='boolean')
-DEFAULT_BECOME_USER = get_config(p, 'privilege_escalation', 'become_user', 'ANSIBLE_BECOME_USER', 'root')
-DEFAULT_BECOME_EXE = get_config(p, 'privilege_escalation', 'become_exe', 'ANSIBLE_BECOME_EXE', None)
-DEFAULT_BECOME_FLAGS = get_config(p, 'privilege_escalation', 'become_flags', 'ANSIBLE_BECOME_FLAGS', None)
-DEFAULT_BECOME_ASK_PASS = get_config(p, 'privilege_escalation', 'become_ask_pass', 'ANSIBLE_BECOME_ASK_PASS', False, value_type='boolean')
-
-# PLUGINS
-
-# Modules that can optimize with_items loops into a single call. Currently
-# these modules must (1) take a "name" or "pkg" parameter that is a list. If
-# the module takes both, bad things could happen.
-# In the future we should probably generalize this even further
-# (mapping of param: squash field)
-DEFAULT_SQUASH_ACTIONS = get_config(p, DEFAULTS, 'squash_actions', 'ANSIBLE_SQUASH_ACTIONS',
- "apk, apt, dnf, homebrew, openbsd_pkg, pacman, pkgng, yum, zypper", value_type='list')
-# paths
-
-DEFAULT_ACTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'action_plugins', 'ANSIBLE_ACTION_PLUGINS',
- '~/.ansible/plugins/action:/usr/share/ansible/plugins/action', value_type='pathlist')
-DEFAULT_CACHE_PLUGIN_PATH = get_config(p, DEFAULTS, 'cache_plugins', 'ANSIBLE_CACHE_PLUGINS',
- '~/.ansible/plugins/cache:/usr/share/ansible/plugins/cache', value_type='pathlist')
-DEFAULT_CALLBACK_PLUGIN_PATH = get_config(p, DEFAULTS, 'callback_plugins', 'ANSIBLE_CALLBACK_PLUGINS',
- '~/.ansible/plugins/callback:/usr/share/ansible/plugins/callback', value_type='pathlist')
-DEFAULT_CONNECTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'connection_plugins', 'ANSIBLE_CONNECTION_PLUGINS',
- '~/.ansible/plugins/connection:/usr/share/ansible/plugins/connection', value_type='pathlist')
-DEFAULT_LOOKUP_PLUGIN_PATH = get_config(p, DEFAULTS, 'lookup_plugins', 'ANSIBLE_LOOKUP_PLUGINS',
- '~/.ansible/plugins/lookup:/usr/share/ansible/plugins/lookup', value_type='pathlist')
-DEFAULT_MODULE_PATH = get_config(p, DEFAULTS, 'library', 'ANSIBLE_LIBRARY',
- '~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules', value_type='pathlist')
-DEFAULT_MODULE_UTILS_PATH = get_config(p, DEFAULTS, 'module_utils', 'ANSIBLE_MODULE_UTILS',
- '~/.ansible/plugins/module_utils:/usr/share/ansible/plugins/module_utils', value_type='pathlist')
-DEFAULT_INVENTORY_PLUGIN_PATH = get_config(p, DEFAULTS, 'inventory_plugins', 'ANSIBLE_INVENTORY_PLUGINS',
- '~/.ansible/plugins/inventory:/usr/share/ansible/plugins/inventory', value_type='pathlist')
-DEFAULT_VARS_PLUGIN_PATH = get_config(p, DEFAULTS, 'vars_plugins', 'ANSIBLE_VARS_PLUGINS',
- '~/.ansible/plugins/vars:/usr/share/ansible/plugins/vars', value_type='pathlist')
-DEFAULT_FILTER_PLUGIN_PATH = get_config(p, DEFAULTS, 'filter_plugins', 'ANSIBLE_FILTER_PLUGINS',
- '~/.ansible/plugins/filter:/usr/share/ansible/plugins/filter', value_type='pathlist')
-DEFAULT_TEST_PLUGIN_PATH = get_config(p, DEFAULTS, 'test_plugins', 'ANSIBLE_TEST_PLUGINS',
- '~/.ansible/plugins/test:/usr/share/ansible/plugins/test', value_type='pathlist')
-DEFAULT_STRATEGY_PLUGIN_PATH = get_config(p, DEFAULTS, 'strategy_plugins', 'ANSIBLE_STRATEGY_PLUGINS',
- '~/.ansible/plugins/strategy:/usr/share/ansible/plugins/strategy', value_type='pathlist')
-
-NETWORK_GROUP_MODULES = get_config(p, DEFAULTS, 'network_group_modules', 'NETWORK_GROUP_MODULES', ['eos', 'nxos', 'ios', 'iosxr', 'junos', 'ce',
- 'vyos', 'sros', 'dellos9', 'dellos10', 'dellos6'],
- value_type='list')
-DEFAULT_STRATEGY = get_config(p, DEFAULTS, 'strategy', 'ANSIBLE_STRATEGY', 'linear')
-DEFAULT_STDOUT_CALLBACK = get_config(p, DEFAULTS, 'stdout_callback', 'ANSIBLE_STDOUT_CALLBACK', 'default')
-# cache
-CACHE_PLUGIN = get_config(p, DEFAULTS, 'fact_caching', 'ANSIBLE_CACHE_PLUGIN', 'memory')
-CACHE_PLUGIN_CONNECTION = get_config(p, DEFAULTS, 'fact_caching_connection', 'ANSIBLE_CACHE_PLUGIN_CONNECTION', None)
-CACHE_PLUGIN_PREFIX = get_config(p, DEFAULTS, 'fact_caching_prefix', 'ANSIBLE_CACHE_PLUGIN_PREFIX', 'ansible_facts')
-CACHE_PLUGIN_TIMEOUT = get_config(p, DEFAULTS, 'fact_caching_timeout', 'ANSIBLE_CACHE_PLUGIN_TIMEOUT', 24 * 60 * 60, value_type='integer')
-
-# Display
-ANSIBLE_FORCE_COLOR = get_config(p, DEFAULTS, 'force_color', 'ANSIBLE_FORCE_COLOR', None, value_type='boolean')
-ANSIBLE_NOCOLOR = get_config(p, DEFAULTS, 'nocolor', 'ANSIBLE_NOCOLOR', None, value_type='boolean')
-ANSIBLE_NOCOWS = get_config(p, DEFAULTS, 'nocows', 'ANSIBLE_NOCOWS', None, value_type='boolean')
-ANSIBLE_COW_SELECTION = get_config(p, DEFAULTS, 'cow_selection', 'ANSIBLE_COW_SELECTION', 'default')
-ANSIBLE_COW_WHITELIST = get_config(p, DEFAULTS, 'cow_whitelist', 'ANSIBLE_COW_WHITELIST', DEFAULT_COW_WHITELIST, value_type='list')
-DISPLAY_SKIPPED_HOSTS = get_config(p, DEFAULTS, 'display_skipped_hosts', 'DISPLAY_SKIPPED_HOSTS', True, value_type='boolean')
-DEFAULT_UNDEFINED_VAR_BEHAVIOR = get_config(p, DEFAULTS, 'error_on_undefined_vars', 'ANSIBLE_ERROR_ON_UNDEFINED_VARS', True, value_type='boolean')
-HOST_KEY_CHECKING = get_config(p, DEFAULTS, 'host_key_checking', 'ANSIBLE_HOST_KEY_CHECKING', True, value_type='boolean')
-SYSTEM_WARNINGS = get_config(p, DEFAULTS, 'system_warnings', 'ANSIBLE_SYSTEM_WARNINGS', True, value_type='boolean')
-DEPRECATION_WARNINGS = get_config(p, DEFAULTS, 'deprecation_warnings', 'ANSIBLE_DEPRECATION_WARNINGS', True, value_type='boolean')
-DEFAULT_CALLABLE_WHITELIST = get_config(p, DEFAULTS, 'callable_whitelist', 'ANSIBLE_CALLABLE_WHITELIST', [], value_type='list')
-COMMAND_WARNINGS = get_config(p, DEFAULTS, 'command_warnings', 'ANSIBLE_COMMAND_WARNINGS', True, value_type='boolean')
-DEFAULT_LOAD_CALLBACK_PLUGINS = get_config(p, DEFAULTS, 'bin_ansible_callbacks', 'ANSIBLE_LOAD_CALLBACK_PLUGINS', False, value_type='boolean')
-DEFAULT_CALLBACK_WHITELIST = get_config(p, DEFAULTS, 'callback_whitelist', 'ANSIBLE_CALLBACK_WHITELIST', [], value_type='list')
-RETRY_FILES_ENABLED = get_config(p, DEFAULTS, 'retry_files_enabled', 'ANSIBLE_RETRY_FILES_ENABLED', True, value_type='boolean')
-RETRY_FILES_SAVE_PATH = get_config(p, DEFAULTS, 'retry_files_save_path', 'ANSIBLE_RETRY_FILES_SAVE_PATH', None, value_type='path')
-DEFAULT_NULL_REPRESENTATION = get_config(p, DEFAULTS, 'null_representation', 'ANSIBLE_NULL_REPRESENTATION', None, value_type='none')
-DISPLAY_ARGS_TO_STDOUT = get_config(p, DEFAULTS, 'display_args_to_stdout', 'ANSIBLE_DISPLAY_ARGS_TO_STDOUT', False, value_type='boolean')
-MAX_FILE_SIZE_FOR_DIFF = get_config(p, DEFAULTS, 'max_diff_size', 'ANSIBLE_MAX_DIFF_SIZE', 1024 * 1024, value_type='integer')
-
-# CONNECTION RELATED
-USE_PERSISTENT_CONNECTIONS = get_config(p, DEFAULTS, 'use_persistent_connections', 'ANSIBLE_USE_PERSISTENT_CONNECTIONS', False, value_type='boolean')
-ANSIBLE_SSH_ARGS = get_config(p, 'ssh_connection', 'ssh_args', 'ANSIBLE_SSH_ARGS', '-C -o ControlMaster=auto -o ControlPersist=60s')
-# WARNING: Someone might be tempted to switch this from percent-formatting
-# to .format() in the future. be sure to read this:
-# http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/ and understand
-# that it may be a security risk to do so.
-ANSIBLE_SSH_CONTROL_PATH = get_config(p, 'ssh_connection', 'control_path', 'ANSIBLE_SSH_CONTROL_PATH', None)
-ANSIBLE_SSH_CONTROL_PATH_DIR = get_config(p, 'ssh_connection', 'control_path_dir', 'ANSIBLE_SSH_CONTROL_PATH_DIR', u'~/.ansible/cp')
-ANSIBLE_SSH_PIPELINING = get_config(p, 'ssh_connection', 'pipelining', 'ANSIBLE_SSH_PIPELINING', False, value_type='boolean')
-ANSIBLE_SSH_RETRIES = get_config(p, 'ssh_connection', 'retries', 'ANSIBLE_SSH_RETRIES', 0, value_type='integer')
-ANSIBLE_SSH_EXECUTABLE = get_config(p, 'ssh_connection', 'ssh_executable', 'ANSIBLE_SSH_EXECUTABLE', 'ssh')
-PARAMIKO_RECORD_HOST_KEYS = get_config(p, 'paramiko_connection', 'record_host_keys', 'ANSIBLE_PARAMIKO_RECORD_HOST_KEYS', True, value_type='boolean')
-PARAMIKO_HOST_KEY_AUTO_ADD = get_config(p, 'paramiko_connection', 'host_key_auto_add', 'ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD', False, value_type='boolean')
-PARAMIKO_PROXY_COMMAND = get_config(p, 'paramiko_connection', 'proxy_command', 'ANSIBLE_PARAMIKO_PROXY_COMMAND', None)
-PARAMIKO_LOOK_FOR_KEYS = get_config(p, 'paramiko_connection', 'look_for_keys', 'ANSIBLE_PARAMIKO_LOOK_FOR_KEYS', True, value_type='boolean')
-PERSISTENT_CONNECT_TIMEOUT = get_config(p, 'persistent_connection', 'connect_timeout', 'ANSIBLE_PERSISTENT_CONNECT_TIMEOUT', 30, value_type='integer')
-PERSISTENT_CONNECT_RETRIES = get_config(p, 'persistent_connection', 'connect_retries', 'ANSIBLE_PERSISTENT_CONNECT_RETRIES', 30, value_type='integer')
-PERSISTENT_CONNECT_INTERVAL = get_config(p, 'persistent_connection', 'connect_interval', 'ANSIBLE_PERSISTENT_CONNECT_INTERVAL', 1, value_type='integer')
-PERSISTENT_CONTROL_PATH_DIR = get_config(p, 'persistent_connection', 'control_path_dir', 'ANSIBLE_PERSISTENT_CONTROL_PATH_DIR', u'~/.ansible/pc')
-
-# obsolete -- will be formally removed
-ACCELERATE_PORT = get_config(p, 'accelerate', 'accelerate_port', 'ACCELERATE_PORT', 5099, value_type='integer')
-ACCELERATE_TIMEOUT = get_config(p, 'accelerate', 'accelerate_timeout', 'ACCELERATE_TIMEOUT', 30, value_type='integer')
-ACCELERATE_CONNECT_TIMEOUT = get_config(p, 'accelerate', 'accelerate_connect_timeout', 'ACCELERATE_CONNECT_TIMEOUT', 1.0, value_type='float')
-ACCELERATE_DAEMON_TIMEOUT = get_config(p, 'accelerate', 'accelerate_daemon_timeout', 'ACCELERATE_DAEMON_TIMEOUT', 30, value_type='integer')
-ACCELERATE_KEYS_DIR = get_config(p, 'accelerate', 'accelerate_keys_dir', 'ACCELERATE_KEYS_DIR', '~/.fireball.keys')
-ACCELERATE_KEYS_DIR_PERMS = get_config(p, 'accelerate', 'accelerate_keys_dir_perms', 'ACCELERATE_KEYS_DIR_PERMS', '700')
-ACCELERATE_KEYS_FILE_PERMS = get_config(p, 'accelerate', 'accelerate_keys_file_perms', 'ACCELERATE_KEYS_FILE_PERMS', '600')
-ACCELERATE_MULTI_KEY = get_config(p, 'accelerate', 'accelerate_multi_key', 'ACCELERATE_MULTI_KEY', False, value_type='boolean')
-PARAMIKO_PTY = get_config(p, 'paramiko_connection', 'pty', 'ANSIBLE_PARAMIKO_PTY', True, value_type='boolean')
-
-# galaxy related
-GALAXY_SERVER = get_config(p, 'galaxy', 'server', 'ANSIBLE_GALAXY_SERVER', 'https://galaxy.ansible.com')
-GALAXY_IGNORE_CERTS = get_config(p, 'galaxy', 'ignore_certs', 'ANSIBLE_GALAXY_IGNORE', False, value_type='boolean')
-# this can be configured to blacklist SCMS but cannot add new ones unless the code is also updated
-GALAXY_SCMS = get_config(p, 'galaxy', 'scms', 'ANSIBLE_GALAXY_SCMS', 'git, hg', value_type='list')
-GALAXY_ROLE_SKELETON = get_config(p, 'galaxy', 'role_skeleton', 'ANSIBLE_GALAXY_ROLE_SKELETON', None, value_type='path')
-GALAXY_ROLE_SKELETON_IGNORE = get_config(p, 'galaxy', 'role_skeleton_ignore', 'ANSIBLE_GALAXY_ROLE_SKELETON_IGNORE', ['^.git$', '^.*/.git_keep$'],
- value_type='list')
-
-STRING_TYPE_FILTERS = get_config(p, 'jinja2', 'dont_type_filters', 'ANSIBLE_STRING_TYPE_FILTERS',
- ['string', 'to_json', 'to_nice_json', 'to_yaml', 'ppretty', 'json'], value_type='list')
-
-# colors
-COLOR_HIGHLIGHT = get_config(p, 'colors', 'highlight', 'ANSIBLE_COLOR_HIGHLIGHT', 'white')
-COLOR_VERBOSE = get_config(p, 'colors', 'verbose', 'ANSIBLE_COLOR_VERBOSE', 'blue')
-COLOR_WARN = get_config(p, 'colors', 'warn', 'ANSIBLE_COLOR_WARN', 'bright purple')
-COLOR_ERROR = get_config(p, 'colors', 'error', 'ANSIBLE_COLOR_ERROR', 'red')
-COLOR_DEBUG = get_config(p, 'colors', 'debug', 'ANSIBLE_COLOR_DEBUG', 'dark gray')
-COLOR_DEPRECATE = get_config(p, 'colors', 'deprecate', 'ANSIBLE_COLOR_DEPRECATE', 'purple')
-COLOR_SKIP = get_config(p, 'colors', 'skip', 'ANSIBLE_COLOR_SKIP', 'cyan')
-COLOR_UNREACHABLE = get_config(p, 'colors', 'unreachable', 'ANSIBLE_COLOR_UNREACHABLE', 'bright red')
-COLOR_OK = get_config(p, 'colors', 'ok', 'ANSIBLE_COLOR_OK', 'green')
-COLOR_CHANGED = get_config(p, 'colors', 'changed', 'ANSIBLE_COLOR_CHANGED', 'yellow')
-COLOR_DIFF_ADD = get_config(p, 'colors', 'diff_add', 'ANSIBLE_COLOR_DIFF_ADD', 'green')
-COLOR_DIFF_REMOVE = get_config(p, 'colors', 'diff_remove', 'ANSIBLE_COLOR_DIFF_REMOVE', 'red')
-COLOR_DIFF_LINES = get_config(p, 'colors', 'diff_lines', 'ANSIBLE_COLOR_DIFF_LINES', 'cyan')
-
-# diff
-DIFF_CONTEXT = get_config(p, 'diff', 'context', 'ANSIBLE_DIFF_CONTEXT', 3, value_type='integer')
-DIFF_ALWAYS = get_config(p, 'diff', 'always', 'ANSIBLE_DIFF_ALWAYS', False, value_type='bool')
-
-# non-configurable things
-MODULE_REQUIRE_ARGS = ['command', 'win_command', 'shell', 'win_shell', 'raw', 'script']
-MODULE_NO_JSON = ['command', 'win_command', 'shell', 'win_shell', 'raw']
+BOOL_TRUE = config.data.BOOL_TRUE
DEFAULT_BECOME_PASS = None
DEFAULT_PASSWORD_CHARS = to_text(ascii_letters + digits + ".,:-_", errors='strict') # characters included in auto-generated passwords
DEFAULT_SUDO_PASS = None
DEFAULT_REMOTE_PASS = None
DEFAULT_SUBSET = None
DEFAULT_SU_PASS = None
+IGNORE_FILES = ["COPYING", "CONTRIBUTING", "LICENSE", "README", "VERSION", "GUIDELINES"] # ignore during module search
+INTERNAL_RESULT_KEYS = ['add_host', 'add_group']
+LOCALHOST = frozenset(['127.0.0.1', 'localhost', '::1'])
+MODULE_REQUIRE_ARGS = ['command', 'win_command', 'shell', 'win_shell', 'raw', 'script']
+MODULE_NO_JSON = ['command', 'win_command', 'shell', 'win_shell', 'raw']
+RESTRICTED_RESULT_KEYS = ['ansible_rsync_path', 'ansible_playbook_python']
+TREE_DIR = None
VAULT_VERSION_MIN = 1.0
VAULT_VERSION_MAX = 1.0
-TREE_DIR = None
-LOCALHOST = frozenset(['127.0.0.1', 'localhost', '::1'])
-# module search
-IGNORE_FILES = ["COPYING", "CONTRIBUTING", "LICENSE", "README", "VERSION", "GUIDELINES"]
-INTERNAL_RESULT_KEYS = ['add_host', 'add_group']
-RESTRICTED_RESULT_KEYS = ['ansible_rsync_path', 'ansible_playbook_python']
-# check all of these extensions when looking for 'variable' files which should be YAML or JSON.
-YAML_FILENAME_EXTENSIONS = [".yml", ".yaml", ".json"]
+YAML_FILENAME_EXTENSIONS = [".yml", ".yaml", ".json"] # check all of these extensions when looking for 'variable' files which should be YAML or JSON.
diff --git a/lib/ansible/executor/playbook_executor.py b/lib/ansible/executor/playbook_executor.py
index b2efd435ff4..1f96e668dd8 100644
--- a/lib/ansible/executor/playbook_executor.py
+++ b/lib/ansible/executor/playbook_executor.py
@@ -192,7 +192,7 @@ class PlaybookExecutor:
retries = sorted(retries)
if len(retries) > 0:
if C.RETRY_FILES_SAVE_PATH:
- basedir = C.shell_expand(C.RETRY_FILES_SAVE_PATH)
+ basedir = C.RETRY_FILES_SAVE_PATH
elif playbook_path:
basedir = os.path.dirname(os.path.abspath(playbook_path))
else:
diff --git a/lib/ansible/parsing/dataloader.py b/lib/ansible/parsing/dataloader.py
index 9d40a3d6b08..a2579254701 100644
--- a/lib/ansible/parsing/dataloader.py
+++ b/lib/ansible/parsing/dataloader.py
@@ -80,6 +80,17 @@ class DataLoader:
a JSON or YAML string.
'''
new_data = None
+
+ # YAML parser will take JSON as it is a subset.
+ if isinstance(data, AnsibleUnicode):
+ # The PyYAML's libyaml bindings use PyUnicode_CheckExact so
+ # they are unable to cope with our subclass.
+ # Unwrap and re-wrap the unicode so we can keep track of line
+ # numbers
+ in_data = text_type(data)
+ else:
+ in_data = data
+
try:
# we first try to load this data as JSON
new_data = json.loads(data)
diff --git a/lib/ansible/playbook/base.py b/lib/ansible/playbook/base.py
index d0f9c6740fd..d1b712f5fb1 100644
--- a/lib/ansible/playbook/base.py
+++ b/lib/ansible/playbook/base.py
@@ -149,20 +149,20 @@ class BaseMeta(type):
class Base(with_metaclass(BaseMeta, object)):
# connection/transport
- _connection = FieldAttribute(isa='string')
- _port = FieldAttribute(isa='int')
+ _connection = FieldAttribute(isa='string')
+ _port = FieldAttribute(isa='int')
_remote_user = FieldAttribute(isa='string')
# variables
_vars = FieldAttribute(isa='dict', priority=100, inherit=False)
# flags and misc. settings
- _environment = FieldAttribute(isa='list')
- _no_log = FieldAttribute(isa='bool')
- _always_run = FieldAttribute(isa='bool')
- _run_once = FieldAttribute(isa='bool')
- _ignore_errors = FieldAttribute(isa='bool')
- _check_mode = FieldAttribute(isa='bool')
+ _environment = FieldAttribute(isa='list')
+ _no_log = FieldAttribute(isa='bool')
+ _always_run = FieldAttribute(isa='bool')
+ _run_once = FieldAttribute(isa='bool')
+ _ignore_errors = FieldAttribute(isa='bool')
+ _check_mode = FieldAttribute(isa='bool')
_any_errors_fatal = FieldAttribute(isa='bool', default=False, always_post_validate=True)
# param names which have been deprecated/removed
diff --git a/lib/ansible/plugins/shell/__init__.py b/lib/ansible/plugins/shell/__init__.py
index bf16fa41ab9..2a34e04145a 100644
--- a/lib/ansible/plugins/shell/__init__.py
+++ b/lib/ansible/plugins/shell/__init__.py
@@ -34,11 +34,12 @@ class ShellBase(object):
def __init__(self):
self.env = dict()
if C.DEFAULT_MODULE_SET_LOCALE:
+ module_locale = C.DEFAULT_MODULE_LANG or os.getenv('LANG', 'en_US.UTF-8')
self.env.update(
dict(
- LANG=C.DEFAULT_MODULE_LANG,
- LC_ALL=C.DEFAULT_MODULE_LANG,
- LC_MESSAGES=C.DEFAULT_MODULE_LANG,
+ LANG=module_locale,
+ LC_ALL=module_locale,
+ LC_MESSAGES=module_locale,
)
)
diff --git a/setup.py b/setup.py
index d43fd299ff9..58f65b60396 100644
--- a/setup.py
+++ b/setup.py
@@ -69,7 +69,9 @@ setup(
'galaxy/data/*/*.*',
'galaxy/data/*/*/.*',
'galaxy/data/*/*/*.*',
- 'galaxy/data/*/tests/inventory'
+ 'galaxy/data/*/tests/inventory',
+ 'config/data/*.yaml',
+ 'config/data/*.yml',
],
},
classifiers=[
diff --git a/test/sanity/code-smell/boilerplate.sh b/test/sanity/code-smell/boilerplate.sh
index b5e726d529a..85092de26e6 100755
--- a/test/sanity/code-smell/boilerplate.sh
+++ b/test/sanity/code-smell/boilerplate.sh
@@ -5,6 +5,7 @@ future1=$(find ./bin -type f -exec grep -HL 'from __future__ import (absolute_im
metaclass2=$(find ./lib/ansible -path ./lib/ansible/modules -prune \
-o -path ./lib/ansible/modules/__init__.py \
+ -o -path ./lib/ansible/config/__init__.py \
-o -path ./lib/ansible/module_utils -prune \
-o -path ./lib/ansible/module_utils/six/_six.py -prune \
-o -path ./lib/ansible/compat/selectors/_selectors2.py -prune \
@@ -15,6 +16,7 @@ metaclass2=$(find ./lib/ansible -path ./lib/ansible/modules -prune \
future2=$(find ./lib/ansible -path ./lib/ansible/modules -prune \
-o -path ./lib/ansible/modules/__init__.py \
+ -o -path ./lib/ansible/config/__init__.py \
-o -path ./lib/ansible/module_utils -prune \
-o -path ./lib/ansible/module_utils/six/_six.py -prune \
-o -path ./lib/ansible/compat/selectors/_selectors2.py -prune \
diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt
index e830f50e8af..7c8810269c1 100644
--- a/test/sanity/pep8/legacy-files.txt
+++ b/test/sanity/pep8/legacy-files.txt
@@ -1,3 +1,8 @@
+hacking/conf2yaml.py
+lib/ansible/constants.py
+lib/ansible/cli/config.py
+lib/ansible/config/data.py
+lib/ansible/config/manager.py
lib/ansible/module_utils/vmware.py
lib/ansible/modules/cloud/amazon/_ec2_ami_search.py
lib/ansible/modules/cloud/amazon/_ec2_vpc.py
@@ -558,3 +563,4 @@ lib/ansible/modules/system/user.py
lib/ansible/modules/utilities/helper/_accelerate.py
lib/ansible/modules/utilities/logic/async_status.py
lib/ansible/modules/utilities/logic/async_wrapper.py
+lib/ansible/playbook/base.py
diff --git a/test/units/cli/test_galaxy.py b/test/units/cli/test_galaxy.py
index e0e2ea1ee88..f03d2b47e23 100644
--- a/test/units/cli/test_galaxy.py
+++ b/test/units/cli/test_galaxy.py
@@ -126,7 +126,7 @@ class TestGalaxy(unittest.TestCase):
def test_execute_remove(self):
# installing role
- gc = GalaxyCLI(args=["install", "--offline", "-p", self.role_path, "-r", self.role_req])
+ gc = GalaxyCLI(args=["install", "--offline", "-p", self.role_path, "-r", self.role_req, '--force'])
gc.parse()
gc.run()
diff --git a/test/units/test_constants.py b/test/units/test_constants.py
index accd99f8ee6..fa9902e7753 100644
--- a/test/units/test_constants.py
+++ b/test/units/test_constants.py
@@ -120,99 +120,3 @@ class TestMkBoolean:
assert constants.mk_boolean("yes") is True
assert constants.mk_boolean("y") is True
assert constants.mk_boolean("on") is True
-
-
-class TestShellExpand:
- def test_shell_expand_none(self):
- assert constants.shell_expand(None) is None
-
- def test_shell_expand_static_path(self):
- assert constants.shell_expand(u'/usr/local') == u'/usr/local'
-
- def test_shell_expand_tilde(self, user):
- assert constants.shell_expand(u'~/local') == os.path.join(user['home'], 'local')
- assert constants.shell_expand(u'~%s/local' % user['username']) == os.path.join(user['home'], 'local')
-
- def test_shell_expand_vars(self, user):
- assert constants.shell_expand(u'$HOME/local') == os.path.join(user['home'], 'local')
-
- os.environ['ANSIBLE_TEST_VAR'] = '/srv/ansible'
- assert constants.shell_expand(u'$ANSIBLE_TEST_VAR/local') == os.path.join('/srv/ansible', 'local')
-
- os.environ['ANSIBLE_TEST_VAR'] = '~'
- assert constants.shell_expand(u'$ANSIBLE_TEST_VAR/local') == os.path.join(user['home'], 'local')
-
- del os.environ['ANSIBLE_TEST_VAR']
- assert constants.shell_expand(u'$ANSIBLE_TEST_VAR/local') == u'$ANSIBLE_TEST_VAR/local'
-
- def test_expand_relative_abs_path(self):
- assert constants.shell_expand('/absolute/path', expand_relative_paths=True) == '/absolute/path'
-
- def test_expand_relative_path_relative_cfg_file(self, cfg_file):
- assert constants.shell_expand(u'relative/path', expand_relative_paths=True) == os.path.join(cfg_file, 'relative/path')
-
- def test_expand_relative_path_relative_cwd(self, cwd, null_cfg_file):
- assert constants.shell_expand(u'relative/path', expand_relative_paths=True) == os.path.join(cwd, 'relative/path')
-
-
-# configparser object
-class TestGetConfig:
- def test_from_config_file(self, cfgparser):
- assert constants.get_config(cfgparser, 'defaults', 'defaults_one', 'ANSIBLE_TEST_VAR', 'foo', value_type=None) == 'data_defaults_one'
- assert constants.get_config(cfgparser, 'level1', 'level1_one', 'ANSIBLE_TEST_VAR', 'foo', value_type=None) == 'data_level1_one'
-
- def test_from_env_var(self, cfgparser):
- os.environ['ANSIBLE_TEST_VAR'] = 'bar'
-
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'foo', value_type=None) == 'bar'
- assert constants.get_config(cfgparser, 'unknown', 'defaults_one', 'ANSIBLE_TEST_VAR', 'foo', value_type=None) == 'bar'
-
- del os.environ['ANSIBLE_TEST_VAR']
-
- def test_from_default(self, cfgparser):
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'foo', value_type=None) == u'foo'
- assert constants.get_config(cfgparser, 'unknown', 'defaults_one', 'ANSIBLE_TEST_VAR', 'foo', value_type=None) == u'foo'
-
- def test_value_type_boolean(self, cfgparser):
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'on', value_type='boolean') is True
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', True, value_type='boolean') is True
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'other', value_type='boolean') is False
-
- def test_value_type_integer(self, cfgparser):
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', '10', value_type='integer') == 10
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 10, value_type='integer') == 10
-
- def test_value_type_float(self, cfgparser):
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', '10', value_type='float') == 10.0
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 10, value_type='float') == 10.0
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', '11.5', value_type='float') == 11.5
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 11.5, value_type='float') == 11.5
-
- def test_value_type_list(self, cfgparser):
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'one,two,three', value_type='list') == ['one', 'two', 'three']
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', ['one', 'two', 'three'], value_type='list') == ['one', 'two', 'three']
-
- def test_value_type_none(self, cfgparser):
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'None', value_type='none') is None
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', None, value_type='none') is None
-
- def test_value_type_path(self, cfgparser, user, cfg_file):
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', '~/local', value_type='path') == os.path.join(user['home'], 'local')
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'local', value_type='path') == 'local'
- assert constants.get_config(cfgparser, 'defaults', 'unknown', 'ANSIBLE_TEST_VAR', 'local', value_type='path', expand_relative_paths=True) \
- == os.path.join(cfg_file, 'local')
-
-# Need to implement tests for these
-# def test_value_type_pathlist(self, cfgparser):
-# pass
-#
-# def test_value_type_string(self, cfgparser):
-# pass
-#
-# def test_value_type_temppath(self, cfgparser):
-# pass
-
-
-# Need to test this
-# def test_load_config_file():
-# pass