Просмотр исходного кода

fix: remove appstore connect integration and tables (#73960)

Followed the guideline available at:
https://develop.sentry.dev/database-migrations/#deleting-tables as much
as I can.

I basically created a migration that doesn't get executed unless we
manually run it. Please let me know if this is not the preferred
approach.

Once this gets merged in:
- we need to manually run the migration to remove the database tables in
production.
- land another PR to remove the existing TODOs and noops.

Let's wait until July 10 to remove all data.

cc @kahest 

Ref: https://github.com/getsentry/sentry/issues/51994
Yagiz Nizipli 8 месяцев назад
Родитель
Сommit
2294902062

+ 0 - 3
.github/CODEOWNERS

@@ -536,14 +536,11 @@ static/app/components/events/eventStatisticalDetector/                    @getse
 /src/sentry/api/endpoints/event_reprocessable.py                     @getsentry/processing
 /src/sentry/api/endpoints/project_reprocessing.py                    @getsentry/processing
 /src/sentry/api/endpoints/chunk.py                                   @getsentry/processing
-/src/sentry/api/endpoints/project_app_store_connect_credentials.py   @getsentry/processing
 /src/sentry/lang/native/                                             @getsentry/processing
 /src/sentry/processing/realtime_metrics/                             @getsentry/processing
-/src/sentry/tasks/app_store_connect.py                               @getsentry/processing
 /src/sentry/tasks/assemble.py                                        @getsentry/processing
 /src/sentry/tasks/low_priority_symbolication.py                      @getsentry/processing
 /src/sentry/tasks/symbolication.py                                   @getsentry/processing
-/src/sentry/utils/appleconnect/                                      @getsentry/processing
 /tests/sentry/tasks/test_low_priority_symbolication.py               @getsentry/processing
 /src/sentry/tasks/reprocessing.py                                    @getsentry/processing
 /src/sentry/tasks/reprocessing2.py                                   @getsentry/processing

+ 0 - 41
fixtures/backup/model_dependencies/detailed.json

@@ -706,24 +706,6 @@
       ]
     ]
   },
-  "sentry.appconnectbuild": {
-    "dangling": false,
-    "foreign_keys": {
-      "project": {
-        "kind": "FlexibleForeignKey",
-        "model": "sentry.project",
-        "nullable": false
-      }
-    },
-    "model": "sentry.appconnectbuild",
-    "relocation_dependencies": [],
-    "relocation_scope": "Excluded",
-    "silos": [
-      "Region"
-    ],
-    "table_name": "sentry_appconnectbuild",
-    "uniques": []
-  },
   "sentry.artifactbundle": {
     "dangling": false,
     "foreign_keys": {
@@ -3111,29 +3093,6 @@
       ]
     ]
   },
