Exemplo n.º 1
0
    def ansible_playbook(environment, playbook, *cmd_args):
        if os.path.isabs(playbook):
            playbook_path = playbook
        else:
            playbook_path = os.path.join(ANSIBLE_DIR, '{playbook}'.format(playbook=playbook))
        cmd_parts = (
            'ansible-playbook',
            playbook_path,
            '-i', environment.paths.inventory_source,
            '-e', '@{}'.format(environment.paths.vault_yml),
            '-e', '@{}'.format(environment.paths.public_yml),
            '-e', '@{}'.format(environment.paths.generated_yml),
            '--diff',
        ) + get_limit() + cmd_args

        public_vars = environment.public_vars
        cmd_parts += get_user_arg(public_vars, unknown_args, use_factory_auth)

        if has_arg(unknown_args, '-D', '--diff') or has_arg(unknown_args, '-C', '--check'):
            puts(colored.red("Options --diff and --check not allowed. Please remove -D, --diff, -C, --check."))
            puts("These ansible-playbook options are managed automatically by commcare-cloud and cannot be set manually.")
            return 2  # exit code

        ask_vault_pass = public_vars.get('commcare_cloud_use_vault', True)
        if ask_vault_pass:
            cmd_parts += ('--vault-password-file={}/echo_vault_password.sh'.format(ANSIBLE_DIR),)

        cmd_parts_with_common_ssh_args = get_common_ssh_args(environment, use_factory_auth=use_factory_auth)
        cmd_parts += cmd_parts_with_common_ssh_args
        cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
        print_command(cmd)
        env_vars = ansible_context.env_vars
        if ask_vault_pass:
            env_vars['ANSIBLE_VAULT_PASSWORD'] = environment.get_ansible_vault_password()
        return subprocess.call(cmd_parts, env=env_vars)
Exemplo n.º 2
0
def exec_fab_command(env_name, *extra_args):
    cmd_parts = (
        'fab', '-f', FABFILE,
        env_name,
    ) + tuple(extra_args)
    cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
    print_command(cmd)
    return subprocess.call(cmd_parts)
Exemplo n.º 3
0
 def run(self, args, ssh_args):
     address = self.lookup_server_address(args)
     if ':' in address:
         address, port = address.split(':')
         ssh_args = ['-p', port] + ssh_args
     cmd_parts = [self.command, address] + ssh_args
     cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
     print_command(cmd)
     return subprocess.call(cmd_parts)
Exemplo n.º 4
0
def check_output(cmd_parts, env):

    env_vars = os.environ.copy()
    env_vars.update(env)
    cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
    print_command('{} {}'.format(
        ' '.join('{}={}'.format(key, value) for key, value in env.items()),
        cmd,
    ))
    return subprocess.check_output(cmd_parts, env=env_vars)
Exemplo n.º 5
0
def run_on_control_instead(args, sys_argv):
    argv = [arg for arg in sys_argv][1:]
    argv.remove('--control')
    executable = 'commcare-cloud'
    branch = getattr(args, 'branch', 'master')
    cmd_parts = [
        executable, args.env_name, 'ssh', 'control', '-t',
        'source ~/init-ansible && git fetch --prune && git checkout {branch} '
        '&& git reset --hard origin/{branch} && source ~/init-ansible && {cchq} {cchq_args}'
        .format(branch=branch, cchq=executable, cchq_args=' '.join([shlex_quote(arg) for arg in argv]))
    ]

    print_command(' '.join([shlex_quote(part) for part in cmd_parts]))
    os.execvp(executable, cmd_parts)
