ansible/bin/ansible-playbook
2012-07-24 14:39:45 +02:00

171 lines
5.4 KiB
Python
Executable file

#!/usr/bin/env python
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#######################################################
import os
import sys
import getpass
import ansible.playbook
import ansible.constants as C
from ansible import errors
from ansible import callbacks
from ansible import utils
ANSIBLE_COLOR=True
if os.getenv("ANSIBLE_NOCOLOR") is not None:
ANSIBLE_COLOR=False
if not sys.stdout.isatty():
ANSIBLE_COLOR=False
# --- begin "pretty"
#
# pretty - A miniature library that provides a Python print and stdout
# wrapper that makes colored terminal text easier to use (eg. without
# having to mess around with ANSI escape sequences). This code is public
# domain - there is no license except that you must leave this header.
#
# Copyright (C) 2008 Brian Nez <thedude at bri1 dot com>
#
# http://nezzen.net/2008/06/23/colored-text-in-python-using-ansi-escape-sequences/
codeCodes = {
'black': '0;30', 'bright gray': '0;37',
'blue': '0;34', 'white': '1;37',
'green': '0;32', 'bright blue': '1;34',
'cyan': '0;36', 'bright green': '1;32',
'red': '0;31', 'bright cyan': '1;36',
'purple': '0;35', 'bright red': '1;31',
'yellow': '0;33', 'bright purple': '1;35',
'dark gray': '1;30', 'bright yellow': '1;33',
'normal': '0'
}
def stringc(text, color):
"""String in color."""
if ANSIBLE_COLOR:
return "\033["+codeCodes[color]+"m"+text+"\033[0m"
else:
return text
# --- end "pretty"
def colorize(lead, num, color):
"""Print `lead' = `num' in `color'"""
if num == 0:
color='black';
if ANSIBLE_COLOR:
return "%s%s%-15s" % (stringc(lead, color), stringc("=", color), stringc(str(num), color))
else:
return "%s=%-4s" % (lead, str(num))
def hostcolor(host, t):
if ANSIBLE_COLOR:
if t['failures'] != 0 or t['unreachable'] != 0:
return "%-41s" % stringc(host, 'red')
return "%-30s" % host
def main(args):
''' run ansible-playbook operations '''
# create parser for CLI options
usage = "%prog playbook.yml"
parser = utils.base_parser(constants=C, usage=usage, connect_opts=True, runas_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',
help="only run plays and tasks tagged with these values")
options, args = parser.parse_args(args)
if len(args) == 0:
parser.print_help(file=sys.stderr)
return 1
sshpass = None
sudopass = None
if options.ask_pass:
sshpass = getpass.getpass(prompt="SSH password: ")
if options.ask_sudo_pass:
sudopass = getpass.getpass(prompt="sudo password: ")
options.sudo = True
if options.sudo_user:
options.sudo = True
options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
extra_vars = utils.parse_kv(options.extra_vars)
only_tags = options.tags.split(",")
# run all playbooks specified on the command line
for playbook in args:
stats = callbacks.AggregateStats()
playbook_cb = callbacks.PlaybookCallbacks(verbose=options.verbose)
runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=options.verbose)
pb = ansible.playbook.PlayBook(
playbook=playbook,
module_path=options.module_path,
host_list=options.inventory,
forks=options.forks,
verbose=options.verbose,
remote_user=options.remote_user,
remote_pass=sshpass,
callbacks=playbook_cb,
runner_callbacks=runner_cb,
stats=stats,
timeout=options.timeout,
transport=options.connection,
sudo=options.sudo,
sudo_user=options.sudo_user,
sudo_pass=sudopass,
extra_vars=extra_vars,
private_key_file=options.private_key_file,
only_tags=only_tags,
)
try:
pb.run()
hosts = sorted(pb.stats.processed.keys())
print callbacks.banner("PLAY RECAP")
for h in hosts:
t = pb.stats.summarize(h)
print "%-30s : %s %s %s %s " % (
hostcolor(h, t),
colorize('ok', t['ok'], 'green'),
colorize('changed', t['changed'], 'yellow'),
colorize('unreachable', t['unreachable'], 'red'),
colorize('failed', t['failures'], 'red'))
print "\n"
except errors.AnsibleError, e:
print >>sys.stderr, "ERROR: %s" % e
return 1
return 0
if __name__ == "__main__":
try:
sys.exit(main(sys.argv[1:]))
except errors.AnsibleError, e:
print >>sys.stderr, "ERROR: %s" % e
sys.exit(1)