Esempio n. 1
0
def get_versions_for_service(
        service: str, deploy_groups: Collection[str],
        soa_dir: str) -> Mapping[DeploymentVersion, Tuple[str, str]]:
    """Returns a dictionary of 2-tuples of the form (timestamp, deploy_group) for each version tuple of (deploy sha, image_version)"""
    if service is None:
        return {}
    git_url = get_git_url(service=service, soa_dir=soa_dir)
    all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    deploy_groups, _ = validate_given_deploy_groups(all_deploy_groups,
                                                    deploy_groups)
    previously_deployed_versions: Dict[DeploymentVersion, Tuple[str, str]] = {}
    for ref, sha in list_remote_refs(git_url).items():
        regex_match = extract_tags(ref)
        try:
            deploy_group = regex_match["deploy_group"]
            tstamp = regex_match["tstamp"]
            image_version = regex_match["image_version"]
        except KeyError:
            pass
        else:
            # Now we filter and dedup by picking the most recent sha for a deploy group
            # Note that all strings are greater than ''
            if deploy_group in deploy_groups:
                version = DeploymentVersion(sha=sha,
                                            image_version=image_version)
                tstamp_so_far = previously_deployed_versions.get(
                    version, ("all", ""))[1]
                if tstamp > tstamp_so_far:
                    previously_deployed_versions[version] = (tstamp,
                                                             deploy_group)
    return previously_deployed_versions
Esempio n. 2
0
def get_git_shas_for_service(service, deploy_groups, soa_dir):
    """Returns a dictionary of 2-tuples of the form (timestamp, deploy_group) for each deploy sha"""
    if service is None:
        return []
    git_url = get_git_url(service=service, soa_dir=soa_dir)
    all_deploy_groups = list_deploy_groups(
        service=service,
        soa_dir=soa_dir,
    )
    deploy_groups, _ = validate_given_deploy_groups(all_deploy_groups, deploy_groups)
    previously_deployed_shas = {}
    for ref, sha in list_remote_refs(git_url).items():
        regex_match = extract_tags(ref)
        try:
            deploy_group = regex_match['deploy_group']
            tstamp = regex_match['tstamp']
        except KeyError:
            pass
        else:
            # Now we filter and dedup by picking the most recent sha for a deploy group
            # Note that all strings are greater than ''
            if deploy_group in deploy_groups:
                tstamp_so_far = previously_deployed_shas.get(sha, ('all', ''))[1]
                if tstamp > tstamp_so_far:
                    previously_deployed_shas[sha] = (tstamp, deploy_group)
    return previously_deployed_shas
Esempio n. 3
0
def paasta_rollback(args):
    """Call mark_for_deployment with rollback parameters
    :param args: contains all the arguments passed onto the script: service,
    deploy groups and sha. These arguments will be verified and passed onto
    mark_for_deployment.
    """
    soa_dir = args.soa_dir
    service = figure_out_service_name(args, soa_dir)

    git_url = get_git_url(service, soa_dir)
    given_deploy_groups = {deploy_group for deploy_group in args.deploy_groups.split(",") if deploy_group}

    all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    deploy_groups, invalid = validate_given_deploy_groups(all_deploy_groups, given_deploy_groups)

    if len(invalid) > 0:
        paasta_print(
            PaastaColors.yellow(
                "These deploy groups are not valid and will be skipped: %s.\n" % (",").join(invalid),
            ),
        )

    if len(deploy_groups) == 0:
        paasta_print(PaastaColors.red("ERROR: No valid deploy groups specified for %s.\n" % (service)))
        return 1

    git_shas = get_git_shas_for_service(service, deploy_groups, soa_dir)
    commit = args.commit
    if not commit:
        paasta_print("Please specify a commit to mark for rollback (-k, --commit).")
        list_previous_commits(service, deploy_groups, bool(given_deploy_groups), git_shas)
        return 1
    elif commit not in git_shas and not args.force:
        paasta_print(PaastaColors.red("This Git SHA has never been deployed before."))
        paasta_print("Please double check it or use --force to skip this verification.\n")
        list_previous_commits(service, deploy_groups, bool(given_deploy_groups), git_shas)
        return 1

    returncode = 0

    for deploy_group in deploy_groups:
        returncode = max(
            mark_for_deployment(
                git_url=git_url,
                service=service,
                deploy_group=deploy_group,
                commit=commit,
            ),
            returncode,
        )

    return returncode