Exemplo n.º 6
0
    def run(self, args, unknown_args):
        environment = get_environment(args.env_name)
        run_dir = environment.paths.get_env_file_path('.generated-terraform')
        modules_dir = os.path.join(TERRAFORM_DIR, 'modules')
        modules_dest = os.path.join(run_dir, 'modules')
        if not os.path.isdir(run_dir):
            os.mkdir(run_dir)
        if not os.path.isdir(run_dir):
            os.mkdir(run_dir)
        if not (os.path.exists(modules_dest) and os.readlink(modules_dest) == modules_dir):
            os.symlink(modules_dir, modules_dest)

        if args.username != get_default_username():
            print_help_message_about_the_commcare_cloud_default_username_env_var(args.username)

        key_name = args.username

        try:
            generate_terraform_entrypoint(environment, key_name, run_dir,
                                          apply_immediately=args.apply_immediately)
        except UnauthorizedUser as e:
            allowed_users = environment.users_config.dev_users.present
            puts(colored.red(
                "Unauthorized user {}.\n\n"
                "Use COMMCARE_CLOUD_DEFAULT_USERNAME or --username to pass in one of the allowed ssh users:{}"
                .format(e.username, '\n  - '.join([''] + allowed_users))))
            return -1

        if not args.skip_secrets and unknown_args and unknown_args[0] in ('plan', 'apply'):
            rds_password = (
                environment.get_vault_variables()['secrets']['POSTGRES_USERS']['root']['password']
                if environment.terraform_config.rds_instances
                else ''
            )

            with open(os.path.join(run_dir, 'secrets.auto.tfvars'), 'w') as f:
                print('rds_password = {}'.format(json.dumps(rds_password)), file=f)

        env_vars = {'AWS_PROFILE': aws_sign_in(environment.terraform_config.aws_profile)}
        all_env_vars = os.environ.copy()
        all_env_vars.update(env_vars)
        cmd_parts = ['terraform'] + unknown_args
        cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
        print_command('cd {}; {} {}; cd -'.format(
            run_dir,
            ' '.join('{}={}'.format(key, value) for key, value in env_vars.items()),
            cmd,
        ))
        return subprocess.call(cmd, shell=True, env=all_env_vars, cwd=run_dir)
Exemplo n.º 7
0
    def run(self, args, unknown_args):
        env = os.environ.copy()
        put_virtualenv_bin_on_the_path()
        if not os.path.exists(ANSIBLE_ROLES_PATH):
            os.makedirs(ANSIBLE_ROLES_PATH)

        env['ANSIBLE_ROLES_PATH'] = ANSIBLE_ROLES_PATH
        cmd_parts = ['ansible-galaxy', 'install', '-f', '-r', os.path.join(ANSIBLE_DIR, 'requirements.yml')]
        cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
        print_command(cmd)
        p = subprocess.Popen(cmd, stdin=subprocess.PIPE, shell=True, env=env)
        p.communicate()

        puts(colored.blue("To finish first-time installation, run `manage-commcare-cloud configure`".format()))
        return p.returncode
Exemplo n.º 8
0
def run_ansible_module(environment, ansible_context, inventory_group, module, module_args,
                       become, become_user, factory_auth, *extra_args):
    cmd_parts = (
        'ansible', inventory_group,
        '-m', module,
        '-i', environment.paths.inventory_source,
        '-a', module_args,
        '--diff',
    ) + tuple(extra_args)

    environment.create_generated_yml()
    public_vars = environment.public_vars
    cmd_parts += get_user_arg(public_vars, extra_args, use_factory_auth=factory_auth)
    become = become or bool(become_user)
    become_user = become_user
    include_vars = False
    if become:
        cmd_parts += ('--become',)
        include_vars = True
        if become_user:
            cmd_parts += ('--become-user', become_user)

    if include_vars:
        cmd_parts += (
            '-e', '@{}'.format(environment.paths.vault_yml),
            '-e', '@{}'.format(environment.paths.public_yml),
            '-e', '@{}'.format(environment.paths.generated_yml),
        )

    ask_vault_pass = include_vars and public_vars.get('commcare_cloud_use_vault', True)
    if ask_vault_pass:
        cmd_parts += ('--vault-password-file={}/echo_vault_password.sh'.format(ANSIBLE_DIR),)
    cmd_parts_with_common_ssh_args = get_common_ssh_args(environment, use_factory_auth=factory_auth)
    cmd_parts += cmd_parts_with_common_ssh_args
    cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
    print_command(cmd)
    env_vars = ansible_context.env_vars
    if ask_vault_pass:
        env_vars['ANSIBLE_VAULT_PASSWORD'] = environment.get_ansible_vault_password()
    return subprocess.call(cmd_parts, env=env_vars)
