Esempio n. 1
0
def main():
    (cred, args, inventory) = init()

    all_hosts = utils.get_all_hosts(args.inventory, pattern=args.servers)
    if 'localhost' in all_hosts:
        all_hosts.remove('localhost')

    if len(all_hosts) == 0:
        logger.error("Error: No hosts have been selected")
        exit(1)

    vars = utils.load_group_vars('all', args.inventory)
    if not args.force and 'FORCE' in vars:
        args.force = vars['FORCE']

    start_time = time.time()

    # Handle the action if we have one
    if args.action:
        if 'DNS_PROVIDER' in vars:
            args.dns = vars['DNS_PROVIDER']
        if 'PROVIDER' in vars:
            args.provider = vars['PROVIDER']
        if (cred is None) and (args.provider != 'vagrant'):
            logger.warning("Warning: provider credentials file not found (%s). You may not run actions." % SECRET_FILE)
            exit(1)

        logger.info("Executing [%s] for platform [%s] on servers %s on %d server(s)" % (args.action, args.provider, args.servers, len(all_hosts)))
        if not args.force:
            if not utils.prompt("Are you sure?"):
                return

        # Load the VM module
        try:
            vm_mod = import_module("vmbuilder.vm.vm_%s" % args.provider)
            if not args.action.startswith('dns'):
                vm_action = getattr(vm_mod, "%s" % args.action)
        except Exception as e:
            logger.error("Error loading provider [%s]: %s" % (args.provider, e))
            exit(1)

        # Load the DNS module
        if args.dns or args.action.startswith('dns'):
            try:
                dns_mod = import_module("vmbuilder.dns.dns_%s" % args.dns)
                dnsupdate = getattr(dns_mod, "%s" % 'dnsupdate')
                dnsremove = getattr(dns_mod, "%s" % 'dnsremove')
                if args.action.startswith('dns'):
                    dnsaction = getattr(dns_mod, "%s" % args.action)
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                logger.error("Error loading DNS provider [%s]: %s (%s:%s)" % (args.dns, e, fname, exc_tb.tb_lineno))
                exit(1)

        # If action is for the DNS provider
        if args.dns and args.action.startswith('dns'):
            try:
                vm_getip = getattr(vm_mod, "%s" % 'getip')
                ips = vm_getip(all_hosts, cred, args.dry)
                dnsaction(all_hosts, cred, ips, args.dry, args.inventory)
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                logger.error("Error executing action [%s] with DNS provider [%s]: %s (%s:%s)" % (args.action, args.dns, e, fname, exc_tb.tb_lineno))
                exit(1)
        # Provider now
        else:
            # use the provider module
            try:
                ips = vm_action(all_hosts, cred, args.dry, args.inventory)
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
                logger.error("Error executing action [%s] with provider [%s]: %s (%s:%s)" % (args.action, args.provider, e, fname, exc_tb.tb_lineno))
                exit(1)

            # On build update DNS
            if (args.action == 'build'):
                if args.dns:
                    dnsupdate(all_hosts, cred, ips, args.dry)
                args.playbook = 'bootstrap'
                vault = False
                if vars['ENVIRONMENT'] == 'production':
                    vault = True
                playbook(args.servers, args, 'bootstrap', args.dry, inventory=args.inventory, sudo=False, vault=vault)

            # On destroy remove DNS entries
            if (args.action == 'destroy') and args.dns:
                for h in all_hosts:
                    utils.runcmd("ssh-keygen -R %s 2> /dev/null" % h)
                    cur_ip = None
                    if ips is not None and h in ips and 'private_ip_address' in ips[h]:
                        cur_ip = ips[h]['private_ip_address']
                    if cur_ip is not None:
                        utils.runcmd("ssh-keygen -R %s 2> /dev/null" % cur_ip)
                if args.dns:
                    dnsremove(all_hosts, cred, ips, args.dry)

    # If we have a playbook, play it
    if not args.action and args.playbook:
        logger.info("Running playbook [%s] on group [%s] %d server(s)" % (args.playbook, args.servers, len(all_hosts)))
        if not args.force:
            if not utils.prompt("Are you sure? "):
                return
        vault = False
        if vars['ENVIRONMENT'] == 'production':
            vault = True
        playbook(args.servers, args, args.playbook, args.dry, inventory=args.inventory, vault=vault)

    end_time = time.time()
    logger.info("Time elapsed: %s" % utils.humanize_time(end_time - start_time))
Esempio n. 2
0
def init():
    if '--version' in sys.argv:
        print("vmbuilder version %s" % (VERSION))
        exit(0)

    if not os.path.exists("%s/%s" % (utils.ANSIBLE_DIR, 'group_vars/all')):
        print("ERROR: Maybe this not a vmbuilder path")
        exit(1)

    # Load config from group_vars/all
    cfg = utils.load_group_vars('all', inventory='hosts')

    # Make sure hosts inventory exists
    inventory = 'hosts'
    if 'inventory' in cfg:
        inventory = cfg['inventory']
    if not os.path.exists("%s/%s" % (utils.ANSIBLE_DIR, inventory)):
        print("ERROR: No inventory found (hosts file).")
        exit(1)

    # If providers secrets exist, load them
    cred = utils.load_vars(SECRET_FILE)

    def_play = cfg['playbook'] if 'playbook' in cfg else None
    p1 = glob.glob("%s/*.yml" % utils.ANSIBLE_DIR)
    p2 = [fn.replace('.yml', '') for fn in p1] + p1
    playbooks = [fn.replace(utils.ANSIBLE_DIR + '/', '') for fn in p2]
    playbooks.remove('bootstrap')

    # Create the argument parser
    parser = argparse.ArgumentParser(prog='vmbuilder.py')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-a', dest="action", choices=ACTIONS)
    group.add_argument('-p', dest="playbook", choices=playbooks, default=def_play)
    parser.add_argument('-i', dest="inventory", default='hosts')
    parser.add_argument('-t', dest="tags")
    parser.add_argument('-e', dest="vars")
    parser.add_argument('-l', dest="servers", default='all')
    parser.add_argument('-v', dest="verbal", action="store_true")
    parser.add_argument('-f', dest="force", action="store_true")
    parser.add_argument('-d', dest="dry", action="store_true")
    parser.add_argument('-x', dest="extra")
    args = parser.parse_args()

    # Make sure the logger is on the right level
    if args.verbal:
        createLogger(logging.DEBUG)
    else:
        createLogger(logging.INFO)

    # No playbook and no action
    if (args.playbook is None) and (args.action is None):
        logger.error("You need an action or a playbook. Please provide one!")
        exit(1)

    if (args.playbook is not None) and args.playbook.endswith('.yml'):
        args.playbook = args.playbook[:-4]

    if args.tags is not None:
        args.tags = args.tags.split(',')

    fnextra = EXTRAVARS_OVERRIDE_FILE.format(host=platform.node())
    if os.path.exists(fnextra):
        extravars = utils.load_vars(fnextra)
        if args.vars is None:
            args.vars = ''
        else:
            args.vars += ' '
        for k in extravars:
            args.vars += "%s='%s' " % (k, extravars[k])

    return (cred, args, inventory)