Esempio n. 4
0
def paasta_rollback(args):
    """Call mark_for_deployment with rollback parameters
    :param args: contains all the arguments passed onto the script: service,
    deploy groups and sha. These arguments will be verified and passed onto
    mark_for_deployment.
    """
    soa_dir = args.soa_dir
    service = figure_out_service_name(args, soa_dir)

    git_url = get_git_url(service, soa_dir)
    given_deploy_groups = {
        deploy_group
        for deploy_group in args.deploy_groups.split(",") if deploy_group
    }

    all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    deploy_groups, invalid = validate_given_deploy_groups(
        all_deploy_groups, given_deploy_groups)

    if len(invalid) > 0:
        paasta_print(
            PaastaColors.yellow(
                "These deploy groups are not valid and will be skipped: %s.\n"
                % (",").join(invalid), ), )

    if len(deploy_groups) == 0:
        paasta_print(
            PaastaColors.red(
                "ERROR: No valid deploy groups specified for %s.\n" %
                (service)))
        return 1

    commit = args.commit
    if not commit:
        list_previous_commits(service, deploy_groups,
                              bool(given_deploy_groups), soa_dir)
        return 1

    returncode = 0

    for deploy_group in deploy_groups:
        returncode = max(
            mark_for_deployment(
                git_url=git_url,
                service=service,
                deploy_group=deploy_group,
                commit=commit,
            ),
            returncode,
        )

    return returncode
Esempio n. 5
0
def validate_deploy_group(deploy_group, service, soa_dir):
    """Validate deploy_group.

    Raise exception if the specified deploy group is not used anywhere.
    """
    in_use_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    _, invalid_deploy_groups = \
        validate_given_deploy_groups(in_use_deploy_groups, [deploy_group])

    if len(invalid_deploy_groups) == 1:
        raise DeployGroupError("ERROR: These deploy groups are not currently "
                               "used anywhere: {}.\n"
                               "You probably need one of these in-use deploy "
                               "groups?:\n   {}".format(
                                   ",".join(invalid_deploy_groups),
                                   ",".join(in_use_deploy_groups)))
Esempio n. 6
0
def validate_deploy_group(deploy_group, service, soa_dir):
    """Validate deploy_group.

    Raise exception if the specified deploy group is not used anywhere.
    """
    in_use_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    _, invalid_deploy_groups = \
        validate_given_deploy_groups(in_use_deploy_groups, [deploy_group])

    if len(invalid_deploy_groups) == 1:
        raise DeployGroupError("ERROR: These deploy groups are not currently "
                               "used anywhere: {0}.\n"
                               "You probably need one of these in-use deploy "
                               "groups?:\n   {1}".format(
                                   ",".join(invalid_deploy_groups),
                                   ",".join(in_use_deploy_groups)))
Esempio n. 7
0
def test_list_deploy_groups_parses_configs(
    mock_get_instance_configs_for_service, ):
    mock_get_instance_configs_for_service.return_value = [
        MarathonServiceConfig(
            service='foo',
            cluster='',
            instance='',
            config_dict={'deploy_group': 'fake_deploy_group'},
            branch_dict=None,
        ),
        MarathonServiceConfig(
            service='foo',
            cluster='fake_cluster',
            instance='fake_instance',
            config_dict={},
            branch_dict=None,
        ),
    ]
    actual = utils.list_deploy_groups(service="foo")
    assert actual == {'fake_deploy_group', 'fake_cluster.fake_instance'}
Esempio n. 8
0
def test_list_deploy_groups_parses_configs(
    mock_get_instance_configs_for_service, ):
    mock_get_instance_configs_for_service.return_value = [
        MarathonServiceConfig(
            service="foo",
            cluster="",
            instance="",
            config_dict={"deploy_group": "fake_deploy_group"},
            branch_dict=None,
        ),
        MarathonServiceConfig(
            service="foo",
            cluster="fake_cluster",
            instance="fake_instance",
            config_dict={},
            branch_dict=None,
        ),
    ]
    actual = utils.list_deploy_groups(service="foo")
    assert actual == {"fake_deploy_group", "fake_cluster.fake_instance"}
Esempio n. 9
0
def paasta_rollback(args):
    """Call mark_for_deployment with rollback parameters
    :param args: contains all the arguments passed onto the script: service,
    deploy groups and sha. These arguments will be verified and passed onto
    mark_for_deployment.
    """
    soa_dir = args.soa_dir
    service = figure_out_service_name(args, soa_dir)

    git_url = get_git_url(service, soa_dir)
    given_deploy_groups = {deploy_group for deploy_group in args.deploy_groups.split(",") if deploy_group}

    all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    deploy_groups, invalid = validate_given_deploy_groups(all_deploy_groups, given_deploy_groups)

    if len(invalid) > 0:
        print PaastaColors.yellow("These deploy groups are not valid and will be skipped: %s.\n" % (",").join(invalid))

    if len(deploy_groups) == 0:
        print PaastaColors.red("ERROR: No valid deploy groups specified for %s.\n" % (service))
        return 1

    commit = args.commit
    if not commit:
        list_previous_commits(service, deploy_groups, bool(given_deploy_groups), soa_dir)
        return 1

    returncode = 0

    for deploy_group in deploy_groups:
        returncode = max(
            mark_for_deployment(
                git_url=git_url,
                service=service,
                deploy_group=deploy_group,
                commit=commit,
            ),
            returncode,
        )

    return returncode