Exemplo n.º 9
0
def run_ansible_module(environment,
                       ansible_context,
                       inventory_group,
                       module,
                       module_args,
                       become=True,
                       become_user=None,
                       use_factory_auth=False,
                       quiet=False,
                       extra_args=()):
    extra_args = tuple(extra_args)
    if not quiet:
        extra_args = ("--diff", ) + extra_args
    else:
        extra_args = ("--one-line", ) + extra_args

    cmd_parts = (
        'ansible',
        inventory_group,
        '-m',
        module,
        '-i',
        environment.paths.inventory_source,
        '-a',
        module_args,
    ) + extra_args

    environment.create_generated_yml()
    public_vars = environment.public_vars
    cmd_parts += get_user_arg(public_vars,
                              extra_args,
                              use_factory_auth=use_factory_auth)
    become = become or bool(become_user)
    become_user = become_user
    needs_secrets = False
    env_vars = ansible_context.env_vars

    if become:
        cmd_parts += ('--become', )
        needs_secrets = True
        if become_user:
            cmd_parts += ('--become-user', become_user)

    if needs_secrets:
        cmd_parts += (
            '-e',
            '@{}'.format(environment.paths.public_yml),
            '-e',
            '@{}'.format(environment.paths.generated_yml),
        )
        cmd_parts += environment.secrets_backend.get_extra_ansible_args()
        env_vars.update(
            environment.secrets_backend.get_extra_ansible_env_vars())

    cmd_parts_with_common_ssh_args = get_common_ssh_args(
        environment, use_factory_auth=use_factory_auth)
    cmd_parts += cmd_parts_with_common_ssh_args
    cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
    if not quiet:
        print_command(cmd)
    return subprocess.call(cmd_parts, env=env_vars)
 def run(self, args, unknown_args):
     if unknown_args:
         sys.stderr.write(
             "Ignoring extra argument(s): {}\n".format(unknown_args))
     print_command(self.lookup_server_address(args))
Exemplo n.º 11
0
    def run(self, args, unknown_args):
        if 'destroy' in unknown_args:
            puts(
                color_error(
                    "Refusing to run a terraform command containing the argument 'destroy'."
                ))
            puts(color_error("It's simply not worth the risk."))
            exit(-1)

        environment = get_environment(args.env_name)
        run_dir = environment.paths.get_env_file_path('.generated-terraform')
        modules_dir = os.path.join(TERRAFORM_DIR, 'modules')
        modules_dest = os.path.join(run_dir, 'modules')
        if not os.path.isdir(run_dir):
            os.mkdir(run_dir)
        if not os.path.isdir(run_dir):
            os.mkdir(run_dir)
        if not (os.path.exists(modules_dest)
                and os.readlink(modules_dest) == modules_dir):
            os.symlink(modules_dir, modules_dest)

        if args.username != get_default_username():
            print_help_message_about_the_commcare_cloud_default_username_env_var(
                args.username)

        key_name = args.username

        try:
            generate_terraform_entrypoint(
                environment,
                key_name,
                run_dir,
                apply_immediately=args.apply_immediately)
        except UnauthorizedUser as e:
            allowed_users = environment.users_config.dev_users.present
            puts(
                color_error(
                    "Unauthorized user {}.\n\n"
                    "Use COMMCARE_CLOUD_DEFAULT_USERNAME or --username to pass in one of the allowed ssh users:{}"
                    .format(e.username, '\n  - '.join([''] + allowed_users))))
            return -1

        if not args.skip_secrets and unknown_args and unknown_args[0] in (
                'plan', 'apply'):
            rds_password = (
                environment.get_secret('POSTGRES_USERS.root.password')
                if environment.terraform_config.rds_instances else '')

            with open(os.path.join(run_dir, 'secrets.auto.tfvars'),
                      'w',
                      encoding='utf-8') as f:
                print('rds_password = {}'.format(json.dumps(rds_password)),
                      file=f)

        env_vars = {'AWS_PROFILE': aws_sign_in(environment)}
        all_env_vars = os.environ.copy()
        all_env_vars.update(env_vars)
        cmd_parts = ['terraform'] + unknown_args
        cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts)
        print_command('cd {}; {} {}; cd -'.format(
            run_dir,
            ' '.join('{}={}'.format(key, value)
                     for key, value in env_vars.items()),
            cmd,
        ))
        return subprocess.call(cmd, shell=True, env=all_env_vars, cwd=run_dir)