def run(self, args, unknown_args): assert args.action == 'migrate' or not args.no_stop, \ "You can only use --no-stop with migrate" environment = get_environment(args.env_name) environment.create_generated_yml() migration = CouchMigration(environment, args.migration_plan) check_connection(migration.target_couch_config.get_control_node()) if migration.separate_source_and_target: check_connection(migration.source_couch_config.get_control_node()) ansible_context = AnsibleContext(args) if args.limit and args.action != 'clean': puts( color_notice( 'Ignoring --limit (it only applies to "clean" action).')) if args.action == 'describe': return describe(migration) if args.action == 'plan': return plan(migration) if args.action == 'migrate': return migrate(migration, ansible_context, args.skip_check, args.no_stop) if args.action == 'commit': return commit(migration, ansible_context) if args.action == 'clean': return clean(migration, ansible_context, args.skip_check, args.limit)
def _act_on_pillows(self, action): # Used to stop or start pillows service = Pillowtop(self.environment, AnsibleContext(None)) exit_code = service.run(action=action) if not exit_code == 0: print("ERROR while trying to {} pillows. Exiting.".format(action)) sys.exit(1)
def run(self, args, unknown_args): environment = get_environment(args.env_name) environment.create_generated_yml() plan = read_plan(args.plan_path, environment, args.limit) working_directory = _get_working_dir(args.plan_path, environment) ansible_context = AnsibleContext(args) environment.get_ansible_vault_password() if plan.source_env != environment and args.action in ('prepare', 'cleanup'): plan.source_env.get_ansible_vault_password() if args.action == 'prepare': for target_host, source_configs in plan.configs.items(): self.log("Creating scripts to copy files.") prepare_file_copy_scripts(target_host, source_configs, working_directory) self.log("Moving scripts to target hosts.") copy_scripts_to_target_host(target_host, working_directory, environment, ansible_context) self.log("Establishing auth between target and source.") setup_auth(plan, environment, ansible_context, working_directory) if args.action == 'copy': def run_check(): return execute_file_copy_scripts(environment, list(plan.configs), check_mode=True) def run_apply(): return execute_file_copy_scripts(environment, list(plan.configs), check_mode=False) return run_action_with_check_mode(run_check, run_apply, args.skip_check) if args.action == 'cleanup': teardown_auth(plan, environment, ansible_context, working_directory) shutil.rmtree(working_directory)
def run(self, args, unknown_args): environment = get_environment(args.env_name) environment.create_generated_yml() ansible_context = AnsibleContext(args) def _run_ansible(args, *unknown_args): return run_ansible_module(environment, ansible_context, args.inventory_group, args.module, args.module_args, become=args.become, become_user=args.become_user, use_factory_auth=args.use_factory_auth, extra_args=unknown_args) def run_check(): with environment.secrets_backend.suppress_datadog_event(): return _run_ansible(args, '--check', *unknown_args) def run_apply(): return _run_ansible(args, *unknown_args) return run_action_with_check_mode(run_check, run_apply, args.skip_check, args.quiet)
def run(self, args, unknown_args): environment = get_environment(args.env_name) environment.create_generated_yml() migration = CouchMigration(environment, args.migration_plan) check_connection(migration.target_couch_config.get_control_node()) if migration.separate_source_and_target: check_connection(migration.source_couch_config.get_control_node()) ansible_context = AnsibleContext(args) if args.action == 'describe': return describe(migration) if args.action == 'plan': return plan(migration) if args.action == 'migrate': return migrate(migration, ansible_context, args.skip_check) if args.action == 'commit': return commit(migration) if args.actoin == 'clean': return clean(migration, ansible_context, args.skip_check)
def run(self, args, unknown_args, always_skip_check=False): environment = get_environment(args.env_name) environment.create_generated_yml() ansible_context = AnsibleContext(args) check_branch(args) run_ansible_playbook(environment, args.playbook, ansible_context, args.skip_check, args.quiet, always_skip_check, args.limit, args.use_factory_auth, unknown_args)
def run(self, args, unknown_args): environment = get_environment(args.env_name) environment.create_generated_yml() ansible_context = AnsibleContext(args) if args.action == 'start': start_downtime(environment, ansible_context, args) if args.action == 'end': end_downtime(environment, ansible_context)
def run_ansible_playbook_command(environment, args): skip_check = True environment.create_generated_yml() ansible_context = AnsibleContext(args) return ansible_playbook.run_ansible_playbook( environment, 'deploy_stack.yml', ansible_context, skip_check=skip_check, quiet=skip_check, always_skip_check=skip_check, limit='formplayer', use_factory_auth=False, unknown_args=('--tags=formplayer_deploy',), respect_ansible_skip=True, )
def _run_rolling_restart_yml(self, tags, limit): from commcare_cloud.commands.ansible.ansible_playbook import run_ansible_playbook extra_args = ['--tags={}'.format(tags)] if limit: extra_args.extend(['--limit={}'.format(limit)]) run_ansible_playbook(environment=self.environment, playbook='es_rolling_restart.yml', ansible_context=AnsibleContext(args=None), unknown_args=extra_args, skip_check=True, quiet=True)
def run(self, args, unknown_args): environment = get_environment(args.env_name) services = [SERVICES_BY_NAME[name] for name in args.services] ansible_context = AnsibleContext(args) non_zero_exits = [] for service_cls in services: service = service_cls(environment, ansible_context) exit_code = service.run(args.action, args.limit, args.process_pattern) if exit_code != 0: non_zero_exits.append(exit_code) return non_zero_exits[0] if non_zero_exits else 0
def run(self, args, unknown_args): environment = get_environment(args.env_name) environment.create_generated_yml() ansible_context = AnsibleContext(args) def _run_ansible(args, *unknown_args): return run_ansible_module(environment, ansible_context, args.inventory_group, args.module, args.module_args, args.become, args.become_user, args.use_factory_auth, *unknown_args) def run_check(): return _run_ansible(args, '--check', *unknown_args) def run_apply(): return _run_ansible(args, *unknown_args) return run_action_with_check_mode(run_check, run_apply, args.skip_check, args.quiet)
def run(self, args, unknown_args): args.module = 'datadog_event' environment = get_environment(args.env_name) datadog_api_key = environment.get_secret('DATADOG_API_KEY') datadog_app_key = environment.get_secret('DATADOG_APP_KEY') tags = args.tags or [] tags.append("environment:{}".format(args.env_name)) args.module_args = "api_key={api_key} app_key={app_key} " \ "tags='{tags}' text='{text}' title='{title}' aggregation_key={agg}".format( api_key=datadog_api_key, app_key=datadog_app_key, tags=",".join(tags), text=args.event_text, title=args.event_title, agg='commcare-cloud' ) return run_ansible_module( environment, AnsibleContext(args), '127.0.0.1', args.module, args.module_args, become=False, quiet=True )
def run(self, args, unknown_args): args.module = 'datadog_event' environment = get_environment(args.env_name) vault = environment.get_vault_variables()['secrets'] tags = "environment:{}".format(args.env_name) args.module_args = "api_key={api_key} app_key={app_key} " \ "tags='{tags}' text='{text}' title='{title}' aggregation_key={agg}".format( api_key=vault['DATADOG_API_KEY'], app_key=vault['DATADOG_APP_KEY'], tags=tags, text=args.event_text, title=args.event_title, agg='commcare-cloud' ) return run_ansible_module( environment, AnsibleContext(args), '127.0.0.1', args.module, args.module_args, False, False, False, )
def run(self, args, unknown_args, always_skip_check=False): environment = get_environment(args.env_name) environment.create_generated_yml() ansible_context = AnsibleContext(args) check_branch(args) public_vars = environment.public_vars ask_vault_pass = public_vars.get('commcare_cloud_use_vault', True) def ansible_playbook(environment, playbook, *cmd_args): cmd_parts = ( 'ansible-playbook', os.path.join(ANSIBLE_DIR, '{playbook}'.format(playbook=playbook)), '-i', environment.paths.inventory_ini, '-e', '@{}'.format(environment.paths.vault_yml), '-e', '@{}'.format(environment.paths.public_yml), '-e', '@{}'.format(environment.paths.generated_yml), '--diff', ) + cmd_args if not has_arg(unknown_args, '-u', '--user'): cmd_parts += ('-u', 'ansible') if not has_arg(unknown_args, '-f', '--forks'): cmd_parts += ('--forks', '15') known_hosts_filepath = environment.paths.known_hosts if os.path.exists(known_hosts_filepath): cmd_parts += ("--ssh-common-args='-o=UserKnownHostsFile=%s'" % (known_hosts_filepath, ), ) 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 if ask_vault_pass: cmd_parts += ('--vault-password-file=/bin/cat', ) cmd_parts += get_common_ssh_args(public_vars) cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts) print_command(cmd) if ask_vault_pass: environment.get_ansible_vault_password() p = subprocess.Popen(cmd, stdin=subprocess.PIPE, shell=True, env=ansible_context.env_vars) if ask_vault_pass: p.communicate(input='{}\n'.format( environment.get_ansible_vault_password())) else: p.communicate() return p.returncode def run_check(): return ansible_playbook(environment, args.playbook, '--check', *unknown_args) def run_apply(): return ansible_playbook(environment, args.playbook, *unknown_args) exit_code = 0 if always_skip_check: user_wants_to_apply = ask( 'This command will apply without running the check first. Continue?', quiet=args.quiet) elif args.skip_check: user_wants_to_apply = ask( 'Do you want to apply without running the check first?', quiet=args.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( colored.green( u"✓ Check completed with status code {}".format( exit_code))) user_wants_to_apply = ask( 'Do you want to apply these changes?', quiet=args.quiet) else: puts( colored.red(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=args.quiet) if user_wants_to_apply: exit_code = run_apply() if exit_code == 0: puts( colored.green( u"✓ Apply completed with status code {}".format( exit_code))) else: puts( colored.red(u"✗ Apply failed with status code {}".format( exit_code))) return exit_code
def run(self, args, unknown_args): environment = get_environment(args.environment) ansible_context = AnsibleContext(args) public_vars = environment.public_vars def _run_ansible(args, *unknown_args): cmd_parts = ( 'ANSIBLE_CONFIG={}'.format( os.path.join(ANSIBLE_DIR, 'ansible.cfg')), 'ansible', args.inventory_group, '-m', args.module, '-i', environment.paths.inventory_ini, '-u', args.remote_user, '-a', args.module_args, '--diff', ) + tuple(unknown_args) become = args.become or bool(args.become_user) become_user = args.become_user include_vars = False if become: cmd_parts += ('--become', ) if become_user not in ('cchq', ): # ansible user can do things as cchq without a password, # but needs the ansible user password in order to do things as other users. # In that case, we need to pull in the vault variable containing this password include_vars = True if become_user: cmd_parts += ('--become-user', args.become_user) if include_vars: cmd_parts += ( '-e', '@{}'.format(environment.paths.vault_yml), '-e', '@{}'.format(environment.paths.public_yml), ) ask_vault_pass = include_vars and public_vars.get( 'commcare_cloud_use_vault', True) if ask_vault_pass: cmd_parts += ('--vault-password-file=/bin/cat', ) cmd_parts += get_common_ssh_args(public_vars) cmd = ' '.join(shlex_quote(arg) for arg in cmd_parts) print_command(cmd) p = subprocess.Popen(cmd, stdin=subprocess.PIPE, shell=True, env=ansible_context.env_vars) if ask_vault_pass: p.communicate(input='{}\n'.format( ansible_context.get_ansible_vault_password())) else: p.communicate() return p.returncode def run_check(): return _run_ansible(args, '--check', *unknown_args) def run_apply(): return _run_ansible(args, *unknown_args) exit_code = 0 if args.skip_check: user_wants_to_apply = ask( 'Do you want to apply without running the check first?', quiet=args.quiet) else: exit_code = run_check() if exit_code == 1: # this means there was an error before ansible was able to start running exit(exit_code) return # for IDE elif exit_code == 0: puts( colored.green( u"✓ Check completed with status code {}".format( exit_code))) user_wants_to_apply = ask( 'Do you want to apply these changes?', quiet=args.quiet) else: puts( colored.red(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=args.quiet) if user_wants_to_apply: exit_code = run_apply() if exit_code == 0: puts( colored.green( u"✓ Apply completed with status code {}".format( exit_code))) else: puts( colored.red(u"✗ Apply failed with status code {}".format( exit_code))) exit(exit_code)