Esempio n. 10
0
def test_list_deploy_groups_parses_configs(
    mock_get_instance_configs_for_service,
):
    mock_get_instance_configs_for_service.return_value = [
        MarathonServiceConfig(
            service='foo',
            cluster='',
            instance='',
            config_dict={'deploy_group': 'fake_deploy_group'},
            branch_dict={},
        ),
        MarathonServiceConfig(
            service='foo',
            cluster='fake_cluster',
            instance='fake_instance',
            config_dict={},
            branch_dict={},
        ),
    ]
    actual = utils.list_deploy_groups(service="foo")
    assert actual == set(['fake_deploy_group', 'fake_cluster.fake_instance'])
Esempio n. 11
0
def get_git_shas_for_service(service, deploy_groups, soa_dir):
    """Returns a dictionary of 2-tuples of the form (timestamp, deploy_group) for each deploy sha"""
    if service is None:
        return []
    git_url = get_git_url(service=service, soa_dir=soa_dir)
    all_deploy_groups = list_deploy_groups(
        service=service,
        soa_dir=soa_dir,
    )
    deploy_groups, _ = validate_given_deploy_groups(all_deploy_groups, deploy_groups)
    previously_deployed_shas = {}
    for ref, sha in list_remote_refs(git_url).items():
        regex_match = extract_tags(ref)
        try:
            deploy_group = regex_match['deploy_group']
            tstamp = regex_match['tstamp']
        except KeyError:
            pass
        else:
            # note that all strings are greater than ''
            if deploy_group in deploy_groups and tstamp > previously_deployed_shas.get(sha, ''):
                previously_deployed_shas[sha] = (tstamp, deploy_group)
    return previously_deployed_shas.items()
Esempio n. 12
0
def paasta_mark_for_deployment(args):
    """Wrapping mark_for_deployment"""
    if args.verbose:
        log.setLevel(level=logging.DEBUG)
    else:
        log.setLevel(level=logging.INFO)

    service = args.service
    if service and service.startswith('services-'):
        service = service.split('services-', 1)[1]
    validate_service_name(service, soa_dir=args.soa_dir)

    in_use_deploy_groups = list_deploy_groups(
        service=service,
        soa_dir=args.soa_dir,
    )
    _, invalid_deploy_groups = validate_given_deploy_groups(in_use_deploy_groups, [args.deploy_group])

    if len(invalid_deploy_groups) == 1:
        paasta_print(PaastaColors.red(
            "ERROR: These deploy groups are not currently used anywhere: %s.\n" % (",").join(invalid_deploy_groups)))
        paasta_print(PaastaColors.red(
            "This isn't technically wrong because you can mark-for-deployment before deploying there"))
        paasta_print(PaastaColors.red("but this is probably a typo. Did you mean one of these in-use deploy groups?:"))
        paasta_print(PaastaColors.red("   %s" % (",").join(in_use_deploy_groups)))
        paasta_print()
        paasta_print(PaastaColors.red("Continuing regardless..."))

    if args.git_url is None:
        args.git_url = get_git_url(service=service, soa_dir=args.soa_dir)

    old_git_sha = get_currently_deployed_sha(service=service, deploy_group=args.deploy_group)
    if old_git_sha == args.commit:
        paasta_print("Warning: The sha asked to be deployed already matches what is set to be deployed:")
        paasta_print(old_git_sha)
        paasta_print("Continuing anyway.")

    ret = mark_for_deployment(
        git_url=args.git_url,
        deploy_group=args.deploy_group,
        service=service,
        commit=args.commit,
    )
    if args.block:
        try:
            wait_for_deployment(service=service,
                                deploy_group=args.deploy_group,
                                git_sha=args.commit,
                                soa_dir=args.soa_dir,
                                timeout=args.timeout)
            line = "Deployment of {0} for {1} complete".format(args.commit, args.deploy_group)
            _log(
                service=service,
                component='deploy',
                line=line,
                level='event'
            )
        except (KeyboardInterrupt, TimeoutError):
            if args.auto_rollback is True:
                if old_git_sha == args.commit:
                    paasta_print("Error: --auto-rollback was requested, but the previous sha")
                    paasta_print("is the same that was requested with --commit. Can't rollback")
                    paasta_print("automatically.")
                else:
                    paasta_print("Auto-Rollback requested. Marking the previous sha")
                    paasta_print("(%s) for %s as desired." % (args.deploy_group, old_git_sha))
                    mark_for_deployment(
                        git_url=args.git_url,
                        deploy_group=args.deploy_group,
                        service=service,
                        commit=old_git_sha,
                    )
            else:
                paasta_print("Waiting for deployment aborted. PaaSTA will continue to try to deploy this code.")
                paasta_print("If you wish to see the status, run:")
                paasta_print()
                paasta_print("    paasta status -s %s -v" % service)
                paasta_print()
            ret = 1
        except NoInstancesFound:
            return 1
    if old_git_sha is not None and old_git_sha != args.commit and not args.auto_rollback:
        paasta_print()
        paasta_print("If you wish to roll back, you can run:")
        paasta_print()
        paasta_print(PaastaColors.bold("    paasta rollback --service %s --deploy-group %s --commit %s " % (
            service, args.deploy_group, old_git_sha))
        )
    return ret
