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.
This commit is contained in:
parent
05a128c2be
commit
1c81ddf8d4
6 changed files with 38 additions and 8 deletions
|
@ -28,6 +28,7 @@ Ansible Changes By Release
|
||||||
* make remote_md5 internal function work with non-bash shells
|
* make remote_md5 internal function work with non-bash shells
|
||||||
* allow user to be passed in via --extra-vars (regression)
|
* 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 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
|
0.6 "Cabo" -- August 6, 2012
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ def main(args):
|
||||||
|
|
||||||
# create parser for CLI options
|
# create parser for CLI options
|
||||||
usage = "%prog playbook.yml"
|
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,
|
parser.add_option('-e', '--extra-vars', dest="extra_vars", default=None,
|
||||||
help="set additional key=value variables from the CLI")
|
help="set additional key=value variables from the CLI")
|
||||||
parser.add_option('-t', '--tags', dest='tags', default='all',
|
parser.add_option('-t', '--tags', dest='tags', default='all',
|
||||||
|
@ -102,6 +102,7 @@ def main(args):
|
||||||
extra_vars=extra_vars,
|
extra_vars=extra_vars,
|
||||||
private_key_file=options.private_key_file,
|
private_key_file=options.private_key_file,
|
||||||
only_tags=only_tags,
|
only_tags=only_tags,
|
||||||
|
subset=options.subset,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
|
|
@ -35,4 +35,5 @@ DEFAULT_SUDO_USER = os.environ.get('ANSIBLE_SUDO_USER','root')
|
||||||
DEFAULT_REMOTE_PORT = 22
|
DEFAULT_REMOTE_PORT = 22
|
||||||
DEFAULT_TRANSPORT = os.environ.get('ANSIBLE_TRANSPORT','paramiko')
|
DEFAULT_TRANSPORT = os.environ.get('ANSIBLE_TRANSPORT','paramiko')
|
||||||
DEFAULT_TRANSPORT_OPTS = ['local', 'paramiko', 'ssh']
|
DEFAULT_TRANSPORT_OPTS = ['local', 'paramiko', 'ssh']
|
||||||
|
DEFAULT_SUBSET = None
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Inventory(object):
|
||||||
Host inventory for ansible.
|
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' ]
|
'parser', '_vars_per_host', '_vars_per_group', '_hosts_cache' ]
|
||||||
|
|
||||||
def __init__(self, host_list=C.DEFAULT_HOST_LIST):
|
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
|
# a list of host(names) to contain current inquiries to
|
||||||
self._restriction = None
|
self._restriction = None
|
||||||
|
self._subset = None
|
||||||
|
|
||||||
# whether the inventory file is a script
|
# whether the inventory file is a script
|
||||||
self._is_script = False
|
self._is_script = False
|
||||||
|
@ -103,7 +104,9 @@ class Inventory(object):
|
||||||
inverted = False
|
inverted = False
|
||||||
for group in groups:
|
for group in groups:
|
||||||
for host in group.get_hosts():
|
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
|
# must test explicitly for None because [] means no hosts allowed
|
||||||
if self._restriction==None or host.name in self._restriction:
|
if self._restriction==None or host.name in self._restriction:
|
||||||
if inverted:
|
if inverted:
|
||||||
|
@ -187,12 +190,28 @@ class Inventory(object):
|
||||||
def get_restriction(self):
|
def get_restriction(self):
|
||||||
return self._restriction
|
return self._restriction
|
||||||
|
|
||||||
def restrict_to(self, restriction, append_missing=False):
|
def restrict_to(self, restriction):
|
||||||
""" Restrict list operations to the hosts given in 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:
|
if type(restriction) != list:
|
||||||
restriction = [ restriction ]
|
restriction = [ restriction ]
|
||||||
self._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):
|
def lift_restriction(self):
|
||||||
""" Do not restrict list operations """
|
""" Do not restrict list operations """
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,8 @@ class PlayBook(object):
|
||||||
sudo = False,
|
sudo = False,
|
||||||
sudo_user = C.DEFAULT_SUDO_USER,
|
sudo_user = C.DEFAULT_SUDO_USER,
|
||||||
extra_vars = None,
|
extra_vars = None,
|
||||||
only_tags = None):
|
only_tags = None,
|
||||||
|
subset = C.DEFAULT_SUBSET):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
playbook: path to a playbook file
|
playbook: path to a playbook file
|
||||||
|
@ -105,6 +106,7 @@ class PlayBook(object):
|
||||||
self.only_tags = only_tags
|
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:
|
if not self.inventory._is_script:
|
||||||
self.global_vars.update(self.inventory.get_group_variables('all'))
|
self.global_vars.update(self.inventory.get_group_variables('all'))
|
||||||
|
|
|
@ -336,7 +336,8 @@ def increment_debug(option, opt, value, parser):
|
||||||
global VERBOSITY
|
global VERBOSITY
|
||||||
VERBOSITY += 1
|
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 '''
|
''' create an options parser for any ansible script '''
|
||||||
|
|
||||||
parser = SortedOptParser(usage, version=version("%prog"))
|
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',
|
parser.add_option('-M', '--module-path', dest='module_path',
|
||||||
help="specify path(s) to module library (default=%s)" % constants.DEFAULT_MODULE_PATH,
|
help="specify path(s) to module library (default=%s)" % constants.DEFAULT_MODULE_PATH,
|
||||||
default=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',
|
parser.add_option('-T', '--timeout', default=constants.DEFAULT_TIMEOUT, type='int',
|
||||||
dest='timeout',
|
dest='timeout',
|
||||||
help="override the SSH timeout in seconds (default=%s)" % constants.DEFAULT_TIMEOUT)
|
help="override the SSH timeout in seconds (default=%s)" % constants.DEFAULT_TIMEOUT)
|
||||||
|
|
Loading…
Reference in a new issue