From 9df612f00742f824fdb1e128c852ffcee76b0c9a Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sat, 24 Mar 2012 16:19:38 -0400 Subject: [PATCH] Add a "-o" override option so hosts not in a playbook can still be managed by a playbook. --- bin/ansible-playbook | 8 +++++++- lib/ansible/playbook.py | 45 ++++++++++++++++++++++++----------------- lib/ansible/runner.py | 7 ++++++- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/bin/ansible-playbook b/bin/ansible-playbook index 111a753a29..d9c6d38e35 100755 --- a/bin/ansible-playbook +++ b/bin/ansible-playbook @@ -50,6 +50,8 @@ def main(args): help="ask for SSH password") parser.add_option("-M", "--module-path", dest="module_path", help="path to module library", default=C.DEFAULT_MODULE_PATH) + parser.add_option('-o', '--override-hosts', dest="override_hosts", default=None, + help="run playbook against these hosts regardless of inventory settings") parser.add_option('-T', '--timeout', default=C.DEFAULT_TIMEOUT, type='int', dest='timeout', help="set the SSH timeout in seconds") @@ -62,6 +64,9 @@ def main(args): sshpass = None if options.ask_pass: sshpass = getpass.getpass(prompt="SSH password: ") + override_hosts = None + if options.override_hosts: + override_hosts = options.override_hosts.split(",") # run all playbooks specified on the command line for playbook in args: @@ -73,7 +78,8 @@ def main(args): verbose=True, remote_pass=sshpass, callbacks=callbacks.PlaybookCallbacks(), - timeout=options.timeout + timeout=options.timeout, + override_hosts=override_hosts, ) try: results = pb.run() diff --git a/lib/ansible/playbook.py b/lib/ansible/playbook.py index 3e024f6267..8197ba6a9e 100755 --- a/lib/ansible/playbook.py +++ b/lib/ansible/playbook.py @@ -47,24 +47,26 @@ class PlayBook(object): # ***************************************************** def __init__(self, - playbook =None, - host_list =C.DEFAULT_HOST_LIST, - module_path =C.DEFAULT_MODULE_PATH, - forks =C.DEFAULT_FORKS, - timeout =C.DEFAULT_TIMEOUT, - remote_user =C.DEFAULT_REMOTE_USER, - remote_pass =C.DEFAULT_REMOTE_PASS, - verbose=False, - callbacks=None): + playbook = None, + host_list = C.DEFAULT_HOST_LIST, + module_path = C.DEFAULT_MODULE_PATH, + forks = C.DEFAULT_FORKS, + timeout = C.DEFAULT_TIMEOUT, + remote_user = C.DEFAULT_REMOTE_USER, + remote_pass = C.DEFAULT_REMOTE_PASS, + override_hosts = None, + verbose = False, + callbacks = None): - self.host_list = host_list - self.module_path = module_path - self.forks = forks - self.timeout = timeout - self.remote_user = remote_user - self.remote_pass = remote_pass - self.verbose = verbose - self.callbacks = callbacks + self.host_list = host_list + self.module_path = module_path + self.forks = forks + self.timeout = timeout + self.remote_user = remote_user + self.remote_pass = remote_pass + self.verbose = verbose + self.callbacks = callbacks + self.override_hosts = override_hosts self.callbacks.set_playbook(self) # store the list of changes/invocations/failure counts @@ -83,7 +85,8 @@ class PlayBook(object): self.basedir = os.path.dirname(playbook) self.playbook = self._parse_playbook(playbook) - self.host_list, self.groups = ansible.runner.Runner.parse_hosts(host_list) + self.host_list, self.groups = ansible.runner.Runner.parse_hosts( + host_list, override_hosts=self.override_hosts) # ***************************************************** @@ -499,7 +502,11 @@ class PlayBook(object): ''' run a list of tasks for a given pattern, in order ''' # get configuration information about the pattern - pattern = pg['hosts'] + pattern = pg.get('hosts',None) + if self.override_hosts: + pattern = 'all' + if pattern is None: + raise errors.AnsibleError('hosts declaration is required') vars = self._get_vars(pg, self.basedir) vars_files = pg.get('vars_files', {}) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 9b9e8d897e..c64fa38686 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -149,9 +149,14 @@ class Runner(object): # ***************************************************** @classmethod - def parse_hosts(cls, host_list): + def parse_hosts(cls, host_list, override_hosts=None): ''' parse the host inventory file, returns (hosts, groups) ''' + if override_hosts is not None: + if type(override_hosts) != list: + raise errors.AnsibleError("override hosts must be a list") + return (override_hosts, dict(ungrouped=override_hosts)) + if type(host_list) == list: raise Exception("function can only be called on inventory files")