Esempio n. 13
0
def paasta_rollback(args):
    """Call mark_for_deployment with rollback parameters
    :param args: contains all the arguments passed onto the script: service,
    deploy groups and sha. These arguments will be verified and passed onto
    mark_for_deployment.
    """
    soa_dir = args.soa_dir
    service = figure_out_service_name(args, soa_dir)

    deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir)
    deploy_authz_check(deploy_info, service)

    git_url = get_git_url(service, soa_dir)
    given_deploy_groups = {
        deploy_group for deploy_group in args.deploy_groups.split(",") if deploy_group
    }

    all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    deploy_groups, invalid = validate_given_deploy_groups(
        all_deploy_groups, given_deploy_groups
    )

    if len(invalid) > 0:
        print(
            PaastaColors.yellow(
                "These deploy groups are not valid and will be skipped: %s.\n"
                % (",").join(invalid)
            )
        )

    if len(deploy_groups) == 0:
        print(
            PaastaColors.red(
                "ERROR: No valid deploy groups specified for %s.\n" % (service)
            )
        )
        return 1

    git_shas = get_git_shas_for_service(service, deploy_groups, soa_dir)
    commit = args.commit
    if not commit:
        print("Please specify a commit to mark for rollback (-k, --commit).")
        list_previous_commits(
            service, deploy_groups, bool(given_deploy_groups), git_shas
        )
        return 1
    elif commit not in git_shas and not args.force:
        print(PaastaColors.red("This Git SHA has never been deployed before."))
        print("Please double check it or use --force to skip this verification.\n")
        list_previous_commits(
            service, deploy_groups, bool(given_deploy_groups), git_shas
        )
        return 1

    returncode = 0

    for deploy_group in deploy_groups:
        rolled_back_from = get_currently_deployed_sha(service, deploy_group)
        returncode |= mark_for_deployment(
            git_url=git_url, service=service, deploy_group=deploy_group, commit=commit
        )

        # we could also gate this by the return code from m-f-d, but we probably care more about someone wanting to
        # rollback than we care about if the underlying machinery was successfully able to complete the request
        if rolled_back_from != commit:
            audit_action_details = {
                "rolled_back_from": rolled_back_from,
                "rolled_back_to": commit,
                "rollback_type": RollbackTypes.USER_INITIATED_ROLLBACK.value,
                "deploy_group": deploy_group,
            }
            _log_audit(
                action="rollback", action_details=audit_action_details, service=service
            )

    return returncode
