From f0a4a17ff6a4239d2b465831dd75815b747145aa Mon Sep 17 00:00:00 2001 From: Chris Gardner Date: Sat, 1 Jun 2013 20:32:28 +0100 Subject: [PATCH 01/33] Add Solaris O/S facts "distribution" and "distribution_*" --- library/system/setup | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/library/system/setup b/library/system/setup index 0315a351dad..3c65b2a02ac 100644 --- a/library/system/setup +++ b/library/system/setup @@ -102,7 +102,8 @@ class Facts(object): '/etc/vmware-release': 'VMwareESX', '/etc/openwrt_release': 'OpenWrt', '/etc/system-release': 'OtherLinux', - '/etc/alpine-release': 'Alpine' } + '/etc/alpine-release': 'Alpine', + '/etc/release': 'Solaris' } SELINUX_MODE_DICT = { 1: 'enforcing', 0: 'permissive', -1: 'disabled' } # A list of dicts. If there is a platform with more than one @@ -135,7 +136,7 @@ class Facts(object): return self.facts # Platform - # patform.system() can be Linux, Darwin, Java, or Windows + # platform.system() can be Linux, Darwin, Java, or Windows def get_platform_facts(self): self.facts['system'] = platform.system() self.facts['kernel'] = platform.release() @@ -235,6 +236,15 @@ class Facts(object): data = get_file_content(path) self.facts['distribution'] = 'Alpine' self.facts['distribution_version'] = data + elif name == 'Solaris': + data = get_file_content(path).split('\n')[0] + if 'Oracle Solaris' in data: + data = " ".join(data.split()[1:None]) + self.facts['distribution'] = data.split()[0] + self.facts['distribution_version'] = data.split()[1] + distribution_release = " ".join(data.split()[2:None]) + if distribution_release != 'X86' and distribution_release != 'SPARC': + self.facts['distribution_release'] = distribution_release else: self.facts['distribution'] = name From 2ba47318dce7f721e47ed7fad10367ded7e7930a Mon Sep 17 00:00:00 2001 From: Chris Gardner Date: Mon, 3 Jun 2013 22:33:01 +0100 Subject: [PATCH 02/33] Use first line from /etc/release in "distribution_release" for consistency across Solaris and derivatives. --- library/system/setup | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/system/setup b/library/system/setup index 3c65b2a02ac..af442a3b771 100644 --- a/library/system/setup +++ b/library/system/setup @@ -238,13 +238,13 @@ class Facts(object): self.facts['distribution_version'] = data elif name == 'Solaris': data = get_file_content(path).split('\n')[0] + ora_prefix = '' if 'Oracle Solaris' in data: - data = " ".join(data.split()[1:None]) + data = data.replace('Oracle ','') + ora_prefix = 'Oracle ' self.facts['distribution'] = data.split()[0] self.facts['distribution_version'] = data.split()[1] - distribution_release = " ".join(data.split()[2:None]) - if distribution_release != 'X86' and distribution_release != 'SPARC': - self.facts['distribution_release'] = distribution_release + self.facts['distribution_release'] = ora_prefix + data else: self.facts['distribution'] = name From 94e66ef5584560b87acef33159d187c90e442d97 Mon Sep 17 00:00:00 2001 From: Andrew Straw Date: Sun, 9 Jun 2013 20:03:28 +0000 Subject: [PATCH 03/33] allow apt-key module to work with binary key --- lib/ansible/module_common.py | 5 +++-- library/packaging/apt_key | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/ansible/module_common.py b/lib/ansible/module_common.py index a8083100ea0..fb07049eaa1 100644 --- a/lib/ansible/module_common.py +++ b/lib/ansible/module_common.py @@ -859,7 +859,7 @@ class AnsibleModule(object): self.cleanup(tmp_dest) self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, e)) - def run_command(self, args, check_rc=False, close_fds=False, executable=None, data=None): + def run_command(self, args, check_rc=False, close_fds=False, executable=None, data=None, binary_data=False): ''' Execute a command, returns rc, stdout, and stderr. args is the command to run @@ -895,7 +895,8 @@ class AnsibleModule(object): stderr=subprocess.PIPE) if data: cmd.stdin.write(data) - cmd.stdin.write('\\n') + if not binary_data: + cmd.stdin.write('\\n') out, err = cmd.communicate() rc = cmd.returncode except (OSError, IOError), e: diff --git a/library/packaging/apt_key b/library/packaging/apt_key index de4ada8c399..d996a61a953 100644 --- a/library/packaging/apt_key +++ b/library/packaging/apt_key @@ -112,7 +112,7 @@ def download_key(module, url): def add_key(module, key): cmd = "apt-key add -" - (rc, out, err) = module.run_command(cmd, data=key, check_rc=True) + (rc, out, err) = module.run_command(cmd, data=key, check_rc=True, binary_data=True) return True def remove_key(module, key_id): From deaf499ba1635673eb7259008a19a77bc16d04e7 Mon Sep 17 00:00:00 2001 From: Rike-Benjamin Schuppner Date: Mon, 10 Jun 2013 15:51:35 +0200 Subject: [PATCH 04/33] Remove duplicate host file reads by removing a legacy check. This allows using a form such as ansible -i <( arbitrary command ) all -m ping --- lib/ansible/inventory/__init__.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/ansible/inventory/__init__.py b/lib/ansible/inventory/__init__.py index 17e501f1431..d5df2f89d92 100644 --- a/lib/ansible/inventory/__init__.py +++ b/lib/ansible/inventory/__init__.py @@ -90,12 +90,8 @@ class Inventory(object): self.parser = InventoryScript(filename=host_list) self.groups = self.parser.groups.values() else: - data = file(host_list).read() - if not data.startswith("---"): - self.parser = InventoryParser(filename=host_list) - self.groups = self.parser.groups.values() - else: - raise errors.AnsibleError("YAML inventory support is deprecated in 0.6 and removed in 0.7, see the migration script in examples/scripts in the git checkout") + self.parser = InventoryParser(filename=host_list) + self.groups = self.parser.groups.values() utils.plugins.vars_loader.add_directory(self.basedir(), with_subdir=True) else: From 71afb9e43213b86cef9748469fa225dd10342548 Mon Sep 17 00:00:00 2001 From: Rike-Benjamin Schuppner Date: Mon, 10 Jun 2013 15:52:04 +0200 Subject: [PATCH 05/33] Use with guard for file reads. --- lib/ansible/inventory/ini.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ansible/inventory/ini.py b/lib/ansible/inventory/ini.py index 8412f4acac5..1c7ae58bf15 100644 --- a/lib/ansible/inventory/ini.py +++ b/lib/ansible/inventory/ini.py @@ -33,11 +33,11 @@ class InventoryParser(object): def __init__(self, filename=C.DEFAULT_HOST_LIST): - fh = open(filename) - self.lines = fh.readlines() - self.groups = {} - self.hosts = {} - self._parse() + with open(filename) as fh: + self.lines = fh.readlines() + self.groups = {} + self.hosts = {} + self._parse() def _parse(self): From 47c8396598e53247717c3df90525fa949f2c3c65 Mon Sep 17 00:00:00 2001 From: "gw0 [http://gw.tnode.com/]" Date: Mon, 10 Jun 2013 22:43:50 +0200 Subject: [PATCH 06/33] Fix `mongodb_user` compatibility with MongoDB 2.2 (used in Debian 7). --- library/database/mongodb_user | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/database/mongodb_user b/library/database/mongodb_user index bba1c192d05..91506da4cb3 100644 --- a/library/database/mongodb_user +++ b/library/database/mongodb_user @@ -81,11 +81,16 @@ author: Elliott Foster import ConfigParser try: - from pymongo import MongoClient from pymongo.errors import ConnectionFailure from pymongo.errors import OperationFailure + from pymongo import MongoClient except ImportError: - pymongo_found = False + try: # for older PyMongo 2.2 + from pymongo import Connection as MongoClient + except ImportError: + pymongo_found = False + else: + pymongo_found = True else: pymongo_found = True From 643b5e2c5db32f0fd84175011a63e114825f0e8b Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Mon, 10 Jun 2013 18:37:56 -0400 Subject: [PATCH 07/33] Fix dead link, remove redundant section. --- docsite/latest/rst/gettingstarted.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docsite/latest/rst/gettingstarted.rst b/docsite/latest/rst/gettingstarted.rst index 70ee4a56a44..34241673c93 100644 --- a/docsite/latest/rst/gettingstarted.rst +++ b/docsite/latest/rst/gettingstarted.rst @@ -108,12 +108,6 @@ using "make install". This is done through `python-distutils`: $ cd ./ansible $ sudo make install -Release Tarballs -++++++++++++++++ - -For those that do not want to use git or a package manager, (or for packagers themselves), -tarballs of past Ansible releases are available at `http://ansibleworks.com/releases/ `_. - Via Pip +++++++ @@ -249,7 +243,7 @@ Tagged Releases Tarballs of releases are available on the ansible.cc page. -* `Ansible/downloads `_ +* `Ansible/downloads `_ These releases are also tagged in the git repository with the release version. From f6521d88f5e9cb5dc092bd4bf7ae69dd408a6e82 Mon Sep 17 00:00:00 2001 From: Jan-Piet Mens Date: Tue, 11 Jun 2013 09:13:32 +0200 Subject: [PATCH 08/33] setup epoch time doesn't have tics on Python 2.6.4 (Solaris). --- library/system/setup | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/system/setup b/library/system/setup index 274fb469ee9..d627ba6e720 100644 --- a/library/system/setup +++ b/library/system/setup @@ -365,6 +365,8 @@ class Facts(object): self.facts['date_time']['minute'] = now.strftime('%M') self.facts['date_time']['second'] = now.strftime('%S') self.facts['date_time']['epoch'] = now.strftime('%s') + if self.facts['date_time']['epoch'][0] == '%': + self.facts['date_time']['epoch'] = str(int(time.time())) self.facts['date_time']['date'] = now.strftime('%Y-%m-%d') self.facts['date_time']['time'] = now.strftime('%H:%M:%S') self.facts['date_time']['iso8601_micro'] = now.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ") From 767c208e6c169bca1951de602eb03f39d56419af Mon Sep 17 00:00:00 2001 From: Stijn Tintel Date: Tue, 11 Jun 2013 14:37:30 +0200 Subject: [PATCH 09/33] Fix MySQL 5.6 compatibility In MySQL 5.6, the root account created by default during MySQL installation has the PROXY ... WITH GRANT OPTION privilege for ''@'', that is, for all users. The mysql_user module tries to revoke this privilege, but this fails: _mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''@'' FROM 'root'@'localhost'' at line 1") Quick fix: don't revoke privilege if user is root and the privilege to revoke contains PROXY. --- library/database/mysql_user | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/database/mysql_user b/library/database/mysql_user index 9c61e7a6be6..5d0d0d68ed3 100644 --- a/library/database/mysql_user +++ b/library/database/mysql_user @@ -153,8 +153,9 @@ def user_mod(cursor, user, host, password, new_priv): # the new specification, then revoke all privileges on it. for db_table, priv in curr_priv.iteritems(): if db_table not in new_priv: - privileges_revoke(cursor, user,host,db_table) - changed = True + if user != "root" and "PROXY" not in priv: + privileges_revoke(cursor, user,host,db_table) + changed = True # If the user doesn't currently have any privileges on a db.table, then # we can perform a straight grant operation. From f9f0f5ce2cc50865b8c2423d1e439de2f05e0d52 Mon Sep 17 00:00:00 2001 From: Raul Melo Date: Wed, 12 Jun 2013 18:59:20 +0200 Subject: [PATCH 10/33] HP-UX virtualization facts --- library/system/setup | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/library/system/setup b/library/system/setup index 274fb469ee9..543fd655d23 100644 --- a/library/system/setup +++ b/library/system/setup @@ -1872,6 +1872,45 @@ class LinuxVirtual(Virtual): self.facts['virtualization_role'] = 'host' return +class HPUXVirtual(Virtual): + """ + This is a HP-UX specific subclass of Virtual. It defines + - virtualization_type + - virtualization_role + """ + platform = 'HP-UX' + + def __init__(self): + Virtual.__init__(self) + + def populate(self): + self.get_virtual_facts() + return self.facts + + def get_virtual_facts(self): + if os.path.exists('/usr/sbin/vecheck'): + rc, out, err = module.run_command("/usr/sbin/vecheck") + if rc == 0: + self.facts['virtualization_type'] = 'guest' + self.facts['virtualization_role'] = 'HP vPar' + if os.path.exists('/opt/hpvm/bin/hpvminfo'): + rc, out, err = module.run_command("/opt/hpvm/bin/hpvminfo") + if rc == 0 and re.match('.*Running.*HPVM vPar.*', out): + self.facts['virtualization_type'] = 'guest' + self.facts['virtualization_role'] = 'HPVM vPar' + elif rc == 0 and re.match('.*Running.*HPVM guest.*', out): + self.facts['virtualization_type'] = 'guest' + self.facts['virtualization_role'] = 'HPVM IVM' + elif rc == 0 and re.match('.*Running.*HPVM host.*', out): + self.facts['virtualization_type'] = 'host' + self.facts['virtualization_role'] = 'HPVM' + if os.path.exists('/usr/sbin/parstatus'): + rc, out, err = module.run_command("/usr/sbin/parstatus") + if rc == 0: + self.facts['virtualization_type'] = 'guest' + self.facts['virtualization_role'] = 'HP nPar' + + class SunOSVirtual(Virtual): """ This is a SunOS-specific subclass of Virtual. It defines From 46ad4299a88d83a45053e6db3207e750701606b5 Mon Sep 17 00:00:00 2001 From: "Edgars M." Date: Thu, 13 Jun 2013 15:17:35 +0300 Subject: [PATCH 11/33] Fixed Issue #3193 --- library/packaging/rhn_register | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/packaging/rhn_register b/library/packaging/rhn_register index ae01607748c..87e0ef78f1e 100644 --- a/library/packaging/rhn_register +++ b/library/packaging/rhn_register @@ -181,7 +181,7 @@ class Rhn(RegistrationBase): Returns: str ''' url = urlparse.urlparse(self.config['serverURL']) - return url.netloc.replace('xmlrpc.','') + return url[1].replace('xmlrpc.','') @property def systemid(self): From 499c7309e37e4c0569fa87b177d3f248d62245c8 Mon Sep 17 00:00:00 2001 From: Chris Hoffman Date: Thu, 13 Jun 2013 15:19:35 -0400 Subject: [PATCH 12/33] Fixing documentation error --- library/packaging/npm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/packaging/npm b/library/packaging/npm index a158b1478c5..7857a20107f 100644 --- a/library/packaging/npm +++ b/library/packaging/npm @@ -53,7 +53,7 @@ options: - The executable location for npm. - This is useful if you are using a version manager, such as nvm required: false - default: nvm + default: null production: description: - Install dependencies in production mode, excluding devDependencies From 0d4eec36f4e6619c9b375580e88800bbf43f6623 Mon Sep 17 00:00:00 2001 From: trbs Date: Thu, 13 Jun 2013 23:05:08 +0200 Subject: [PATCH 13/33] fixed x-bits in git --- examples/scripts/yaml_to_ini.py | 0 hacking/authors.sh | 0 lib/ansible/utils/module_docs.py | 0 library/system/filesystem | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 examples/scripts/yaml_to_ini.py mode change 100644 => 100755 hacking/authors.sh mode change 100755 => 100644 lib/ansible/utils/module_docs.py mode change 100755 => 100644 library/system/filesystem diff --git a/examples/scripts/yaml_to_ini.py b/examples/scripts/yaml_to_ini.py old mode 100644 new mode 100755 diff --git a/hacking/authors.sh b/hacking/authors.sh old mode 100644 new mode 100755 diff --git a/lib/ansible/utils/module_docs.py b/lib/ansible/utils/module_docs.py old mode 100755 new mode 100644 diff --git a/library/system/filesystem b/library/system/filesystem old mode 100755 new mode 100644 From 10dc5ae8768618c50f7a5b2d0df4696cc6c1e47d Mon Sep 17 00:00:00 2001 From: trbs Date: Thu, 13 Jun 2013 23:09:22 +0200 Subject: [PATCH 14/33] minor fix, path name of ansible.cfg in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67498069a96..6167d7edd30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -449,7 +449,7 @@ Highlighted Core Changes: Other Core Changes: -* ansible config file can also go in '.ansible.cfg' in cwd in addition to ~/.ansible.cfg and /etc/ansible/ansible.cfg +* ansible config file can also go in 'ansible.cfg' in cwd in addition to ~/.ansible.cfg and /etc/ansible/ansible.cfg * fix for inventory hosts at API level when hosts spec is a list and not a colon delimited string * ansible-pull example now sets up logrotate for the ansible-pull cron job log * negative host matching (!hosts) fixed for external inventory script usage From 653fac2f5ce1d90903de121fe7d0ac69d2f0e1f8 Mon Sep 17 00:00:00 2001 From: trbs Date: Thu, 13 Jun 2013 23:13:54 +0200 Subject: [PATCH 15/33] fix loading order of ansible.cfg in documentation --- docsite/latest/rst/examples.rst | 4 ++-- examples/ansible.cfg | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docsite/latest/rst/examples.rst b/docsite/latest/rst/examples.rst index 5edb9a23615..6fa38a4352f 100644 --- a/docsite/latest/rst/examples.rst +++ b/docsite/latest/rst/examples.rst @@ -259,8 +259,8 @@ Ansible has an optional configuration file that can be used to tune settings and the first config file it finds present: 1. File specified by the ``ANSIBLE_CONFIG`` environment variable -2. ``ansible.cfg`` in the current working directory. (version 0.8 and up) -3. ``~/.ansible.cfg`` +2. ``~/.ansible.cfg`` +3. ``ansible.cfg`` in the current working directory. (version 0.8 and up) 4. ``/etc/ansible/ansible.cfg`` For those running from source, a sample configuration file lives in the examples/ directory. The RPM will install configuration into /etc/ansible/ansible.cfg automatically. diff --git a/examples/ansible.cfg b/examples/ansible.cfg index 6536550c1c5..dc42359fcaf 100644 --- a/examples/ansible.cfg +++ b/examples/ansible.cfg @@ -1,6 +1,8 @@ # 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/ansible.cfg, whichever it finds first +# ansible will read ~/.ansible.cfg, ansible.cfg in the current working directory or +# /etc/ansible/ansible.cfg, whichever it finds first [defaults] From 8a55210fb6e28629886b5af10cc7e2ca125c4cb1 Mon Sep 17 00:00:00 2001 From: Chris Hoffman Date: Thu, 13 Jun 2013 20:43:14 -0400 Subject: [PATCH 16/33] Removing all the default: null from the documentation --- library/packaging/npm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/packaging/npm b/library/packaging/npm index 7857a20107f..67df45c719a 100644 --- a/library/packaging/npm +++ b/library/packaging/npm @@ -31,17 +31,14 @@ options: description: - The name of a node.js library to install requires: false - default: null path: description: - The base path where to install the node.js libraries required: false - default: null version: description: - The version to be installed required: false - default: null global: description: - Install the node.js library globally @@ -53,7 +50,6 @@ options: - The executable location for npm. - This is useful if you are using a version manager, such as nvm required: false - default: null production: description: - Install dependencies in production mode, excluding devDependencies From 0840af5bdabce4fb39dd2860d4a9a0908e466d6d Mon Sep 17 00:00:00 2001 From: Derek Carter Date: Thu, 13 Jun 2013 23:02:04 -0400 Subject: [PATCH 17/33] fixed msg bug in library/cloud/quantum_network --- library/cloud/quantum_network | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/cloud/quantum_network b/library/cloud/quantum_network index c5866c0a173..3d2090256cf 100644 --- a/library/cloud/quantum_network +++ b/library/cloud/quantum_network @@ -167,7 +167,7 @@ def _get_net_id(quantum, module): try: networks = quantum.list_networks(**kwargs) except Exception as e: - module.fail_json("Error in listing quantum networks: %s" % e.message) + module.fail_json(msg = "Error in listing quantum networks: %s" % e.message) if not networks['networks']: return None return networks['networks'][0]['id'] From dcb06a23069f48a18b6b41c292be6d1377b40dd5 Mon Sep 17 00:00:00 2001 From: Veeti Paananen Date: Fri, 14 Jun 2013 14:29:45 +0300 Subject: [PATCH 18/33] Document the data argument for apt_key --- library/packaging/apt_key | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/packaging/apt_key b/library/packaging/apt_key index de4ada8c399..adb94f5e699 100644 --- a/library/packaging/apt_key +++ b/library/packaging/apt_key @@ -37,6 +37,11 @@ options: default: none description: - identifier of key + data: + required: false + default: none + description: + - keyfile contents url: required: false default: none From d65f45f0b2c50e119271e2d7eaeecb0dd9b918ce Mon Sep 17 00:00:00 2001 From: David Golden Date: Fri, 14 Jun 2013 09:55:38 -0400 Subject: [PATCH 19/33] Expand sudo_user after variable merging Previous commit c3659741 expanded sudo_user during task construction, but this is too early as it does not pick up variables set during the play. This commit moves sudo_user expansion to the runner after variables have been merged. --- lib/ansible/playbook/task.py | 2 +- lib/ansible/runner/__init__.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index c6d260cda4c..ac9972fc592 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -115,7 +115,7 @@ class Task(object): self.args = ds.get('args', {}) if self.sudo: - self.sudo_user = template.template(play.basedir, ds.get('sudo_user', play.sudo_user), module_vars) + self.sudo_user = ds.get('sudo_user', play.sudo_user) self.sudo_pass = ds.get('sudo_pass', play.playbook.sudo_pass) else: self.sudo_user = None diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 9ee9e54a12b..94c886e6aa1 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -386,6 +386,10 @@ class Runner(object): if self.inventory.basedir() is not None: inject['inventory_dir'] = self.inventory.basedir() + # late processing of parameterized sudo_user + if self.sudo_user is not None: + self.sudo_user = template.template(self.basedir, self.sudo_user, inject) + # allow with_foo to work in playbooks... items = None items_plugin = self.module_vars.get('items_lookup_plugin', None) From d7ba2e06ebb516c70737c75d751a12b0c37d6fe9 Mon Sep 17 00:00:00 2001 From: Lorin Hochstein Date: Fri, 14 Jun 2013 11:13:38 -0400 Subject: [PATCH 20/33] Document: with_file(glob) relative path and roles Document that with_file and with_fileglob path is relative to the files directory inside of a role. --- docsite/latest/rst/playbooks.rst | 6 ++++-- docsite/latest/rst/playbooks2.rst | 32 ++++++++++++++++++------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/docsite/latest/rst/playbooks.rst b/docsite/latest/rst/playbooks.rst index c0d069bd2e3..d0e0506780f 100644 --- a/docsite/latest/rst/playbooks.rst +++ b/docsite/latest/rst/playbooks.rst @@ -150,11 +150,11 @@ These variables can be used later in the playbook like this:: $varname or ${varname} or {{ varname }} -If you ever want to do anything complex like uppercasing a string, {{ varname }} is best, as it uses the Jinja2 templating engine. It is a good idea to get in the habit of using this form most of the time when the output is to be a string. +If you ever want to do anything complex like uppercasing a string, {{ varname }} is best, as it uses the Jinja2 templating engine. It is a good idea to get in the habit of using this form most of the time when the output is to be a string. If just referencing the value of another simple variable though, it's fine to say $x or ${x}. This is common for when a datastructure has a member that is the value of another datastructure. -To learn more about Jinja2, you can optionally see the `Jinja2 docs `_ - though remember that Jinja2 loops and conditionals are only for 'templates' in Ansible, in playbooks, ansible has the 'when' and 'with' keywords for conditionals and loops. +To learn more about Jinja2, you can optionally see the `Jinja2 docs `_ - though remember that Jinja2 loops and conditionals are only for 'templates' in Ansible, in playbooks, ansible has the 'when' and 'with' keywords for conditionals and loops. If there are discovered variables about the system, called 'facts', these variables bubble up back into the playbook, and can be used on each system just like explicitly set variables. Ansible provides several @@ -438,6 +438,8 @@ inside another. play are going to get the same tasks. ('*when*' provides some ability for hosts to conditionally skip tasks). +.. _roles: + Roles ````` diff --git a/docsite/latest/rst/playbooks2.rst b/docsite/latest/rst/playbooks2.rst index 2dfc8e76224..362e6b20587 100644 --- a/docsite/latest/rst/playbooks2.rst +++ b/docsite/latest/rst/playbooks2.rst @@ -264,7 +264,7 @@ Conditional Execution ````````````````````` (Note: this section covers 1.2 conditionals, if you are using a previous version, select -the previous version of the documentation, `Ansible 1.1 Docs `_ . +the previous version of the documentation, `Ansible 1.1 Docs `_ . Those conditional forms continue to be operational in 1.2, although the new mechanisms are cleaner.) Sometimes you will want to skip a particular step on a particular host. This could be something @@ -290,7 +290,7 @@ decide to do something conditionally based on success or failure:: - action: command /bin/something when: result|failed - action: command /bin/something_else - when: result|sucess + when: result|sucess As a reminder, to see what derived variables are available, you can do:: @@ -305,7 +305,7 @@ Tip: Sometimes you'll get back a variable that's a string and you'll want to do Variables defined in the playbooks or inventory can also be used. -If a required variable has not been set, you can skip or fail using Jinja2's +If a required variable has not been set, you can skip or fail using Jinja2's `defined` test. For example:: tasks: @@ -315,7 +315,7 @@ If a required variable has not been set, you can skip or fail using Jinja2's - fail: msg="Bailing out: this play requires 'bar'" when: bar is not defined -This is especially useful in combination with the conditional import of vars +This is especially useful in combination with the conditional import of vars files (see below). It's also easy to provide your own facts if you want, which is covered in :doc:`moduledev`. To run them, just @@ -467,6 +467,12 @@ be used like this:: with_file: - /home/foo/.ssh/id_rsa.pub +.. note:: + + When using ``with_fileglob`` or ``with_file`` with :ref:`roles`, if you + specify a relative path (e.g., :file:`./foo`), Ansible resolves the path + relative to the :file:`roles//files` directory. + .. versionadded: 0.9 Many new lookup abilities were added in 0.9. Remeber lookup plugins are run on the *controlling* machine:: @@ -809,8 +815,8 @@ a good idea:: delegate_to: 127.0.0.1 -These commands will run on 127.0.0.1, which is the machine running Ansible. There is also a shorthand syntax that -you can use on a per-task basis: 'local_action'. Here is the same playbook as above, but using the shorthand +These commands will run on 127.0.0.1, which is the machine running Ansible. There is also a shorthand syntax that +you can use on a per-task basis: 'local_action'. Here is the same playbook as above, but using the shorthand syntax for delegating to 127.0.0.1:: --- @@ -904,17 +910,17 @@ event the same variable name occurs in more than one place, what happens? There of precedence, and within those tiers, some minor ordering rules that you probably won't even need to remember. We'll explain them anyway though. -Variables that are set during the execution of the play have highest priority. This includes registered -variables and facts, which are discovered pieces of information about remote hosts. +Variables that are set during the execution of the play have highest priority. This includes registered +variables and facts, which are discovered pieces of information about remote hosts. Descending in priority are variables defined in the playbook. 'vars_files' as defined in the playbook are next up, followed by variables as passed to ansible-playbook via --extra-vars (-e), then variables defined in the 'vars' section. These should all be taken to be basically the same thing -- good places to define constants about what the play does to all hosts -in the play. +in the play. Finally, inventory variables have the least priority. Variables about hosts override those about groups. -If a variable is defined in multiple groups and one group is a child of the other, the child group variable -will override the variable set in the parent. +If a variable is defined in multiple groups and one group is a child of the other, the child group variable +will override the variable set in the parent. This makes the 'group_vars/all' file the best place to define a default value you wish to override in another group, or even in a playbook. For example, your organization might set a default ntp server in group_vars/all @@ -922,8 +928,8 @@ and then override it based on a group based on a geographic region. However if in a vars section of a playbook, you know from reading the playbook that THAT specific value is definitely the one that is going to be used. You won't be fooled by some variable from inventory sneaking up on you. -So, in short, if you want something easy to remember: facts beat playbook definitions, and -playbook definitions beat inventory variables. +So, in short, if you want something easy to remember: facts beat playbook definitions, and +playbook definitions beat inventory variables. Check Mode ("Dry Run") --check From 7681b1ce68369f1c21eaa621ddedde20d782896d Mon Sep 17 00:00:00 2001 From: Dale Sedivec Date: Fri, 14 Jun 2013 13:27:59 -0500 Subject: [PATCH 21/33] Improve Markdown (and other) module doc output - The html_ify filter now escapes HTML found in module documentation. THIS COULD AFFECT MORE THAN JUST MARKDOWN but I didn't see any modules expecting to use e.g. HTML entities or HTML tags in their documentation. - The markdown_ify filter (used as jpfunc in markdown.j2) escapes at least a few Markdown in-line formatting characters. - Improvements to markdown.j2: - Call jpfunc on the module name heading so that it gets escaped for Markdown (e.g. my_module_name becomes my\_module\_name). - Added paragraph breaks between paragraphs in the description. - Added examples heading, which is consistent with the notes heading below it. --- hacking/module_formatter.py | 11 +++++++++-- hacking/templates/markdown.j2 | 9 +++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hacking/module_formatter.py b/hacking/module_formatter.py index 7eb1e106fbe..e16575676e7 100755 --- a/hacking/module_formatter.py +++ b/hacking/module_formatter.py @@ -30,6 +30,7 @@ import optparse import time import datetime import subprocess +import cgi import ansible.utils import ansible.utils.module_docs as module_docs @@ -62,11 +63,13 @@ def latex_ify(text): def html_ify(text): - t = _ITALIC.sub("" + r"\1" + "", text) + t = cgi.escape(text) + t = _ITALIC.sub("" + r"\1" + "", t) t = _BOLD.sub("" + r"\1" + "", t) t = _MODULE.sub("" + r"\1" + "", t) t = _URL.sub("" + r"\1" + "", t) t = _CONST.sub("" + r"\1" + "", t) + return t def json_ify(text): @@ -105,9 +108,13 @@ def rst_ify(text): return t +_MARKDOWN = re.compile(r"[*_`]") + def markdown_ify(text): - t = _ITALIC.sub("_" + r"\1" + "_", text) + t = cgi.escape(text) + t = _MARKDOWN.sub(r"\\\g<0>", t) + t = _ITALIC.sub("_" + r"\1" + "_", t) t = _BOLD.sub("**" + r"\1" + "**", t) t = _MODULE.sub("*" + r"\1" + "*", t) t = _URL.sub("[" + r"\1" + "](" + r"\1" + ")", t) diff --git a/hacking/templates/markdown.j2 b/hacking/templates/markdown.j2 index 0cc8151fde9..6f9bb0b3d88 100644 --- a/hacking/templates/markdown.j2 +++ b/hacking/templates/markdown.j2 @@ -1,4 +1,4 @@ -## @{ module }@ +## @{ module | jpfunc }@ {# ------------------------------------------ # @@ -11,7 +11,8 @@ New in version @{ version_added }@. {% endif %} {% for desc in description -%} -@{ desc | jpfunc }@ +@{ desc | jpfunc }@ + {% endfor %} {% if options -%} @@ -35,6 +36,10 @@ New in version @{ version_added }@. {% endif %} +{% if examples or plainexamples %} +#### Examples +{% endif %} + {% for example in examples %} {% if example['description'] %} * @{ example['description'] | jpfunc }@ From 8b188429c77f7c91481dacd453ba0ab931539139 Mon Sep 17 00:00:00 2001 From: Serge van Ginderachter Date: Fri, 14 Jun 2013 20:45:58 +0200 Subject: [PATCH 22/33] docfix on file module, aliases for path parameter --- library/files/file | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/files/file b/library/files/file index ed957819eb4..85befb3415e 100644 --- a/library/files/file +++ b/library/files/file @@ -42,7 +42,7 @@ options: - defines the file being managed, unless when used with C(state=link), and then sets the destination to create a symbolic link to using I(src) required: true default: [] - aliases: [] + aliases: ['dest', 'name'] state: description: - If C(directory), all immediate subdirectories will be created if they From 9dfc420927bf3cf7b2aff938164941edfef2213a Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Sat, 15 Jun 2013 16:27:45 +0200 Subject: [PATCH 23/33] openbsd_pkg: Add check_mode support. The biggest change has been to package_latest since it was previously just comparing version numbers before and after an upgrade had run. We now parse the output from a dry run instead. Thanks to Johan Belin for triggering the discussion :). --- library/packaging/openbsd_pkg | 77 ++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/library/packaging/openbsd_pkg b/library/packaging/openbsd_pkg index f5bd6b5dbe9..1f1e7707bf9 100644 --- a/library/packaging/openbsd_pkg +++ b/library/packaging/openbsd_pkg @@ -98,16 +98,26 @@ def get_package_state(name, specific_version): return False # Function used to make sure a package is present. -def package_present(name, installed_state): - install_cmd = 'pkg_add -I' +def package_present(name, installed_state, module): + if module.check_mode: + install_cmd = 'pkg_add -In' + else: + install_cmd = 'pkg_add -I' + if installed_state is False: - rc, stdout, stderr = execute_command("%s %s" % (install_cmd, name), syslogging) + + # Attempt to install the package + (rc, stdout, stderr) = execute_command("%s %s" % (install_cmd, name), syslogging) + # pkg_add returns 0 even if the package does not exist # so depend on stderr instead if something bad happened. if stderr: rc = 1 changed=False else: + if module.check_mode: + module.exit_json(changed=True) + changed=True else: rc = 0 @@ -118,47 +128,65 @@ def package_present(name, installed_state): return (rc, stdout, stderr, changed) # Function used to make sure a package is the latest available version. -def package_latest(name, installed_state, specific_version): +def package_latest(name, installed_state, specific_version, module): + if module.check_mode: + upgrade_cmd = 'pkg_add -umn' + else: + upgrade_cmd = 'pkg_add -um' - upgrade_cmd = 'pkg_add -u' pre_upgrade_name = '' - post_upgrade_name = '' + if installed_state is True: - # pkg_add -u exits 0 even if no update was needed, so compare the - # installed package before and after to know if we changed anything. + # Fetch name of currently installed package pre_upgrade_name = get_current_name(name, specific_version) + # Attempt to upgrade the package (rc, stdout, stderr) = execute_command("%s %s" % (upgrade_cmd, name), syslogging) - # 'pkg_add -u' returns 0 even when something strange happened, stdout - # should be empty if everything went fine. - if stdout: - rc=1 - - post_upgrade_name = get_current_name(name, specific_version) + # Look for output looking something like "nmap-6.01->6.25: ok" to see if + # something changed (or would have changed). Use \W to delimit the match + # from progress meter output. + match = re.search("\W%s->.+: ok\W" % pre_upgrade_name, stdout) + if match: + if module.check_mode: + module.exit_json(changed=True) - if pre_upgrade_name == post_upgrade_name: - changed = False - else: changed = True + else: + changed = False + + # 'pkg_add -u' returns 0 even when something strange happened, stderr + # should be empty if everything went fine. + if stderr: + rc=1 return (rc, stdout, stderr, changed) else: # If package was not installed at all just make it present. - return package_present(name, installed_state) + return package_present(name, installed_state, module) # Function used to make sure a package is not installed. -def package_absent(name, installed_state): - remove_cmd = 'pkg_delete -I' +def package_absent(name, installed_state, module): + if module.check_mode: + remove_cmd = 'pkg_delete -In' + else: + remove_cmd = 'pkg_delete -I' + if installed_state is True: + + # Attempt to remove the package rc, stdout, stderr = execute_command("%s %s" % (remove_cmd, name), syslogging) if rc == 0: + if module.check_mode: + module.exit_json(changed=True) + changed=True else: changed=False + else: rc = 0 stdout = '' @@ -175,7 +203,8 @@ def main(): argument_spec = dict( name = dict(required=True), state = dict(required=True, choices=['absent', 'installed', 'latest', 'present', 'removed']), - ) + ), + supports_check_mode = True ) name = module.params['name'] @@ -201,11 +230,11 @@ def main(): # Perform requested action if state in ['installed', 'present']: - (rc, stdout, stderr, changed) = package_present(name, installed_state) + (rc, stdout, stderr, changed) = package_present(name, installed_state, module) elif state in ['absent', 'removed']: - (rc, stdout, stderr, changed) = package_absent(name, installed_state) + (rc, stdout, stderr, changed) = package_absent(name, installed_state, module) elif state == 'latest': - (rc, stdout, stderr, changed) = package_latest(name, installed_state, specific_version) + (rc, stdout, stderr, changed) = package_latest(name, installed_state, specific_version, module) if rc != 0: if stderr: From 2470c3f26dea94cf77f31a624748dfa3356bfd87 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Sat, 15 Jun 2013 12:16:25 -0400 Subject: [PATCH 24/33] now you have the option to NOT set the password if the user already exists, this works well for 'initial password setting' on user creation and avoids having extra tasks and conditionals. Signed-off-by: Brian Coca --- library/system/user | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/library/system/user b/library/system/user index 88f79aab246..af134a3c83b 100644 --- a/library/system/user +++ b/library/system/user @@ -158,6 +158,18 @@ options: - Set a passphrase for the SSH key. If no passphrase is provided, the SSH key will default to having no passphrase. + update_password: + required: false + default: always + choices: ['always', 'on_creation'] + version_added: "1.3" + description: + - Control when does ansible update passwords. + C(always) will update if they differ. + C(on_creation) will only update the password if user is being created. +examples: + - code: 'user: name=johnd comment="John Doe" uid=1040' + description: "Add the user 'johnd' with a specific uid and a primary group of 'admin'" examples: - code: 'user: name=johnd comment="John Doe" uid=1040' description: "Add the user 'johnd' with a specific uid and a primary group of 'admin'" @@ -226,6 +238,7 @@ class User(object): self.ssh_type = module.params['ssh_key_type'] self.ssh_comment = module.params['ssh_key_comment'] self.ssh_passphrase = module.params['ssh_key_passphrase'] + self.update_password = module.params['update_password'] if module.params['ssh_key_file'] is not None: self.ssh_file = module.params['ssh_key_file'] else: @@ -357,7 +370,7 @@ class User(object): cmd.append('-s') cmd.append(self.shell) - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd.append('-p') cmd.append(self.password) @@ -690,7 +703,7 @@ class FreeBsdUser(User): (rc, out, err) = (None, '', '') # we have to set the password in a second command - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd = [ self.module.get_bin_path('chpass', True), '-p', @@ -836,7 +849,7 @@ class OpenBSDUser(User): cmd.append('-L') cmd.append(self.login_class) - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd.append('-p') cmd.append(self.password) @@ -989,7 +1002,7 @@ class NetBSDUser(User): cmd.append('-L') cmd.append(self.login_class) - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd.append('-p') cmd.append(self.password) @@ -1154,7 +1167,7 @@ class SunOS(User): (rc, out, err) = (None, '', '') # we have to set the password by editing the /etc/shadow file - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: try: lines = [] for line in open(self.SHADOWFILE, 'rb').readlines(): @@ -1303,7 +1316,7 @@ class AIX(User): (rc, out, err) = self.execute_command(cmd) # set password with chpasswd - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd = [] cmd.append('echo "'+self.name+':'+self.password+'" |') cmd.append(self.module.get_bin_path('chpasswd', True)) @@ -1354,7 +1367,8 @@ def main(): ssh_key_type=dict(default=ssh_defaults['type'], type='str'), ssh_key_file=dict(default=None, type='str'), ssh_key_comment=dict(default=ssh_defaults['comment'], type='str'), - ssh_key_passphrase=dict(default=None, type='str') + ssh_key_passphrase=dict(default=None, type='str'), + update_password=dict(default='always',choices=['always','on_create'],type='str') ), supports_check_mode=True ) From 5c69918d53c6d4e9fdc648506623922acf246fc8 Mon Sep 17 00:00:00 2001 From: Jan-Piet Mens Date: Fri, 14 Jun 2013 11:53:43 +0200 Subject: [PATCH 25/33] DOCS: standardize on EXAMPLES (a.k.a. Docs-JumboPatch JetLag Edition) Migrated all examples: in DOCUMENTATION=''' string to standalone EXAMPLES=''' string Added deprecation warning to moduledev.rst and remove deprecated example from it Fixed up a few typos and uppercased some acronyms. add consistency to how EXAMPLES are formatted --- docsite/latest/rst/moduledev.rst | 9 +-- library/cloud/cloudformation | 26 ++++----- library/cloud/glance_image | 20 +++++-- library/cloud/keystone_user | 20 ++++--- library/cloud/nova_compute | 29 +++++----- library/cloud/nova_keypair | 22 ++++--- library/cloud/quantum_floating_ip | 19 ++++--- library/cloud/quantum_floating_ip_associate | 16 ++++-- library/cloud/quantum_network | 21 ++++--- library/cloud/quantum_router | 6 +- library/cloud/quantum_router_gateway | 13 +++-- library/cloud/quantum_router_interface | 14 +++-- library/cloud/quantum_subnet | 26 +++++---- library/cloud/rax | 28 ++++----- library/cloud/s3 | 14 ++--- library/cloud/virt | 3 +- library/commands/command | 14 +++-- library/commands/raw | 8 ++- library/commands/script | 19 ++++--- library/commands/shell | 8 ++- library/database/mongodb_user | 13 +++-- library/database/mysql_db | 8 ++- library/database/mysql_user | 22 ++++--- library/database/postgresql_db | 19 +++++-- library/database/postgresql_user | 28 +++++---- library/database/riak | 17 +++--- library/files/assemble | 8 ++- library/files/copy | 18 +++--- library/files/file | 9 +-- library/files/ini_file | 19 ++++--- library/files/lineinfile | 14 ++--- library/files/template | 13 +++-- library/inventory/add_host | 18 +++--- library/inventory/group_by | 12 ++-- library/messaging/rabbitmq_plugin | 8 ++- library/messaging/rabbitmq_user | 14 ++++- library/messaging/rabbitmq_vhost | 8 ++- library/monitoring/monit | 8 ++- library/monitoring/nagios | 63 +++++++++++++-------- library/net_infrastructure/netscaler | 19 ++++--- library/network/slurp | 16 +++--- library/network/uri | 55 +++++++++--------- library/notification/mail | 34 +++++------ library/packaging/apt | 49 +++++++++------- library/packaging/apt_key | 24 +++++--- library/packaging/apt_repository | 13 +++-- library/packaging/easy_install | 13 +++-- library/packaging/macports | 10 ++-- library/packaging/npm | 38 ++++++++----- library/packaging/openbsd_pkg | 18 +++--- library/packaging/opkg | 8 +-- library/packaging/pacman | 24 ++++---- library/packaging/pip | 48 +++++++++------- library/packaging/pkgin | 18 +++--- library/packaging/pkgng | 15 ++--- library/packaging/redhat_subscription | 16 ++++-- library/packaging/rhn_channel | 2 +- library/packaging/rhn_register | 39 ++++++++----- library/packaging/svr4pkg | 19 ++++--- library/packaging/yum | 11 ++-- library/packaging/zypper | 12 ++-- library/source_control/bzr | 8 ++- library/source_control/git | 20 ++++--- library/source_control/hg | 8 ++- library/source_control/subversion | 8 ++- library/system/authorized_key | 7 ++- library/system/cron | 27 +++++---- library/system/facter | 8 ++- library/system/filesystem | 13 +++-- library/system/group | 8 ++- library/system/lvg | 24 +++++--- library/system/lvol | 23 +++++--- library/system/mount | 17 +++--- library/system/ohai | 8 ++- library/system/ping | 8 ++- library/system/seboolean | 8 ++- library/system/selinux | 10 ++-- library/system/service | 38 ++++++++----- library/system/sysctl | 20 ++++--- library/system/user | 18 +++--- library/system/zfs | 25 +++++--- library/utilities/debug | 19 ++++--- library/utilities/fail | 12 ++-- library/utilities/pause | 18 +++--- library/utilities/set_fact | 8 +-- library/utilities/wait_for | 2 +- library/web_infrastructure/django_manage | 20 +++---- library/web_infrastructure/supervisorctl | 2 +- 88 files changed, 914 insertions(+), 628 deletions(-) diff --git a/docsite/latest/rst/moduledev.rst b/docsite/latest/rst/moduledev.rst index 995f4993765..011688854c2 100644 --- a/docsite/latest/rst/moduledev.rst +++ b/docsite/latest/rst/moduledev.rst @@ -363,12 +363,9 @@ Include it in your module file like this:: module: modulename short_description: This is a sentence describing the module # ... snip ... - examples: - - code: modulename opt1=arg1 opt2=arg2 - description: Optional words describing this example ''' -The ``description``, ``notes`` and ``description`` within ``examples`` +The ``description``, and ``notes`` support formatting in some of the output formats (e.g. ``rst``, ``man``). These formatting functions are ``U()``, ``M()``, ``I()``, and ``C()`` for URL, module, italic, and constant-width respectively. It is suggested @@ -376,7 +373,7 @@ to use ``C()`` for file and option names, and ``I()`` when referencing parameters; module names should be specifies as ``M(module)``. Examples (which typically contain colons, quotes, etc.) are difficult -to format with YAML, so these can (alternatively, or additionally) be +to format with YAML, so these must be written in plain text in an ``EXAMPLES`` string within the module like this:: @@ -385,7 +382,7 @@ like this:: ''' The ``module_formatter.py`` script and ``ansible-doc(1)`` append the -``EXAMPLES`` blob after any existing ``examples`` you may have in the +``EXAMPLES`` blob after any existing (deprecated) ``examples`` you may have in the YAML ``DOCUMENTATION`` string. Building & Testing diff --git a/library/cloud/cloudformation b/library/cloud/cloudformation index e08cea42469..9069bf9f416 100644 --- a/library/cloud/cloudformation +++ b/library/cloud/cloudformation @@ -72,19 +72,19 @@ author: James S. Martin ''' EXAMPLES = ''' - # Basic task example - tasks: - - name: launch ansible cloudformation example - action: cloudformation > - stack_name="ansible-cloudformation" state=present - region=us-east-1 disable_rollback=yes - template=files/cloudformation-example.json - args: - template_parameters: - KeyName: jmartin - DiskType: ephemeral - InstanceType: m1.small - ClusterSize: 3 +# Basic task example +tasks: +- name: launch ansible cloudformation example + action: cloudformation > + stack_name="ansible-cloudformation" state=present + region=us-east-1 disable_rollback=yes + template=files/cloudformation-example.json + args: + template_parameters: + KeyName: jmartin + DiskType: ephemeral + InstanceType: m1.small + ClusterSize: 3 ''' import boto.cloudformation.connection diff --git a/library/cloud/glance_image b/library/cloud/glance_image index af95c7d6efe..d792272cf3a 100644 --- a/library/cloud/glance_image +++ b/library/cloud/glance_image @@ -85,12 +85,12 @@ options: default: None is_public: description: - - Wether the image can be accesed publically + - Wether the image can be accessed publicly required: false default: 'yes' copy_from: description: - - A url from where the image can be downloaded, mutually exculsive with file parameter + - A url from where the image can be downloaded, mutually exclusive with file parameter required: false default: None timeout: @@ -103,14 +103,22 @@ options: - The path to the file which has to be uploaded, mutually exclusive with copy_from required: false default: None -examples: - - code: "glance_image: login_username=admin login_password=passme login_tenant_name=admin name=cirros container_format=bare - disk_format=qcow2 state=present copy_from=http:launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img" - description: "Uploads an image from an http url" requirements: ["glanceclient", "keystoneclient"] ''' +EXAMPLES = ''' +# Upload an image from an HTTP URL +- glance_image: login_username=admin + login_password=passme + login_tenant_name=admin + name=cirros + container_format=bare + disk_format=qcow2 + state=present + copy_from=http:launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img +''' + import time try: import glanceclient diff --git a/library/cloud/keystone_user b/library/cloud/keystone_user index 65b4a6604fa..ea8fc7e1751 100644 --- a/library/cloud/keystone_user +++ b/library/cloud/keystone_user @@ -32,7 +32,7 @@ options: default: 'http://127.0.0.1:35357/v2.0/' user: description: - - The name of the user that has to added/removed from openstack + - The name of the user that has to added/removed from OpenStack required: false default: None password: @@ -65,17 +65,21 @@ options: - Indicate desired state of the resource choices: ['present', 'absent'] default: present -examples: - - code: 'keystone_user: tenant=demo tenant_description="Default Tenant"' - description: Create a tenant - - code: 'keystone_user: user=john tenant=demo password=secrete' - description: Create a user - - code: 'keystone_user: role=admin user=john tenant=demo' - description: Apply the admin role to the john user in the demo tenant requirements: [ python-keystoneclient ] author: Lorin Hochstein ''' +EXAMPLES = ''' +# Create a tenant +- keystone_user: tenant=demo tenant_description="Default Tenant" + +# Create a user +- keystone_user: user=john tenant=demo password=secrete + +# Apply the admin role to the john user in the demo tenant +- keystone_user: role=admin user=john tenant=demo +''' + try: from keystoneclient.v2_0 import client except ImportError: diff --git a/library/cloud/nova_compute b/library/cloud/nova_compute index d9afc53a362..e26474ea38f 100644 --- a/library/cloud/nova_compute +++ b/library/cloud/nova_compute @@ -25,7 +25,7 @@ except ImportError: DOCUMENTATION = ''' --- module: nova_compute -short_description: Create/Delete VM's from OpenStack +short_description: Create/Delete VMs from OpenStack description: - Create or Remove virtual machines from Openstack. options: @@ -71,41 +71,45 @@ options: default: None flavor_id: description: - - The id of the flavor in which the new vm has to be created + - The id of the flavor in which the new VM has to be created required: false default: 1 key_name: description: - - The keypair name to be used when creating a vm + - The key pair name to be used when creating a VM required: false default: None security_groups: description: - - The name of the security group to which the vm should be added + - The name of the security group to which the VM should be added required: false default: None nics: description: - - A list of network id's to which the vm's interface should be attached + - A list of network id's to which the VM's interface should be attached required: false default: None meta: description: - - A list of key value pairs that should be provided as a metadata to the new vm + - A list of key value pairs that should be provided as a metadata to the new VM required: false default: None wait: description: - - If the module should wait for the vm to be created. + - If the module should wait for the VM to be created. required: false default: 'yes' wait_for: description: - - The amount of time the module should wait for the vm to get into active state + - The amount of time the module should wait for the VM to get into active state required: false default: 180 -examples: - - code: "nova_compute: +requirements: ["novaclient"] +''' + +EXAMPLES = ''' +# Creates a new VM and attaches to a network and passes metadata to the instance +- nova_compute: state: present login_username: admin login_password: admin @@ -119,10 +123,9 @@ examples: - net-id: 34605f38-e52a-25d2-b6ec-754a13ffb723 meta: hostname: test1 - group: uge_master" - description: "Creates a new VM and attaches to a network and passes metadata to the instance" -requirements: ["novaclient"] + group: uge_master ''' + def _delete_server(module, nova): name = None try: diff --git a/library/cloud/nova_keypair b/library/cloud/nova_keypair index 6edce4da26c..f9c449af529 100644 --- a/library/cloud/nova_keypair +++ b/library/cloud/nova_keypair @@ -25,9 +25,9 @@ except ImportError: DOCUMENTATION = ''' --- module: nova_keypair -short_description: Add/Delete keypair from nova +short_description: Add/Delete key pair from nova description: - - Add or Remove keypair from nova . + - Add or Remove key pair from nova . options: login_username: description: @@ -61,7 +61,7 @@ options: default: present name: description: - - Name that has to be given to the keypair + - Name that has to be given to the key pair required: true default: None public_key: @@ -70,14 +70,18 @@ options: required: false default: None -examples: - - code: "nova_keypair: state=present login_username=admin login_password=admin login_tenant_name=admin name=ansible_key - public_key={{ lookup('file','~/.ssh/id_rsa.pub') }}" - description: "Creates a keypair with the running users public key" - - code: "nova_keypair: state=present login_username=admin login_password=admin login_tenant_name=admin name=ansible_key" - description: "Creates a new keypair and the private key returned after the run." requirements: ["novaclient"] ''' +EXAMPLES = ''' +# Creates a key pair with the running users public key +- nova_keypair: state=present login_username=admin + login_password=admin login_tenant_name=admin name=ansible_key + public_key={{ lookup('file','~/.ssh/id_rsa.pub') }} + +# Creates a new key pair and the private key returned after the run. +- nova_keypair: state=present login_username=admin login_password=admin + login_tenant_name=admin name=ansible_key +''' def main(): module = AnsibleModule( diff --git a/library/cloud/quantum_floating_ip b/library/cloud/quantum_floating_ip index 22c00f7c052..8b89a405a34 100644 --- a/library/cloud/quantum_floating_ip +++ b/library/cloud/quantum_floating_ip @@ -27,9 +27,9 @@ except ImportError: DOCUMENTATION = ''' --- module: quantum_floating_ip -short_description: Add/Remove floating ip from an instance +short_description: Add/Remove floating IP from an instance description: - - Add or Remove a floating ip to an instance + - Add or Remove a floating IP to an instance options: login_username: description: @@ -63,21 +63,24 @@ options: default: present network_name: description: - - Name of the nework from which ip has to be assigned to vm. Please make sure the network is an external network + - Name of the network from which IP has to be assigned to VM. Please make sure the network is an external network required: true default: None instance_name: description: - - The name of the instance to which the ip address should be assigned + - The name of the instance to which the IP address should be assigned required: true default: None -examples: - - code: "quantum_floating_ip: state=present login_username=admin login_password=admin login_tenant_name=admin - network_name=external_network instance_name=vm1" - description: "Assigns a floating ip to the instance from an external network" requirements: ["novaclient", "quantumclient", "keystoneclient"] ''' +EXAMPLES = ''' +# Assign a floating ip to the instance from an external network +- quantum_floating_ip: state=present login_username=admin login_password=admin + login_tenant_name=admin network_name=external_network + instance_name=vm1 +''' + def _get_ksclient(module, kwargs): try: kclient = ksclient.Client(username=kwargs.get('login_username'), diff --git a/library/cloud/quantum_floating_ip_associate b/library/cloud/quantum_floating_ip_associate index b3214ce95b4..9884aa725ee 100644 --- a/library/cloud/quantum_floating_ip_associate +++ b/library/cloud/quantum_floating_ip_associate @@ -27,9 +27,9 @@ except ImportError: DOCUMENTATION = ''' --- module: quantum_floating_ip_associate -short_description: Associate or disassociate a particular floating ip with an instance +short_description: Associate or disassociate a particular floating IP with an instance description: - - Associates or disassociates a specific floating ip with a particular instance + - Associates or disassociates a specific floating IP with a particular instance options: login_username: description: @@ -63,7 +63,7 @@ options: default: present instance_name: description: - - name of the instance to which the public ip should be assigned + - name of the instance to which the public IP should be assigned required: true default: None ip_address: @@ -75,8 +75,14 @@ requirements: ["quantumclient", "keystoneclient"] ''' EXAMPLES = ''' -# Associate a specific floating ip with an Instance -quantum_floating_ip_associate: state=present login_username=admin login_password=admin login_tenant_name=admin ip_address=1.1.1.1 instance_name=vm1 +# Associate a specific floating IP with an Instance +quantum_floating_ip_associate: + state=present + login_username=admin + login_password=admin + login_tenant_name=admin + ip_address=1.1.1.1 + instance_name=vm1 ''' def _get_ksclient(module, kwargs): diff --git a/library/cloud/quantum_network b/library/cloud/quantum_network index c5866c0a173..d2b263a9aff 100644 --- a/library/cloud/quantum_network +++ b/library/cloud/quantum_network @@ -94,19 +94,22 @@ options: - Wether the state should be marked as up or down required: false default: true -examples: - - code: "quantum_network: state=present login_username=admin login_password=admin - provider_network_type=gre login_tenant_name=admin - provider_segmentation_id=1 tenant_name=tenant1 name=t1network" - description: "Createss a GRE nework with tunnel id of 1 for tenant 1" - - code: "quantum_network: state=present login_username=admin login_password=admin - provider_network_type=local login_tenant_name=admin - provider_segmentation_id=1 router_external=yes name=external_network" - description: "Creates an external,public network" requirements: ["quantumclient", "keystoneclient"] ''' +EXAMPLES = ''' +# Creates an external,public network +- quantum_network: state=present login_username=admin login_password=admin + provider_network_type=gre login_tenant_name=admin + provider_segmentation_id=1 tenant_name=tenant1 name=t1network" + +# Createss a GRE nework with tunnel id of 1 for tenant 1 +- quantum_network: state=present login_username=admin login_password=admin + provider_network_type=local login_tenant_name=admin + provider_segmentation_id=1 router_external=yes name=external_network +''' + _os_keystone = None _os_tenant_id = None diff --git a/library/cloud/quantum_router b/library/cloud/quantum_router index d849ce15e91..74df17d2906 100644 --- a/library/cloud/quantum_router +++ b/library/cloud/quantum_router @@ -79,7 +79,11 @@ requirements: ["quantumclient", "keystoneclient"] EXAMPLES = ''' # Creates a router for tenant admin -quantum_router: state=present login_username=admin login_password=admin login_tenant_name=admin name=router1" +quantum_router: state=present + login_username=admin + login_password=admin + login_tenant_name=admin + name=router1" ''' _os_keystone = None diff --git a/library/cloud/quantum_router_gateway b/library/cloud/quantum_router_gateway index 2777a728939..10cfe2a03c9 100644 --- a/library/cloud/quantum_router_gateway +++ b/library/cloud/quantum_router_gateway @@ -45,7 +45,7 @@ options: default: 'yes' auth_url: description: - - The keystone url for authentication + - The keystone URL for authentication required: false default: 'http://127.0.0.1:35357/v2.0/' region_name: @@ -68,13 +68,16 @@ options: - Name of the external network which should be attached to the router. required: true default: None -examples: - - code: "quantum_router_gateway: state=present login_username=admin login_password=admin - login_tenant_name=admin router_name=external_router network_name=external_network" - description: "Attaches an external network with a router to allow flow of external traffic" requirements: ["quantumclient", "keystoneclient"] ''' +EXAMPLES = ''' +# Attach an external network with a router to allow flow of external traffic +- quantum_router_gateway: state=present login_username=admin login_password=admin + login_tenant_name=admin router_name=external_router + network_name=external_network +''' + _os_keystone = None def _get_ksclient(module, kwargs): try: diff --git a/library/cloud/quantum_router_interface b/library/cloud/quantum_router_interface index 407bc5731f6..7e7a95d91b2 100644 --- a/library/cloud/quantum_router_interface +++ b/library/cloud/quantum_router_interface @@ -45,7 +45,7 @@ options: default: 'yes' auth_url: description: - - The keystone url for authentication + - The keystone URL for authentication required: false default: 'http://127.0.0.1:35357/v2.0/' region_name: @@ -73,13 +73,17 @@ options: - Name of the tenant whose subnet has to be attached. required: false default: None -examples: - - code: "quantum_router_interface: state=present login_username=admin login_password=admin login_tenant_name=admin - tenant_name=tenant1 router_name=external_route subnet_name=t1subnet" - description: "Attach tenant1's subnet to the external router" requirements: ["quantumclient", "keystoneclient"] ''' +EXAMPLES = ''' +# Attach tenant1's subnet to the external router +- quantum_router_interface: state=present login_username=admin + login_password=admin login_tenant_name=admin + tenant_name=tenant1 router_name=external_route subnet_name=t1subnet +''' + + _os_keystone = None _os_tenant_id = None diff --git a/library/cloud/quantum_subnet b/library/cloud/quantum_subnet index 5cb50befb06..deee46cd83a 100644 --- a/library/cloud/quantum_subnet +++ b/library/cloud/quantum_subnet @@ -25,9 +25,9 @@ except ImportError: DOCUMENTATION = ''' --- module: quantum_subnet -short_description: Add/Remove floating ip from an instance +short_description: Add/Remove floating IP from an instance description: - - Add or Remove a floating ip to an instance + - Add or Remove a floating IP to an instance options: login_username: description: @@ -46,7 +46,7 @@ options: default: True auth_url: description: - - The keystone url for authentication + - The keystone URL for authentication required: false default: 'http://127.0.0.1:35357/v2.0/' region_name: @@ -61,12 +61,12 @@ options: default: present network_name: description: - - Name of the nework to which the subnet should be attached + - Name of the network to which the subnet should be attached required: true default: None cidr: description: - - The cidr representation of the subnet that should be assigned to the subnet + - The CIDR representation of the subnet that should be assigned to the subnet required: true default: None tenant_name: @@ -91,22 +91,24 @@ options: default: None allocation_pool_start: description: - - From the subnet pool the starting address from which the ip should be allocated + - From the subnet pool the starting address from which the IP should be allocated required: false default: None allocation_pool_end: description: - - From the subnet pool the last ip that should be assigned to the virtual machines + - From the subnet pool the last IP that should be assigned to the virtual machines required: false default: None -examples: - - code: "quantum_subnet: state=present login_username=admin login_password=admin login_tenant_name=admin tenant_name=tenant1 - network_name=network1 name=net1subnet cidr=192.168.0.0/24" - description: "Create a subnet for a tenant with the specified subnet" - requirements: ["quantum", "keystoneclient"] ''' +EXAMPLES = ''' +# Create a subnet for a tenant with the specified subnet +- quantum_subnet: state=present login_username=admin login_password=admin + login_tenant_name=admin tenant_name=tenant1 + network_name=network1 name=net1subnet cidr=192.168.0.0/24" +''' + _os_keystone = None _os_tenant_id = None _os_network_id = None diff --git a/library/cloud/rax b/library/cloud/rax index 754b3751c46..24dd9670330 100644 --- a/library/cloud/rax +++ b/library/cloud/rax @@ -19,7 +19,7 @@ DOCUMENTATION = ''' module: rax short_description: create / delete an instance in Rackspace Public Cloud description: - - creates / deletes Rackspace Public Cloud instances and optionally waits for it to be 'running'. + - creates / deletes a Rackspace Public Cloud instance and optionally waits for it to be 'running'. version_added: "1.2" options: service: @@ -74,19 +74,6 @@ options: description: - how long before wait gives up, in seconds default: 300 -examples: - - code: | - - name: Create a server - local_action: - module: rax - creds_file: ~/.raxpub - service: cloudservers - name: rax-test1 - flavor: 5 - image: b11d9567-e412-4255-96b9-bd63ab23bcfe - wait: yes - state: present - description: "Example from Ansible Playbooks" requirements: [ "pyrax" ] author: Jesse Keating notes: @@ -95,6 +82,19 @@ notes: - RAX_REGION defines a Rackspace Public Cloud region (DFW, ORD, LON, ...) ''' +EXAMPLES = ''' +- name: Create a server + local_action: + module: rax + creds_file: ~/.raxpub + service: cloudservers + name: rax-test1 + flavor: 5 + image: b11d9567-e412-4255-96b9-bd63ab23bcfe + wait: yes + state: present +''' + import sys import time import os diff --git a/library/cloud/s3 b/library/cloud/s3 index a8cc5a3b4d7..0f7b64b9c4e 100644 --- a/library/cloud/s3 +++ b/library/cloud/s3 @@ -17,9 +17,9 @@ DOCUMENTATION = ''' --- module: s3 -short_description: idempotent s3 module putting a file into S3. +short_description: idempotent S3 module putting a file into S3. description: - - This module allows the user to dictate the presence of a given file in an S3 bucket. If or once the key (file) exists in the bucket, it returns a time-expired download url. This module has a dependency on python-boto. + - This module allows the user to dictate the presence of a given file in an S3 bucket. If or once the key (file) exists in the bucket, it returns a time-expired download URL. This module has a dependency on python-boto. version_added: "1.1" options: bucket: @@ -41,7 +41,7 @@ options: aliases: [] dest: description: - - the destination in s3, if different from path + - the destination in S3, if different from path required: false default: null aliases: [] @@ -53,7 +53,7 @@ options: aliases: [] overwrite: description: - - force overwrite if a file with the same name already exists. Does not support files uploaded to s3 with multipart upload. + - force overwrite if a file with the same name already exists. Does not support files uploaded to S3 with multipart upload. required: false default: false version_added: "1.2" @@ -63,13 +63,11 @@ author: Lester Wade, Ralph Tice EXAMPLES = ''' # Simple PUT operation - module: s3 - bucket: mybucket +- s3: bucket: mybucket path: /path/to/file state: present # Force and overwrite if checksums don't match - module: s3 - bucket: mybucket +- s3: bucket: mybucket path: /path/to/file state: present overwrite: yes diff --git a/library/cloud/virt b/library/cloud/virt index 2ac079058a4..792be96a2b3 100644 --- a/library/cloud/virt +++ b/library/cloud/virt @@ -61,8 +61,7 @@ author: Michael DeHaan, Seth Vidal EXAMPLES = ''' # a playbook task line: -tasks: - - virt: name=alpha state=running +- virt: name=alpha state=running # /usr/bin/ansible invocations ansible host -m virt -a "name=alpha command=status" diff --git a/library/commands/command b/library/commands/command index ad6ed6c171e..fb649380812 100644 --- a/library/commands/command +++ b/library/commands/command @@ -65,19 +65,23 @@ options: required: false default: null version_added: "0.9" -examples: - - code: "command: /sbin/shutdown -t now" - description: "Example from Ansible Playbooks" - - code: "command: /usr/bin/make_database.sh arg1 arg2 creates=/path/to/database" - description: "C(creates), C(removes), and C(chdir) can be specified after the command. For instance, if you only want to run a command if a certain file does not exist, use this." notes: - If you want to run a command through the shell (say you are using C(<), C(>), C(|), etc), you actually want the M(shell) module instead. The M(command) module is much more secure as it's not affected by the user's environment. + - " C(creates), C(removes), and C(chdir) can be specified after the command. For instance, if you only want to run a command if a certain file does not exist, use this." author: Michael DeHaan ''' +EXAMPLES = ''' +# Example from Ansible Playbooks +- command: /sbin/shutdown -t now + +# Run the command if the specified file does not exist +- command: /usr/bin/make_database.sh arg1 arg2 creates=/path/to/database +''' + def main(): # the command module is the one ansible module that does not take key=value args diff --git a/library/commands/raw b/library/commands/raw index 96b495dd018..dc4c09d4258 100644 --- a/library/commands/raw +++ b/library/commands/raw @@ -27,9 +27,6 @@ description: available. There is no change handler support for this module. - This module does not require python on the remote system, much like the M(script) module. -examples: - - description: Example from C(/usr/bin/ansible) to bootstrap a legacy python 2.4 host - code: "action: raw yum -y install python-simplejson" notes: - If you want to execute a command securely and predictably, it may be better to use the M(command) module instead. Best practices when writing @@ -38,3 +35,8 @@ notes: judgement. author: Michael DeHaan ''' + +EXAMPLES = ''' +# Bootstrap a legacy python 2.4 host +- raw: yum -y install python-simplejson +''' diff --git a/library/commands/script b/library/commands/script index c5e0e0b9270..00a1bced30a 100644 --- a/library/commands/script +++ b/library/commands/script @@ -4,12 +4,12 @@ DOCUMENTATION = """ module: script short_description: Runs a local script on a remote node after transferring it description: - - The M(script) module takes the script name followed by a list of - space-delimited arguments. - - The pathed local script will be transfered to the remote node and then executed. - - The given script will be processed through the shell environment on the remote node. - - This module does not require python on the remote system, much like - the M(raw) module. + - "The M(script) module takes the script name followed by a list of + space-delimited arguments. " + - "The local script at path will be transfered to the remote node and then executed. " + - "The given script will be processed through the shell environment on the remote node. " + - "This module does not require python on the remote system, much like + the M(raw) module. " options: free_form: description: @@ -17,11 +17,12 @@ options: required: true default: null aliases: [] -examples: - - description: "Example from Ansible Playbooks" - code: "action: script /some/local/script.sh --some-arguments 1234" notes: - It is usually preferable to write Ansible modules than pushing scripts. Convert your script to an Ansible module for bonus points! author: Michael DeHaan """ +EXAMPLES = ''' +# Example from Ansible Playbooks +- script: /some/local/script.sh --some-arguments 1234 +''' diff --git a/library/commands/shell b/library/commands/shell index 13c6041f022..ff57b4d456f 100644 --- a/library/commands/shell +++ b/library/commands/shell @@ -34,9 +34,6 @@ options: required: false default: null version_added: "0.9" -examples: - - code: "shell: somescript.sh >> somelog.txt" - description: Execute the command in remote shell notes: - If you want to execute a command securely and predictably, it may be better to use the M(command) module instead. Best practices when writing @@ -46,3 +43,8 @@ notes: requirements: [ ] author: Michael DeHaan ''' + +EXAMPLES = ''' +# Execute the command in remote shell; stdout goes to the specified file on the remote +- shell: somescript.sh >> somelog.txt +''' diff --git a/library/database/mongodb_user b/library/database/mongodb_user index bba1c192d05..748c41a089a 100644 --- a/library/database/mongodb_user +++ b/library/database/mongodb_user @@ -67,11 +67,6 @@ options: required: false default: present choices: [ "present", "absent" ] -examples: - - code: "mongodb_user: database=burgers name=bob password=12345 state=present" - description: Create 'burgers' database user with name 'bob' and password '12345'. - - code: "mongodb_user: database=burgers name=bob state=absent" - description: Delete 'burgers' database user with name 'bob'. notes: - Requires the pymongo Python package on the remote host, version 2.4.2+. This can be installed using pip or the OS package manager. @see http://api.mongodb.org/python/current/installation.html @@ -79,6 +74,14 @@ requirements: [ "pymongo" ] author: Elliott Foster ''' +EXAMPLES = ''' +# Create 'burgers' database user with name 'bob' and password '12345'. +- mongodb_user: database=burgers name=bob password=12345 state=present + +# Delete 'burgers' database user with name 'bob'. +- mongodb_user: database=burgers name=bob state=absent +''' + import ConfigParser try: from pymongo import MongoClient diff --git a/library/database/mysql_db b/library/database/mysql_db index 6fe9cae0e30..5ab49710fe5 100644 --- a/library/database/mysql_db +++ b/library/database/mysql_db @@ -72,9 +72,6 @@ options: description: - Where to dump/get the C(.sql) file required: false -examples: - - code: "mysql_db: db=bobdata state=present" - description: Create a new database with name 'bobdata' notes: - Requires the MySQLdb Python package on the remote host. For Ubuntu, this is as easy as apt-get install python-mysqldb. (See M(apt).) @@ -86,6 +83,11 @@ requirements: [ ConfigParser ] author: Mark Theunissen ''' +EXAMPLES = ''' +# Create a new database with name 'bobdata' +- mysql_db: db=bobdata state=present +''' + import ConfigParser import os try: diff --git a/library/database/mysql_user b/library/database/mysql_user index 9c61e7a6be6..1f193d851ab 100644 --- a/library/database/mysql_user +++ b/library/database/mysql_user @@ -72,15 +72,6 @@ options: required: false default: present choices: [ "present", "absent" ] -examples: - - code: "mysql_user: name=bob password=12345 priv=*.*:ALL state=present" - description: Create database user with name 'bob' and password '12345' with all database privileges - - code: "mysql_user: login_user=root login_password=123456 name=sally state=absent" - description: Ensure no user named 'sally' exists, also passing in the auth credentials. - - code: mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanotherdb.*:ALL - description: Example privileges string format - - code: "mysql_user: name=root password=abc123 login_unix_socket=/var/run/mysqld/mysqld.sock" - description: Example using login_unix_socket to connect to server notes: - Requires the MySQLdb Python package on the remote host. For Ubuntu, this is as easy as apt-get install python-mysqldb. @@ -99,9 +90,22 @@ author: Mark Theunissen ''' EXAMPLES = """ +# Create database user with name 'bob' and password '12345' with all database privileges +- mysql_user: name=bob password=12345 priv=*.*:ALL state=present + +# Ensure no user named 'sally' exists, also passing in the auth credentials. +- mysql_user: login_user=root login_password=123456 name=sally state=absent + +# Example privileges string format +mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanotherdb.*:ALL + +# Example using login_unix_socket to connect to server +- mysql_user: name=root password=abc123 login_unix_socket=/var/run/mysqld/mysqld.sock + # Example .my.cnf file for setting the root password # Note: don't use quotes around the password, because the mysql_user module # will include them in the password but the mysql client will not + [client] user=root password=n<_665{vS43y diff --git a/library/database/postgresql_db b/library/database/postgresql_db index 4fc83722e8a..2025456bf0d 100644 --- a/library/database/postgresql_db +++ b/library/database/postgresql_db @@ -80,11 +80,6 @@ options: required: false default: present choices: [ "present", "absent" ] -examples: - - code: "postgresql_db: db=acme" - description: Create a new database with name C(acme) - - code: "postgresql_db: db=acme encoding='UTF-8' lc_collate='de_DE.UTF-8' lc_ctype='de_DE.UTF-8' template='template0'" - description: Create a new database with name C(acme) and specific encoding and locale settings. If a template different from C(template0) is specified, encoding and locale settings must match those of the template. notes: - The default authentication assumes that you are either logging in as or sudo'ing to the C(postgres) account on the host. - This module uses I(psycopg2), a Python PostgreSQL database adapter. You must ensure that psycopg2 is installed on @@ -93,6 +88,20 @@ requirements: [ psycopg2 ] author: Lorin Hochstein ''' +EXAMPLES = ''' +# Create a new database with name "acme" +- postgresql_db: db=acme + +# Create a new database with name "acme" and specific encoding and locale +# settings. If a template different from "template0" is specified, encoding +# and locale settings must match those of the template. +- postgresql_db: db=acme + encoding='UTF-8' + lc_collate='de_DE.UTF-8' + lc_ctype='de_DE.UTF-8' + template='template0' +''' + try: import psycopg2 import psycopg2.extras diff --git a/library/database/postgresql_user b/library/database/postgresql_user index 9304c10a5f5..90667c156a5 100644 --- a/library/database/postgresql_user +++ b/library/database/postgresql_user @@ -90,17 +90,6 @@ options: required: false default: present choices: [ "present", "absent" ] -examples: - - code: "postgresql_user: db=acme user=django password=ceec4eif7ya priv=CONNECT/products:ALL" - description: Create django user and grant access to database and products table - - code: "postgresql_user: user=rails password=secret role_attr_flags=CREATEDB,NOSUPERUSER" - description: Create rails user, grant privilege to create other databases and demote rails from super user status - - code: "postgresql_user: db=acme user=test priv=ALL/products:ALL state=absent fail_on_user=no" - description: Remove test user privileges from acme - - code: "postgresql_user: db=test user=test priv=ALL state=absent" - description: Remove test user from test database and the cluster - - code: INSERT,UPDATE/table:SELECT/anothertable:ALL - description: Example privileges string format notes: - The default authentication assumes that you are either logging in as or sudo'ing to the postgres account on the host. @@ -117,6 +106,23 @@ requirements: [ psycopg2 ] author: Lorin Hochstein ''' +EXAMPLES = ''' +# Create django user and grant access to database and products table +- postgresql_user: db=acme user=django password=ceec4eif7ya priv=CONNECT/products:ALL + +# Create rails user, grant privilege to create other databases and demote rails from super user status +- postgresql_user: user=rails password=secret role_attr_flags=CREATEDB,NOSUPERUSER + +# Remove test user privileges from acme +- postgresql_user: db=acme user=test priv=ALL/products:ALL state=absent fail_on_user=no + +# Remove test user from test database and the cluster +- postgresql_user: db=test user=test priv=ALL state=absent + +# Example privileges string format +INSERT,UPDATE/table:SELECT/anothertable:ALL +''' + import re try: diff --git a/library/database/riak b/library/database/riak index 78c99fb4593..fe26b4a184c 100644 --- a/library/database/riak +++ b/library/database/riak @@ -73,15 +73,18 @@ options: default: kv aliases: [] choices: ['kv'] -examples: - - code: "riak: command=join target_node=riak@10.1.1.1" - description: "Join's a Riak node to another node" - - code: "riak: wait_for_handoffs=yes" - description: "Wait for handoffs to finish. Use with async and poll." - - code: "riak: wait_for_service=kv" - description: "Wait for riak_kv service to startup" ''' +EXAMPLES = ''' +# Join's a Riak node to another node +- riak: command=join target_node=riak@10.1.1.1 + +# Wait for handoffs to finish. Use with async and poll. +- riak: wait_for_handoffs=yes + +# Wait for riak_kv service to startup +- riak: wait_for_service=kv +''' import re diff --git a/library/files/assemble b/library/files/assemble index eeb9f3eb3d5..5da9646a344 100644 --- a/library/files/assemble +++ b/library/files/assemble @@ -60,12 +60,14 @@ options: description: - all arguments accepted by the M(file) module also work here required: false -examples: - - code: "assemble: src=/etc/someapp/fragments dest=/etc/someapp/someapp.conf" - description: "Example from Ansible Playbooks" author: Stephen Fromm ''' +EXAMPLES = ''' +# Example from Ansible Playbooks +- assemble: src=/etc/someapp/fragments dest=/etc/someapp/someapp.conf +''' + # =========================================== # Support method diff --git a/library/files/copy b/library/files/copy index 66653485a0b..51dbe66d0aa 100644 --- a/library/files/copy +++ b/library/files/copy @@ -73,19 +73,23 @@ options: description: - all arguments accepted by the M(file) module also work here required: false -examples: - - code: "copy: src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644" - description: "Example from Ansible Playbooks" - - code: "copy: src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes" - description: "Copy a new C(ntp.conf) file into place, backing up the original if it differs from the copied version" - - code: "copy: src=/mine/sudoers dest=/etc/sudoers validate='visudo -c %s'" - description: "Copy a new C(sudoers) file into place, after passing validation with visudo" author: Michael DeHaan notes: - The "copy" module can't be used to recursively copy directory structures to the target machine. Please see the "Delegation" section of the Advanced Playbooks documentation for a better approach to recursive copies. ''' +EXAMPLES = ''' +# Example from Ansible Playbooks +- copy: src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644 + +# Copy a new "ntp.conf file into place, backing up the original if it differs from the copied version +- copy: src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes + +# Copy a new "sudoers" file into place, after passing validation with visudo +- copy: src=/mine/sudoers dest=/etc/sudoers validate='visudo -c %s' +''' + def main(): module = AnsibleModule( diff --git a/library/files/file b/library/files/file index ed957819eb4..89d247dd4fc 100644 --- a/library/files/file +++ b/library/files/file @@ -120,16 +120,17 @@ options: version_added: "1.1" description: - recursively set the specified file attributes (applies only to state=directory) -examples: - - code: "file: path=/etc/foo.conf owner=foo group=foo mode=0644" - description: Example from Ansible Playbooks - - code: "file: src=/file/to/link/to dest=/path/to/symlink owner=foo group=foo state=link" notes: - See also M(copy), M(template), M(assemble) requirements: [ ] author: Michael DeHaan ''' +EXAMPLES = ''' +- file: path=/etc/foo.conf owner=foo group=foo mode=0644 +- file: src=/file/to/link/to dest=/path/to/symlink owner=foo group=foo state=link +''' + def main(): # FIXME: pass this around, should not use global diff --git a/library/files/ini_file b/library/files/ini_file index c1de5fee39d..c0c2fe54e98 100644 --- a/library/files/ini_file +++ b/library/files/ini_file @@ -62,15 +62,6 @@ options: description: - all arguments accepted by the M(file) module also work here required: false -examples: - - code: "ini_file: dest=/etc/conf section=drinks option=fav value=lemonade mode=0600 backup=yes" - description: Ensure C(fav=lemonade) is in section C([drinks]) in said file - - code: | - ini_file: dest=/etc/anotherconf - section=drinks - option=temperature - value=cold - backup=yes notes: - While it is possible to add an I(option) without specifying a I(value), this makes no sense. @@ -82,6 +73,16 @@ requirements: [ ConfigParser ] author: Jan-Piet Mens ''' +EXAMPLES = ''' +# Ensure "fav=lemonade is in section "[drinks]" in specified file +- ini_file: dest=/etc/conf section=drinks option=fav value=lemonade mode=0600 backup=yes + +- ini_file: dest=/etc/anotherconf + section=drinks + option=temperature + value=cold + backup=yes +''' import ConfigParser diff --git a/library/files/lineinfile b/library/files/lineinfile index ae4e0c7b458..29ff9603fdf 100644 --- a/library/files/lineinfile +++ b/library/files/lineinfile @@ -114,19 +114,19 @@ options: """ EXAMPLES = r""" - lineinfile: dest=/etc/selinux/config regexp=^SELINUX= line=SELINUX=disabled +- lineinfile: dest=/etc/selinux/config regexp=^SELINUX= line=SELINUX=disabled - lineinfile: dest=/etc/sudoers state=absent regexp="^%wheel" +- lineinfile: dest=/etc/sudoers state=absent regexp="^%wheel" - lineinfile: dest=/etc/hosts regexp='^127\.0\.0\.1' line='127.0.0.1 localhost' owner=root group=root mode=0644 +- lineinfile: dest=/etc/hosts regexp='^127\.0\.0\.1' line='127.0.0.1 localhost' owner=root group=root mode=0644 - lineinfile: dest=/etc/httpd/conf/httpd.conf regexp="^Listen " insertafter="^#Listen " line="Listen 8080" +- lineinfile: dest=/etc/httpd/conf/httpd.conf regexp="^Listen " insertafter="^#Listen " line="Listen 8080" - lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default" +- lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default" - lineinfile: dest=/etc/sudoers state=present regexp='^%wheel' line='%wheel ALL=(ALL) NOPASSWD: ALL' +- lineinfile: dest=/etc/sudoers state=present regexp='^%wheel' line='%wheel ALL=(ALL) NOPASSWD: ALL' - lineinfile: dest=/opt/jboss-as/bin/standalone.conf regexp='^(.*)Xms(\d+)m(.*)$' line='\1Xms${xms}m\3' backrefs=yes +- lineinfile: dest=/opt/jboss-as/bin/standalone.conf regexp='^(.*)Xms(\d+)m(.*)$' line='\1Xms${xms}m\3' backrefs=yes """ def write_changes(module,lines,dest): diff --git a/library/files/template b/library/files/template index b7133dc2c78..f93fcb453ac 100644 --- a/library/files/template +++ b/library/files/template @@ -45,11 +45,6 @@ options: description: - all arguments accepted by the M(file) module also work here required: false -examples: - - code: "template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644" - description: "Example from Ansible Playbooks" - - code: "action: template src=/mine/sudoers dest=/etc/sudoers validate='visudo -c %s'" - description: "Copy a new C(sudoers) file into place, after passing validation with visudo" notes: - Since Ansible version 0.9, templates are loaded with C(trim_blocks=True). - 'You can override jinja2 settings by adding a special header to template file. @@ -57,3 +52,11 @@ notes: requirements: [] author: Michael DeHaan ''' + +EXAMPLES = ''' +# Example from Ansible Playbooks +- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644 + +# Copy a new "sudoers file into place, after passing validation with visudo +- action: template src=/mine/sudoers dest=/etc/sudoers validate='visudo -c %s' +''' diff --git a/library/inventory/add_host b/library/inventory/add_host index b8204a52a6a..997c8b87d6f 100644 --- a/library/inventory/add_host +++ b/library/inventory/add_host @@ -19,11 +19,15 @@ options: - The groups to add the hostname to, comma separated. required: false author: Seth Vidal -examples: - - description: add host to group 'just_created' with variable foo=42 - code: add_host hostname=${ip_from_ec2} groups=just_created foo=42 - - description: add a host with a non-standard port local to your machines - code: add_host hostname='${new_ip}:${new_port}' - - description: add a host alias that we reach through a tunnel - code: add_host hostname=${new_ip} ansible_ssh_host=${inventory_hostname} ansible_ssh_port=${new_port}' +''' + +EXAMPLES = ''' +# add host to group 'just_created' with variable foo=42 +- add_host: hostname=${ip_from_ec2} groups=just_created foo=42 + +# add a host with a non-standard port local to your machines +- add_host: hostname='${new_ip}:${new_port}' + +# add a host alias that we reach through a tunnel +- add_host: hostname=${new_ip} ansible_ssh_host=${inventory_hostname} ansible_ssh_port=${new_port}' ''' diff --git a/library/inventory/group_by b/library/inventory/group_by index a8e6b83574a..e2868faadf1 100644 --- a/library/inventory/group_by +++ b/library/inventory/group_by @@ -13,11 +13,13 @@ options: - The variables whose values will be used as groups required: true author: Jeroen Hoekx -examples: - - description: Create groups based on the machine architecture - code: group_by key=${ansible_machine} - - description: Create groups like 'kvm-host' - code: group_by key=${ansible_virtualization_type}-${ansible_virtualization_role} notes: - Spaces in group names are converted to dashes '-'. ''' + +EXAMPLES = ''' +# Create groups based on the machine architecture +- group_by: key=${ansible_machine} +# Create groups like 'kvm-host' +- group_by: key=${ansible_virtualization_type}-${ansible_virtualization_role} +''' diff --git a/library/messaging/rabbitmq_plugin b/library/messaging/rabbitmq_plugin index 3a2933a18c2..c9a90f31aa6 100644 --- a/library/messaging/rabbitmq_plugin +++ b/library/messaging/rabbitmq_plugin @@ -46,9 +46,11 @@ options: required: false default: enabled choices: [enabled, disabled] -examples: - - code: rabbitmq_plugin names=rabbitmq_management state=enabled - description: Enables the rabbitmq_management plugin +''' + +EXAMPLES = ''' +# Enables the rabbitmq_management plugin +- rabbitmq_plugin: names=rabbitmq_management state=enabled ''' class RabbitMqPlugins(object): diff --git a/library/messaging/rabbitmq_user b/library/messaging/rabbitmq_user index ad38de8bb51..77cf67f9f29 100644 --- a/library/messaging/rabbitmq_user +++ b/library/messaging/rabbitmq_user @@ -86,9 +86,17 @@ options: required: false default: present choices: [present, absent] -examples: - - code: rabbitmq_user user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* state=present - description: Add user to server and assign full access control +''' + +EXAMPLES = ''' +# Add user to server and assign full access control +- rabbitmq_user: user=joe + password=changeme + vhost=/ + configure_priv=.* + read_priv=.* + write_priv=.* + state=present ''' class RabbitMqUser(object): diff --git a/library/messaging/rabbitmq_vhost b/library/messaging/rabbitmq_vhost index 6a99bd56c60..f36da079dd8 100644 --- a/library/messaging/rabbitmq_vhost +++ b/library/messaging/rabbitmq_vhost @@ -50,9 +50,11 @@ options: - The state of vhost default: present choices: [present, absent] -examples: - - code: 'rabbitmq_vhost: name=/test state=present' - description: Ensure that the vhost /test exists. +''' + +EXAMPLES = ''' +# Ensure that the vhost /test exists. +- rabbitmq_vhost: name=/test state=present ''' class RabbitMqVhost(object): diff --git a/library/monitoring/monit b/library/monitoring/monit index de47bc0c264..1219186d502 100644 --- a/library/monitoring/monit +++ b/library/monitoring/monit @@ -38,13 +38,15 @@ options: required: true default: null choices: [ "present", "started", "stopped", "restarted", "monitored", "unmonitored", "reloaded" ] -examples: - - code: "monit: name=httpd state=started" - description: Manage the state of program I(httpd) to be in I(started) state. requirements: [ ] author: Darryl Stoflet ''' +EXAMPLES = ''' +# Manage the state of program "httpd" to be in "started" state. +- monit: name=httpd state=started +''' + def main(): arg_spec = dict( diff --git a/library/monitoring/nagios b/library/monitoring/nagios index 4c6cb09a0c9..33622b11711 100644 --- a/library/monitoring/nagios +++ b/library/monitoring/nagios @@ -75,31 +75,44 @@ options: author: Tim Bielawa requirements: [ "Nagios" ] -examples: - - description: set 30 minutes of apache downtime - code: "nagios: action=downtime minutes=30 service=httpd host=$inventory_hostname" - - description: schedule an hour of HOST downtime - code: "nagios: action=downtime minutes=60 service=host host=$inventory_hostname" - - description: schedule downtime for ALL services on HOST - code: "nagios: action=downtime minutes=45 service=all host=$inventory_hostname" - - description: schedule downtime for a few services - code: "nagios: action=downtime services=frob,foobar,qeuz host=$inventory_hostname" - - description: enable SMART disk alerts - code: "nagios: action=enable_alerts service=smart host=$inventory_hostname" - - description: "two services at once: disable httpd and nfs alerts" - code: "nagios: action=disable_alerts service=httpd,nfs host=$inventory_hostname" - - description: disable HOST alerts - code: "nagios: action=disable_alerts service=host host=$inventory_hostname" - - description: silence ALL alerts - code: "nagios: action=silence host=$inventory_hostname" - - description: unsilence all alerts - code: "nagios: action=unsilence host=$inventory_hostname" - - description: SHUT UP NAGIOS - code: "nagios: action=silence_nagios" - - description: ANNOY ME NAGIOS - code: "nagios: action=unsilence_nagios" - - description: command something - code: "nagios: action=command command='DISABLE_FAILURE_PREDICTION'" +''' + +EXAMPLES = ''' +# set 30 minutes of apache downtime +- nagios: action=downtime minutes=30 service=httpd host={{ inventory_hostname }} + +# schedule an hour of HOST downtime +- nagios: action=downtime minutes=60 service=host host=$inventory_hostname + +# schedule downtime for ALL services on HOST +- nagios: action=downtime minutes=45 service=all host=$inventory_hostname + +# schedule downtime for a few services +- nagios: action=downtime services=frob,foobar,qeuz host=$inventory_hostname + +# enable SMART disk alerts +- nagios: action=enable_alerts service=smart host=$inventory_hostname + +# "two services at once: disable httpd and nfs alerts" +- nagios: action=disable_alerts service=httpd,nfs host=$inventory_hostname + +# disable HOST alerts +- nagios: action=disable_alerts service=host host=$inventory_hostname + +# silence ALL alerts +- nagios: action=silence host=$inventory_hostname + +# unsilence all alerts +- nagios: action=unsilence host=$inventory_hostname + +# SHUT UP NAGIOS +- nagios: action=silence_nagios + +# ANNOY ME NAGIOS +- nagios: action=unsilence_nagios + +# command something +- nagios: action=command command='DISABLE_FAILURE_PREDICTION' ''' import ConfigParser diff --git a/library/net_infrastructure/netscaler b/library/net_infrastructure/netscaler index c1179840210..13646df642e 100644 --- a/library/net_infrastructure/netscaler +++ b/library/net_infrastructure/netscaler @@ -73,18 +73,21 @@ options: default: server choices: ["server", "service"] aliases: [] - -examples: - - code: ansible host -m netscaler -a "nsc_host=nsc.example.com user=apiuser password=apipass" - description: "Disable the server" - - code: ansible host -m netscaler -a "nsc_host=nsc.example.com user=apiuser password=apipass action=enable" - description: "Enable the server" - - code: ansible host -m netscaler -a "nsc_host=nsc.example.com user=apiuser password=apipass name=local:8080 type=service action=disable" - description: "Disable the service local:8080" requirements: [ "urllib", "urllib2" ] author: Nandor Sivok ''' +EXAMPLES = ''' +# Disable the server +ansible host -m netscaler -a "nsc_host=nsc.example.com user=apiuser password=apipass" + +# Enable the server +ansible host -m netscaler -a "nsc_host=nsc.example.com user=apiuser password=apipass action=enable" + +# Disable the service local:8080 +ansible host -m netscaler -a "nsc_host=nsc.example.com user=apiuser password=apipass name=local:8080 type=service action=disable" +''' + import json import urllib diff --git a/library/network/slurp b/library/network/slurp index cdac4b68050..1f9975fda05 100644 --- a/library/network/slurp +++ b/library/network/slurp @@ -33,20 +33,20 @@ options: required: true default: null aliases: [] -examples: - - code: | - ansible host -m slurp -a 'src=/tmp/xx' - host | success >> { - "content": "aGVsbG8gQW5zaWJsZSB3b3JsZAo=", - "encoding": "base64" - } - description: "Example using C(/usr/bin/ansible)" notes: - "See also: M(fetch)" requirements: [] author: Michael DeHaan ''' +EXAMPLES = ''' +ansible host -m slurp -a 'src=/tmp/xx' + host | success >> { + "content": "aGVsbG8gQW5zaWJsZSB3b3JsZAo=", + "encoding": "base64" + } +''' + import base64 def main(): diff --git a/library/network/uri b/library/network/uri index 4385ea56ba4..9b4477e8f52 100644 --- a/library/network/uri +++ b/library/network/uri @@ -120,40 +120,41 @@ options: description: - all arguments accepted by the M(file) module also work here required: false -examples: - - code: "uri: url=http://www.awesome.com" - description: "Check that you can connect (GET) to a page and it returns a status 200" - - code: | - action: uri url=http://www.awesome.com return_content=yes - register: webpage +# informational: requirements for nodes +requirements: [ urlparse, httplib2 ] +author: Romeo Theriault +''' - action: fail - when_string: '"AWESOME" not in "${webpage.content}"' +EXAMPLES = ''' +# Check that you can connect (GET) to a page and it returns a status 200 +- uri: url=http://www.example.com - description: Check that a page returns a status 200 and fail if the word AWESOME is not in the page contents. +# Check that a page returns a status 200 and fail if the word AWESOME is not in the page contents. +- action: uri url=http://www.example.com return_content=yes + register: webpage - - code: | - action: > - uri url=https://your.jira.server.com/rest/api/2/issue/ - method=POST user=your_username password=your_pass - body='$FILE(issue.json)' force_basic_auth=yes - status_code=201 HEADER_Content-Type="application/json" - description: "Create a JIRA issue." + action: fail + when_string: '"AWESOME" not in "${webpage.content}"' - - code: | - action: > - uri url=https://your.form.based.auth.app.com/index.php - method=POST body="name=your_username&password=your_password&enter=Sign%20in" - status_code=302 HEADER_Content-Type="application/x-www-form-urlencoded" - register: login - action: uri url=https://your.form.based.auth.app.com/dashboard.php method=GET return_content=yes HEADER_Cookie="${login.set_cookie}" - description: "Login to a form based webpage, then use the cookie that got returned to access the app in later tasks." +# Create a JIRA issue. +action: > + uri url=https://your.jira.example.com/rest/api/2/issue/ + method=POST user=your_username password=your_pass + body='$FILE(issue.json)' force_basic_auth=yes + status_code=201 HEADER_Content-Type="application/json" -# informational: requirements for nodes -requirements: [ urlparse, httplib2 ] -author: Romeo Theriault +action: > + uri url=https://your.form.based.auth.examle.com/index.php + method=POST body="name=your_username&password=your_password&enter=Sign%20in" + status_code=302 HEADER_Content-Type="application/x-www-form-urlencoded" +register: login + +# Login to a form based webpage, then use the returned cookie to +# access the app in later tasks. +action: uri url=https://your.form.based.auth.example.com/dashboard.php + method=GET return_content=yes HEADER_Cookie="${login.set_cookie}" ''' HAS_HTTPLIB2 = True diff --git a/library/notification/mail b/library/notification/mail index 5c6faaeb37f..3fe344aa04d 100644 --- a/library/notification/mail +++ b/library/notification/mail @@ -99,24 +99,26 @@ options: - The character set of email being sent default: 'us-ascii' requred: false -examples: - - description: "Example playbook sending mail to root" - code: "local_action: mail msg='System ${ansible_hostname} has been sucessfully provisioned.'" - - description: Send e-mail to a bunch of users, attaching files - code: | - - local_action: mail - host='127.0.0.1' - port=2025 - subject="Ansible-report" - body="Hello, this is an e-mail. I hope you like it ;-)" - from="jane@example.net (Jane Jolie)" - to="John Doe , Suzie Something " - cc="Charlie Root " - attach="/etc/group /tmp/pavatar2.png" - headers=Reply-To=john@example.com|X-Special="Something or other" - charset=utf8 """ +EXAMPLES = ''' +# Example playbook sending mail to root +local_action: mail msg='System ${ansible_hostname} has been sucessfully provisioned.' + +# Send e-mail to a bunch of users, attaching files +- local_action: mail + host='127.0.0.1' + port=2025 + subject="Ansible-report" + body="Hello, this is an e-mail. I hope you like it ;-)" + from="jane@example.net (Jane Jolie)" + to="John Doe , Suzie Something " + cc="Charlie Root " + attach="/etc/group /tmp/pavatar2.png" + headers=Reply-To=john@example.com|X-Special="Something or other" + charset=utf8 +''' + import os import sys import smtplib diff --git a/library/packaging/apt b/library/packaging/apt index 04d7eb82b9d..684fec470af 100644 --- a/library/packaging/apt +++ b/library/packaging/apt @@ -87,27 +87,38 @@ author: Matthew Williams notes: - Three of the upgrade modes (C(full), C(safe) and its alias C(yes)) require C(aptitude), otherwise C(apt-get) suffices. -examples: - - code: "apt: pkg=foo update_cache=yes" - description: Update repositories cache and install C(foo) package - - code: "apt: pkg=foo state=absent" - description: Remove C(foo) package - - code: "apt: pkg=foo state=present" - description: Install the package C(foo) - - code: "apt: pkg=foo=1.00 state=present" - description: Install the version '1.00' of package C(foo) - - code: "apt: pkg=nginx state=latest default_release=squeeze-backports update_cache=yes" - description: Update the repository cache and update package C(nginx) to latest version using default release C(squeeze-backport) - - code: "apt: pkg=openjdk-6-jdk state=latest install_recommends=no" - description: Install latest version of C(openjdk-6-jdk) ignoring C(install-reccomends) - - code: "apt: upgrade=dist" - description: Update all packages to the latest version - - code: "apt: update_cache=yes" - description: Run the equivalent of C(apt-get update) as a separate step - - code: "apt: update_cache=yes cache_valid_time=3600" - description: Only run C(update_cache=yes) if the last one is more than more than 3600 seconds ago ''' +EXAMPLES = ''' +# Update repositories cache and install "foo" package +- apt: pkg=foo update_cache=yes + +# Remove "foo" package +- apt: pkg=foo state=absent + +# Install the package "foo" +- apt: pkg=foo state=present + +# Install the version '1.00' of package "foo" +- apt: pkg=foo=1.00 state=present + +# Update the repository cache and update package "nginx" to latest version using default release squeeze-backport +- apt: pkg=nginx state=latest default_release=squeeze-backports update_cache=yes + +# Install latest version of "openjdk-6-jdk" ignoring "install-reccomends" +- apt: pkg=openjdk-6-jdk state=latest install_recommends=no + +# Update all packages to the latest version +- apt: upgrade=dist + +# Run the equivalent of "apt-get update" as a separate step +- apt: update_cache=yes + +# Only run "update_cache=yes" if the last one is more than more than 3600 seconds ago +- apt: update_cache=yes cache_valid_time=3600 +''' + + import traceback # added to stave off future warnings about apt api import warnings diff --git a/library/packaging/apt_key b/library/packaging/apt_key index de4ada8c399..b5b0e844ded 100644 --- a/library/packaging/apt_key +++ b/library/packaging/apt_key @@ -48,17 +48,23 @@ options: default: present description: - used to specify if key is being added or revoked -examples: - - code: "apt_key: url=https://ftp-master.debian.org/keys/archive-key-6.0.asc state=present" - description: Add an Apt signing key, uses whichever key is at the URL - - code: "apt_key: id=473041FA url=https://ftp-master.debian.org/keys/archive-key-6.0.asc state=present" - description: Add an Apt signing key, will not download if present - - code: "apt_key: url=https://ftp-master.debian.org/keys/archive-key-6.0.asc state=absent" - description: Remove an Apt signing key, uses whichever key is at the URL - - code: "apt_key: id=473041FA state=absent" - description: Remove a Apt specific signing key ''' +EXAMPLES = ''' +# Add an Apt signing key, uses whichever key is at the URL +- apt_key: url=https://ftp-master.debian.org/keys/archive-key-6.0.asc state=present + +# Add an Apt signing key, will not download if present +- apt_key: id=473041FA url=https://ftp-master.debian.org/keys/archive-key-6.0.asc state=present + +# Remove an Apt signing key, uses whichever key is at the URL +- apt_key: url=https://ftp-master.debian.org/keys/archive-key-6.0.asc state=absent + +# Remove a Apt specific signing key +- apt_key: id=473041FA state=absent +''' + + # FIXME: standardize into module_common from urllib2 import urlopen, URLError from traceback import format_exc diff --git a/library/packaging/apt_repository b/library/packaging/apt_repository index 6e3b98fd854..0dc42838806 100644 --- a/library/packaging/apt_repository +++ b/library/packaging/apt_repository @@ -47,14 +47,17 @@ notes: - This module cannot be used on Debian Squeeze (Version 6) as there is no C(add-apt-repository) in C(python-software-properties) - A bug in C(apt-add-repository) always adds C(deb) and C(deb-src) types for repositories (see the issue on Launchpad U(https://bugs.launchpad.net/ubuntu/+source/software-properties/+bug/987264)), if a repo doesn't have source information (eg MongoDB repo from 10gen) the system will fail while updating repositories. author: Matt Wright -examples: -- code: "apt_repository: repo=ppa:nginx/stable" - description: Add nginx stable repository from PPA -- code: "apt_repository: repo='deb http://archive.canonical.com/ubuntu hardy partner'" - description: Add specified repository into sources. requirements: [ python-apt ] ''' +EXAMPLES = ''' +# Add nginx stable repository from PPA +- apt_repository: repo=ppa:nginx/stable + +# Add specified repository into sources. +- apt_repository: repo='deb http://archive.canonical.com/ubuntu hardy partner' +''' + import platform try: diff --git a/library/packaging/easy_install b/library/packaging/easy_install index 2f0feaebeb0..c8f03f9c82d 100644 --- a/library/packaging/easy_install +++ b/library/packaging/easy_install @@ -57,11 +57,6 @@ options: C(pyvenv), C(virtualenv), C(virtualenv2). required: false default: virtualenv -examples: - - code: "easy_install: name=pip" - description: "Examples from Ansible Playbooks" - - code: "easy_install: name=flask virtualenv=/webapps/myapp/venv" - description: "Install I(Flask) (U(http://flask.pocoo.org/)) into the specified I(virtualenv)" notes: - Please note that the M(easy_install) module can only install Python libraries. Thus this module is not able to remove libraries. It is @@ -73,6 +68,14 @@ requirements: [ "virtualenv" ] author: Matt Wright ''' +EXAMPLES = ''' +# Examples from Ansible Playbooks +- easy_install: name=pip + +# Install Flast into the specified virtualenv. +- easy_install: name=flask virtualenv=/webapps/myapp/venv +''' + def _is_package_installed(module, name, easy_install): cmd = '%s --dry-run %s' % (easy_install, name) rc, status_stdout, status_stderr = module.run_command(cmd) diff --git a/library/packaging/macports b/library/packaging/macports index 2ba6effe37e..83da1516a34 100644 --- a/library/packaging/macports +++ b/library/packaging/macports @@ -46,11 +46,11 @@ options: notes: [] ''' EXAMPLES = ''' -macports: name=foo state=present -macports: name=foo state=present update_cache=yes -macports: name=foo state=absent -macports: name=foo state=active -macports: name=foo state=inactive +- macports: name=foo state=present +- macports: name=foo state=present update_cache=yes +- macports: name=foo state=absent +- macports: name=foo state=active +- macports: name=foo state=inactive ''' diff --git a/library/packaging/npm b/library/packaging/npm index a158b1478c5..2457561da5b 100644 --- a/library/packaging/npm +++ b/library/packaging/npm @@ -65,21 +65,29 @@ options: required: false default: present choices: [ "present", "absent", "latest" ] -examples: - - code: "npm: name=coffee-script path=/app/location" - description: Install I(coffee-script) node.js package. - - code: "npm: name=coffee-script version=1.6.1 path=/app/location" - description: Install I(coffee-script) node.js package on version 1.6.1. - - code: "npm: name=coffee-script global=yes" - description: Install I(coffee-script) node.js package globally. - - code: "npm: name=coffee-script global=yes state=absent" - description: Remove the globally package I(coffee-script). - - code: "npm: path=/app/location" - description: Install packages based on package.json. - - code: "npm: path=/app/location state=latest" - description: Update packages based on package.json to their latest version. - - code: "npm: path=/app/location executable=/opt/nvm/v0.10.1/bin/npm state=present" - description: Install packages based on package.json using the npm installed with nvm v0.10.1. +''' + +EXAMPLES = ''' +description: Install "coffee-script" node.js package. +- npm: name=coffee-script path=/app/location + +description: Install "coffee-script" node.js package on version 1.6.1. +- npm: name=coffee-script version=1.6.1 path=/app/location + +description: Install "coffee-script" node.js package globally. +- npm: name=coffee-script global=yes + +description: Remove the globally package "coffee-script". +- npm: name=coffee-script global=yes state=absent + +description: Install packages based on package.json. +- npm: path=/app/location + +description: Update packages based on package.json to their latest version. +- npm: path=/app/location state=latest + +description: Install packages based on package.json using the npm installed with nvm v0.10.1. +- npm: path=/app/location executable=/opt/nvm/v0.10.1/bin/npm state=present ''' import os diff --git a/library/packaging/openbsd_pkg b/library/packaging/openbsd_pkg index f5bd6b5dbe9..0cda1b6c1a5 100644 --- a/library/packaging/openbsd_pkg +++ b/library/packaging/openbsd_pkg @@ -40,13 +40,17 @@ options: - C(present) will make sure the package is installed. C(latest) will make sure the latest version of the package is installed. C(absent) will make sure the specified package is not installed. -examples: - - description: Make sure nmap is installed - code: "openbsd_pkg: name=nmap state=present" - - description: Make sure nmap is the latest version - code: "openbsd_pkg: name=nmap state=latest" - - description: Make sure nmap is not installed - code: "openbsd_pkg: name=nmap state=absent" +''' + +EXAMPLES = ''' +# Make sure nmap is installed +- openbsd_pkg: name=nmap state=present + +# Make sure nmap is the latest version +- openbsd_pkg: name=nmap state=latest + +# Make sure nmap is not installed +- openbsd_pkg: name=nmap state=absent ''' # select whether we dump additional debug info through syslog diff --git a/library/packaging/opkg b/library/packaging/opkg index 7ba2c5e3cd8..1bed0901ed1 100644 --- a/library/packaging/opkg +++ b/library/packaging/opkg @@ -45,10 +45,10 @@ options: notes: [] ''' EXAMPLES = ''' -opkg: name=foo state=present -opkg: name=foo state=present update_cache=yes -opkg: name=foo state=absent -opkg: name=foo,bar state=absent +- opkg: name=foo state=present +- opkg: name=foo state=present update_cache=yes +- opkg: name=foo state=absent +- opkg: name=foo,bar state=absent ''' diff --git a/library/packaging/pacman b/library/packaging/pacman index fdfb2113c6a..e2dbd5b2a65 100644 --- a/library/packaging/pacman +++ b/library/packaging/pacman @@ -47,16 +47,20 @@ options: author: Afterburn notes: [] -examples: - - code: "pacman: name=foo state=installed" - description: install package foo - - code: "pacman: name=foo state=absent" - description: remove package foo - - code: "pacman: name=foo,bar state=absent" - description: remove packages foo and bar - - code: "pacman: name=bar, state=installed, update_cache=yes" - description: update the package database (pacman -Syy) and install bar (bar will be the updated if a newer version exists) - +''' + +EXAMPLES = ''' +# Install package foo +- pacman: name=foo state=installed + +# Remove package foo +- pacman: name=foo state=absent + +# Remove packages foo and bar +- pacman: name=foo,bar state=absent + +# Update the package database (pacman -Syy) and install bar (bar will be the updated if a newer version exists) +- pacman: name=bar, state=installed, update_cache=yes ''' diff --git a/library/packaging/pip b/library/packaging/pip index ceffe923fb0..1415ffa8941 100644 --- a/library/packaging/pip +++ b/library/packaging/pip @@ -91,31 +91,41 @@ options: required: false default: null version_added: "1.0" -examples: - - code: "pip: name=flask" - description: Install I(flask) python package. - - code: "pip: name=flask version=0.8" - description: Install I(flask) python package on version 0.8. - - code: "pip: name='svn+http://myrepo/svn/MyApp#egg=MyApp'" - description: Install I(MyApp) using one of the remote protocols (bzr+,hg+,git+,svn+) or tarballs (zip, gz, bz2) C(pip) supports. You do not have to supply '-e' option in extra_args. For these source names, C(use_mirrors) is ignored and not applicable. - - code: "pip: name=flask virtualenv=/my_app/venv" - description: "Install I(Flask) (U(http://flask.pocoo.org/)) into the specified I(virtualenv), inheriting none of the globally installed modules" - - code: "pip: name=flask virtualenv=/my_app/venv virtualenv_site_packages=yes" - description: "Install I(Flask) (U(http://flask.pocoo.org/)) into the specified I(virtualenv), inheriting globally installed modules" - - code: "pip: name=flask virtualenv=/my_app/venv virtualenv_command=virtualenv-2.7" - description: "Install I(Flask) (U(http://flask.pocoo.org/)) into the specified I(virtualenv), using Python 2.7" - - code: "pip: requirements=/my_app/requirements.txt" - description: Install specified python requirements. - - code: "pip: requirements=/my_app/requirements.txt virtualenv=/my_app/venv" - description: Install specified python requirements in indicated I(virtualenv). - - code: "pip: requirements=/my_app/requirements.txt extra_args='-i https://example.com/pypi/simple'" - description: Install specified python requirements and custom Index URL. notes: - Please note that virtualenv (U(http://www.virtualenv.org/)) must be installed on the remote host if the virtualenv parameter is specified. requirements: [ "virtualenv", "pip" ] author: Matt Wright ''' +EXAMPLES = ''' +# Install (flask) python package. +- pip: name=flask + +# Install (flask) python package on version 0.8. +- pip: name=flask version=0.8 + +# Install (MyApp) using one of the remote protocols (bzr+,hg+,git+,svn+) or tarballs (zip, gz, bz2) (pip) supports. You do not have to supply '-e' option in extra_args. For these source names, (use_mirrors) is ignored and not applicable. +- pip: name='svn+http://myrepo/svn/MyApp#egg=MyApp' + +# Install (Flask) into the specified (virtualenv), inheriting none of the globally installed modules +- pip: name=flask virtualenv=/my_app/venv + +# Install (Flask) into the specified (virtualenv), inheriting globally installed modules +- pip: name=flask virtualenv=/my_app/venv virtualenv_site_packages=yes + +# Install (Flask) into the specified (virtualenv), using Python 2.7 +- pip: name=flask virtualenv=/my_app/venv virtualenv_command=virtualenv-2.7 + +# Install specified python requirements. +- pip: requirements=/my_app/requirements.txt + +# Install specified python requirements in indicated (virtualenv). +- pip: requirements=/my_app/requirements.txt virtualenv=/my_app/venv + +# Install specified python requirements and custom Index URL. +- pip: requirements=/my_app/requirements.txt extra_args='-i https://example.com/pypi/simple' +''' + def _get_full_name(name, version=None): if version is None: diff --git a/library/packaging/pkgin b/library/packaging/pkgin index e7154a50ca3..cc0d012f7b2 100644 --- a/library/packaging/pkgin +++ b/library/packaging/pkgin @@ -40,13 +40,17 @@ options: default: present author: Shaun Zinck notes: [] -examples: - - code: "pkgin: name=foo state=present" - description: install package foo" - - code: "pkgin: name=foo state=absent" - description: remove package foo - - code: "pkgin: name=foo,bar state=absent" - description: remove packages foo and bar +''' + +EXAMPLES = ''' +# install package foo" +- pkgin: name=foo state=present + +# remove package foo +- pkgin: name=foo state=absent + +# remove packages foo and bar +- pkgin: name=foo,bar state=absent ''' diff --git a/library/packaging/pkgng b/library/packaging/pkgng index ec0469bdc36..fa341b2f80d 100644 --- a/library/packaging/pkgng +++ b/library/packaging/pkgng @@ -54,13 +54,14 @@ options: author: bleader notes: - When using pkgsite, be careful that already in cache packages won't be downloaded again. -examples: - - code: "pkgng: name=foo state=present" - description: install package foo" - - code: "pkgng: name=foo state=absent" - description: remove package foo - - code: "pkgng: name=foo,bar state=absent" - description: remove packages foo and bar +''' + +EXAMPLES = ''' +# Install package foo +- pkgng: name=foo state=present + +# Remove packages foo and bar +- pkgng: name=foo,bar state=absent ''' diff --git a/library/packaging/redhat_subscription b/library/packaging/redhat_subscription index 9869738e184..414b0df886f 100644 --- a/library/packaging/redhat_subscription +++ b/library/packaging/redhat_subscription @@ -59,11 +59,17 @@ options: - Specify a subscription pool name to consume. Regular expressions accepted. required: False default: '^$' -examples: - - code: redhat_subscription action=register username=joe_user password=somepass autosubscribe=true - description: Register as user I(joe_user) with password I(somepass) and auto-subscribe to available content. - - code: redhat_subscription action=register activationkey=1-222333444 pool='^(Red Hat Enterprise Server|Red Hat Virtualization)$' - description: Register with activationkey I(1-222333444) and consume subscriptions matching the names I(Red hat Enterprise Server) and I(Red Hat Virtualization) +''' + +EXAMPLES = ''' +# Register as user (joe_user) with password (somepass) and auto-subscribe to available content. +- redhat_subscription: action=register username=joe_user password=somepass autosubscribe=true + +# Register with activationkey (1-222333444) and consume subscriptions matching +# the names (Red hat Enterprise Server) and (Red Hat Virtualization) +- redhat_subscription: action=register + activationkey=1-222333444 + pool='^(Red Hat Enterprise Server|Red Hat Virtualization)$' ''' import os diff --git a/library/packaging/rhn_channel b/library/packaging/rhn_channel index f49693cf3db..8b044a57450 100644 --- a/library/packaging/rhn_channel +++ b/library/packaging/rhn_channel @@ -43,7 +43,7 @@ options: ''' EXAMPLES = ''' -rhn_channel: name=rhel-x86_64-server-v2vwin-6 sysname=server01 url=https://rhn.redhat.com/rpc/api user=rhnuser password=guessme +- rhn_channel: name=rhel-x86_64-server-v2vwin-6 sysname=server01 url=https://rhn.redhat.com/rpc/api user=rhnuser password=guessme ''' import xmlrpclib diff --git a/library/packaging/rhn_register b/library/packaging/rhn_register index ae01607748c..085c6922749 100644 --- a/library/packaging/rhn_register +++ b/library/packaging/rhn_register @@ -44,22 +44,31 @@ options: - Optionally specify a list of comma-separated channels to subscribe to upon successful registration. required: false default: [] +''' -examples: - - code: rhn_register state=absent username=joe_user password=somepass - description: Unregister system from RHN. - - - code: rhn_register state=present username=joe_user password=somepass - description: Register as user I(joe_user) with password I(somepass) and auto-subscribe to available content. - - - code: rhn_register state=present activationkey=1-222333444 enable_eus=true - description: Register with activationkey I(1-222333444) and enable extended update support. - - - code: rhn_register state=present username=joe_user password=somepass server_url=https://xmlrpc.my.satellite/XMLRPC - description: Register as user I(joe_user) with password I(somepass) against a satellite server specified by I(server_url). - - - code: rhn_register state=present username=joe_user password=somepass channels=rhel-x86_64-server-6-foo-1,rhel-x86_64-server-6-bar-1 - description: Register as user I(joe_user) with password I(somepass) and enable channels I(rhel-x86_64-server-6-foo-1) and I(rhel-x86_64-server-6-bar-1). +EXAMPLES = ''' +# Unregister system from RHN. +- code: rhn_register state=absent username=joe_user password=somepass + +# Register as user (joe_user) with password (somepass) and auto-subscribe to available content. +- code: rhn_register state=present username=joe_user password=somepass + +# Register with activationkey (1-222333444) and enable extended update support. +- code: rhn_register state=present activationkey=1-222333444 enable_eus=true + +# Register as user (joe_user) with password (somepass) against a satellite +# server specified by (server_url). +- rhn_register: + state=present + username=joe_user + password=somepass + server_url=https://xmlrpc.my.satellite/XMLRPC + +# Register as user (joe_user) with password (somepass) and enable +# channels (rhel-x86_64-server-6-foo-1) and (rhel-x86_64-server-6-bar-1). +- rhn_register: state=present username=joe_user + password=somepass + channels=rhel-x86_64-server-6-foo-1,rhel-x86_64-server-6-bar-1 ''' import sys diff --git a/library/packaging/svr4pkg b/library/packaging/svr4pkg index 9bab2c10a7c..211383c6135 100644 --- a/library/packaging/svr4pkg +++ b/library/packaging/svr4pkg @@ -53,15 +53,20 @@ options: proxy: description: - HTTP[s] proxy to be used if C(src) is a URL. +''' + +EXAMPLES = ''' +# Install a package from an already copied file +- svr4pkg: name=CSWcommon src=/tmp/cswpkgs.pkg state=present + +# Install a package directly from an http site +- svr4pkg: name=CSWpkgutil src=http://get.opencsw.org/now state=present -examples: - - code: svr4pkg name=CSWcommon src=/tmp/cswpkgs.pkg state=present - description: Install a package from an already copied file - - code: 'svr4pkg name=CSWpkgutil src=http://get.opencsw.org/now state=present' - description: Install a package directly from an http site - - code: svr4pkg name=SUNWgnome-sound-recorder state=absent - description: Ensure that a package is not installed. +# Ensure that a package is not installed. +- svr4pkg: name=SUNWgnome-sound-recorder state=absent ''' + + import os import tempfile diff --git a/library/packaging/yum b/library/packaging/yum index 921b13db1ad..226df89d4b2 100644 --- a/library/packaging/yum +++ b/library/packaging/yum @@ -86,17 +86,18 @@ options: default: "no" choices: ["yes", "no"] aliases: [] - -examples: - - code: yum name=httpd state=latest - - code: yum name=httpd state=removed - - code: yum name=httpd enablerepo=testing state=installed notes: [] # informational: requirements for nodes requirements: [ yum, rpm ] author: Seth Vidal ''' +EXAMPLES = ''' +- yum: name=httpd state=latest +- yum: name=httpd state=removed +- yum: name=httpd enablerepo=testing state=installed +''' + def_qf = "%{name}-%{version}-%{release}.%{arch}" repoquery='/usr/bin/repoquery' diff --git a/library/packaging/zypper b/library/packaging/zypper index a43ec56106d..c2e1c95c797 100644 --- a/library/packaging/zypper +++ b/library/packaging/zypper @@ -60,16 +60,20 @@ options: choices: [ "yes", "no" ] aliases: [] -examples: - - code: "zypper: name=nmap state=present" - - code: "zypper: name=nmap state=latest" - - code: "zypper: name=nmap state=absent" notes: [] # informational: requirements for nodes requirements: [ zypper, rpm ] author: Patrick Callahan ''' +EXAMPLES = ''' +# Install "nmap" +- zypper: name=nmap state=present + +# Remove the "nmap" package +- zypper: name=nmap state=absent +''' + # Function used for getting the name of a currently installed package. def get_current_name(m, name): cmd = '/bin/rpm -q --qf \'%{NAME}-%{VERSION}\'' diff --git a/library/source_control/bzr b/library/source_control/bzr index bda9bd311f4..b1eba0e2e56 100644 --- a/library/source_control/bzr +++ b/library/source_control/bzr @@ -50,9 +50,11 @@ options: description: - If C(yes), any modified files in the working tree will be discarded. -examples: - - code: "bzr name=bzr+ssh://foosball.example.org/path/to/branch dest=/srv/checkout version=22" - description: Example bzr checkout from Ansible Playbooks +''' + +EXAMPLES = ''' +# Example bzr checkout from Ansible Playbooks +- bzr: name=bzr+ssh://foosball.example.org/path/to/branch dest=/srv/checkout version=22 ''' import re diff --git a/library/source_control/git b/library/source_control/git index 8b29e0b80ae..49b7f91b913 100644 --- a/library/source_control/git +++ b/library/source_control/git @@ -73,13 +73,19 @@ options: - If C(yes), repository will be updated using the supplied remote. Otherwise the repo will be left untouched. Prior to 1.2, this was always 'yes' and could not be disabled. -examples: - - code: "git: repo=git://foosball.example.org/path/to/repo.git dest=/srv/checkout version=release-0.22" - description: Example git checkout from Ansible Playbooks - - code: "git: repo=ssh://git@github.com/mylogin/hello.git dest=/home/mylogin/hello" - description: Example read-write git checkout from github - - code: "git: repo=git://foosball.example.org/path/to/repo.git dest=/srv/checkout update=no" - description: Example just ensuring the repo checkout exists +''' + +EXAMPLES = ''' +# Example git checkout from Ansible Playbooks +- git: repo=git://foosball.example.org/path/to/repo.git + dest=/srv/checkout + version=release-0.22 + +# Example read-write git checkout from github +- git: repo=ssh://git@github.com/mylogin/hello.git dest=/home/mylogin/hello + +# Example just ensuring the repo checkout exists +- git: repo=git://foosball.example.org/path/to/repo.git dest=/srv/checkout update=no ''' import re diff --git a/library/source_control/hg b/library/source_control/hg index 3e78dc257bc..8753692d7b8 100644 --- a/library/source_control/hg +++ b/library/source_control/hg @@ -72,13 +72,15 @@ notes: C(StrictHostKeyChecking no) in C(.ssh/config) which will accept and authorize the connection on behalf of the user. However, if you run as a different user such as setting sudo to True), for example, root will not look at the user .ssh/config setting. -examples: - - code: "hg: repo=https://bitbucket.org/user/repo1 dest=/home/user/repo1 revision=stable purge=yes" - description: Ensure the current working copy is inside the stable branch and deletes untracked files if any. requirements: [ ] ''' +EXAMPLES = ''' +# Ensure the current working copy is inside the stable branch and deletes untracked files if any. +- hg: repo=https://bitbucket.org/user/repo1 dest=/home/user/repo1 revision=stable purge=yes +''' + def _set_hgrc(hgrc, vals): parser = ConfigParser.SafeConfigParser() parser.read(hgrc) diff --git a/library/source_control/subversion b/library/source_control/subversion index 7b7df7cec3e..db380d40e98 100644 --- a/library/source_control/subversion +++ b/library/source_control/subversion @@ -61,9 +61,11 @@ options: - --password parameter passed to svn. required: false default: null -examples: - - code: "subversion: repo=svn+ssh://an.example.org/path/to/repo dest=/src/checkout" - description: Checkout subversion repository to specified folder. +''' + +EXAMPLES = ''' +# Checkout subversion repository to specified folder. +- subversion: repo=svn+ssh://an.example.org/path/to/repo dest=/src/checkout ''' import re diff --git a/library/system/authorized_key b/library/system/authorized_key index f70bc69ce1d..ee32839b47d 100644 --- a/library/system/authorized_key +++ b/library/system/authorized_key @@ -66,10 +66,13 @@ author: Brad Olson EXAMPLES = ''' # Example using key data from a local file on the management machine -authorized_key: user=charlie key="{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" +- authorized_key: user=charlie key="{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" # Using alternate directory locations: -authorized_key: user=charlie key="{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" path='/etc/ssh/authorized_keys/charlie' manage_dir=no +- authorized_key: user=charlie + key="{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}" + path='/etc/ssh/authorized_keys/charlie' + manage_dir=no ''' # Makes sure the public key line is present or absent in the user's .ssh/authorized_keys. diff --git a/library/system/cron b/library/system/cron index 9baa6601185..633bccba8ad 100644 --- a/library/system/cron +++ b/library/system/cron @@ -114,22 +114,29 @@ options: default: "no" choices: [ "yes", "no" ] aliases: [] - -examples: - - code: 'cron: name="check dirs" hour="5,2" job="ls -alh > /dev/null"' - description: Ensure a job that runs at 2 and 5 exists. Creates an entry like "* 5,2 * * ls -alh > /dev/null" - - code: 'cron: name="an old job" cron job="/some/dir/job.sh" state=absent' - description: 'Ensure an old job is no longer present. Removes any job that is preceded by "#Ansible: an old job" in the crontab' - - code: 'cron: name="a job for reboot" reboot=yes job="/some/job.sh"' - description: 'Creates an entry like "@reboot /some/job.sh"' - - code: 'cron: name="yum autoupdate" weekday="2" minute=0 hour=12 user="root" job="YUMINTERACTIVE=0 /usr/sbin/yum-autoupdate" cron_file=ansible_yum-autoupdate' - requirements: - cron author: Dane Summers updates: Mike Grozak """ +EXAMPLES = ''' +# Ensure a job that runs at 2 and 5 exists. +# Creates an entry like "* 5,2 * * ls -alh > /dev/null" +- cron: name="check dirs" hour="5,2" job="ls -alh > /dev/null" + +# Ensure an old job is no longer present. Removes any job that is prefixed +# by "#Ansible: an old job" from the crontab +- cron: name="an old job" cron job="/some/dir/job.sh" state=absent + +# Creates an entry like "@reboot /some/job.sh" +- cron: name="a job for reboot" reboot=yes job="/some/job.sh" + +- cron: name="yum autoupdate" weekday="2" minute=0 hour=12 + user="root" job="YUMINTERACTIVE=0 /usr/sbin/yum-autoupdate" + cron_file=ansible_yum-autoupdate +''' + import re import tempfile import os diff --git a/library/system/facter b/library/system/facter index 9bb807dcff1..ef0bdc850b4 100644 --- a/library/system/facter +++ b/library/system/facter @@ -30,14 +30,16 @@ description: JSON data that can be useful for inventory purposes. version_added: "0.2" options: {} -examples: - - code: ansible www.example.net -m facter - description: "Example command-line invocation" notes: [] requirements: [ "facter", "ruby-json" ] author: Michael DeHaan ''' +EXAMPLES = ''' +# Example command-line invocation +ansible www.example.net -m facter +''' + def main(): module = AnsibleModule( argument_spec = dict() diff --git a/library/system/filesystem b/library/system/filesystem index 0adad9ad5b0..3c80d9445cd 100755 --- a/library/system/filesystem +++ b/library/system/filesystem @@ -44,15 +44,18 @@ options: opts: description: - List of options to be passed to mkfs command. -examples: - - description: Create a ext2 filesystem on /dev/sdb1. - code: filesystem fstype=ext2 dev=/dev/sdb1 - - description: Create a ext4 filesystem on /dev/sdb1 and check disk blocks. - code: filesystem fstype=ext4 dev=/dev/sdb1 opts="-cc" notes: - uses mkfs command ''' +EXAMPLES = ''' +# Create a ext2 filesystem on /dev/sdb1. +- filesystem: fstype=ext2 dev=/dev/sdb1 + +# Create a ext4 filesystem on /dev/sdb1 and check disk blocks. +- filesystem: fstype=ext4 dev=/dev/sdb1 opts="-cc" +''' + def main(): module = AnsibleModule( argument_spec = dict( diff --git a/library/system/group b/library/system/group index 034baa514d3..a4f68cd7fe0 100644 --- a/library/system/group +++ b/library/system/group @@ -48,12 +48,14 @@ options: choices: [ "yes", "no" ] description: - If I(yes), indicates that the group created is a system group. -examples: - - code: "group: name=somegroup state=present" - description: Example group command from Ansible Playbooks ''' +EXAMPLES = ''' +# Example group command from Ansible Playbooks +- group: name=somegroup state=present +''' + import grp import syslog import platform diff --git a/library/system/lvg b/library/system/lvg index a90d8e32266..f302a27441a 100644 --- a/library/system/lvg +++ b/library/system/lvg @@ -53,19 +53,25 @@ options: description: - If yes, allows to remove volume group with logical volumes. required: false -examples: - - description: Create a volume group on top of /dev/sda1 with physical extent size = 32MB. - code: lvg vg=vg.services pvs=/dev/sda1 pesize=32 - - description: Create or resize a volume group on top of /dev/sdb1 and /dev/sdc5. - If, for example, we already have VG vg.services on top of /dev/sdb1, this VG will be extended by /dev/sdc5. - Or if vg.services was created on top of /dev/sda5, we first extend it with /dev/sdb1 and /dev/sdc5, and then reduce by /dev/sda5. - code: lvg vg=vg.services pvs=/dev/sdb1,/dev/sdc5 - - description: Remove a volume group with name vg.services. - code: lvg vg=vg.services state=absent notes: - module does not modify PE size for already present volume group ''' +EXAMPLES = ''' +# Create a volume group on top of /dev/sda1 with physical extent size = 32MB. +- lvg: vg=vg.services pvs=/dev/sda1 pesize=32 + +# Create or resize a volume group on top of /dev/sdb1 and /dev/sdc5. +# If, for example, we already have VG vg.services on top of /dev/sdb1, +# this VG will be extended by /dev/sdc5. Or if vg.services was created on +# top of /dev/sda5, we first extend it with /dev/sdb1 and /dev/sdc5, +# and then reduce by /dev/sda5. +- lvg: vg=vg.services pvs=/dev/sdb1,/dev/sdc5 + +# Remove a volume group with name vg.services. +- lvg: vg=vg.services state=absent +''' + def parse_vgs(data): vgs = [] for line in data.splitlines(): diff --git a/library/system/lvol b/library/system/lvol index 36cf4763bba..ec22f99dd5f 100644 --- a/library/system/lvol +++ b/library/system/lvol @@ -44,19 +44,24 @@ options: description: - Control if the logical volume exists. required: false -examples: - - description: Create a logical volume of 512m. - code: lvol vg=firefly lv=test size=512 - - description: Extend the logical volume to 1024m. - code: lvol vg=firefly lv=test size=1024 - - description: Reduce the logical volume to 512m - code: lvol vg=firefly lv=test size=512 - - description: Remove the logical volume. - code: lvol vg=firefly lv=test state=absent notes: - Filesystems on top of the volume are not resized. ''' +EXAMPLES = ''' +# Create a logical volume of 512m. +- lvol: vg=firefly lv=test size=512 + +# Extend the logical volume to 1024m. +- lvol: vg=firefly lv=test size=1024 + +# Reduce the logical volume to 512m +- lvol: vg=firefly lv=test size=512 + +# Remove the logical volume. +- lvol: vg=firefly lv=test state=absent +''' + def parse_lvs(data): lvs = [] for line in data.splitlines(): diff --git a/library/system/mount b/library/system/mount index fdc4378bdf4..485155cd4ec 100644 --- a/library/system/mount +++ b/library/system/mount @@ -67,18 +67,21 @@ options: required: true choices: [ "present", "absent", "mounted", "unmounted" ] default: null -examples: - - code: "mount: name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present" - description: "Mount DVD read-only" - - code: "mount: name=/srv/disk src='LABEL=SOME_LABEL' state=present" - description: "Mount up device by label" - - code: "mount: name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present" - description: "Mount up device by UUID" notes: [] requirements: [] author: Seth Vidal ''' +EXAMPLES = ''' +# Mount DVD read-only +- mount: name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present + +# Mount up device by label +- mount: name=/srv/disk src='LABEL=SOME_LABEL' state=present + +# Mount up device by UUID +- mount: name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present +''' def write_fstab(lines, dest): diff --git a/library/system/ohai b/library/system/ohai index fd048a7df2b..fc7704898cb 100644 --- a/library/system/ohai +++ b/library/system/ohai @@ -30,14 +30,16 @@ description: I(Ohai) data is a bit more verbose and nested than I(facter). version_added: "0.6" options: {} -examples: - - code: ansible webservers -m ohai --tree=/tmp/ohaidata - description: "Retrieve I(ohai) data from all Web servers and store in one-file per host" notes: [] requirements: [ "ohai" ] author: Michael DeHaan ''' +EXAMPLES = ''' +# Retrieve (ohai) data from all Web servers and store in one-file per host +ansible webservers -m ohai --tree=/tmp/ohaidata +''' + def main(): module = AnsibleModule( argument_spec = dict() diff --git a/library/system/ping b/library/system/ping index 4bb99de0454..69507111aec 100644 --- a/library/system/ping +++ b/library/system/ping @@ -28,12 +28,14 @@ description: contact. It does not make sense in playbooks, but it is useful from C(/usr/bin/ansible) options: {} -examples: - - code: ansible webservers -m ping - description: Test 'webservers' status author: Michael DeHaan ''' +EXAMPLES = ''' +# Test 'webservers' status +ansible webservers -m ping +''' + def main(): module = AnsibleModule( argument_spec = dict( diff --git a/library/system/seboolean b/library/system/seboolean index 36ea7a77c25..b45e94f0844 100644 --- a/library/system/seboolean +++ b/library/system/seboolean @@ -42,15 +42,17 @@ options: required: true default: null choices: [ 'yes', 'no' ] -examples: - - code: "seboolean: name=httpd_can_network_connect state=yes persistent=yes" - description: Set I(httpd_can_network_connect) flag on and keep it persistent across reboots notes: - Not tested on any debian based system requirements: [ ] author: Stephen Fromm ''' +EXAMPLES = ''' +# Set (httpd_can_network_connect) flag on and keep it persistent across reboots +- seboolean: name=httpd_can_network_connect state=yes persistent=yes +''' + try: import selinux HAVE_SELINUX=True diff --git a/library/system/selinux b/library/system/selinux index 60752013a94..98e1fdb35ad 100644 --- a/library/system/selinux +++ b/library/system/selinux @@ -42,16 +42,18 @@ options: - path to the SELinux configuration file, if non-standard required: false default: "/etc/selinux/config" -examples: - - code: "selinux: policy=targeted state=enforcing" - - code: "selinux: policy=targeted state=permissive" - - code: "selinux: state=disabled" notes: - Not tested on any debian based system requirements: [ libselinux-python ] author: Derek Carter ''' +EXAMPLES = ''' +- selinux: policy=targeted state=enforcing +- selinux: policy=targeted state=permissive +- selinux: state=disabled +''' + import os import re import sys diff --git a/library/system/service b/library/system/service index fe3f334bfe3..3970144e917 100644 --- a/library/system/service +++ b/library/system/service @@ -58,21 +58,29 @@ options: description: - Additional arguments provided on the command line aliases: [ 'args' ] -examples: - - description: Example action to start service httpd, if not running - code: "service: name=httpd state=started" - - description: Example action to stop service httpd, if running - code: "service: name=httpd state=stopped" - - description: Example action to restart service httpd, in all cases - code: "service: name=httpd state=restarted" - - description: Example action to reload service httpd, in all cases - code: "service: name=httpd state=reloaded" - - description: Example action to enable service httpd, and not touch the running state - code: "service: name=httpd enabled=yes" - - description: Example action to start service foo, based on running process /usr/bin/foo - code: "service: name=foo pattern=/usr/bin/foo state=started" - - description: Example action to restart network service for interface eth0 - code: "service: name=network state=restarted args=eth0" +''' + +EXAMPLES = ''' +# Example action to start service httpd, if not running +- service: name=httpd state=started + +# Example action to stop service httpd, if running +- service: name=httpd state=stopped + +# Example action to restart service httpd, in all cases +- service: name=httpd state=restarted + +# Example action to reload service httpd, in all cases +- service: name=httpd state=reloaded + +# Example action to enable service httpd, and not touch the running state +- service: name=httpd enabled=yes + +# Example action to start service foo, based on running process /usr/bin/foo +- service: name=foo pattern=/usr/bin/foo state=started + +# Example action to restart network service for interface eth0 +- service: name=network state=restarted args=eth0 ''' import platform diff --git a/library/system/sysctl b/library/system/sysctl index 493a8a6e50d..be23a1d6305 100644 --- a/library/system/sysctl +++ b/library/system/sysctl @@ -63,18 +63,24 @@ options: - specifies the absolute path to C(sysctl.conf), if not /etc/sysctl.conf required: false default: /etc/sysctl.conf -examples: - - code: "sysctl: name=vm.swappiness value=5 state=present" - description: "Set vm.swappiness to 5 in /etc/sysctl.conf" - - code: "sysctl: name=kernel.panic state=absent sysctl_file=/etc/sysctl.conf" - description: "Remove kernel.panic entry from /etc/sysctl.conf" - - code: "sysctl: name=kernel.panic value=3 sysctl_file=/tmp/test_sysctl.conf check=before reload=no" - description: Set kernel.panic to 3 in /tmp/test_sysctl.conf, check if the sysctl key seems writable, but do not reload sysctl, and do not check kernel value after (not needed, because not the real /etc/sysctl.conf updated) notes: [] requirements: [] author: David "DaviXX" CHANIAL ''' +EXAMPLES = ''' +# Set vm.swappiness to 5 in /etc/sysctl.conf +- sysctl: name=vm.swappiness value=5 state=present + +# Remove kernel.panic entry from /etc/sysctl.conf +- sysctl: name=kernel.panic state=absent sysctl_file=/etc/sysctl.conf + +# Set kernel.panic to 3 in /tmp/test_sysctl.conf, check if the sysctl key +# seems writable, but do not reload sysctl, and do not check kernel value +# after (not needed, because not the real /etc/sysctl.conf updated) +- sysctl: name=kernel.panic value=3 sysctl_file=/tmp/test_sysctl.conf check=before reload=no +''' + # ============================================================== import os diff --git a/library/system/user b/library/system/user index 88f79aab246..91d926284c9 100644 --- a/library/system/user +++ b/library/system/user @@ -158,13 +158,17 @@ options: - Set a passphrase for the SSH key. If no passphrase is provided, the SSH key will default to having no passphrase. -examples: - - code: 'user: name=johnd comment="John Doe" uid=1040' - description: "Add the user 'johnd' with a specific uid and a primary group of 'admin'" - - code: "user: name=johnd state=absent remove=yes" - description: "Remove the user 'johnd'" - - code: 'user: name=jsmith generate_ssh_key=yes ssh_key_bits=2048' - description: "Create a 2048-bit SSH key for user jsmith" +''' + +EXAMPLES = ''' +# Add the user 'johnd' with a specific uid and a primary group of 'admin' +- user: name=johnd comment="John Doe" uid=1040 + +# Remove the user 'johnd' +- user: name=johnd state=absent remove=yes + +# Create a 2048-bit SSH key for user jsmith +- user: name=jsmith generate_ssh_key=yes ssh_key_bits=2048 ''' import os diff --git a/library/system/zfs b/library/system/zfs index adfe3069f09..2428320313e 100644 --- a/library/system/zfs +++ b/library/system/zfs @@ -206,17 +206,24 @@ options: - The zoned property. required: False choices: ['on','off'] -examples: - - code: zfs name=rpool/myfs state=present - description: Create a new file system called myfs in pool rpool - - code: zfs name=rpool/myvol state=present volsize=10M - description: Create a new volume called myvol in pool rpool. - - code: zfs name=rpool/myfs@mysnapshot state=present - description: Create a snapshot of rpool/myfs file system. - - code: zfs name=rpool/myfs2 state=present snapdir=enabled - description: Create a new file system called myfs2 with snapdir enabled author: Johan Wiren ''' + +EXAMPLES = ''' +# Create a new file system called myfs in pool rpool +- zfs: name=rpool/myfs state=present + +# Create a new volume called myvol in pool rpool. +- zfs: name=rpool/myvol state=present volsize=10M + +# Create a snapshot of rpool/myfs file system. +- zfs: name=rpool/myfs@mysnapshot state=present + +# Create a new file system called myfs2 with snapdir enabled +- zfs: name=rpool/myfs2 state=present snapdir=enabled +''' + + import os class Zfs(object): diff --git a/library/utilities/debug b/library/utilities/debug index c0ae3c3e63b..9d279d62916 100644 --- a/library/utilities/debug +++ b/library/utilities/debug @@ -43,13 +43,16 @@ options: required: false default: "no" choices: [ "yes", "no" ] -examples: - - code: | - - action: debug msg="System $inventory_hostname has uuid $ansible_product_uuid" - - action: debug msg="System $inventory_hostname lacks a gateway" fail=yes - only_if: "is_unset('${ansible_default_ipv4.gateway}')" - - action: debug msg="System $inventory_hostname has gateway ${ansible_default_ipv4.gateway}" - only_if: "is_set('${ansible_default_ipv4.gateway}')" - description: "Example that prints the loopback address and gateway for each host" author: Dag Wieers ''' + +EXAMPLES = ''' +# Example that prints the loopback address and gateway for each host +- action: debug msg="System $inventory_hostname has uuid $ansible_product_uuid" + +- action: debug msg="System $inventory_hostname lacks a gateway" fail=yes + only_if: "is_unset('${ansible_default_ipv4.gateway}')" + +- action: debug msg="System $inventory_hostname has gateway ${ansible_default_ipv4.gateway}" + only_if: "is_set('${ansible_default_ipv4.gateway}')" +''' diff --git a/library/utilities/fail b/library/utilities/fail index 2f9aa37438e..e9c072f2c75 100644 --- a/library/utilities/fail +++ b/library/utilities/fail @@ -33,12 +33,12 @@ options: fail will simple bail out with a generic message. required: false default: "'Failed as requested from task'" -examples: - - code: | - fail: msg="The system may not be provisioned according to the CMDB status." - only_if: "'$cmdb_status' != 'to-be-staged'" - - description: "Example playbook using fail and only_if together" author: Dag Wieers ''' + +EXAMPLES = ''' +# Example playbook using fail and only_if together +- fail: msg="The system may not be provisioned according to the CMDB status." + only_if: "'$cmdb_status' != 'to-be-staged'" +''' diff --git a/library/utilities/pause b/library/utilities/pause index 92cda0719fc..6e8a83afe61 100644 --- a/library/utilities/pause +++ b/library/utilities/pause @@ -26,11 +26,15 @@ options: required: false default: null author: Tim Bielawa -examples: - - description: Pause for 5 minutes to build app cache. - code: "pause: minutes=5" - - description: Pause until you can verify updates to an application were successful. - code: "pause:" - - description: A helpful reminder of what to look out for post-update. - code: 'pause: prompt="Make sure org.foo.FooOverload exception is not present"' +''' + +EXAMPLES = ''' +# Pause for 5 minutes to build app cache. +- pause: minutes=5 + +# Pause until you can verify updates to an application were successful. +- pause: + +# A helpful reminder of what to look out for post-update. +- pause: prompt="Make sure org.foo.FooOverload exception is not present" ''' diff --git a/library/utilities/set_fact b/library/utilities/set_fact index a02c7f55376..f8ef8466a52 100644 --- a/library/utilities/set_fact +++ b/library/utilities/set_fact @@ -42,10 +42,10 @@ notes: EXAMPLES = ''' # Example setting host facts using key=value pairs -set_fact: one_fact="something" other_fact="{{ local_var * 2 }}" +- set_fact: one_fact="something" other_fact="{{ local_var * 2 }}" # Example setting host facts using complex arguments -set_fact: - one_fact: something - other_fact: "{{ local_var * 2 }}" +- set_fact: + one_fact: something + other_fact: "{{ local_var * 2 }}" ''' diff --git a/library/utilities/wait_for b/library/utilities/wait_for index f702b4e7f98..a7fee8935fb 100644 --- a/library/utilities/wait_for +++ b/library/utilities/wait_for @@ -67,7 +67,7 @@ author: Jeroen Hoekx EXAMPLES = ''' # wait 300 seconds for port 8000 to become open on the host, don't start checking for 10 seconds -wait_for: port=8000 delay=10" +- wait_for: port=8000 delay=10" ''' def main(): diff --git a/library/web_infrastructure/django_manage b/library/web_infrastructure/django_manage index c8f89ce9917..0138b5fa246 100644 --- a/library/web_infrastructure/django_manage +++ b/library/web_infrastructure/django_manage @@ -80,22 +80,22 @@ author: Scott Anderson EXAMPLES = """ # Run cleanup on the application installed in '$django_dir'. -django_manage: command=cleanup app_path=$django_dir +- django_manage: command=cleanup app_path=$django_dir # Load the $initial_data fixture into the application -django_manage: command=loaddata app_path=$django_dir fixtures=$initial_data +- django_manage: command=loaddata app_path=$django_dir fixtures=$initial_data #Run syncdb on the application -django_manage: > - command=syncdb - app_path=$django_dir - settings=$settings_app_name - pythonpath=$settings_dir - virtualenv=$virtualenv_dir - database=$mydb +- django_manage: > + command=syncdb + app_path=$django_dir + settings=$settings_app_name + pythonpath=$settings_dir + virtualenv=$virtualenv_dir + database=$mydb #Run the SmokeTest test case from the main app. Useful for testing deploys. -django_manage command=test app_path=django_dir apps=main.SmokeTest +- django_manage: command=test app_path=django_dir apps=main.SmokeTest """ diff --git a/library/web_infrastructure/supervisorctl b/library/web_infrastructure/supervisorctl index 3666e7d3978..0185af5648e 100644 --- a/library/web_infrastructure/supervisorctl +++ b/library/web_infrastructure/supervisorctl @@ -44,7 +44,7 @@ author: Matt Wright EXAMPLES = ''' # Manage the state of program to be in 'started' state. -supervisorctl: name=my_app state=started +- supervisorctl: name=my_app state=started ''' def main(): From 4942a06bc2b229b10df19491fbe64e166f53e6ab Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Sat, 15 Jun 2013 16:28:43 -0400 Subject: [PATCH 26/33] now modules can implement with_items list globbing w/o updating hardcoded lists in ansible code, just add WITH_ITEMS_USES_LIST in a comment anywhere, and of course, support recieving params as list. Signed-off-by: Brian Coca --- lib/ansible/runner/__init__.py | 8 ++++++-- library/packaging/apt | 1 + library/packaging/pkgng | 1 + library/packaging/yum | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 9ee9e54a12b..b27f475a59d 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -163,6 +163,7 @@ class Runner(object): self.is_playbook = is_playbook self.environment = environment self.complex_args = complex_args + self.module_with_list = False self.callbacks.runner = self @@ -405,8 +406,8 @@ class Runner(object): if type(items) != list: raise errors.AnsibleError("lookup plugins have to return a list: %r" % items) - if len(items) and utils.is_list_of_strings(items) and self.module_name in [ 'apt', 'yum', 'pkgng' ]: - # hack for apt, yum, and pkgng so that with_items maps back into a single module call + if len(items) and utils.is_list_of_strings(items) and self.module_with_list: + # with_items maps back into a single module call, making modules that support this more efficient inject['item'] = ",".join(items) items = None @@ -711,6 +712,9 @@ class Runner(object): if 'WANT_JSON' in module_data: module_style = 'non_native_want_json' + if 'WITH_ITEMS_USES_LIST' in module_data: + self.module_with_list = True + complex_args_json = utils.jsonify(complex_args) # We force conversion of module_args to str because module_common calls shlex.split, # a standard library function that incorrectly handles Unicode input before Python 2.7.3. diff --git a/library/packaging/apt b/library/packaging/apt index 04d7eb82b9d..1a6ce392cf4 100644 --- a/library/packaging/apt +++ b/library/packaging/apt @@ -1,5 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# WITH_ITEMS_USES_LIST # (c) 2012, Flowroute LLC # Written by Matthew Williams diff --git a/library/packaging/pkgng b/library/packaging/pkgng index ec0469bdc36..ce59e28e534 100644 --- a/library/packaging/pkgng +++ b/library/packaging/pkgng @@ -1,5 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# WITH_ITEMS_USES_LIST # (c) 2013, bleader # Written by bleader diff --git a/library/packaging/yum b/library/packaging/yum index 921b13db1ad..698c8bf6f3b 100644 --- a/library/packaging/yum +++ b/library/packaging/yum @@ -1,5 +1,6 @@ #!/usr/bin/python -tt # -*- coding: utf-8 -*- +# WITH_ITEMS_USES_LIST # (c) 2012, Red Hat, Inc # Written by Seth Vidal From 36df7e8c9530583e13c2026a74d4fb20bbee1724 Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Sat, 15 Jun 2013 18:31:31 -0400 Subject: [PATCH 27/33] cut and docs for facts.d mechanism for setup module --- library/system/setup | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/library/system/setup b/library/system/setup index 274fb469ee9..b626ead79c4 100644 --- a/library/system/setup +++ b/library/system/setup @@ -30,6 +30,9 @@ import struct import datetime import getpass import subprocess +import ConfigParser +import StringIO + DOCUMENTATION = ''' --- @@ -42,6 +45,15 @@ options: - if supplied, only return facts that match this shell-style (fnmatch) wildcard. required: false default: '*' + fact_path: + version_added: "1.3" + description: + - path used for local ansible facts (*.fact) - files in this dir + will be run (if executable) and their results be added to ansible_local facts + if a file is not executable it is read. + File/results format can be json or ini-format + required: false + default: '/etc/ansible/facts.d' description: - This module is automatically called by playbooks to gather useful variables about remote hosts that can be used in playbooks. It can also be @@ -131,6 +143,7 @@ class Facts(object): self.get_lsb_facts() self.get_date_time_facts() self.get_user_facts() + self.get_local_facts() def populate(self): return self.facts @@ -169,6 +182,51 @@ class Facts(object): self.facts['architecture'] = data[0] + def get_local_facts(self): + + fact_path = module.params.get('fact_path', None) + if not fact_path or not os.path.exists(fact_path): + return + + local = {} + for fn in sorted(glob.glob(fact_path + '/*.fact')): + # where it will sit under local facts + fact_base = os.path.basename(fn).replace('.fact','') + if os.access(fn, os.X_OK): + # run it + # try to read it as json first + # if that fails read it with ConfigParser + # if that fails, skip it + rc, out, err = module.run_command(fn) + else: + out = open(fn).read() + + # load raw json + fact = 'loading %s' % fact_base + try: + fact = json.loads(out) + except ValueError, e: + # load raw ini + cp = ConfigParser.ConfigParser() + try: + cp.readfp(StringIO.StringIO(out)) + except ConfigParser.Error, e: + fact="error loading fact - please check content" + else: + fact = {} + #print cp.sections() + for sect in cp.sections(): + if sect not in fact: + fact[sect] = {} + for opt in cp.options(sect): + val = cp.get(sect, opt) + fact[sect][opt]=val + + local[fact_base] = fact + if not local: + return + self.facts['local'] = local + # platform.dist() is deprecated in 2.6 # in 2.6 and newer, you should use platform.linux_distribution() def get_distribution_facts(self): @@ -2002,6 +2060,7 @@ def main(): module = AnsibleModule( argument_spec = dict( filter=dict(default="*", required=False), + fact_path=dict(default='/etc/ansible/facts.d', required=False), ), supports_check_mode = True, ) From 512d7ba5318b37fbdacaab3377e2f2f4ff8a3889 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 16 Jun 2013 22:09:35 -0400 Subject: [PATCH 28/33] Spelling fixes --- library/cloud/glance_image | 2 +- library/cloud/quantum_network | 4 ++-- library/cloud/quantum_subnet | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/cloud/glance_image b/library/cloud/glance_image index d792272cf3a..3ef823d1ae3 100644 --- a/library/cloud/glance_image +++ b/library/cloud/glance_image @@ -85,7 +85,7 @@ options: default: None is_public: description: - - Wether the image can be accessed publicly + - Whether the image can be accessed publicly required: false default: 'yes' copy_from: diff --git a/library/cloud/quantum_network b/library/cloud/quantum_network index d2b263a9aff..09cedc670f4 100644 --- a/library/cloud/quantum_network +++ b/library/cloud/quantum_network @@ -86,12 +86,12 @@ options: default: false shared: description: - - Wether this network is shared or not + - Whether this network is shared or not required: false default: false admin_state_up: description: - - Wether the state should be marked as up or down + - Whether the state should be marked as up or down required: false default: true requirements: ["quantumclient", "keystoneclient"] diff --git a/library/cloud/quantum_subnet b/library/cloud/quantum_subnet index deee46cd83a..5835cb6fbb4 100644 --- a/library/cloud/quantum_subnet +++ b/library/cloud/quantum_subnet @@ -81,7 +81,7 @@ options: default: 4 enable_dhcp: description: - - Wether DHCP should be enabled for this subnet. + - Whether DHCP should be enabled for this subnet. required: false default: true gateway_ip: From a4223e119d3315d00a35da8ebb9a5c9c6e09bba1 Mon Sep 17 00:00:00 2001 From: trbs Date: Thu, 13 Jun 2013 23:05:08 +0200 Subject: [PATCH 29/33] fixed x-bits in git --- examples/scripts/yaml_to_ini.py | 0 hacking/authors.sh | 0 lib/ansible/utils/module_docs.py | 0 library/system/filesystem | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 examples/scripts/yaml_to_ini.py mode change 100644 => 100755 hacking/authors.sh mode change 100755 => 100644 lib/ansible/utils/module_docs.py mode change 100755 => 100644 library/system/filesystem diff --git a/examples/scripts/yaml_to_ini.py b/examples/scripts/yaml_to_ini.py old mode 100644 new mode 100755 diff --git a/hacking/authors.sh b/hacking/authors.sh old mode 100644 new mode 100755 diff --git a/lib/ansible/utils/module_docs.py b/lib/ansible/utils/module_docs.py old mode 100755 new mode 100644 diff --git a/library/system/filesystem b/library/system/filesystem old mode 100755 new mode 100644 From 572f49b11fbab3033ee0bb08b6592dd8f688db64 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 16 Jun 2013 22:47:29 -0400 Subject: [PATCH 30/33] Fix merge conflict. --- library/system/user | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/library/system/user b/library/system/user index 91d926284c9..8bc54cee8e9 100644 --- a/library/system/user +++ b/library/system/user @@ -158,6 +158,15 @@ options: - Set a passphrase for the SSH key. If no passphrase is provided, the SSH key will default to having no passphrase. + update_password: + required: false + default: always + choices: ['always', 'on_creation'] + version_added: "1.3" + description: + - Control when does ansible update passwords. + C(always) will update if they differ. + C(on_creation) will only update the password if user is being created. ''' EXAMPLES = ''' @@ -230,6 +239,7 @@ class User(object): self.ssh_type = module.params['ssh_key_type'] self.ssh_comment = module.params['ssh_key_comment'] self.ssh_passphrase = module.params['ssh_key_passphrase'] + self.update_password = module.params['update_password'] if module.params['ssh_key_file'] is not None: self.ssh_file = module.params['ssh_key_file'] else: @@ -361,7 +371,7 @@ class User(object): cmd.append('-s') cmd.append(self.shell) - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd.append('-p') cmd.append(self.password) @@ -694,7 +704,7 @@ class FreeBsdUser(User): (rc, out, err) = (None, '', '') # we have to set the password in a second command - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd = [ self.module.get_bin_path('chpass', True), '-p', @@ -840,7 +850,7 @@ class OpenBSDUser(User): cmd.append('-L') cmd.append(self.login_class) - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd.append('-p') cmd.append(self.password) @@ -993,7 +1003,7 @@ class NetBSDUser(User): cmd.append('-L') cmd.append(self.login_class) - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd.append('-p') cmd.append(self.password) @@ -1158,7 +1168,7 @@ class SunOS(User): (rc, out, err) = (None, '', '') # we have to set the password by editing the /etc/shadow file - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: try: lines = [] for line in open(self.SHADOWFILE, 'rb').readlines(): @@ -1307,7 +1317,7 @@ class AIX(User): (rc, out, err) = self.execute_command(cmd) # set password with chpasswd - if self.password is not None and info[1] != self.password: + if self.update_password == 'always' and self.password is not None and info[1] != self.password: cmd = [] cmd.append('echo "'+self.name+':'+self.password+'" |') cmd.append(self.module.get_bin_path('chpasswd', True)) @@ -1358,7 +1368,8 @@ def main(): ssh_key_type=dict(default=ssh_defaults['type'], type='str'), ssh_key_file=dict(default=None, type='str'), ssh_key_comment=dict(default=ssh_defaults['comment'], type='str'), - ssh_key_passphrase=dict(default=None, type='str') + ssh_key_passphrase=dict(default=None, type='str'), + update_password=dict(default='always',choices=['always','on_create'],type='str') ), supports_check_mode=True ) From 2eb3a9a3c9e8b937ca3223acb3f27cb29ce3a955 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 16 Jun 2013 22:39:11 -0400 Subject: [PATCH 31/33] Resolve docs conflict. --- library/system/user | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/system/user b/library/system/user index 8bc54cee8e9..a16f32c9be0 100644 --- a/library/system/user +++ b/library/system/user @@ -164,9 +164,7 @@ options: choices: ['always', 'on_creation'] version_added: "1.3" description: - - Control when does ansible update passwords. - C(always) will update if they differ. - C(on_creation) will only update the password if user is being created. + - C(always) will update passwords if they differ. C(on_creation) will only set the password for newly created users. ''' EXAMPLES = ''' From 7b763dc487f129926d37722dad94a0924866ee77 Mon Sep 17 00:00:00 2001 From: Jochen Maes Date: Fri, 14 Jun 2013 07:28:24 +0200 Subject: [PATCH 32/33] adds 2 django commands (migrate, collectstatic) Signed-off-by: Jochen Maes --- library/web_infrastructure/django_manage | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/library/web_infrastructure/django_manage b/library/web_infrastructure/django_manage index ae77c36b3d1..eb766c6a0b0 100644 --- a/library/web_infrastructure/django_manage +++ b/library/web_infrastructure/django_manage @@ -28,7 +28,7 @@ description: version_added: "1.1" options: command: - choices: [ 'cleanup', 'flush', 'loaddata', 'runfcgi', 'syncdb', 'test', 'validate' ] + choices: [ 'cleanup', 'flush', 'loaddata', 'runfcgi', 'syncdb', 'test', 'validate', 'migrate', 'collectstatic' ] description: - The name of the Django management command to run. Allowed commands are cleanup, createcachetable, flush, loaddata, syncdb, test, validate. required: true @@ -70,10 +70,24 @@ options: description: - A space-delimited list of fixture file names to load in the database. B(Required) by the 'loaddata' command. required: false + skip: + description: + - Will skip over out-of-order missing migrations, you can only use this parameter with I(migrate) + required: false + merge: + description: + - Will run out-of-order or missing migrations as they are not rollback migrations, you can only use this parameter with 'migrate' command + required: false + link: + description: + - Will create links to the files instead of copying them, you can only use this parameter with 'collectstatic' command + required: false notes: - I(virtualenv) (U(http://www.virtualenv.org)) must be installed on the remote host if the virtualenv parameter is specified. - This module will create a virtualenv if the virtualenv parameter is specified and a virtualenv does not already exist at the given location. - This module assumes English error messages for the 'createcachetable' command to detect table existence, unfortunately. + - To be able to use the migrate command, you must have south installed and added as an app in your settings + - To be able to use the collectstatic command, you must have enabled staticfiles in your settings requirements: [ "virtualenv", "django" ] author: Scott Anderson ''' @@ -150,6 +164,8 @@ def main(): syncdb=('database', ), test=('failfast', 'testrunner', 'liveserver', 'apps', ), validate=(), + migrate=('apps', 'skip', 'database', 'merge'), + collectstatic=('link', ), ) command_required_param_map = dict( @@ -162,6 +178,7 @@ def main(): 'flush', 'syncdb', 'test', + 'collectstatic', ) # These params are allowed for certain commands only @@ -169,7 +186,7 @@ def main(): # These params are automatically added to the command if present general_params = ('settings', 'pythonpath', ) - specific_boolean_params = ('failfast', ) + specific_boolean_params = ('failfast', 'skip', 'merge', 'link' ) end_of_command_params = ('apps', 'cache_table', 'fixtures', ) module = AnsibleModule( @@ -187,6 +204,9 @@ def main(): fixtures = dict(default=None, required=False), liveserver = dict(default=None, required=False, aliases=['live_server']), testrunner = dict(default=None, required=False, aliases=['test_runner']), + skip = dict(default=None, required=False, choices=BOOLEANS), + merge = dict(default=None, required=False, choices=BOOLEANS), + link = dict(default=None, required=False, choices=BOOLEANS), ), ) From bfcead8c33192d7cc2ee332ed39136f88e3bd907 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 16 Jun 2013 23:33:49 -0400 Subject: [PATCH 33/33] Remove reference to non-existant module. --- library/utilities/set_fact | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/utilities/set_fact b/library/utilities/set_fact index f8ef8466a52..916e603c599 100644 --- a/library/utilities/set_fact +++ b/library/utilities/set_fact @@ -36,8 +36,6 @@ options: required: true default: null version_added: "1.2" -notes: - - You can set play variables using the C(set_var) module. ''' EXAMPLES = '''