mirror of https://github.com/ansible/ansible.git
1st part of ansible config, adds ansible-config to view/manage configs (#12797)
* Start of ansible config project moved configuration definitions to external yaml file vs hardcoded * updated constants to be a data strcutures that are looped over and also return origin of setting changed to manager/data scheme for base classes new cli ansible-config to view/manage ansible configuration settings * prints green for default/unchanged and yellow for those that have been overriden * added list action to show all configurable settings and their associated ini and env var names * allows specifying config file to see what result would look like * TBD update, edit and view options removed test for functions that have been removed env_Vars are now list of dicts allows for version_added and deprecation in future added a couple of descriptions for future doc autogeneration ensure test does not fail if delete_me exists normalized 'path expansion' added yaml config to setup packaging removed unused imports better encoding handling updated as per feedback * pep8pull/25709/head
parent
4344132a7d
commit
74842adc07
@ -0,0 +1 @@
|
||||
ansible
|
@ -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))
|
||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# 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 <command> --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'))
|
@ -1,20 +0,0 @@
|
||||
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Make coding more python3-ish
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 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
|
File diff suppressed because it is too large
Load Diff
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 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')
|
||||
|
Loading…
Reference in New Issue