Esempio n. 14
0
def paasta_mark_for_deployment(args):
    """Wrapping mark_for_deployment"""
    if args.verbose:
        log.setLevel(level=logging.DEBUG)
    else:
        log.setLevel(level=logging.INFO)

    service = args.service
    if service and service.startswith('services-'):
        service = service.split('services-', 1)[1]
    validate_service_name(service, soa_dir=args.soa_dir)

    in_use_deploy_groups = list_deploy_groups(
        service=service,
        soa_dir=args.soa_dir,
    )
    _, invalid_deploy_groups = validate_given_deploy_groups(
        in_use_deploy_groups, [args.deploy_group])

    if len(invalid_deploy_groups) == 1:
        paasta_print(
            PaastaColors.red(
                "ERROR: These deploy groups are not currently used anywhere: %s.\n"
                % (",").join(invalid_deploy_groups), ))
        paasta_print(
            PaastaColors.red(
                "This isn't technically wrong because you can mark-for-deployment before deploying there",
            ))
        paasta_print(
            PaastaColors.red(
                "but this is probably a typo. Did you mean one of these in-use deploy groups?:"
            ))
        paasta_print(
            PaastaColors.red("   %s" % (",").join(in_use_deploy_groups)))
        paasta_print()
        paasta_print(PaastaColors.red("Continuing regardless..."))

    if args.git_url is None:
        args.git_url = get_git_url(service=service, soa_dir=args.soa_dir)

    try:
        validate_full_git_sha(args.commit)
    except ArgumentTypeError:
        refs = remote_git.list_remote_refs(args.git_url)
        commits = short_to_full_git_sha(short=args.commit, refs=refs)
        if len(commits) != 1:
            raise ValueError(
                "%s matched %d git shas (with refs pointing at them). Must match exactly 1."
                % (args.commit, len(commits)), )
        args.commit = commits[0]

    old_git_sha = get_currently_deployed_sha(service=service,
                                             deploy_group=args.deploy_group)
    if old_git_sha == args.commit:
        paasta_print(
            "Warning: The sha asked to be deployed already matches what is set to be deployed:"
        )
        paasta_print(old_git_sha)
        paasta_print("Continuing anyway.")

    if args.verify_image:
        if not is_docker_image_already_in_registry(service, args.soa_dir,
                                                   args.commit):
            raise ValueError(
                'Failed to find image in the registry for the following sha %s'
                % args.commit)

    ret = mark_for_deployment(
        git_url=args.git_url,
        deploy_group=args.deploy_group,
        service=service,
        commit=args.commit,
    )
    if args.block and ret == 0:
        try:
            wait_for_deployment(
                service=service,
                deploy_group=args.deploy_group,
                git_sha=args.commit,
                soa_dir=args.soa_dir,
                timeout=args.timeout,
            )
            line = "Deployment of {} for {} complete".format(
                args.commit, args.deploy_group)
            _log(
                service=service,
                component='deploy',
                line=line,
                level='event',
            )
        except (KeyboardInterrupt, TimeoutError):
            if args.auto_rollback is True:
                if old_git_sha == args.commit:
                    paasta_print(
                        "Error: --auto-rollback was requested, but the previous sha"
                    )
                    paasta_print(
                        "is the same that was requested with --commit. Can't rollback"
                    )
                    paasta_print("automatically.")
                else:
                    paasta_print(
                        "Auto-Rollback requested. Marking the previous sha")
                    paasta_print("(%s) for %s as desired." %
                                 (args.deploy_group, old_git_sha))
                    mark_for_deployment(
                        git_url=args.git_url,
                        deploy_group=args.deploy_group,
                        service=service,
                        commit=old_git_sha,
                    )
            else:
                report_waiting_aborted(service, args.deploy_group)
            ret = 1
        except NoSuchCluster:
            report_waiting_aborted(service, args.deploy_group)
    if old_git_sha is not None and old_git_sha != args.commit and not args.auto_rollback:
        paasta_print()
        paasta_print("If you wish to roll back, you can run:")
        paasta_print()
        paasta_print(
            PaastaColors.bold(
                "    paasta rollback --service %s --deploy-group %s --commit %s "
                % (
                    service,
                    args.deploy_group,
                    old_git_sha,
                )), )
    return ret
Esempio n. 15
0
def paasta_mark_for_deployment(args):
    """Wrapping mark_for_deployment"""
    if args.verbose:
        log.setLevel(level=logging.DEBUG)
    else:
        log.setLevel(level=logging.INFO)

    service = args.service
    if service and service.startswith('services-'):
        service = service.split('services-', 1)[1]
    validate_service_name(service, soa_dir=args.soa_dir)

    in_use_deploy_groups = list_deploy_groups(
        service=service,
        soa_dir=args.soa_dir,
    )
    _, invalid_deploy_groups = validate_given_deploy_groups(
        in_use_deploy_groups, [args.deploy_group])

    if len(invalid_deploy_groups) == 1:
        paasta_print(
            PaastaColors.red(
                "ERROR: These deploy groups are not currently used anywhere: %s.\n"
                % (",").join(invalid_deploy_groups)))
        paasta_print(
            PaastaColors.red(
                "This isn't technically wrong because you can mark-for-deployment before deploying there"
            ))
        paasta_print(
            PaastaColors.red(
                "but this is probably a typo. Did you mean one of these in-use deploy groups?:"
            ))
        paasta_print(
            PaastaColors.red("   %s" % (",").join(in_use_deploy_groups)))
        paasta_print()
        paasta_print(PaastaColors.red("Continuing regardless..."))

    if args.git_url is None:
        args.git_url = get_git_url(service=service, soa_dir=args.soa_dir)

    old_git_sha = get_currently_deployed_sha(service=service,
                                             deploy_group=args.deploy_group)
    if old_git_sha == args.commit:
        paasta_print(
            "Warning: The sha asked to be deployed already matches what is set to be deployed:"
        )
        paasta_print(old_git_sha)
        paasta_print("Continuing anyway.")

    ret = mark_for_deployment(
        git_url=args.git_url,
        deploy_group=args.deploy_group,
        service=service,
        commit=args.commit,
    )
    if args.block:
        try:
            wait_for_deployment(service=service,
                                deploy_group=args.deploy_group,
                                git_sha=args.commit,
                                soa_dir=args.soa_dir,
                                timeout=args.timeout)
            line = "Deployment of {} for {} complete".format(
                args.commit, args.deploy_group)
            _log(service=service, component='deploy', line=line, level='event')
        except (KeyboardInterrupt, TimeoutError):
            if args.auto_rollback is True:
                if old_git_sha == args.commit:
                    paasta_print(
                        "Error: --auto-rollback was requested, but the previous sha"
                    )
                    paasta_print(
                        "is the same that was requested with --commit. Can't rollback"
                    )
                    paasta_print("automatically.")
                else:
                    paasta_print(
                        "Auto-Rollback requested. Marking the previous sha")
                    paasta_print("(%s) for %s as desired." %
                                 (args.deploy_group, old_git_sha))
                    mark_for_deployment(
                        git_url=args.git_url,
                        deploy_group=args.deploy_group,
                        service=service,
                        commit=old_git_sha,
                    )
            else:
                paasta_print(
                    "Waiting for deployment aborted. PaaSTA will continue to try to deploy this code."
                )
                paasta_print("If you wish to see the status, run:")
                paasta_print()
                paasta_print("    paasta status -s %s -v" % service)
                paasta_print()
            ret = 1
        except NoInstancesFound:
            return 1
    if old_git_sha is not None and old_git_sha != args.commit and not args.auto_rollback:
        paasta_print()
        paasta_print("If you wish to roll back, you can run:")
        paasta_print()
        paasta_print(
            PaastaColors.bold(
                "    paasta rollback --service %s --deploy-group %s --commit %s "
                % (service, args.deploy_group, old_git_sha)))
    return ret
