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)
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)
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)
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)
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)
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)
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
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)
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))
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)