def announce_deploy_start(environment, service_name): send_email( environment, subject="{user} has initiated a {system_name} deploy to {environment}".format( user=get_default_username(), system_name=service_name, environment=environment.meta_config.deploy_env, ), )
def _announce_formplayer_deploy_start(environment): mail_admins( environment, subject="{user} has initiated a formplayer deploy to {environment}.".format( user=get_default_username(), environment=environment.meta_config.deploy_env, ), message='', )
def get_diff_context(self): context = { "new_version_details": self.new_version_details, "user": get_default_username(), "LABELS_TO_EXPAND": LABELS_TO_EXPAND, "errors": [], "warnings": [] } if self.deployed_commit_matches_latest_commit: context["errors"].append( "Versions are identical. No changes since last deploy.") return context if not (self.current_commit and self.deploy_commit): context["warnings"].append("Insufficient info to get deploy diff.") return context context["compare_url"] = self.url if not self.generate_diff: disabled_msg = "Deploy diffs disabled for this environment." print(color_warning(disabled_msg)) context["warnings"].append(disabled_msg) return context if not self.repo.permissions: # using unauthenticated API calls, skip diff creation to avoid hitting rate limits print( color_warning( "Diff generation skipped. Supply a Github token to see deploy diffs." )) context["warnings"].append("Diff omitted.") return context try: pr_numbers = self._get_pr_numbers() except GithubException as e: print(color_error(f"Error getting diff commits: {e}")) context["warnings"].append( "There was an error fetching the PRs since the last deploy.") return context if len(pr_numbers) > 500: context["warnings"].append("There are too many PRs to display.") return context elif not pr_numbers: context["warnings"].append("No PRs merged since last release.") return context pool = Pool(5) pr_infos = [_f for _f in pool.map(self._get_pr_info, pr_numbers) if _f] context["pr_infos"] = pr_infos prs_by_label = self._get_prs_by_label(pr_infos) context["prs_by_label"] = prs_by_label return context
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( 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_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)} 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 call_record_deploy_success(environment, diff, start_time, end_time): delta = end_time - start_time args = [ '--user', get_default_username(), '--environment', environment.meta_config.deploy_env, '--url', diff.url, '--minutes', str(int(delta.total_seconds() // 60)), '--commit', diff.deploy_commit, ] commcare_cloud(environment.name, 'django-manage', 'record_deploy_success', *args)
def get_server_address(environment, group): host_group = split_host_group(group) username, group, index = host_group.user, host_group.group, host_group.index if ':' in group: display.warning( "Use '[x]' to select hosts instead of ':x' which has been deprecated." ) group, index = group.rsplit(':', 1) try: index = int(index) except (TypeError, ValueError): raise HostMatchException( "Non-numeric group index: {}".format(index)) if not username: default_username = get_default_username() if default_username.is_guess: username = "" else: username = "******".format(default_username) if re.match(r'(\d+\.?){4}', group): # short circuit for IP addresses return username + group try: servers = get_instance_group(environment, group) except IOError as err: raise HostMatchException(err) except KeyError: raise HostMatchException( "Unknown server name/group: {}\n".format(group)) if index is not None and index > len(servers) - 1: raise HostMatchException( "Invalid group index: {index}\n" "Please specify a number between 0 and {max} inclusive\n".format( index=index, max=len(servers) - 1)) if len(servers) > 1: if index is None: raise HostMatchException( "There are {num} servers in the '{group}' group\n" "Please specify the index of the server. Example: {group}:0\n". format(num=len(servers), group=group)) server = servers[index] else: server = servers[index or 0] return username + server
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 record_deploy_in_datadog(environment, diff, tdelta): if environment.public_vars.get('DATADOG_ENABLED', False): print(color_summary(f">> Recording deploy in Datadog")) diff_url = f"\nDiff link: [Git Diff]({diff.url})" deploy_notification_text = ( "Formplayer has been successfully deployed to " "*{}* by *{}* in *{}* minutes.\nRelease Name: {}{}".format( environment.name, get_default_username(), int(tdelta.total_seconds() / 60) or '?', environment.new_release_name(), diff_url)) commcare_cloud(environment.name, 'send-datadog-event', 'Formplayer Deploy Success', deploy_notification_text, '--alert_type', "success", show_command=False)
def get_server_address(environment, group, exit=sys.exit): if "@" in group: username, group = group.split('@', 1) username += "@" else: default_username = get_default_username() if default_username.is_guess: username = "" else: username = "******".format(default_username) if re.match(r'(\d+\.?){4}', group): # short circuit for IP addresses return username + group if ':' in group: group, index = group.rsplit(':', 1) try: index = int(index) except (TypeError, ValueError): exit("Non-numeric group index: {}".format(index)) else: index = None try: servers = get_instance_group(environment, group) except IOError as err: exit(err) except KeyError as err: exit("Unknown server name/group: {}\n".format(group)) if index is not None and index > len(servers) - 1: exit("Invalid group index: {index}\n" "Please specify a number between 0 and {max} inclusive\n".format( index=index, max=len(servers) - 1)) if len(servers) > 1: if index is None: exit( "There are {num} servers in the '{group}' group\n" "Please specify the index of the server. Example: {group}:0\n". format(num=len(servers), group=group)) server = servers[index] else: server = servers[index or 0] return username + server
class Terraform(CommandBase): command = 'terraform' help = "Run terraform for this env with the given arguments" arguments = ( Argument('--skip-secrets', action='store_true', help=""" Skip regenerating the secrets file. Good for not having to enter vault password again. """), Argument('--username', default=get_default_username(), help=""" The username of the user whose public key will be put on new servers. Normally this would be _your_ username. Defaults to the value of the COMMCARE_CLOUD_DEFAULT_USERNAME environment variable or else the username of the user running the command. """), ) 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) 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'] 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)