Esempio n. 16
0
def paasta_mark_for_deployment(args):
    """Wrapping mark_for_deployment"""
    if args.verbose:
        log.setLevel(level=logging.DEBUG)
    else:
        log.setLevel(level=logging.INFO)

    service = args.service
    if service and service.startswith('services-'):
        service = service.split('services-', 1)[1]
    validate_service_name(service, soa_dir=args.soa_dir)

    deploy_group = args.deploy_group
    in_use_deploy_groups = list_deploy_groups(
        service=service,
        soa_dir=args.soa_dir,
    )
    _, invalid_deploy_groups = validate_given_deploy_groups(
        in_use_deploy_groups, [deploy_group])

    if len(invalid_deploy_groups) == 1:
        paasta_print(
            PaastaColors.red(
                "ERROR: These deploy groups are not currently used anywhere: %s.\n"
                % (",").join(invalid_deploy_groups), ))
        paasta_print(
            PaastaColors.red(
                "This isn't technically wrong because you can mark-for-deployment before deploying there",
            ))
        paasta_print(
            PaastaColors.red(
                "but this is probably a typo. Did you mean one of these in-use deploy groups?:"
            ))
        paasta_print(
            PaastaColors.red("   %s" % (",").join(in_use_deploy_groups)))
        paasta_print()
        paasta_print(PaastaColors.red("Continuing regardless..."))

    if args.git_url is None:
        args.git_url = get_git_url(service=service, soa_dir=args.soa_dir)

    commit = validate_git_sha(sha=args.commit, git_url=args.git_url)

    old_git_sha = get_currently_deployed_sha(service=service,
                                             deploy_group=deploy_group)
    if old_git_sha == commit:
        paasta_print(
            "Warning: The sha asked to be deployed already matches what is set to be deployed:"
        )
        paasta_print(old_git_sha)
        paasta_print("Continuing anyway.")

    if args.verify_image:
        if not is_docker_image_already_in_registry(service, args.soa_dir,
                                                   commit):
            raise ValueError(
                'Failed to find image in the registry for the following sha %s'
                % commit)

    deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir)
    slack_notifier = SlackDeployNotifier(
        deploy_info=deploy_info,
        service=service,
        deploy_group=deploy_group,
        commit=commit,
        old_commit=old_git_sha,
        git_url=args.git_url,
    )

    ret = mark_for_deployment(
        git_url=args.git_url,
        deploy_group=deploy_group,
        service=service,
        commit=commit,
    )
    slack_notifier.notify_after_mark(ret=ret)

    if args.block and ret == 0:
        try:
            wait_for_deployment(
                service=service,
                deploy_group=deploy_group,
                git_sha=commit,
                soa_dir=args.soa_dir,
                timeout=args.timeout,
            )
            line = f"Deployment of {commit} for {deploy_group} complete"
            _log(
                service=service,
                component='deploy',
                line=line,
                level='event',
            )
            slack_notifier.notify_after_good_deploy()
        except (KeyboardInterrupt, TimeoutError):
            if args.auto_rollback is True:
                if old_git_sha == commit:
                    paasta_print(
                        "Error: --auto-rollback was requested, but the previous sha"
                    )
                    paasta_print(
                        "is the same that was requested with --commit. Can't rollback"
                    )
                    paasta_print("automatically.")
                else:
                    paasta_print(
                        "Auto-Rollback requested. Marking the previous sha")
                    paasta_print(
                        f"({deploy_group}) for {old_git_sha} as desired.")
                    mark_for_deployment(
                        git_url=args.git_url,
                        deploy_group=deploy_group,
                        service=service,
                        commit=old_git_sha,
                    )
                    slack_notifier.notify_after_auto_rollback()
            else:
                report_waiting_aborted(service, deploy_group)
                slack_notifier.notify_after_abort()
            ret = 1
        except NoSuchCluster:
            report_waiting_aborted(service, deploy_group)
            slack_notifier.notify_after_abort()
    if old_git_sha is not None and old_git_sha != commit and not args.auto_rollback:
        paasta_print()
        paasta_print("If you wish to roll back, you can run:")
        paasta_print()
        paasta_print(
            PaastaColors.bold(
                "    paasta rollback --service {} --deploy-group {} --commit {} "
                .format(
                    service,
                    deploy_group,
                    old_git_sha,
                )), )
    return ret
Esempio n. 17
0
def paasta_mark_for_deployment(args):
    """Wrapping mark_for_deployment"""
    if args.verbose:
        log.setLevel(level=logging.DEBUG)
    else:
        log.setLevel(level=logging.INFO)

    service = args.service
    if service and service.startswith('services-'):
        service = service.split('services-', 1)[1]
    validate_service_name(service, soa_dir=args.soa_dir)

    in_use_deploy_groups = list_deploy_groups(
        service=service,
        soa_dir=args.soa_dir,
    )
    _, invalid_deploy_groups = validate_given_deploy_groups(
        in_use_deploy_groups, [args.deploy_group])

    if len(invalid_deploy_groups) == 1:
        print PaastaColors.red(
            "ERROR: These deploy groups are not currently used anywhere: %s.\n"
            % (",").join(invalid_deploy_groups))
        print PaastaColors.red(
            "This isn't technically wrong because you can mark-for-deployment before deploying there"
        )
        print PaastaColors.red(
            "but this is probably a typo. Did you mean one of these in-use deploy groups?:"
        )
        print PaastaColors.red("   %s" % (",").join(in_use_deploy_groups))
        print ""
        print PaastaColors.red("Continuing regardless...")

    if args.git_url is None:
        args.git_url = get_git_url(service=service, soa_dir=args.soa_dir)

    old_git_sha = get_currently_deployed_sha(service=service,
                                             deploy_group=args.deploy_group)
    if old_git_sha == args.commit:
        print "Warning: The sha asked to be deployed already matches what is set to be deployed:"
        print old_git_sha
        print "Continuing anyway."

    ret = mark_for_deployment(
        git_url=args.git_url,
        deploy_group=args.deploy_group,
        service=service,
        commit=args.commit,
    )
    if args.block:
        try:
            print "Waiting for deployment of {0} for '{1}' complete...".format(
                args.commit, args.deploy_group)
            wait_for_deployment(service=service,
                                deploy_group=args.deploy_group,
                                git_sha=args.commit,
                                soa_dir=args.soa_dir,
                                timeout=args.timeout)
            line = "Deployment of {0} for {1} complete".format(
                args.commit, args.deploy_group)
            _log(service=service, component='deploy', line=line, level='event')
        except (KeyboardInterrupt, TimeoutError):
            print "Waiting for deployment aborted. PaaSTA will continue to try to deploy this code."
            print "If you wish to see the status, run:"
            print ""
            print "    paasta status -s %s -v" % service
            print ""
            ret = 1
    if old_git_sha is not None and old_git_sha != args.commit:
        print ""
        print "If you wish to roll back, you can run:"
        print ""
        print PaastaColors.bold(
            "    paasta rollback --service %s --deploy-group %s --commit %s " %
            (service, args.deploy_group, old_git_sha))
    return ret