-  "sentry.latestappconnectbuildscheck": {
-    "dangling": false,
-    "foreign_keys": {
-      "project": {
-        "kind": "FlexibleForeignKey",
-        "model": "sentry.project",
-        "nullable": false
-      }
-    },
-    "model": "sentry.latestappconnectbuildscheck",
-    "relocation_dependencies": [],
-    "relocation_scope": "Excluded",
-    "silos": [
-      "Region"
-    ],
-    "table_name": "sentry_latestappconnectbuildscheck",
-    "uniques": [
-      [
-        "project",
-        "source_id"
-      ]
-    ]
-  },
   "sentry.latestreporeleaseenvironment": {
     "dangling": false,
     "foreign_keys": {

+ 0 - 6
fixtures/backup/model_dependencies/flat.json

@@ -99,9 +99,6 @@
     "sentry.apiapplication",
     "sentry.user"
   ],
-  "sentry.appconnectbuild": [
-    "sentry.project"
-  ],
   "sentry.artifactbundle": [
     "sentry.file",
     "sentry.organization"
@@ -431,9 +428,6 @@
     "sentry.organizationintegration"
   ],
   "sentry.integrationfeature": [],
-  "sentry.latestappconnectbuildscheck": [
-    "sentry.project"
-  ],
   "sentry.latestreporeleaseenvironment": [
     "sentry.commit",
     "sentry.deploy",

+ 0 - 2
fixtures/backup/model_dependencies/sorted.json

@@ -63,7 +63,6 @@
   "sentry.notificationsettingoption",
   "sentry.monitor",
   "sentry.lostpasswordhash",
-  "sentry.latestappconnectbuildscheck",
   "sentry.integrationexternalproject",
   "sentry.identity",
   "sentry.grouptombstone",
@@ -92,7 +91,6 @@
   "sentry.authenticator",
   "sentry.assistantactivity",
   "sentry.artifactbundle",
-  "sentry.appconnectbuild",
   "sentry.apikey",
   "sentry.apiapplication",
   "replays.replayrecordingsegment",

+ 0 - 2
fixtures/backup/model_dependencies/truncate.json

@@ -63,7 +63,6 @@
   "sentry_notificationsettingoption",
   "sentry_monitor",
   "sentry_lostpasswordhash",
-  "sentry_latestappconnectbuildscheck",
   "sentry_integrationexternalproject",
   "sentry_identity",
   "sentry_grouptombstone",
@@ -92,7 +91,6 @@
   "auth_authenticator",
   "sentry_assistant_activity",
   "sentry_artifactbundle",
-  "sentry_appconnectbuild",
   "sentry_apikey",
   "sentry_apiapplication",
   "replays_replayrecordingsegment",

+ 1 - 1
migrations_lockfile.txt

@@ -10,6 +10,6 @@ hybridcloud: 0016_add_control_cacheversion
 nodestore: 0002_nodestore_no_dictfield
 remote_subscriptions: 0003_drop_remote_subscription
 replays: 0004_index_together
-sentry: 0734_rm_reprocessing_step1
+sentry: 0735_sunset_appstore_connect_integration
 social_auth: 0002_default_auto_field
 uptime: 0003_drop_remote_subscription

+ 0 - 81
scripts/appconnect_cli.py

@@ -1,81 +0,0 @@
-#!/usr/bin/env sentry exec
-"""Dumb CLI to experiment with our App Store Connect functionality.
-
-It contains several useful tools to manipulate the database during development.  Exactly
-what it does can be easily changed based on new needs though, nothing is set in stone.
-
-Most actions assume you have only one App Store Connect source and will simply pick the
-first one found.
-"""
-import sys
-from pprint import pprint
-
-import orjson
-
-from sentry.lang.native.appconnect import SYMBOL_SOURCES_PROP_NAME
-from sentry.models.appconnectbuilds import AppConnectBuild
-from sentry.models.project import Project
-from sentry.tasks import app_store_connect
-
-PROJECT_ID = 2
-
-
-def main(argv):
-    if argv[0] == "dump-cfg":
-        # Dumps the symbolSource configuration as stored in the project option.
-        project = Project.objects.get(pk=PROJECT_ID)
-        raw_config = project.get_option(SYMBOL_SOURCES_PROP_NAME, default="[]")
-        config = orjson.loads(raw_config)
-        pprint(config)
-
-    elif argv[0] == "dsyms":
-        # Start the dsym_download task for first config found (needs running workers).
-        config = appconnect_config()
-        app_store_connect.dsym_download(PROJECT_ID, config["id"])
-
-    elif argv[0] == "zip":
-        # "Uploads" DIFs into sentry from a zipfile passed as argument.
-        project = Project.objects.get(pk=PROJECT_ID)
-        app_store_connect.create_difs_from_dsyms_zip(argv[1], project)
-
-    elif argv[0] == "dump-db":
-        # Dumps (part of) the AppConnectBuild table.
-        for build in AppConnectBuild.objects.all():
-            print(  # noqa: S002
-                f"{build!r} app_id={build.app_id} bundle_id={build.bundle_id} platform={build.platform} version={build.bundle_short_version} build={build.bundle_version} fetched={build.fetched}"
-            )
-
-    elif argv[0] == "reset-fetched":
-        # Resets the fetched state of the AppConnectBuild table, so dsym_download task will
-        # process the entries again.
-        for build in AppConnectBuild.objects.all():
-            build.fetched = False
-            build.save()
-
-    elif argv[0] == "task":
-        # Manually trigger the dsym_download task right now (needs running workers).
-        config = appconnect_config()
-        app_store_connect.dsym_download.apply_async(
-            kwargs={"project_id": PROJECT_ID, "config_id": config["id"]}
-        )
-
-    else:
-        raise ValueError("Unknown command")
-
-
-def appconnect_config():
-    project = Project.objects.get(pk=PROJECT_ID)
-    raw_config = project.get_option(SYMBOL_SOURCES_PROP_NAME, default="[]")
-    symbol_sources = orjson.loads(raw_config)
-    for config in symbol_sources:
-        if config["type"] == "appStoreConnect":
-            return config
-    else:
-        raise KeyError("appStoreConnect config not found")
-
-
-if __name__ == "__main__":
-    if sys.argv[2].startswith("--project="):
-        project_arg = sys.argv.pop(2)
-        PROJECT_ID = int(project_arg[10:])
-    main(sys.argv[2:])

+ 1 - 9
src/sentry/api/endpoints/project_details.py

@@ -331,6 +331,7 @@ class ProjectAdminSerializer(ProjectMemberSerializer):
             # This should only apply to sources which are being fed to symbolicator.
             # App Store Connect in particular is managed in a completely different
             # way, and needs its `id` to stay valid for a longer time.
+            # TODO(@anonrig): Remove this when all AppStore connect data is removed.
             if source["type"] != "appStoreConnect":
                 source["id"] = str(uuid4())
 
@@ -346,15 +347,6 @@ class ProjectAdminSerializer(ProjectMemberSerializer):
                 "Organization is not allowed to set custom symbol sources"
             )
 
-        has_multiple_appconnect = features.has(
-            "organizations:app-store-connect-multiple", organization, actor=request.user
-        )
-        appconnect_sources = [s for s in sources if s.get("type") == "appStoreConnect"]
-        if not has_multiple_appconnect and len(appconnect_sources) > 1:
-            raise serializers.ValidationError(
-                "Only one Apple App Store Connect application is allowed in this project"
-            )
-
         return sources_json
 
     def validate_groupingEnhancements(self, value):

+ 5 - 7
src/sentry/api/endpoints/project_symbol_sources.py

@@ -21,7 +21,6 @@ from sentry.apidocs.parameters import GlobalParams, ProjectParams
 from sentry.lang.native.sources import (
     REDACTED_SOURCE_SCHEMA,
     REDACTED_SOURCES_SCHEMA,
-    SOURCES_WITHOUT_APPSTORE_CONNECT,
     VALID_CASINGS,
     VALID_LAYOUTS,
     InvalidSourcesError,
@@ -213,7 +212,7 @@ class ProjectSymbolSourcesEndpoint(ProjectEndpoint):
         """
         id = request.GET.get("id")
         custom_symbol_sources_json = project.get_option("sentry:symbol_sources") or []
-        sources = parse_sources(custom_symbol_sources_json, False)
+        sources = parse_sources(custom_symbol_sources_json)
         redacted = redact_source_secrets(sources)
 
         if id:
@@ -245,7 +244,7 @@ class ProjectSymbolSourcesEndpoint(ProjectEndpoint):
         id = request.GET.get("id")
         custom_symbol_sources_json = project.get_option("sentry:symbol_sources") or []
 
-        sources = parse_sources(custom_symbol_sources_json, False)
+        sources = parse_sources(custom_symbol_sources_json)
 
         if id:
             filtered_sources = [src for src in sources if src["id"] != id]
@@ -274,7 +273,7 @@ class ProjectSymbolSourcesEndpoint(ProjectEndpoint):
         Add a custom symbol source to a project.
         """
         custom_symbol_sources_json = project.get_option("sentry:symbol_sources") or []
-        sources = parse_sources(custom_symbol_sources_json, False)
+        sources = parse_sources(custom_symbol_sources_json)
 
         source = request.data
 
@@ -287,8 +286,7 @@ class ProjectSymbolSourcesEndpoint(ProjectEndpoint):
         sources.append(source)
 
         try:
-            # TODO(@anonrig): Update this schema when AppStore connect is sunset.
-            validate_sources(sources, schema=SOURCES_WITHOUT_APPSTORE_CONNECT)
+            validate_sources(sources)
         except InvalidSourcesError:
             return Response(status=400)
 
@@ -322,7 +320,7 @@ class ProjectSymbolSourcesEndpoint(ProjectEndpoint):
         source = request.data
 
         custom_symbol_sources_json = project.get_option("sentry:symbol_sources") or []
-        sources = parse_sources(custom_symbol_sources_json, False)
+        sources = parse_sources(custom_symbol_sources_json)
 
         if id is None:
             return Response(data={"error": "Missing source id"}, status=404)

+ 0 - 18
src/sentry/api/exceptions.py

@@ -134,24 +134,6 @@ class TwoFactorRequired(SentryAPIException):
     message = "Organization requires two-factor authentication to be enabled"
 
 
-class AppConnectForbiddenError(SentryAPIException):
-    status_code = status.HTTP_403_FORBIDDEN
-    code = "app-connect-forbidden-error"
-    message = "App connect Forbidden error"
-
-
-class AppConnectAuthenticationError(SentryAPIException):
-    status_code = status.HTTP_401_UNAUTHORIZED
-    code = "app-connect-authentication-error"
-    message = "App connect authentication error"
-
-
-class AppConnectMultipleSourcesError(SentryAPIException):
-    status_code = status.HTTP_401_UNAUTHORIZED
-    code = "app-connect-multiple-sources-error"
-    message = "Only one Apple App Store Connect application is allowed in this project"
-
-
 class ConflictError(APIException):
     status_code = status.HTTP_409_CONFLICT
 

Некоторые файлы не были показаны из-за большого количества измененных файлов