Example #1
0
def delete_team(object_id, continuous=True, **kwargs):
    from sentry.models import Team, TeamStatus, Project, ProjectStatus

    try:
        t = Team.objects.get(id=object_id)
    except Team.DoesNotExist:
        return

    if t.status == TeamStatus.VISIBLE:
        raise DeleteAborted('Aborting team deletion as status is invalid')

    if t.status != TeamStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Team, instance=t)
        t.update(status=TeamStatus.DELETION_IN_PROGRESS)

    # Delete 1 project at a time since this is expensive by itself
    for project in Project.objects.filter(team=t).order_by('id')[:1]:
        logger.info('Removing Project id=%s where team=%s', project.id, t.id)
        project.update(status=ProjectStatus.DELETION_IN_PROGRESS)
        delete_project(project.id, continuous=False)
        if continuous:
            delete_team.delay(object_id=object_id, countdown=15)
        return

    t.delete()
Example #2
0
def delete_team(object_id, continuous=True, **kwargs):
    from sentry.models import Team, TeamStatus, Project, ProjectStatus

    try:
        t = Team.objects.get(id=object_id)
    except Team.DoesNotExist:
        return

    if t.status == TeamStatus.VISIBLE:
        raise DeleteAborted('Aborting team deletion as status is invalid')

    if t.status != TeamStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Team, instance=t)
        t.update(status=TeamStatus.DELETION_IN_PROGRESS)

    # Delete 1 project at a time since this is expensive by itself
    for project in Project.objects.filter(team=t).order_by('id')[:1]:
        logger.info('Removing Project id=%s where team=%s', project.id, t.id)
        project.update(status=ProjectStatus.DELETION_IN_PROGRESS)
        delete_project(project.id, continuous=False)
        if continuous:
            delete_team.delay(object_id=object_id, countdown=15)
        return

    t.delete()
Example #3
0
def delete_organization(object_id, continuous=True, **kwargs):
    from sentry.models import (
        Organization, OrganizationMember, OrganizationStatus, Team, TeamStatus
    )

    try:
        o = Organization.objects.get(id=object_id)
    except Organization.DoesNotExist:
        return

    if o.status == OrganizationStatus.VISIBLE:
        raise DeleteAborted('Aborting organization deletion as status is invalid')

    if o.status != OrganizationStatus.DELETION_IN_PROGRESS:
        o.update(status=OrganizationStatus.DELETION_IN_PROGRESS)
        pending_delete.send(sender=Organization, instance=o)

    for team in Team.objects.filter(organization=o).order_by('id')[:1]:
        logger.info('Removing Team id=%s where organization=%s', team.id, o.id)
        team.update(status=TeamStatus.DELETION_IN_PROGRESS)
        delete_team(team.id, continuous=False)
        if continuous:
            delete_organization.delay(object_id=object_id, countdown=15)
        return

    model_list = (OrganizationMember,)

    has_more = delete_objects(model_list, relation={'organization': o}, logger=logger)
    if has_more:
        if continuous:
            delete_organization.delay(object_id=object_id, countdown=15)
        return
    o.delete()
Example #4
0
def delete_organization(object_id, transaction_id=None, **kwargs):
    from sentry import deletions
    from sentry.models import Organization, OrganizationStatus

    try:
        instance = Organization.objects.get(id=object_id)
    except Organization.DoesNotExist:
        return

    if instance.status == OrganizationStatus.VISIBLE:
        raise DeleteAborted

    # compat: can be removed after we switch to scheduled deletions
    if instance.status != OrganizationStatus.DELETION_IN_PROGRESS:
        pending_delete.send(
            sender=type(instance),
            instance=instance,
        )

    task = deletions.get(
        model=Organization,
        query={
            'id': object_id,
        },
        transaction_id=transaction_id or uuid4().hex,
    )
    has_more = task.chunk()
    if has_more:
        delete_organization.apply_async(
            kwargs={
                'object_id': object_id,
                'transaction_id': transaction_id
            },
            countdown=15,
        )
Example #5
0
def delete_organization(object_id,
                        transaction_id=None,
                        continuous=True,
                        **kwargs):
    from sentry.models import (Organization, OrganizationMember,
                               OrganizationStatus, Team, TeamStatus, Commit,
                               CommitAuthor, Repository)

    try:
        o = Organization.objects.get(id=object_id)
    except Organization.DoesNotExist:
        return

    if o.status == OrganizationStatus.VISIBLE:
        raise DeleteAborted(
            'Aborting organization deletion as status is invalid')

    if o.status != OrganizationStatus.DELETION_IN_PROGRESS:
        o.update(status=OrganizationStatus.DELETION_IN_PROGRESS)
        pending_delete.send(sender=Organization, instance=o)

    for team in Team.objects.filter(organization=o).order_by('id')[:1]:
        team.update(status=TeamStatus.DELETION_IN_PROGRESS)
        delete_team(team.id, transaction_id=transaction_id, continuous=False)
        if continuous:
            delete_organization.apply_async(
                kwargs={
                    'object_id': object_id,
                    'transaction_id': transaction_id
                },
                countdown=15,
            )
        return

    model_list = (OrganizationMember, Commit, CommitAuthor, Repository)

    has_more = delete_objects(
        model_list,
        transaction_id=transaction_id,
        relation={'organization_id': o.id},
        logger=logger,
    )
    if has_more:
        if continuous:
            delete_organization.apply_async(
                kwargs={
                    'object_id': object_id,
                    'transaction_id': transaction_id
                },
                countdown=15,
            )
        return
    o_id = o.id
    o.delete()
    logger.info('object.delete.executed',
                extra={
                    'object_id': o_id,
                    'transaction_id': transaction_id,
                    'model': Organization.__name__,
                })
Example #6
0
def delete_repository(object_id, transaction_id=None, actor_id=None, **kwargs):
    from sentry import deletions
    from sentry.models import Repository, User

    try:
        instance = Repository.objects.get(id=object_id)
    except Repository.DoesNotExist:
        return

    if instance.status == ObjectStatus.VISIBLE:
        raise DeleteAborted

    # compat: can be removed after we switch to scheduled deletions
    if instance.status != ObjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(
            sender=type(instance),
            instance=instance,
            actor=User.objects.get(id=actor_id) if actor_id else None,
        )

    task = deletions.get(
        model=Repository,
        actor_id=actor_id,
        query={"id": object_id},
        transaction_id=transaction_id or uuid4().hex,
    )
    has_more = task.chunk()
    if has_more:
        delete_repository.apply_async(
            kwargs={"object_id": object_id, "transaction_id": transaction_id, "actor_id": actor_id},
            countdown=15,
        )
Example #7
0
def delete_organization(object_id, transaction_id=None, actor_id=None, **kwargs):
    from sentry import deletions
    from sentry.models import Organization, OrganizationStatus

    try:
        instance = Organization.objects.get(id=object_id)
    except Organization.DoesNotExist:
        return

    if instance.status == OrganizationStatus.VISIBLE:
        raise DeleteAborted

    # compat: can be removed after we switch to scheduled deletions
    if instance.status != OrganizationStatus.DELETION_IN_PROGRESS:
        pending_delete.send(
            sender=type(instance),
            instance=instance,
        )

    task = deletions.get(
        model=Organization,
        query={
            'id': object_id,
        },
        transaction_id=transaction_id or uuid4().hex,
        actor_id=actor_id,
    )
    has_more = task.chunk()
    if has_more:
        delete_organization.apply_async(
            kwargs={'object_id': object_id,
                    'transaction_id': transaction_id,
                    'actor_id': actor_id},
            countdown=15,
        )
Example #8
0
def run_deletion(deletion_id):
    from sentry import deletions
    from sentry.models import ScheduledDeletion

    try:
        deletion = ScheduledDeletion.objects.get(id=deletion_id)
    except ScheduledDeletion.DoesNotExist:
        return

    if deletion.aborted:
        raise DeleteAborted

    if not deletion.in_progress:
        actor = deletion.get_actor()
        instance = deletion.get_instance()
        with transaction.atomic():
            deletion.update(in_progress=True)
            pending_delete.send(sender=type(instance), instance=instance, actor=actor)

    task = deletions.get(
        model=deletion.get_model(),
        query={"id": deletion.object_id},
        transaction_id=deletion.guid,
        actor_id=deletion.actor_id,
    )
    has_more = task.chunk()
    if has_more:
        run_deletion.apply_async(kwargs={"deletion_id": deletion_id}, countdown=15)
    deletion.delete()
 def delete_instance(self, instance):
     pending_delete.send(
         sender=type(instance),
         instance=instance,
         actor=self.get_actor(),
     )
     return super(RepositoryDeletionTask, self).delete_instance(instance)
Example #10
0
def generic_delete(app_label, model_name, object_id, transaction_id=None,
                   continuous=True, actor_id=None, **kwargs):
    from sentry.models import User

    model = get_model(app_label, model_name)

    try:
        instance = model.objects.get(id=object_id)
    except model.DoesNotExist:
        return

    if instance.status == ObjectStatus.VISIBLE:
        raise DeleteAborted

    if instance.status == ObjectStatus.PENDING_DELETION:
        if actor_id:
            actor = User.objects.get(id=actor_id)
        else:
            actor = None
        instance.update(status=ObjectStatus.DELETION_IN_PROGRESS)
        pending_delete.send(sender=model, instance=instance, actor=actor)

    # TODO(dcramer): it'd be nice if we could collect relations here and
    # cascade efficiently
    instance_id = instance.id
    instance.delete()
    logger.info('object.delete.executed', extra={
        'object_id': instance_id,
        'transaction_id': transaction_id,
        'model': model.__name__,
    })
Example #11
0
def delete_team(object_id, transaction_id=None, continuous=True, **kwargs):
    from sentry.models import Team, TeamStatus, Project, ProjectStatus

    try:
        t = Team.objects.get(id=object_id)
    except Team.DoesNotExist:
        return

    if t.status == TeamStatus.VISIBLE:
        raise DeleteAborted('Aborting team deletion as status is invalid')

    if t.status != TeamStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Team, instance=t)
        t.update(status=TeamStatus.DELETION_IN_PROGRESS)

    # Delete 1 project at a time since this is expensive by itself
    for project in Project.objects.filter(team=t).order_by('id')[:1]:
        project.update(status=ProjectStatus.DELETION_IN_PROGRESS)
        delete_project(project.id, transaction_id=transaction_id, continuous=False)
        if continuous:
            delete_team.apply_async(
                kwargs={'object_id': object_id, 'transaction_id': transaction_id},
                countdown=15,
            )
        return

    t_id = t.id
    t.delete()
    logger.info('object.delete.executed', extra={
        'object_id': t_id,
        'transaction_id': transaction_id,
        'model': Team.__name__,
    })
Example #12
0
def delete_organization(object_id, continuous=True, **kwargs):
    from sentry.models import (Organization, OrganizationMember,
                               OrganizationStatus, Team, TeamStatus)

    try:
        o = Organization.objects.get(id=object_id)
    except Team.DoesNotExist:
        return

    if o.status == OrganizationStatus.VISIBLE:
        raise DeleteAborted(
            'Aborting organization deletion as status is invalid')

    if o.status != OrganizationStatus.DELETION_IN_PROGRESS:
        o.update(status=OrganizationStatus.DELETION_IN_PROGRESS)
        pending_delete.send(sender=Organization, instance=o)

    for team in Team.objects.filter(organization=o).order_by('id')[:1]:
        logger.info('Removing Team id=%s where organization=%s', team.id, o.id)
        team.update(status=TeamStatus.DELETION_IN_PROGRESS)
        delete_team(team.id, continuous=False)
        if continuous:
            delete_organization.delay(object_id=object_id, countdown=15)
        return

    model_list = (OrganizationMember, )

    has_more = delete_objects(model_list,
                              relation={'organization': o},
                              logger=logger)
    if has_more:
        if continuous:
            delete_organization.delay(object_id=object_id, countdown=15)
        return
    o.delete()
Example #13
0
def generic_delete(app_label, model_name, object_id, transaction_id=None,
                   continuous=True, actor_id=None, **kwargs):
    from sentry.models import User

    model = get_model(app_label, model_name)

    try:
        instance = model.objects.get(id=object_id)
    except model.DoesNotExist:
        return

    if instance.status == ObjectStatus.VISIBLE:
        raise DeleteAborted

    if instance.status == ObjectStatus.PENDING_DELETION:
        if actor_id:
            actor = User.objects.get(id=actor_id)
        else:
            actor = None
        instance.update(status=ObjectStatus.DELETION_IN_PROGRESS)
        pending_delete.send(sender=model, instance=instance, actor=actor)

    # TODO(dcramer): it'd be nice if we could collect relations here and
    # cascade efficiently
    instance_id = instance.id
    instance.delete()
    logger.info('object.delete.executed', extra={
        'object_id': instance_id,
        'transaction_id': transaction_id,
        'model': model.__name__,
    })
