Commit 1c81ddf8 by Michael DeHaan

add the limit option, which can be used to further confine the patterns selected…

add the limit option, which can be used to further confine the patterns selected by "hosts:" in ansible-playbooks
to an additional pattern (a subset) specified on the command line.  For instance, a playbook could be reusable
and target "webservers" and "dbservers", but you want to test only in the stage environment, or a few boxes at a time.
parent 05a128c2
......@@ -28,6 +28,7 @@ Ansible Changes By Release
* make remote_md5 internal function work with non-bash shells
* allow user to be passed in via --extra-vars (regression)
* add ability to store the result of any command in a register (see examples/playbooks/register_logic.yml)
* add --limit option, which can be used to further confine the pattern given in ansible-playbooks
0.6 "Cabo" -- August 6, 2012
......
......@@ -52,7 +52,7 @@ def main(args):
# create parser for CLI options
usage = "%prog playbook.yml"
parser = utils.base_parser(constants=C, usage=usage, connect_opts=True, runas_opts=True)
parser = utils.base_parser(constants=C, usage=usage, connect_opts=True, runas_opts=True, subset_opts=True)
parser.add_option('-e', '--extra-vars', dest="extra_vars", default=None,
help="set additional key=value variables from the CLI")
parser.add_option('-t', '--tags', dest='tags', default='all',
......@@ -102,6 +102,7 @@ def main(args):
extra_vars=extra_vars,
private_key_file=options.private_key_file,
only_tags=only_tags,
subset=options.subset,
)
try:
......
......@@ -35,4 +35,5 @@ DEFAULT_SUDO_USER = os.environ.get('ANSIBLE_SUDO_USER','root')
DEFAULT_REMOTE_PORT = 22
DEFAULT_TRANSPORT = os.environ.get('ANSIBLE_TRANSPORT','paramiko')
DEFAULT_TRANSPORT_OPTS = ['local', 'paramiko', 'ssh']
DEFAULT_SUBSET = None
......@@ -34,7 +34,7 @@ class Inventory(object):
Host inventory for ansible.
"""
__slots__ = [ 'host_list', 'groups', '_restriction', '_is_script',
__slots__ = [ 'host_list', 'groups', '_restriction', '_subset', '_is_script',
'parser', '_vars_per_host', '_vars_per_group', '_hosts_cache' ]
def __init__(self, host_list=C.DEFAULT_HOST_LIST):
......@@ -55,6 +55,7 @@ class Inventory(object):
# a list of host(names) to contain current inquiries to
self._restriction = None
self._subset = None
# whether the inventory file is a script
self._is_script = False
......@@ -103,7 +104,9 @@ class Inventory(object):
inverted = False
for group in groups:
for host in group.get_hosts():
if self._match(group.name, pat) or pat == 'all' or self._match(host.name, pat):
if self._subset and host.name not in self._subset:
continue
if pat == 'all' or self._match(group.name, pat) or self._match(host.name, pat):
# must test explicitly for None because [] means no hosts allowed
if self._restriction==None or host.name in self._restriction:
if inverted:
......@@ -187,12 +190,28 @@ class Inventory(object):
def get_restriction(self):
return self._restriction
def restrict_to(self, restriction, append_missing=False):
""" Restrict list operations to the hosts given in restriction """
def restrict_to(self, restriction):
"""
Restrict list operations to the hosts given in restriction. This is used
to exclude failed hosts in main playbook code, don't use this for other
reasons.
"""
if type(restriction) != list:
restriction = [ restriction ]
self._restriction = restriction
def subset(self, subset_pattern):
"""
Limits inventory results to a subset of inventory that matches a given
pattern, such as to select a given geographic of numeric slice amongst
a previous 'hosts' selection that only select roles, or vice versa.
Corresponds to --limit parameter to ansible-playbook
"""
if subset_pattern is None:
self._subset = None
else:
self._subset = self.list_hosts(subset_pattern)
def lift_restriction(self):
""" Do not restrict list operations """
......
......@@ -57,7 +57,8 @@ class PlayBook(object):
sudo = False,
sudo_user = C.DEFAULT_SUDO_USER,
extra_vars = None,
only_tags = None):
only_tags = None,
subset = C.DEFAULT_SUBSET):
"""
playbook: path to a playbook file
......@@ -104,7 +105,8 @@ class PlayBook(object):
self.private_key_file = private_key_file
self.only_tags = only_tags
self.inventory = ansible.inventory.Inventory(host_list)
self.inventory = ansible.inventory.Inventory(host_list)
self.inventory.subset(subset)
if not self.inventory._is_script:
self.global_vars.update(self.inventory.get_group_variables('all'))
......
......@@ -336,7 +336,8 @@ def increment_debug(option, opt, value, parser):
global VERBOSITY
VERBOSITY += 1
def base_parser(constants=C, usage="", output_opts=False, runas_opts=False, async_opts=False, connect_opts=False):
def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
async_opts=False, connect_opts=False, subset_opts=False):
''' create an options parser for any ansible script '''
parser = SortedOptParser(usage, version=version("%prog"))
......@@ -357,6 +358,11 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False, asyn
parser.add_option('-M', '--module-path', dest='module_path',
help="specify path(s) to module library (default=%s)" % constants.DEFAULT_MODULE_PATH,
default=constants.DEFAULT_MODULE_PATH)
if subset_opts:
parser.add_option('-l', '--limit', default=constants.DEFAULT_SUBSET, dest='subset',
help='further limit selected hosts to an additional pattern')
parser.add_option('-T', '--timeout', default=constants.DEFAULT_TIMEOUT, type='int',
dest='timeout',
help="override the SSH timeout in seconds (default=%s)" % constants.DEFAULT_TIMEOUT)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment