Skip to content

Commit

Permalink
ref(backup): Encapsulate old export config (#54322)
Browse files Browse the repository at this point in the history
There are a number of properties of the export system API that we'd like
to eventually change. These include:

- Barring users from manually excluding/including specific models on
export
- Only exporting `sentry...` models

To keep the original behavior export system intact until we debut these
changes, this commit hides the behind `OldExportConfig`, which allows
them to be toggled on (for tests) but left off for the actual CLI tool
(for now).

Issue: getsentry/team-ospo#171
  • Loading branch information
azaslavsky authored Aug 9, 2023
1 parent b231b0a commit 295c12d
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 47 deletions.
8 changes: 0 additions & 8 deletions fixtures/backup/datetime-with-unzeroed-millis.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
[
{
"model": "sites.site",
"pk": 1,
"fields": {
"domain": "example.com",
"name": "example.com"
}
},
{
"model": "sentry.option",
"pk": 1,
Expand Down
8 changes: 0 additions & 8 deletions fixtures/backup/datetime-with-zeroed-millis.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
[
{
"model": "sites.site",
"pk": 1,
"fields": {
"domain": "example.com",
"name": "example.com"
}
},
{
"model": "sentry.option",
"pk": 1,
Expand Down
8 changes: 0 additions & 8 deletions fixtures/backup/fresh-install.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
[
{
"model": "sites.site",
"pk": 1,
"fields": {
"domain": "example.com",
"name": "example.com"
}
},
{
"model": "sentry.option",
"pk": 1,
Expand Down
8 changes: 0 additions & 8 deletions fixtures/backup/single-option.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
[
{
"model": "sites.site",
"pk": 1,
"fields": {
"domain": "example.com",
"name": "example.com"
}
},
{
"model": "sentry.option",
"pk": 1,
Expand Down
26 changes: 18 additions & 8 deletions src/sentry/backup/exports.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from datetime import datetime, timedelta, timezone
from typing import NamedTuple

import click
from django.core.serializers import serialize
Expand Down Expand Up @@ -76,6 +77,7 @@ def sort_dependencies():
rel_model = getattr(field.remote_field, "model", None)
if rel_model is not None and rel_model != model:
deps.append(rel_model)

model_dependencies.append((model, deps))

model_dependencies.reverse()
Expand Down Expand Up @@ -119,20 +121,28 @@ def sort_dependencies():
return model_list


def exports(dest, indent, exclude, printer=click.echo):
"""Exports core metadata for the Sentry installation."""
class OldExportConfig(NamedTuple):
"""While we are migrating to the new backup system, we need to take care not to break the old
and relatively untested workflows. This model allows us to stub in the old configs."""

# Do we include models that aren't in `sentry.*` databases, like the native Django ones (sites,
# sessions, etc)?
include_non_sentry_models: bool = False

# A list of models to exclude from the export - eventually we want to deprecate and remove this
# option.
excluded_models: set[str] = set()


if exclude is None:
exclude = ()
else:
exclude = exclude.lower().split(",")
def exports(dest, old_config: OldExportConfig, indent: int, printer=click.echo):
"""Exports core data for the Sentry installation."""

def yield_objects():
# Collate the objects to be serialized.
for model in sort_dependencies():
if (
not getattr(model, "__include_in_export__", True)
or model.__name__.lower() in exclude
not getattr(model, "__include_in_export__", old_config.include_non_sentry_models)
or model.__name__.lower() in old_config.excluded_models
or model._meta.proxy
):
printer(f">> Skipping model <{model.__name__}>", err=True)
Expand Down
23 changes: 18 additions & 5 deletions src/sentry/runner/commands/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import click

from sentry.backup.exports import exports
from sentry.backup.exports import OldExportConfig, exports
from sentry.backup.imports import imports
from sentry.runner.decorators import configuration

Expand All @@ -12,7 +12,7 @@
@click.option("--silent", "-q", default=False, is_flag=True, help="Silence all debug output.")
@configuration
def import_(src, silent):
"""CLI command wrapping the `exec_import` functionality."""
"""Imports core data for a Sentry installation."""

imports(src, (lambda *args, **kwargs: None) if silent else click.echo)

Expand All @@ -26,6 +26,19 @@ def import_(src, silent):
@click.option("--exclude", default=None, help="Models to exclude from export.", metavar="MODELS")
@configuration
def export(dest, silent, indent, exclude):
"""Exports core metadata for the Sentry installation."""

exports(dest, indent, exclude, (lambda *args, **kwargs: None) if silent else click.echo)
"""Exports core data for the Sentry installation."""

if exclude is None:
exclude = []
else:
exclude = exclude.lower().split(",")

exports(
dest,
OldExportConfig(
include_non_sentry_models=True,
excluded_models=set(exclude),
),
indent,
(lambda *args, **kwargs: None) if silent else click.echo,
)
4 changes: 2 additions & 2 deletions src/sentry/testutils/helpers/backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.core.management import call_command

from sentry.backup.comparators import ComparatorMap
from sentry.backup.exports import exports
from sentry.backup.exports import OldExportConfig, exports
from sentry.backup.findings import ComparatorFindings
from sentry.backup.helpers import get_exportable_final_derivations_of, get_final_derivations_of
from sentry.backup.imports import imports
Expand Down Expand Up @@ -39,7 +39,7 @@ def export_to_file(path: Path) -> JSONData:

json_file_path = str(path)
with open(json_file_path, "w+") as tmp_file:
exports(tmp_file, 2, None, NOOP_PRINTER)
exports(tmp_file, OldExportConfig(), 2, NOOP_PRINTER)

with open(json_file_path) as tmp_file:
output = json.load(tmp_file)
Expand Down

0 comments on commit 295c12d

Please sign in to comment.