Example #14
0
def delete_project(object_id, continuous=True, **kwargs):
    from sentry.models import (
        Activity, EventMapping, Group, GroupAssignee, GroupBookmark,
        GroupEmailThread, GroupHash, GroupMeta, GroupResolution,
        GroupRuleStatus, GroupSeen, GroupTagKey, GroupTagValue, Project,
        ProjectKey, ProjectStatus, SavedSearchUserDefault, SavedSearch, TagKey,
        TagValue, UserReport
    )

    try:
        p = Project.objects.get(id=object_id)
    except Project.DoesNotExist:
        return

    if p.status == ProjectStatus.VISIBLE:
        raise DeleteAborted('Aborting project deletion as status is invalid')

    if p.status != ProjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Project, instance=p)
        p.update(status=ProjectStatus.DELETION_IN_PROGRESS)

    # XXX: remove keys first to prevent additional data from flowing in
    model_list = (
        Activity, EventMapping, GroupAssignee, GroupBookmark, GroupEmailThread,
        GroupHash, GroupSeen, GroupRuleStatus, GroupTagKey,
        GroupTagValue, ProjectKey, TagKey, TagValue, SavedSearchUserDefault,
        SavedSearch, UserReport
    )
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    # TODO(dcramer): no project relation so we cant easily bulk
    # delete today
    has_more = delete_objects([GroupMeta, GroupResolution],
                              relation={'group__project': p},
                              logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    has_more = delete_events(relation={'project_id': p.id}, logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    model_list = (Group,)
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return
    p.delete()
Example #15
0
    def delete_instance(self, instance):
        # TODO child_relations should also send pending_delete so we
        # don't have to do this here.
        pending_delete.send(sender=type(instance),
                            instance=instance,
                            actor=self.get_actor())

        return super().delete_instance(instance)
Example #16
0
def delete_project(object_id, continuous=True, **kwargs):
    from sentry.models import (Activity, EventMapping, Group, GroupAssignee,
                               GroupBookmark, GroupEmailThread, GroupHash,
                               GroupMeta, GroupResolution, GroupRuleStatus,
                               GroupSeen, GroupTagKey, GroupTagValue, Project,
                               ProjectKey, ProjectStatus,
                               SavedSearchUserDefault, SavedSearch, TagKey,
                               TagValue, UserReport)

    try:
        p = Project.objects.get(id=object_id)
    except Project.DoesNotExist:
        return

    if p.status == ProjectStatus.VISIBLE:
        raise DeleteAborted('Aborting project deletion as status is invalid')

    if p.status != ProjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Project, instance=p)
        p.update(status=ProjectStatus.DELETION_IN_PROGRESS)

    # XXX: remove keys first to prevent additional data from flowing in
    model_list = (Activity, EventMapping, GroupAssignee, GroupBookmark,
                  GroupEmailThread, GroupHash, GroupSeen, GroupRuleStatus,
                  GroupTagKey, GroupTagValue, ProjectKey, TagKey, TagValue,
                  SavedSearchUserDefault, SavedSearch, UserReport)
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    # TODO(dcramer): no project relation so we cant easily bulk
    # delete today
    has_more = delete_objects([GroupMeta, GroupResolution],
                              relation={'group__project': p},
                              logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    has_more = delete_events(relation={'project_id': p.id}, logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    model_list = (Group, )
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return
    p.delete()
Example #17
0
def run_deletion(deletion_id, first_pass=True):
    from sentry import deletions
    from sentry.models import ScheduledDeletion

    try:
        deletion = ScheduledDeletion.objects.get(id=deletion_id)
    except ScheduledDeletion.DoesNotExist:
        return

    try:
        instance = deletion.get_instance()
    except ObjectDoesNotExist:
        logger.info(
            "object.delete.object-missing",
            extra={
                "object_id": deletion.object_id,
                "transaction_id": deletion.guid,
                "model": deletion.model_name,
            },
        )
        deletion.delete()
        return

    task = deletions.get(
        model=deletion.get_model(),
        query={"id": deletion.object_id},
        transaction_id=deletion.guid,
        actor_id=deletion.actor_id,
    )
    if not task.should_proceed(instance):
        logger.info(
            "object.delete.aborted",
            extra={
                "object_id": deletion.object_id,
                "transaction_id": deletion.guid,
                "model": deletion.model_name,
            },
        )
        deletion.delete()
        return

    if first_pass:
        actor = deletion.get_actor()
        pending_delete.send(sender=type(instance),
                            instance=instance,
                            actor=actor)

    has_more = task.chunk()
    if has_more:
        run_deletion.apply_async(kwargs={
            "deletion_id": deletion_id,
            "first_pass": False
        },
                                 countdown=15)
    else:
        deletion.delete()
Example #18
0
def delete_organization(object_id, transaction_id=None, continuous=True, **kwargs):
    from sentry.models import (
        Organization, OrganizationMember, OrganizationStatus, Team, TeamStatus,
        Commit, CommitAuthor, CommitFileChange, Environment, Release, ReleaseCommit,
        ReleaseEnvironment, ReleaseFile, ReleaseHeadCommit, Repository
    )

    try:
        o = Organization.objects.get(id=object_id)
    except Organization.DoesNotExist:
        return

    if o.status == OrganizationStatus.VISIBLE:
        raise DeleteAborted('Aborting organization deletion as status is invalid')

    if o.status != OrganizationStatus.DELETION_IN_PROGRESS:
        o.update(status=OrganizationStatus.DELETION_IN_PROGRESS)
        pending_delete.send(sender=Organization, instance=o)

    for team in Team.objects.filter(organization=o).order_by('id')[:1]:
        team.update(status=TeamStatus.DELETION_IN_PROGRESS)
        delete_team(team.id, transaction_id=transaction_id, continuous=False)
        if continuous:
            delete_organization.apply_async(
                kwargs={'object_id': object_id, 'transaction_id': transaction_id},
                countdown=15,
            )
        return

    model_list = (
        OrganizationMember, CommitFileChange, Commit, CommitAuthor,
        Environment, Repository, Release, ReleaseCommit,
        ReleaseEnvironment, ReleaseFile, ReleaseHeadCommit
    )

    has_more = delete_objects(
        model_list,
        transaction_id=transaction_id,
        relation={'organization_id': o.id},
        logger=logger,
    )
    if has_more:
        if continuous:
            delete_organization.apply_async(
                kwargs={'object_id': object_id, 'transaction_id': transaction_id},
                countdown=15,
            )
        return
    o_id = o.id
    o.delete()
    logger.info('object.delete.executed', extra={
        'object_id': o_id,
        'transaction_id': transaction_id,
        'model': Organization.__name__,
    })
Example #19
0
def delete_project(object_id, continuous=True, **kwargs):
    from sentry.models import (
        Project, ProjectKey, ProjectStatus, TagKey, TagValue, GroupTagKey,
        GroupTagValue, Activity, EventMapping, Group, GroupEmailThread,
        GroupRuleStatus, GroupHash, GroupSeen, UserReport
    )

    try:
        p = Project.objects.get(id=object_id)
    except Project.DoesNotExist:
        return

    if p.status == ProjectStatus.VISIBLE:
        raise DeleteAborted('Aborting project deletion as status is invalid')

    if p.status != ProjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Project, instance=p)
        p.update(status=ProjectStatus.DELETION_IN_PROGRESS)

    # XXX: remove keys first to prevent additional data from flowing in
    model_list = (
        ProjectKey, TagKey, TagValue, GroupTagKey, GroupTagValue, EventMapping,
        Activity, GroupRuleStatus, GroupHash, GroupSeen, UserReport,
        GroupEmailThread
    )
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    has_more = delete_events(relation={'project_id': p.id}, logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    model_list = (Group,)
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return
    p.delete()
Example #20
0
def generic_delete(app_label,
                   model_name,
                   object_id,
                   transaction_id=None,
                   actor_id=None,
                   **kwargs):
    from sentry import deletions
    from sentry.models import User

    model = get_model(app_label, model_name)

    try:
        instance = model.objects.get(id=object_id)
    except model.DoesNotExist:
        return

    if instance.status != ObjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(
            sender=type(instance),
            instance=instance,
            actor=User.objects.get(id=actor_id) if actor_id else None,
        )

    if instance.status == ObjectStatus.VISIBLE:
        raise DeleteAborted

    task = deletions.get(
        model=model,
        actor_id=actor_id,
        query={
            'id': object_id,
        },
        transaction_id=transaction_id or uuid4().hex,
    )
    has_more = task.chunk()
    if has_more:
        generic_delete.apply_async(
            kwargs={
                'app_label': app_label,
                'model_name': model_name,
                'object_id': object_id,
                'transaction_id': transaction_id,
                'actor_id': actor_id,
            },
            countdown=15,
        )
Example #21
0
def generic_delete(app_label, model_name, object_id, transaction_id=None, actor_id=None, **kwargs):
    from sentry import deletions
    from sentry.models import User

    model = get_model(app_label, model_name)

    try:
        instance = model.objects.get(id=object_id)
    except model.DoesNotExist:
        return

    if instance.status != ObjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(
            sender=type(instance),
            instance=instance,
            actor=User.objects.get(id=actor_id) if actor_id else None,
        )

    if instance.status == ObjectStatus.VISIBLE:
        raise DeleteAborted

    task = deletions.get(
        model=model,
        actor_id=actor_id,
        query={
            'id': object_id,
        },
        transaction_id=transaction_id or uuid4().hex,
    )
    has_more = task.chunk()
    if has_more:
        generic_delete.apply_async(
            kwargs={
                'app_label': app_label,
                'model_name': model_name,
                'object_id': object_id,
                'transaction_id': transaction_id,
                'actor_id': actor_id,
            },
            countdown=15,
        )
Example #22
0
def delete_repository(object_id, transaction_id=None, continuous=True,
                      actor_id=None, **kwargs):
    from sentry.models import Commit, Repository, User

    try:
        repo = Repository.objects.get(id=object_id)
    except Repository.DoesNotExist:
        return

    if repo.status == ObjectStatus.VISIBLE:
        raise DeleteAborted

    if repo.status == ObjectStatus.PENDING_DELETION:
        if actor_id:
            actor = User.objects.get(id=actor_id)
        else:
            actor = None
        repo.update(status=ObjectStatus.DELETION_IN_PROGRESS)
        pending_delete.send(sender=Repository, instance=repo, actor=actor)

    has_more = delete_objects(
        (Commit,),
        transaction_id=transaction_id,
        relation={'repository_id': repo.id},
        logger=logger,
    )
    if has_more:
        if continuous:
            delete_repository.apply_async(
                kwargs={'object_id': object_id, 'transaction_id': transaction_id},
                countdown=15,
            )
        return

    repo_id = repo.id
    repo.delete()
    logger.info('object.delete.executed', extra={
        'object_id': repo_id,
        'transaction_id': transaction_id,
        'model': Repository.__name__,
    })
Example #23
0
def run_deletion(deletion_id):
    from sentry import deletions
    from sentry.models import ScheduledDeletion

    try:
        deletion = ScheduledDeletion.objects.get(
            id=deletion_id,
        )
    except ScheduledDeletion.DoesNotExist:
        return

    if deletion.aborted:
        raise DeleteAborted

    if not deletion.in_progress:
        actor = deletion.get_actor()
        instance = deletion.get_instance()
        with transaction.atomic():
            deletion.update(in_progress=True)
            pending_delete.send(
                sender=type(instance),
                instance=instance,
                actor=actor,
            )

    task = deletions.get(
        model=deletion.get_model(),
        query={
            'id': deletion.object_id,
        },
        transaction_id=deletion.guid,
        actor_id=deletion.actor_id,
    )
    has_more = task.chunk()
    if has_more:
        run_deletion.apply_async(
            kwargs={'deletion_id': deletion_id},
            countdown=15,
        )
    deletion.delete()
Example #24
0
def delete_organization(object_id,
                        transaction_id=None,
                        actor_id=None,
                        **kwargs):
    # TODO(mark) remove this task once all in flight jobs have been processed.
    from sentry import deletions
    from sentry.models import Organization, OrganizationStatus

    try:
        instance = Organization.objects.get(id=object_id)
    except Organization.DoesNotExist:
        return

    if instance.status == OrganizationStatus.VISIBLE:
        raise DeleteAborted

    # compat: can be removed after we switch to scheduled deletions
    if instance.status != OrganizationStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=type(instance), instance=instance)

    task = deletions.get(
        model=Organization,
        query={"id": object_id},
        transaction_id=transaction_id or uuid4().hex,
        actor_id=actor_id,
    )
    has_more = task.chunk()
    if has_more:
        delete_organization.apply_async(
            kwargs={
                "object_id": object_id,
                "transaction_id": transaction_id,
                "actor_id": actor_id
            },
            countdown=15,
        )
Example #25
0
def delete_project(object_id, continuous=True, **kwargs):
    from sentry.models import (
        Project,
        ProjectKey,
        ProjectStatus,
        TagKey,
        TagValue,
        GroupTagKey,
        GroupTagValue,
        Activity,
        EventMapping,
        Group,
        GroupRuleStatus,
        GroupHash,
        GroupSeen,
    )

    try:
        p = Project.objects.get(id=object_id)
    except Project.DoesNotExist:
        return

    if p.status == ProjectStatus.VISIBLE:
        raise DeleteAborted('Aborting project deletion as status is invalid')

    if p.status != ProjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Project, instance=p)
        p.update(status=ProjectStatus.DELETION_IN_PROGRESS)

    # XXX: remove keys first to prevent additional data from flowing in
    model_list = (
        ProjectKey,
        TagKey,
        TagValue,
        GroupTagKey,
        GroupTagValue,
        EventMapping,
        Activity,
        GroupRuleStatus,
        GroupHash,
        GroupSeen,
    )
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    has_more = delete_events(relation={'project_id': p.id}, logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    model_list = (Group, )
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return
    p.delete()
Example #26
0
 def delete_instance(self, instance):
     pending_delete.send(sender=type(instance),
                         instance=instance,
                         actor=self.get_actor())
     return super().delete_instance(instance)
Example #27
0
def delete_project(object_id, transaction_id=None, continuous=True, **kwargs):
    from sentry.models import (
        Activity, EventMapping, EventUser, Group, GroupAssignee, GroupBookmark,
        GroupEmailThread, GroupHash, GroupMeta, GroupRelease, GroupResolution,
        GroupRuleStatus, GroupSeen, GroupSubscription, GroupSnooze, GroupTagKey,
        GroupTagValue, Project, ProjectBookmark, ProjectKey, ProjectStatus,
        Release, ReleaseFile, SavedSearchUserDefault, SavedSearch, TagKey,
        TagValue, UserReport, ReleaseEnvironment, Environment
    )

    try:
        p = Project.objects.get(id=object_id)
    except Project.DoesNotExist:
        return

    if p.status == ProjectStatus.VISIBLE:
        raise DeleteAborted('Aborting project deletion as status is invalid')

    if p.status != ProjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Project, instance=p)
        p.update(status=ProjectStatus.DELETION_IN_PROGRESS)

    # Immediately revoke keys
    project_keys = list(ProjectKey.objects.filter(project_id=object_id).values_list('id', flat=True))
    ProjectKey.objects.filter(project_id=object_id).delete()
    for key_id in project_keys:
        logger.info('object.delete.executed', extra={
            'object_id': key_id,
            'transaction_id': transaction_id,
            'model': ProjectKey.__name__,
        })

    model_list = (
        Activity, EventMapping, EventUser, GroupAssignee, GroupBookmark,
        GroupEmailThread, GroupHash, GroupRelease, GroupRuleStatus, GroupSeen,
        GroupSubscription, GroupTagKey, GroupTagValue, ProjectBookmark,
        ProjectKey, TagKey, TagValue, SavedSearchUserDefault, SavedSearch,
        UserReport, ReleaseEnvironment, Environment
    )
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, transaction_id=transaction_id, logger=logger)
        if has_more:
            if continuous:
                delete_project.apply_async(
                    kwargs={'object_id': object_id, 'transaction_id': transaction_id},
                    countdown=15,
                )
            return

    # TODO(dcramer): no project relation so we cant easily bulk
    # delete today
    has_more = delete_objects([GroupMeta, GroupResolution, GroupSnooze],
                              relation={'group__project': p},
                              transaction_id=transaction_id,
                              logger=logger)
    if has_more:
        if continuous:
            delete_project.apply_async(
                kwargs={'object_id': object_id, 'transaction_id': transaction_id},
                countdown=15,
            )
        return

    has_more = delete_events(relation={'project_id': p.id}, transaction_id=transaction_id, logger=logger)
    if has_more:
        if continuous:
            delete_project.apply_async(
                kwargs={'object_id': object_id, 'transaction_id': transaction_id},
            )
        return

    # Release needs to handle deletes after Group is cleaned up as the foreign
    # key is protected
    model_list = (Group, ReleaseFile, Release)
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, transaction_id=transaction_id, logger=logger)
        if has_more:
            if continuous:
                delete_project.apply_async(
                    kwargs={'object_id': object_id, 'transaction_id': transaction_id},
                    countdown=15,
                )
            return

    p_id = p.id
    p.delete()
    logger.info('object.delete.queued', extra={
        'object_id': p_id,
        'transaction_id': transaction_id,
        'model': Project.__name__,
    })
