From 62fbbf76532cb2dc2cc9216aa4dd96182c91e6d2 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Mon, 13 Aug 2012 19:17:14 -0400 Subject: [PATCH] config file support --- MANIFEST.in | 1 + examples/ansible.cfg | 68 +++++++++++++++++++++++++++ lib/ansible/constants.py | 96 ++++++++++++++++++++++++++++++-------- packaging/rpm/ansible.spec | 1 + 4 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 examples/ansible.cfg diff --git a/MANIFEST.in b/MANIFEST.in index 98592d83a2..15d0a74b3c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ include README.md packaging/rpm/ansible.spec COPYING include examples/hosts +include examples/ansible.cfg include packaging/distutils/setup.py recursive-include docs * recursive-include library * diff --git a/examples/ansible.cfg b/examples/ansible.cfg new file mode 100644 index 0000000000..29d9b4874f --- /dev/null +++ b/examples/ansible.cfg @@ -0,0 +1,68 @@ +# config file for ansible -- http://ansible.github.com +# nearly all parameters can be overridden in ansible-playbook or with command line flags +# ansible will read ~/.ansible.cfg or /etc/ansible.cfg, whichever it finds first + +[defaults] + +# location of inventory file, eliminates need to specify -i + +hostfile = /etc/ansible/hosts + +# location of ansible library, eliminates need to specify --module-path + +library = /usr/share/ansible2 + +# default module name used in /usr/bin/ansible when -m is not specified + +module_name = command + +# home directory where temp files are stored on remote systems. Should +# almost always contain $HOME or be a directory writeable by all users + +remote_tmp = $HOME/.ansible/tmp + +# the default pattern for ansible-playbooks ("hosts:") + +pattern = * + +# the default number of forks (parallelism) to be used. Usually you +# can crank this up. + +forks=5 + +# the timeout used by various connection types. Usually this corresponds +# to an SSH timeout + +timeout=10 + +# when using --poll or "poll:" in an ansible playbook, and not specifying +# an explicit poll interval, use this interval + +poll_interval=15 + +# when specifying --sudo to /usr/bin/ansible or "sudo:" in a playbook, +# and not specifying "--sudo-user" or "sudo_user" respectively, sudo +# to this user account + +sudo_user=root + +# connection to use when -c is not specified + +transport=paramiko + +# remote SSH port to be used when --port or "port:" or an equivalent inventory +# variable is not specified. + +remote_port=22 + +# if set, always run /usr/bin/ansible commands as this user, and assume this value +# if "user:" is not set in a playbook. If not set, use the current Unix user +# as the default + +#remote_user=root + +# if set, always use this private key file for authentication, same as if passing +# --private-key-file to ansible or ansible-playbook + +#private_key_file=/path/to/file + diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index b5084837f8..c5363babac 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -17,28 +17,84 @@ import os import pwd +import ConfigParser +import traceback -DEFAULT_HOST_LIST = os.environ.get('ANSIBLE_HOSTS', '/etc/ansible/hosts') -DEFAULT_MODULE_PATH = os.environ.get('ANSIBLE_LIBRARY', '/usr/share/ansible') -DEFAULT_REMOTE_TMP = os.environ.get('ANSIBLE_REMOTE_TMP', '$HOME/.ansible/tmp') +def get_config(p, section, key, env_var, default): + if p is not None: + try: + return p.get(section, key) + except: + if env_var is not None: + return os.environ.get(env_var, default) + return default + else: + if env_var is not None: + return os.environ.get(env_var, default) + return default -DEFAULT_MODULE_NAME = 'command' -DEFAULT_PATTERN = '*' -DEFAULT_FORKS = os.environ.get('ANSIBLE_FORKS',5) -DEFAULT_MODULE_ARGS = os.environ.get('ANSIBLE_MODULE_ARGS','') -DEFAULT_TIMEOUT = os.environ.get('ANSIBLE_TIMEOUT',10) -DEFAULT_POLL_INTERVAL = os.environ.get('ANSIBLE_POLL_INTERVAL',15) -DEFAULT_REMOTE_USER = os.environ.get('ANSIBLE_REMOTE_USER', None) -if DEFAULT_REMOTE_USER is None: - DEFAULT_REMOTE_USER = pwd.getpwuid(os.geteuid())[0] +def load_config_file(): + p = ConfigParser.ConfigParser() + path1 = os.path.expanduser("~/.ansible.cfg") + path2 = "/etc/ansible/ansible.cfg" + if os.path.exists(path1): + print "A1" + p.read(path1) + elif os.path.exists(path2): + print "A2" + p.read(path2) + else: + return None + return p -DEFAULT_REMOTE_PASS = None -DEFAULT_PRIVATE_KEY_FILE = os.environ.get('ANSIBLE_PRIVATE_KEY_FILE',None) -DEFAULT_SUDO_PASS = None -DEFAULT_SUDO_USER = os.environ.get('ANSIBLE_SUDO_USER','root') -DEFAULT_REMOTE_PORT = 22 -DEFAULT_TRANSPORT = os.environ.get('ANSIBLE_TRANSPORT','paramiko') -DEFAULT_TRANSPORT_OPTS = ['local', 'paramiko', 'ssh'] -DEFAULT_SUBSET = None +p = load_config_file() +active_user = pwd.getpwuid(os.geteuid())[0] + +# sections in config file +DEFAULTS='defaults' + +# configurable things +DEFAULT_HOST_LIST = get_config(p, DEFAULTS, 'hostfile', 'ANSIBLE_HOSTS', '/etc/ansible/hosts') +DEFAULT_MODULE_PATH = get_config(p, DEFAULTS, 'library', 'ANSIBLE_LIBRARY', '/usr/share/ansible') +DEFAULT_REMOTE_TMP = get_config(p, DEFAULTS, 'remote_tmp', 'ANSIBLE_REMOTE_TEMP', '$HOME/.ansible/tmp') +DEFAULT_MODULE_NAME = get_config(p, DEFAULTS, 'module_name', None, 'command') +DEFAULT_PATTERN = get_config(p, DEFAULTS, 'pattern', None, '*') +DEFAULT_FORKS = get_config(p, DEFAULTS, 'fork_count', 'ANSIBLE_FORKS', 5) +DEFAULT_MODULE_ARGS = get_config(p, DEFAULTS, 'module_args', 'ANSIBLE_MODULE_ARGS', '') +DEFAULT_TIMEOUT = get_config(p, DEFAULTS, 'timeout', 'ANSIBLE_TIMEOUT', 10) +DEFAULT_POLL_INTERVAL = get_config(p, DEFAULTS, 'poll_interval', 'ANSIBLE_POLL_INTERVAL', 15) +DEFAULT_REMOTE_USER = get_config(p, DEFAULTS, 'remote_user', 'ANSIBLE_REMOTE_USER', active_user) +DEFAULT_PRIVATE_KEY_FILE = get_config(p, DEFAULTS, 'private_key_file', 'ANSIBLE_PRIVATE_KEY_FILE', None) +DEFAULT_SUDO_USER = get_config(p, DEFAULTS, 'sudo_user', 'ANSIBLE_SUDO_USER', 'root') +DEFAULT_REMOTE_PORT = get_config(p, DEFAULTS, 'remote_port', 'ANSIBLE_REMOTE_PORT', 22) +DEFAULT_TRANSPORT = get_config(p, DEFAULTS, 'transport', 'ANSIBLE_TRANSPORT', 'paramiko') + +# non-configurable things +DEFAULT_REMOTE_PASS = None +DEFAULT_TRANSPORT_OPTS = ['local', 'paramiko', 'ssh'] +DEFAULT_SUDO_PASS = None +DEFAULT_SUBSET = None + +def get_config(parser, section, key, env_var, default): + try: + return parser.get(section, key) + except: + if env_var is not None: + return os.environ.get(env_var, default) + return default + +def load_config_file(): + config = ConfigParser.ConfigParser() + path1 = os.path.expanduser("~/.ansible.cfg") + path2 = "/etc/ansible/ansible.cfg" + if os.path.exists(path1): + config.read(path1) + elif os.path.exists(path2): + config.read(path2) + else: + return None + return config + +print "MODULE PATH=%s" % DEFAULT_MODULE_PATH diff --git a/packaging/rpm/ansible.spec b/packaging/rpm/ansible.spec index b7c6a32762..5dfd25b495 100644 --- a/packaging/rpm/ansible.spec +++ b/packaging/rpm/ansible.spec @@ -39,6 +39,7 @@ are transferred to managed machines automatically. %{__python} setup.py install -O1 --root=$RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/etc/ansible/ cp examples/hosts $RPM_BUILD_ROOT/etc/ansible/ +cp examples/ansible.cfg $RPM_BUILD_ROOT/etc/ansible/ mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man1/ cp -v docs/man/man1/*.1 $RPM_BUILD_ROOT/%{_mandir}/man1/ mkdir -p $RPM_BUILD_ROOT/%{_datadir}/ansible