Esempio n. 1
0
def run_action_with_check_mode(run_check, run_apply, skip_check, quiet=False, always_skip_check=False):
    if always_skip_check:
        user_wants_to_apply = ask(
            'This command will apply without running the check first. Continue?',
            quiet=quiet)
    elif skip_check:
        user_wants_to_apply = ask('Do you want to apply without running the check first?',
                                  quiet=quiet)
    else:
        exit_code = run_check()
        if exit_code == 1:
            # this means there was an error before ansible was able to start running
            return exit_code
        elif exit_code == 0:
            puts(color_success(u"✓ Check completed with status code {}".format(exit_code)))
            user_wants_to_apply = ask('Do you want to apply these changes?',
                                      quiet=quiet)
        else:
            puts(color_error(u"✗ Check failed with status code {}".format(exit_code)))
            user_wants_to_apply = ask('Do you want to try to apply these changes anyway?',
                                      quiet=quiet)

    exit_code = 0
    if user_wants_to_apply:
        exit_code = run_apply()
        if exit_code == 0:
            puts(color_success(u"✓ Apply completed with status code {}".format(exit_code)))
        else:
            puts(color_error(u"✗ Apply failed with status code {}".format(exit_code)))

    return exit_code
Esempio n. 2
0
def describe(migration):
    puts('\nMembership')
    with indent():
        puts(get_membership(migration.target_couch_config).get_printable())
    puts('\nDB Info')
    print_db_info(migration.target_couch_config)

    puts('\nShard allocation')
    diff_with_db = None
    if os.path.exists(migration.shard_plan_path):
        diff_with_db = diff_plan(migration)
        if diff_with_db:
            puts(color_highlight('DB allocation differs from plan:\n'))
            puts("{}\n\n".format(diff_with_db))
        else:
            puts(color_success('DB allocation matches plan.'))

    if not diff_with_db:
        print_shard_table([
            get_shard_allocation(migration.target_couch_config, db_name)
            for db_name in sorted(
                get_db_list(migration.target_couch_config.get_control_node()))
        ])

    puts('\nShard count by node')
    print_shard_allocation_by_node([
        get_shard_allocation(migration.target_couch_config, db_name)
        for db_name in sorted(
            get_db_list(migration.target_couch_config.get_control_node()))
    ])
    return 0
Esempio n. 3
0
def commit(migration, ansible_context):
    print_allocation(migration)
    alloc_docs_by_db = {plan.db_name: plan for plan in migration.shard_plan}
    puts(color_summary("Checking shards on disk vs plan. Please wait."))
    if not assert_files(migration, alloc_docs_by_db, ansible_context):
        puts(color_error("Some shard files are not where we expect. Have you run 'migrate'?"))
        puts(color_error("Aborting"))
        return 1
    else:
        puts(color_success("All shards appear to be where we expect according to the plan."))

    if ask("Are you sure you want to update the Couch Database config?"):
        commit_migration(migration)

        diff_with_db = diff_plan(migration)
        if diff_with_db:
            puts(color_error('DB allocation differs from expected:\n'))
            puts("{}\n\n".format(diff_with_db))
            puts("Check the DB state and logs and maybe try running 'commit' again?")
            return 1

        puts(color_highlight("New shard allocation:\n"))
        print_shard_table([
            get_shard_allocation(migration.target_couch_config, db_name)
            for db_name in sorted(get_db_list(migration.target_couch_config.get_control_node()))
        ])
    return 0
Esempio n. 4
0
def aws_sign_in(aws_profile, duration_minutes=DEFAULT_SIGN_IN_DURATION_MINUTES,
                force_new=False):
    """
    Create a temp session through MFA for a given aws profile

    :param aws_profile: The name of an existing aws profile to create a temp session for
    :param duration_minutes: How long to set the session expiration if a new one is created
    :param force_new: If set to True, creates new credentials even if valid ones are found
    :return: The name of temp session profile.
             (Always the passed in profile followed by ':session')
    """
    aws_session_profile = '{}:session'.format(aws_profile)
    if not force_new \
            and _has_valid_session_credentials(aws_session_profile):
        return aws_session_profile

    default_username = get_default_username()
    if default_username.is_guess:
        username = input("Enter username associated with credentials [{}]: ".format(
            default_username)) or default_username
        print_help_message_about_the_commcare_cloud_default_username_env_var(username)
    else:
        username = default_username
    mfa_token = input("Enter your MFA token: ")
    generate_session_profile(aws_profile, username, mfa_token, duration_minutes)

    puts(color_success(u"✓ Sign in accepted"))
    puts("You will be able to use AWS from the command line for the next {} minutes."
         .format(duration_minutes))
    puts(color_notice(
        "To use this session outside of commcare-cloud, "
        "prefix your command with AWS_PROFILE={}:session".format(aws_profile)))
    return aws_session_profile
 def run(self, args, unknown_args):
     environment = get_environment(args.env_name)
     try:
         environment.check()
     except Exception:
         puts(color_error(u"✗ The environment has the following error:"))
         raise
     else:
         puts(color_success(u"✓ The environment configuration is valid."))
Esempio n. 6
0
    def run(self, args, unknown_args):
        limit = args.limit
        environment = get_environment(args.env_name)
        if limit:
            environment.inventory_manager.subset(limit)

        with open(environment.paths.known_hosts, 'r', encoding='utf-8') as known_hosts:
            original_keys_by_host = _get_host_key_map(
                [line.strip() for line in known_hosts.readlines()]
            )

        procs = {}
        for hostname in environment.inventory_hostname_map:
            port = '22'
            if ':' in hostname:
                hostname, port = hostname.split(':')
            cmd = 'ssh-keyscan -T 10 -p {port} {hostname},$(dig +short {hostname})'.format(
                hostname=hostname,
                port=port
            )
            procs[hostname] = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                               universal_newlines=True)

        lines = []
        error_hosts = set()
        for hostname, proc in procs.items():
            sys.stdout.write('[{}]: '.format(hostname))
            proc.wait()
            error, host_lines = _get_lines(proc)
            if error:
                sys.stdout.write(error)
            else:
                sys.stdout.write(str(color_success('fetched key\n')))
                lines.extend(host_lines)

        updated_keys_by_host = _get_host_key_map(lines)

        all_keys = set(original_keys_by_host) | set(updated_keys_by_host)
        lines = []
        for host_key_type in sorted(all_keys):
            host, key_type = host_key_type
            original = original_keys_by_host.pop(host_key_type, None)
            updated = updated_keys_by_host.get(host_key_type, None)
            if updated and original:
                if updated != original:
                    print(color_changed('Updating key: {} {}'.format(*host_key_type)))
            elif updated:
                print(color_added('Adding key: {} {}'.format(*host_key_type)))
            elif original:
                if limit or host in error_hosts:
                    # if we're limiting or there was an error keep original key
                    updated = original
                else:
                    print(color_removed('Removing key: {} {}'.format(*host_key_type)))

            if updated:
                lines.append('{} {} {}'.format(host, key_type, updated))

        with open(environment.paths.known_hosts, 'w', encoding='utf-8') as known_hosts:
            known_hosts.write('\n'.join(sorted(lines)))

        try:
            environment.check_known_hosts()
        except EnvironmentException as e:
            print(color_error(str(e)))
            return 1
        return 0