Example #28
0
def delete_project(object_id, continuous=True, **kwargs):
    from sentry.models import (
        Activity, EventMapping, Group, GroupAssignee, GroupBookmark,
        GroupEmailThread, GroupHash, GroupMeta, GroupResolution,
        GroupRuleStatus, GroupSeen, GroupTagKey, GroupTagValue, Project,
        ProjectBookmark, ProjectKey, ProjectStatus, Release, ReleaseFile,
        SavedSearchUserDefault, SavedSearch, TagKey, TagValue, UserReport
    )

    try:
        p = Project.objects.get(id=object_id)
    except Project.DoesNotExist:
        return

    if p.status == ProjectStatus.VISIBLE:
        raise DeleteAborted('Aborting project deletion as status is invalid')

    if p.status != ProjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Project, instance=p)
        p.update(status=ProjectStatus.DELETION_IN_PROGRESS)

    # Immediately revoke keys
    ProjectKey.objects.filter(project_id=object_id).delete()

    model_list = (
        Activity, EventMapping, GroupAssignee, GroupBookmark, GroupEmailThread,
        GroupHash, GroupSeen, GroupRuleStatus, GroupTagKey, GroupTagValue,
        ProjectBookmark, ProjectKey, TagKey, TagValue, SavedSearchUserDefault,
        SavedSearch, UserReport
    )
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    # TODO(dcramer): no project relation so we cant easily bulk
    # delete today
    has_more = delete_objects([GroupMeta, GroupResolution],
                              relation={'group__project': p},
                              logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    has_more = delete_events(relation={'project_id': p.id}, logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    # Release needs to handle deletes after Group is cleaned up as the foreign
    # key is protected
    model_list = (Group, ReleaseFile, Release)
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    p.delete()
Example #29
0
def delete_project(object_id, continuous=True, **kwargs):
    from sentry.models import (Activity, EventMapping, Group, GroupAssignee,
                               GroupBookmark, GroupEmailThread, GroupHash,
                               GroupMeta, GroupResolution, GroupRuleStatus,
                               GroupSeen, GroupTagKey, GroupTagValue, Project,
                               ProjectBookmark, ProjectKey, ProjectStatus,
                               Release, ReleaseFile, SavedSearchUserDefault,
                               SavedSearch, TagKey, TagValue, UserReport)

    try:
        p = Project.objects.get(id=object_id)
    except Project.DoesNotExist:
        return

    if p.status == ProjectStatus.VISIBLE:
        raise DeleteAborted('Aborting project deletion as status is invalid')

    if p.status != ProjectStatus.DELETION_IN_PROGRESS:
        pending_delete.send(sender=Project, instance=p)
        p.update(status=ProjectStatus.DELETION_IN_PROGRESS)

    # Immediately revoke keys
    ProjectKey.objects.filter(project_id=object_id).delete()

    model_list = (Activity, EventMapping, GroupAssignee, GroupBookmark,
                  GroupEmailThread, GroupHash, GroupSeen, GroupRuleStatus,
                  GroupTagKey, GroupTagValue, ProjectBookmark, ProjectKey,
                  TagKey, TagValue, SavedSearchUserDefault, SavedSearch,
                  UserReport)
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    # TODO(dcramer): no project relation so we cant easily bulk
    # delete today
    has_more = delete_objects([GroupMeta, GroupResolution],
                              relation={'group__project': p},
                              logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    has_more = delete_events(relation={'project_id': p.id}, logger=logger)
    if has_more:
        if continuous:
            delete_project.delay(object_id=object_id, countdown=15)
        return

    # Release needs to handle deletes after Group is cleaned up as the foreign
    # key is protected
    model_list = (Group, ReleaseFile, Release)
    for model in model_list:
        has_more = bulk_delete_objects(model, project_id=p.id, logger=logger)
        if has_more:
            if continuous:
                delete_project.delay(object_id=object_id, countdown=15)
            return

    p.delete()