-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathadmin.py
105 lines (89 loc) · 3.7 KB
/
admin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from flask_admin import Admin, AdminIndexView, BaseView, expose
from flask_admin.contrib.sqla import ModelView
from dynamicannotationdb.models import AnalysisVersion, AnalysisTable
from flask import request, current_app, g, render_template
from middle_auth_client import auth_required, auth_requires_admin
from dynamicannotationdb.migration import DynamicMigration, run_alembic_migration
from sqlalchemy.engine.url import make_url
from materializationengine.info_client import (
get_datastacks,
get_relevant_datastack_info,
)
class MatAdminIndexView(AdminIndexView):
@expose("/", methods=["GET"])
@auth_required
def index(self):
return super(MatAdminIndexView, self).index()
def is_accessible(self):
@auth_required
def helper():
return True
return helper()
def setup_admin(app, db):
admin = Admin(app, name="materializationengine", index_view=MatAdminIndexView())
admin.add_view(MigrationView(name="Migration"))
admin.add_view(ModelView(AnalysisVersion, db.session))
admin.add_view(ModelView(AnalysisTable, db.session))
return admin
def get_allowed_aligned_volumes():
with current_app.app_context():
datastacks = get_datastacks()
aligned_volumes = []
for datastack in datastacks:
aligned_volume_name, pcg_table_name = get_relevant_datastack_info(datastack)
aligned_volumes.append(aligned_volume_name)
return aligned_volumes
class MigrationView(BaseView):
def is_accessible(self):
@auth_required
def helper():
return True
return helper() and g.get("auth_user", {}).get("admin", False)
def inaccessible_callback(self, name, **kwargs):
return render_template("admin/403.html"), 403
@expose("/")
@auth_requires_admin
def index(self):
aligned_volumes = get_allowed_aligned_volumes()
return self.render("admin/migration.html", aligned_volumes=aligned_volumes)
@expose("/migrate_static_schemas", methods=["POST"])
@auth_requires_admin
def migrate_static_schemas(self):
sql_url = request.form.get("sql_url")
aligned_volume = request.form.get("aligned_volume")
sql_base_uri = sql_url.rpartition("/")[0]
sql_uri = make_url(f"{sql_base_uri}/{aligned_volume}")
migrator = run_alembic_migration(str(sql_uri))
return self.render(
"admin/migration.html",
message=migrator,
aligned_volumes=get_allowed_aligned_volumes(),
)
@expose("/migrate_annotation_schemas", methods=["POST"])
@auth_requires_admin
def migrate_annotation_schemas(self):
sql_url = request.form.get("sql_url")
aligned_volume = request.form.get("aligned_volume")
dry_run = request.form.get("dry_run") == "true"
migrator = DynamicMigration(sql_url, aligned_volume)
migrations = migrator.upgrade_annotation_models(dry_run=dry_run)
return self.render(
"admin/migration.html",
message=migrations,
aligned_volumes=get_allowed_aligned_volumes(),
)
@expose("/migrate_foreign_key_constraints", methods=["POST"])
@auth_requires_admin
def migrate_foreign_key_constraints(self):
sql_url = request.form.get("sql_url")
aligned_volume = request.form.get("aligned_volume")
dry_run = request.form.get("dry_run") == "true"
migrator = DynamicMigration(sql_url, aligned_volume)
fkey_constraint_mapping = migrator.apply_cascade_option_to_tables(
dry_run=dry_run
)
return self.render(
"admin/migration.html",
message=fkey_constraint_mapping,
aligned_volumes=get_allowed_aligned_volumes(),
)