Esempio n. 18
0
def paasta_mark_for_deployment(args):
    """Wrapping mark_for_deployment"""
    if args.verbose:
        log.setLevel(level=logging.DEBUG)
    else:
        log.setLevel(level=logging.INFO)

    service = args.service
    if service and service.startswith("services-"):
        service = service.split("services-", 1)[1]
    validate_service_name(service, soa_dir=args.soa_dir)

    deploy_group = args.deploy_group
    in_use_deploy_groups = list_deploy_groups(service=service, soa_dir=args.soa_dir)
    _, invalid_deploy_groups = validate_given_deploy_groups(
        in_use_deploy_groups, [deploy_group]
    )

    if len(invalid_deploy_groups) == 1:
        paasta_print(
            PaastaColors.red(
                "ERROR: These deploy groups are not currently used anywhere: %s.\n"
                % (",").join(invalid_deploy_groups)
            )
        )
        paasta_print(
            PaastaColors.red(
                "This isn't technically wrong because you can mark-for-deployment before deploying there"
            )
        )
        paasta_print(
            PaastaColors.red(
                "but this is probably a typo. Did you mean one of these in-use deploy groups?:"
            )
        )
        paasta_print(PaastaColors.red("   %s" % (",").join(in_use_deploy_groups)))
        paasta_print()
        paasta_print(PaastaColors.red("Continuing regardless..."))

    if args.git_url is None:
        args.git_url = get_git_url(service=service, soa_dir=args.soa_dir)

    commit = validate_git_sha(sha=args.commit, git_url=args.git_url)

    old_git_sha = get_currently_deployed_sha(service=service, deploy_group=deploy_group)
    if old_git_sha == commit:
        paasta_print(
            "Warning: The sha asked to be deployed already matches what is set to be deployed:"
        )
        paasta_print(old_git_sha)
        paasta_print("Continuing anyway.")

    if args.verify_image:
        if not is_docker_image_already_in_registry(service, args.soa_dir, commit):
            raise ValueError(
                "Failed to find image in the registry for the following sha %s" % commit
            )

    deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir)
    deploy_process = MarkForDeploymentProcess(
        service=service,
        deploy_info=deploy_info,
        deploy_group=deploy_group,
        commit=commit,
        old_git_sha=old_git_sha,
        git_url=args.git_url,
        auto_rollback=args.auto_rollback,
        block=args.block,
        soa_dir=args.soa_dir,
        timeout=args.timeout,
        auto_certify_delay=args.auto_certify_delay,
        auto_abandon_delay=args.auto_abandon_delay,
        auto_rollback_delay=args.auto_rollback_delay,
    )
    ret = deploy_process.run()
    return ret
Esempio n. 19
0
def paasta_rollback(args: argparse.Namespace) -> int:
    """Call mark_for_deployment with rollback parameters
    :param args: contains all the arguments passed onto the script: service,
    deploy groups and sha. These arguments will be verified and passed onto
    mark_for_deployment.
    """
    soa_dir = args.soa_dir
    service = figure_out_service_name(args, soa_dir)

    deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir)
    if not can_user_deploy_service(deploy_info, service):
        return 1

    git_url = get_git_url(service, soa_dir)

    if args.all_deploy_groups:
        given_deploy_groups = list_deploy_groups(service=service,
                                                 soa_dir=soa_dir)
    else:
        given_deploy_groups = {
            deploy_group
            for deploy_group in args.deploy_groups.split(",") if deploy_group
        }

    all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
    deploy_groups, invalid = validate_given_deploy_groups(
        all_deploy_groups, given_deploy_groups)

    if len(invalid) > 0:
        print(
            PaastaColors.yellow(
                "These deploy groups are not valid and will be skipped: %s.\n"
                % (",").join(invalid)))

    if len(deploy_groups) == 0 and not args.all_deploy_groups:
        print(
            PaastaColors.red(
                "ERROR: No valid deploy groups specified for %s.\n Use the flag -a to rollback all valid deploy groups for this service"
                % (service)))
        return 1

    versions = get_versions_for_service(service, deploy_groups, soa_dir)
    commit = args.commit
    image_version = args.image_version
    new_version = DeploymentVersion(sha=commit, image_version=image_version)
    if not commit:
        print("Please specify a commit to mark for rollback (-k, --commit).")
        list_previous_versions(service, deploy_groups,
                               bool(given_deploy_groups), versions)
        return 1
    elif new_version not in versions and not args.force:
        print(
            PaastaColors.red(
                f"This version {new_version} has never been deployed before."))
        print(
            "Please double check it or use --force to skip this verification.\n"
        )
        list_previous_versions(service, deploy_groups,
                               bool(given_deploy_groups), versions)
        return 1

    # TODO: Add similar check for when image_version is empty and no-commit redeploys is enforced for requested deploy_group

    returncode = 0

    for deploy_group in deploy_groups:
        rolled_back_from = get_currently_deployed_version(
            service, deploy_group)
        returncode |= mark_for_deployment(
            git_url=git_url,
            service=service,
            deploy_group=deploy_group,
            commit=commit,
            image_version=image_version,
        )

        # we could also gate this by the return code from m-f-d, but we probably care more about someone wanting to
        # rollback than we care about if the underlying machinery was successfully able to complete the request

        if rolled_back_from != new_version:
            audit_action_details = {
                "rolled_back_from": str(rolled_back_from),
                "rolled_back_to": str(new_version),
                "rollback_type": RollbackTypes.USER_INITIATED_ROLLBACK.value,
                "deploy_group": deploy_group,
            }
            _log_audit(action="rollback",
                       action_details=audit_action_details,
                       service=service)

    return returncode