From 6cbd94dfaee3b800303a30c6e6a5337bb0ddc903 Mon Sep 17 00:00:00 2001 From: Stoned Elipot Date: Mon, 2 Sep 2013 12:26:02 +0200 Subject: [PATCH 01/24] Avoid duplicates of the 'all' group when using inventory script. Do not recreate an 'all' group when it is in the inventory script's output, but use the one created upfront. --- lib/ansible/inventory/script.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ansible/inventory/script.py b/lib/ansible/inventory/script.py index 42c46559d99..9474c3ebd76 100644 --- a/lib/ansible/inventory/script.py +++ b/lib/ansible/inventory/script.py @@ -72,7 +72,10 @@ class InventoryScript(object): self.host_vars_from_top = data['hostvars'] continue - group = groups[group_name] = Group(group_name) + if group_name != all.name: + group = groups[group_name] = Group(group_name) + else: + group = all host = None if not isinstance(data, dict): From 36fe595de82407149b951756c06ea95956919ea5 Mon Sep 17 00:00:00 2001 From: Herby Gillot Date: Mon, 2 Sep 2013 22:02:56 -0400 Subject: [PATCH 02/24] ec2 inventory script: Add a global group for EC2 and RDS instances when listing EC2 inventory --- plugins/inventory/ec2.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/inventory/ec2.py b/plugins/inventory/ec2.py index 913ddb5f84a..cd3501da279 100755 --- a/plugins/inventory/ec2.py +++ b/plugins/inventory/ec2.py @@ -349,6 +349,9 @@ class Ec2Inventory(object): key = self.to_safe("tag_" + k + "=" + v) self.push(self.inventory, key, dest) + # Global Tag: tag all EC2 instances + self.push(self.inventory, 'ec2', dest) + def add_rds_instance(self, instance, region): ''' Adds an RDS instance to the inventory and index, as long as it is @@ -400,6 +403,9 @@ class Ec2Inventory(object): # Inventory: Group by parameter group self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), dest) + # Global Tag: all RDS instances + self.push(self.inventory, 'rds', dest) + def get_host_info(self): ''' Get variables about a specific host ''' From aab445a28fd039d55a2a1bdcbe3511bd7366ceda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ka=C5=82u=C5=BCa?= Date: Tue, 10 Sep 2013 11:49:10 +0200 Subject: [PATCH 03/24] add 'chars' parameter to password plugin to allow custom character set It accepts comma separated list of names that are either string module attributes (ascii_letters,digits, etc) or are used literally To enter comma use two commas ',,' somewhere - preferably at the end Qoutes and double qoutes are not supported --- lib/ansible/runner/lookup_plugins/password.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/ansible/runner/lookup_plugins/password.py b/lib/ansible/runner/lookup_plugins/password.py index a09ca4071e8..3d988e03c6d 100644 --- a/lib/ansible/runner/lookup_plugins/password.py +++ b/lib/ansible/runner/lookup_plugins/password.py @@ -22,6 +22,7 @@ import os import errno import random from string import ascii_letters, digits +import string class LookupModule(object): @@ -52,6 +53,7 @@ class LookupModule(object): paramvals = { 'length': LookupModule.LENGTH, 'encrypt': None, + 'chars': ['ascii_letters','digits',".,:-_"], } # get non-default parameters if specified @@ -61,6 +63,11 @@ class LookupModule(object): assert(name in paramvals) if name == 'length': paramvals[name] = int(value) + elif name == 'chars': + use_chars=[] + if ",," in value: use_chars.append(',') + use_chars.extend(value.replace(',,',',').replace('"','').replace("'",'').split(',')) + paramvals['chars'] = use_chars else: paramvals[name] = value except (ValueError, AssertionError) as e: @@ -68,6 +75,7 @@ class LookupModule(object): length = paramvals['length'] encrypt = paramvals['encrypt'] + use_chars = paramvals['chars'] # get password or create it if file doesn't exist path = utils.path_dwim(self.basedir, relpath) @@ -75,7 +83,7 @@ class LookupModule(object): pathdir = os.path.dirname(path) if not os.path.isdir(pathdir): os.makedirs(pathdir) - chars = ascii_letters + digits + ".,:-_" + chars = "".join([getattr(string,c,c) for c in use_chars]) password = ''.join(random.choice(chars) for _ in range(length)) if encrypt is not None: salt = self.random_salt() From 6786773797f3a27377f97ce408262379e655f734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ka=C5=82u=C5=BCa?= Date: Tue, 10 Sep 2013 15:00:29 +0200 Subject: [PATCH 04/24] filter out qoutes since they cause random errors --- lib/ansible/runner/lookup_plugins/password.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ansible/runner/lookup_plugins/password.py b/lib/ansible/runner/lookup_plugins/password.py index 3d988e03c6d..6da0fdbe376 100644 --- a/lib/ansible/runner/lookup_plugins/password.py +++ b/lib/ansible/runner/lookup_plugins/password.py @@ -66,7 +66,7 @@ class LookupModule(object): elif name == 'chars': use_chars=[] if ",," in value: use_chars.append(',') - use_chars.extend(value.replace(',,',',').replace('"','').replace("'",'').split(',')) + use_chars.extend(value.replace(',,',',').split(',')) paramvals['chars'] = use_chars else: paramvals[name] = value @@ -83,7 +83,7 @@ class LookupModule(object): pathdir = os.path.dirname(path) if not os.path.isdir(pathdir): os.makedirs(pathdir) - chars = "".join([getattr(string,c,c) for c in use_chars]) + chars = "".join([getattr(string,c,c) for c in use_chars]).replace('"','').replace("'",'') password = ''.join(random.choice(chars) for _ in range(length)) if encrypt is not None: salt = self.random_salt() From e504ff94e6c8249eaf3f2f1299be775842ec73e0 Mon Sep 17 00:00:00 2001 From: abelbabel Date: Wed, 25 Sep 2013 17:51:17 +0200 Subject: [PATCH 05/24] add check mode support Could it be that easy or do I have missed something? --- library/packaging/pkgng | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/library/packaging/pkgng b/library/packaging/pkgng index fa341b2f80d..e6ad98e4b07 100644 --- a/library/packaging/pkgng +++ b/library/packaging/pkgng @@ -89,9 +89,10 @@ def remove_packages(module, pkgin_path, packages): if not query_package(module, pkgin_path, package): continue - rc, out, err = module.run_command("%s delete -y %s" % (pkgin_path, package)) + if not module.check_mode: + rc, out, err = module.run_command("%s delete -y %s" % (pkgin_path, package)) - if query_package(module, pkgin_path, package): + if not module.check_mode and query_package(module, pkgin_path, package): module.fail_json(msg="failed to remove %s: %s" % (package, out)) remove_c += 1 @@ -110,7 +111,7 @@ def install_packages(module, pkgin_path, packages, cached, pkgsite): if pkgsite != "": pkgsite="PACKAGESITE=%s" % (pkgsite) - if cached == "no": + if not module.check_mode and cached == "no": rc, out, err = module.run_command("%s %s update" % (pkgsite, pkgin_path)) if rc != 0: module.fail_json(msg="Could not update catalogue") @@ -119,9 +120,10 @@ def install_packages(module, pkgin_path, packages, cached, pkgsite): if query_package(module, pkgin_path, package): continue - rc, out, err = module.run_command("%s %s install -U -y %s" % (pkgsite, pkgin_path, package)) + if not module.check_mode: + rc, out, err = module.run_command("%s %s install -U -y %s" % (pkgsite, pkgin_path, package)) - if not query_package(module, pkgin_path, package): + if not module.check_mode and query_package(module, pkgin_path, package): module.fail_json(msg="failed to install %s: %s" % (package, out)) install_c += 1 @@ -134,11 +136,12 @@ def install_packages(module, pkgin_path, packages, cached, pkgsite): def main(): module = AnsibleModule( - argument_spec = dict( - state = dict(default="present", choices=["present","absent"]), - name = dict(aliases=["pkg"], required=True), - cached = dict(default="no", required=False, choices=["yes","no"]), - pkgsite = dict(default="", required=False))) + argument_spec = dict( + state = dict(default="present", choices=["present","absent"]), + name = dict(aliases=["pkg"], required=True), + cached = dict(default="supports_check_modeno", required=False, choices=["yes","no"]), + pkgsite = dict(default="", required=False)) + supports_check_mode = True) pkgin_path = module.get_bin_path('pkg', True) From ee5ab48becd04b24852fdd840edec3906c45d68a Mon Sep 17 00:00:00 2001 From: abelbabel Date: Wed, 25 Sep 2013 18:38:46 +0200 Subject: [PATCH 06/24] removed typo --- library/packaging/pkgng | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/packaging/pkgng b/library/packaging/pkgng index e6ad98e4b07..ea2c5262793 100644 --- a/library/packaging/pkgng +++ b/library/packaging/pkgng @@ -139,7 +139,7 @@ def main(): argument_spec = dict( state = dict(default="present", choices=["present","absent"]), name = dict(aliases=["pkg"], required=True), - cached = dict(default="supports_check_modeno", required=False, choices=["yes","no"]), + cached = dict(default="no", required=False, choices=["yes","no"]), pkgsite = dict(default="", required=False)) supports_check_mode = True) From effcb963f63ca21ee2908ac4cfa5d92b72915cd2 Mon Sep 17 00:00:00 2001 From: abelbabel Date: Wed, 25 Sep 2013 18:50:41 +0200 Subject: [PATCH 07/24] typo --- library/packaging/pkgng | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/packaging/pkgng b/library/packaging/pkgng index ea2c5262793..af1fdf93ef1 100644 --- a/library/packaging/pkgng +++ b/library/packaging/pkgng @@ -140,7 +140,7 @@ def main(): state = dict(default="present", choices=["present","absent"]), name = dict(aliases=["pkg"], required=True), cached = dict(default="no", required=False, choices=["yes","no"]), - pkgsite = dict(default="", required=False)) + pkgsite = dict(default="", required=False)), supports_check_mode = True) pkgin_path = module.get_bin_path('pkg', True) From d133c0aeeec8a7ac2ef0a21830e53881f173a686 Mon Sep 17 00:00:00 2001 From: Blair Zajac Date: Sat, 28 Sep 2013 16:26:08 -0700 Subject: [PATCH 08/24] apt: pass child process stdout and stdout to m.fail_json() and m.exit_json(). Without this, this fails: - name: apt-get dist-upgrade action: apt upgrade=dist register: apt_get_contents - name: apt-get clean action: command apt-get clean when: apt_get_contents.stdout.find("0 upgraded") == -1 TASK: [apt-get clean] ********************************************************* fatal: [192.168.2.2] => error while evaluating conditional: {% if apt_get_contents.stdout.find("0 upgraded") == -1 %} True {% else %} False {% endif %} FATAL: all hosts have already failed -- aborting --- library/packaging/apt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/packaging/apt b/library/packaging/apt index 70cc7e05be0..33ba19b2d46 100644 --- a/library/packaging/apt +++ b/library/packaging/apt @@ -237,9 +237,9 @@ def install(m, pkgspec, cache, upgrade=False, default_release=None, install_reco rc, out, err = m.run_command(cmd) if rc: - m.fail_json(msg="'apt-get install %s' failed: %s" % (packages, err)) + m.fail_json(msg="'apt-get install %s' failed: %s" % (packages, err), stdout=out, stderr=err) else: - m.exit_json(changed=True) + m.exit_json(changed=True, stdout=out, stderr=err) else: m.exit_json(changed=False) @@ -265,8 +265,8 @@ def remove(m, pkgspec, cache, purge=False): rc, out, err = m.run_command(cmd) if rc: - m.fail_json(msg="'apt-get remove %s' failed: %s" % (packages, err)) - m.exit_json(changed=True) + m.fail_json(msg="'apt-get remove %s' failed: %s" % (packages, err), stdout=out, stderr=err) + m.exit_json(changed=True, stdout=out, stderr=err) def upgrade(m, mode="yes", force=False): if m.check_mode: @@ -298,10 +298,10 @@ def upgrade(m, mode="yes", force=False): force_yes, check_arg, upgrade_command) rc, out, err = m.run_command(cmd) if rc: - m.fail_json(msg="'%s %s' failed: %s" % (apt_cmd, upgrade_command, err)) + m.fail_json(msg="'%s %s' failed: %s" % (apt_cmd, upgrade_command, err), stdout=out, stderr=err) if (apt_cmd == APT_GET_CMD and APT_GET_ZERO in out) or (apt_cmd == APTITUDE_CMD and APTITUDE_ZERO in out): - m.exit_json(changed=False, msg=out) - m.exit_json(changed=True, msg=out) + m.exit_json(changed=False, msg=out, stdout=out, stderr=err) + m.exit_json(changed=True, msg=out, stdout=out, stderr=err) def main(): module = AnsibleModule( From 3a8c9f04daf0994fdf0101007e0bce94f590924a Mon Sep 17 00:00:00 2001 From: Blair Zajac Date: Sat, 28 Sep 2013 16:45:19 -0700 Subject: [PATCH 09/24] apt: do not consider not-removed and not-upgraded packages as changes. If one pins a package and does a 'apt-get dist-upgrade' then the output looks like: # apt-get dist-upgrade Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages have been kept back: cassandra 0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded. The check for any changes made should only be on the 'upgraded' and 'newly installed' values and not include the 'to remove' and 'not upgraded' values. --- library/packaging/apt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/packaging/apt b/library/packaging/apt index 70cc7e05be0..a8bb9249548 100644 --- a/library/packaging/apt +++ b/library/packaging/apt @@ -131,8 +131,8 @@ import fnmatch # APT related constants APT_ENVVARS = "DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical" DPKG_OPTIONS = '-o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold"' -APT_GET_ZERO = "0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." -APTITUDE_ZERO = "0 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded." +APT_GET_ZERO = "0 upgraded, 0 newly installed" +APTITUDE_ZERO = "0 packages upgraded, 0 newly installed" APT_LISTS_PATH = "/var/lib/apt/lists" APT_UPDATE_SUCCESS_STAMP_PATH = "/var/lib/apt/periodic/update-success-stamp" From f88fed206029c989759ada7842452afe24cf38f2 Mon Sep 17 00:00:00 2001 From: Brian Harring Date: Mon, 30 Sep 2013 13:20:06 -0400 Subject: [PATCH 10/24] Enforce umask for cron module, so cron_file generated files are 0644. Certain cron implementations get cranky if files in cron.* are group writable. --- library/system/cron | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/system/cron b/library/system/cron index 81e411168b7..04dd065db0b 100644 --- a/library/system/cron +++ b/library/system/cron @@ -426,6 +426,8 @@ def main(): changed = False res_args = dict() + # Ensure all files generated are only writable by the owning user. Primarily relevant for the cron_file option. + os.umask(022) crontab = CronTab(module, user, cron_file) if crontab.syslogging: From a10e017d6e90b5a064fb4ae142f416c4f00ea21c Mon Sep 17 00:00:00 2001 From: Rene Moser Date: Mon, 21 Oct 2013 16:39:18 +0200 Subject: [PATCH 11/24] apt: autoinstall python-apt if not available --- library/packaging/apt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/library/packaging/apt b/library/packaging/apt index 6ab20171866..28c933b694a 100644 --- a/library/packaging/apt +++ b/library/packaging/apt @@ -322,7 +322,13 @@ def main(): ) if not HAS_PYTHON_APT: - module.fail_json(msg="Could not import python modules: apt, apt_pkg. Please install python-apt package.") + try: + module.run_command('apt-get install python-apt -y -q') + global apt, apt_pkg + import apt + import apt_pkg + except: + module.fail_json(msg="Could not import python modules: apt, apt_pkg. Please install python-apt package.") global APTITUDE_CMD APTITUDE_CMD = module.get_bin_path("aptitude", False) From 8f2f8a5b536998843dc6ad6dcdc1613b05f8327b Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Fri, 8 Nov 2013 13:11:15 -0600 Subject: [PATCH 12/24] DRY up dict conversion and fix serialization error --- library/cloud/rax_clb | 54 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/library/cloud/rax_clb b/library/cloud/rax_clb index 76564db59cb..d826d49bdee 100644 --- a/library/cloud/rax_clb +++ b/library/cloud/rax_clb @@ -136,6 +136,30 @@ PROTOCOLS = ['DNS_TCP', 'DNS_UDP', 'FTP', 'HTTP', 'HTTPS', 'IMAPS', 'IMAPv4', 'TCP_CLIENT_FIRST', 'UDP', 'UDP_STREAM', 'SFTP'] +def to_dict(obj): + instance = {} + for key in dir(obj): + value = getattr(obj, key) + if key == 'virtual_ips': + virtual_ips = [] + instance[key] = [] + for vip in value: + vip_dict = {} + for vip_key, vip_value in vars(vip).iteritems(): + if isinstance(vip_value, NON_CALLABLES): + vip_dict[vip_key] = vip_value + instance[key].append(vip_dict) + elif key == 'nodes': + instance[key] = [] + for node in value: + instance[key].append(node.to_dict()) + elif (isinstance(value, NON_CALLABLES) and + not key.startswith('_')): + instance[key] = value + + return instance + + def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol, vip_type, timeout, wait, wait_timeout): for arg in (state, name, port, protocol, vip_type): @@ -210,20 +234,7 @@ def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol, pyrax.utils.wait_for_build(balancer, interval=5, attempts=attempts) balancer.get() - instance = {} - for key, value in vars(balancer).iteritems(): - if key == 'virtual_ips': - virtual_ips = [] - instance[key] = [] - for vip in value: - vip_dict = {} - for vip_key, vip_value in vars(vip).iteritems(): - if isinstance(vip_value, NON_CALLABLES): - vip_dict[vip_key] = vip_value - instance[key].append(vip_dict) - elif (isinstance(value, NON_CALLABLES) and - not key.startswith('_')): - instance[key] = value + instance = to_dict(balancer) result = dict(changed=changed, balancer=instance) @@ -246,20 +257,7 @@ def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol, except Exception, e: module.fail_json(msg='%s' % e.message) - instance = {} - for key, value in vars(balancer).iteritems(): - if key == 'virtual_ips': - virtual_ips = [] - instance[key] = [] - for vip in value: - vip_dict = {} - for vip_key, vip_value in vars(vip).iteritems(): - if isinstance(vip_value, NON_CALLABLES): - vip_dict[vip_key] = vip_value - instance[key].append(vip_dict) - elif (isinstance(value, NON_CALLABLES) and - not key.startswith('_')): - instance[key] = value + instance = to_dict(balancer) if wait: attempts = wait_timeout / 5 From a897bb389cd4606cc63c740d07dbdfc04e2884a7 Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Fri, 8 Nov 2013 13:15:38 -0600 Subject: [PATCH 13/24] Remove unused variable --- library/cloud/rax_clb | 1 - 1 file changed, 1 deletion(-) diff --git a/library/cloud/rax_clb b/library/cloud/rax_clb index d826d49bdee..da8004c212a 100644 --- a/library/cloud/rax_clb +++ b/library/cloud/rax_clb @@ -141,7 +141,6 @@ def to_dict(obj): for key in dir(obj): value = getattr(obj, key) if key == 'virtual_ips': - virtual_ips = [] instance[key] = [] for vip in value: vip_dict = {} From 4013e94cf639d58dd8973d5ad907b7620beb9649 Mon Sep 17 00:00:00 2001 From: James Laska Date: Fri, 8 Nov 2013 14:59:24 -0500 Subject: [PATCH 14/24] Correct documentation URLs --- library/internal/async_status | 5 ++--- library/network/get_url | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/library/internal/async_status b/library/internal/async_status index 865286dd34b..79647da113d 100644 --- a/library/internal/async_status +++ b/library/internal/async_status @@ -24,8 +24,7 @@ DOCUMENTATION = ''' module: async_status short_description: Obtain status of asynchronous task description: - - "This module gets the status of an asynchronous task. See: - U(http://www.ansibleworks.com/docs/playbooks2.html#asynchronous-actions-and-polling)" + - "This module gets the status of an asynchronous task." version_added: "0.5" options: jid: @@ -42,7 +41,7 @@ options: choices: [ "status", "cleanup" ] default: "status" notes: - - See U(http://www.ansibleworks.com/docs/playbooks2.html#asynchronous-actions-and-polling) + - See also U(http://www.ansibleworks.com/docs/playbooks_async.html#asynchronous-actions-and-polling) requirements: [] author: Michael DeHaan ''' diff --git a/library/network/get_url b/library/network/get_url index 35d724febed..d3919da003d 100644 --- a/library/network/get_url +++ b/library/network/get_url @@ -36,7 +36,7 @@ description: the target host, requests will be sent through that proxy. This behaviour can be overridden by setting a variable for this task (see `setting the environment - `_), + `_), or by using the use_proxy option. version_added: "0.6" options: From fe95745a20c7d02933cbb027430b5c6d0ee94517 Mon Sep 17 00:00:00 2001 From: Rob Szewczyk Date: Fri, 8 Nov 2013 17:46:41 -0500 Subject: [PATCH 15/24] Correcting the security group id lookup from the list of security group names --- library/cloud/ec2 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/cloud/ec2 b/library/cloud/ec2 index 09a9a6d1582..5945d930fd4 100644 --- a/library/cloud/ec2 +++ b/library/cloud/ec2 @@ -392,9 +392,7 @@ def create_instances(module, ec2): if group_name: grp_details = ec2.get_all_security_groups() if type(group_name) == list: - # FIXME: this should be a nice list comprehension - # also not py 2.4 compliant - group_id = list(filter(lambda grp: str(grp.id) if str(tmp) in str(grp) else None, grp_details) for tmp in group_name) + group_id = [ str(grp.id) for grp in grp_details if str(grp.name) in group_name ] elif type(group_name) == str: for grp in grp_details: if str(group_name) in str(grp): From bd38e6d92fbfc580b0bfcd396a045d1f176557e2 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 10 Nov 2013 17:57:16 -0500 Subject: [PATCH 16/24] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f20d5e92f5a..516943eaf0c 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ multinode orchestration framework. Read the documentation and more at http://ansibleworks.com/ Many users run straight from the development branch (it's generally fine to do so), but you might also wish to consume a release. You can find -instructions on http://ansibleworks.com/docs/intro_getting_started.html for a variety of platforms. If you want a tarball of the last release, go to -http://ansibleworks.com/releases/ and you can also install with pip (though that will bring in some optional binary dependencies you normally do not need). +instructions [here](on http://ansibleworks.com/docs/intro_getting_started.html) for a variety of platforms. If you want a tarball of the last release, go to +http://ansibleworks.com/releases/ and you can also install with pip. Design Principles ================= From 54c510335af47e9cd9daf5e9237e7e42e1720e18 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 11 Nov 2013 13:23:03 -0500 Subject: [PATCH 17/24] Revert "Revert "Tiny RST link fix in modules documentation"" This reverts commit 658dc7a3661669c15f2b696651ae2522097b44f3. --- docsite/rst/modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docsite/rst/modules.rst b/docsite/rst/modules.rst index 20a72a51d4c..38d0cc04665 100644 --- a/docsite/rst/modules.rst +++ b/docsite/rst/modules.rst @@ -11,7 +11,7 @@ Introduction Ansible ships with a number of modules (called the 'module library') -that can be executed directly on remote hosts or through :doc:`playbooks`. +that can be executed directly on remote hosts or through :doc:`Playbooks `. Users can also write their own modules. These modules can control system resources, like services, packages, or files (anything really), or handle executing system commands. From 9e8eef84e8dd677744dc9384c80a5434eeb36054 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 11 Nov 2013 13:23:27 -0500 Subject: [PATCH 18/24] Revert "Revert "Delete extra word in index.rst"" This reverts commit 85322638909b4f388922d5d2e2dfad7e3ae65e08. --- docsite/rst/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docsite/rst/index.rst b/docsite/rst/index.rst index e292316ab39..96d7ca69b09 100644 --- a/docsite/rst/index.rst +++ b/docsite/rst/index.rst @@ -1,4 +1,3 @@ - Ansible Documentation ===================== @@ -70,7 +69,7 @@ Playbooks Playbooks are Ansible's configuration, deployment, and orchestration language. They can describe a policy you want your remote systems to enforce, or a set of steps in a general IT process. -If Ansible modules are your the tools in your workshop, playbooks are your design plans. +If Ansible modules are the tools in your workshop, playbooks are your design plans. At a basic level, playbooks can be used to manage configurations of and deployments to remote machines. At a more advanced level, they can sequence multi-tier rollouts involving rolling updates, and can delegate actions to other hosts, interacting with monitoring servers and load balancers along the way. From 6e49ee6cfcb83248835db6d9efe61b7f61df2a60 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 11 Nov 2013 14:44:13 -0500 Subject: [PATCH 19/24] Remove commented code block --- lib/ansible/runner/lookup_plugins/password.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/ansible/runner/lookup_plugins/password.py b/lib/ansible/runner/lookup_plugins/password.py index 3949672de93..edf3265d60d 100644 --- a/lib/ansible/runner/lookup_plugins/password.py +++ b/lib/ansible/runner/lookup_plugins/password.py @@ -80,10 +80,7 @@ class LookupModule(object): pathdir = os.path.dirname(path) if not os.path.isdir(pathdir): os.makedirs(pathdir) - """ - chars = ascii_letters + digits + ".,:-_" - password = utils.random_password(length) - """ + chars = "".join([getattr(string,c,c) for c in use_chars]).replace('"','').replace("'",'') password = ''.join(random.choice(chars) for _ in range(length)) From e2b75abb1dda5fd1ff3f7b6b2b5441992146c24d Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 11 Nov 2013 14:54:11 -0500 Subject: [PATCH 20/24] Add char parameter to password lookup plugin docs on docsite --- docsite/rst/playbooks_lookups.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docsite/rst/playbooks_lookups.rst b/docsite/rst/playbooks_lookups.rst index 817e4481013..7178cb06c10 100644 --- a/docsite/rst/playbooks_lookups.rst +++ b/docsite/rst/playbooks_lookups.rst @@ -53,6 +53,32 @@ This length can be changed by passing an extra parameter:: .. note:: If the file already exists, no data will be written to it. If the file has contents, those contents will be read in as the password. Empty files cause the password to return as an empty string +Starting in version 1.4, password accepts a "chars" parameter to allow defining a custom character set in the generated passwords. It accepts comma separated list of names that are either string module attributes (ascii_letters,digits, etc) or are used literally:: + + --- + - hosts: all + + tasks: + + # create a mysql user with a random password using only ascii letters: + - mysql_user: name={{ client }} + password="{{ lookup('password', '/tmp/passwordfile chars=ascii') }}" + priv={{ client }}_{{ tier }}_{{ role }}.*:ALL + + # create a mysql user with a random password using only digits: + - mysql_user: name={{ client }} + password="{{ lookup('password', '/tmp/passwordfile chars=digits,') }}" + priv={{ client }}_{{ tier }}_{{ role }}.*:ALL + + # create a mysql user with a random password using many different char sets: + - mysql_user: name={{ client }} + password="{{ lookup('password', '/tmp/passwordfile chars=ascii,numbers,digits,hexdigits,punctuation') }}" + priv={{ client }}_{{ tier }}_{{ role }}.*:ALL + + (...) + +To enter comma use two commas ',,' somewhere - preferably at the end Qoutes and double qoutes are not supported + .. _more_lookups: More Lookups From 7502e152989461d472f8e0d0bde5b54a14ae7a99 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 11 Nov 2013 22:27:47 -0500 Subject: [PATCH 21/24] Address #4285 remove redundant stderr output in apt module --- library/packaging/apt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/packaging/apt b/library/packaging/apt index ed29e6f3937..5173ce60c75 100644 --- a/library/packaging/apt +++ b/library/packaging/apt @@ -319,7 +319,7 @@ def upgrade(m, mode="yes", force=False, force_yes, check_arg, upgrade_command) rc, out, err = m.run_command(cmd) if rc: - m.fail_json(msg="'%s %s' failed: %s" % (apt_cmd, upgrade_command, err), stdout=out, stderr=err) + m.fail_json(msg="'%s %s' failed: %s" % (apt_cmd, upgrade_command, err), stdout=out) if (apt_cmd == APT_GET_CMD and APT_GET_ZERO in out) or (apt_cmd == APTITUDE_CMD and APTITUDE_ZERO in out): m.exit_json(changed=False, msg=out, stdout=out, stderr=err) m.exit_json(changed=True, msg=out, stdout=out, stderr=err) From aafe7f5b37ac23c345e2ed6ee2c897b0badb29b3 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 11 Nov 2013 23:23:56 -0500 Subject: [PATCH 22/24] Fixes #4877 set type to bool for cache parameter in apt module --- library/packaging/pkgng | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/packaging/pkgng b/library/packaging/pkgng index af1fdf93ef1..dbae01bbb16 100644 --- a/library/packaging/pkgng +++ b/library/packaging/pkgng @@ -139,7 +139,7 @@ def main(): argument_spec = dict( state = dict(default="present", choices=["present","absent"]), name = dict(aliases=["pkg"], required=True), - cached = dict(default="no", required=False, choices=["yes","no"]), + cached = dict(default=False, type='bool'), pkgsite = dict(default="", required=False)), supports_check_mode = True) From 6008ea40ee6b96c037df7cc69bb3397054dc1dda Mon Sep 17 00:00:00 2001 From: James Tanner Date: Tue, 12 Nov 2013 00:02:30 -0500 Subject: [PATCH 23/24] Add more error detail to the service module for FreeBSD --- library/system/service | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/system/service b/library/system/service index 0173031c941..aac7319d753 100644 --- a/library/system/service +++ b/library/system/service @@ -790,9 +790,11 @@ class FreeBsdService(Service): self.rcconf_file = rcfile rc, stdout, stderr = self.execute_command("%s %s %s %s" % (self.svc_cmd, self.name, 'rcvar', self.arguments)) + cmd = "%s %s %s %s" % (self.svc_cmd, self.name, 'rcvar', self.arguments) rcvars = shlex.split(stdout, comments=True) + if not rcvars: - self.module.fail_json(msg="unable to determine rcvar") + self.module.fail_json(msg="unable to determine rcvar", stdout=stdout, stderr=stderr) # In rare cases, i.e. sendmail, rcvar can return several key=value pairs # Usually there is just one, however. In other rare cases, i.e. uwsgi, @@ -805,7 +807,7 @@ class FreeBsdService(Service): break if self.rcconf_key is None: - self.module.fail_json(msg="unable to determine rcvar") + self.module.fail_json(msg="unable to determine rcvar", stdout=stdout, stderr=stderr) return self.service_enable_rcconf() From 48ded5e49337e805ee3a185f2e731cb4ead27ca4 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Tue, 12 Nov 2013 08:54:19 -0500 Subject: [PATCH 24/24] Fix typos in docsite password lookup section --- docsite/rst/playbooks_lookups.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docsite/rst/playbooks_lookups.rst b/docsite/rst/playbooks_lookups.rst index 7178cb06c10..6a69ba230ae 100644 --- a/docsite/rst/playbooks_lookups.rst +++ b/docsite/rst/playbooks_lookups.rst @@ -67,7 +67,7 @@ Starting in version 1.4, password accepts a "chars" parameter to allow defining # create a mysql user with a random password using only digits: - mysql_user: name={{ client }} - password="{{ lookup('password', '/tmp/passwordfile chars=digits,') }}" + password="{{ lookup('password', '/tmp/passwordfile chars=digits') }}" priv={{ client }}_{{ tier }}_{{ role }}.*:ALL # create a mysql user with a random password using many different char sets: @@ -77,7 +77,7 @@ Starting in version 1.4, password accepts a "chars" parameter to allow defining (...) -To enter comma use two commas ',,' somewhere - preferably at the end Qoutes and double qoutes are not supported +To enter comma use two commas ',,' somewhere - preferably at the end. Quotes and double qoutes are not supported. .. _more_lookups: