Feat(Fix): Multi-Tenant Zerotier Org Setups
Imports Network From Zerotier Async Emails Migration guardrails Admin to see all approvals states
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
"""Add per-org ZeroTier credentials to organizations table.
|
||||
|
||||
Revision ID: 028_org_zerotier_config
|
||||
Revises: 026_schema_cleanup
|
||||
Create Date: 2026-03-25
|
||||
|
||||
Adds three nullable columns to `organizations`:
|
||||
- zt_api_token VARCHAR(512) — API token (Central) or authtoken.secret (controller)
|
||||
- zt_api_url VARCHAR(512) — base URL of the controller / Central API
|
||||
- zt_api_mode VARCHAR(32) — "central" | "controller"
|
||||
|
||||
When these are NULL the server-level ZEROTIER_API_* env vars are used instead,
|
||||
so existing deployments are fully backwards-compatible with no data migration needed.
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision = "028_org_zerotier_config"
|
||||
down_revision = "027_fix_cert_serial_uniqueness"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def _col_exists(conn, table: str, column: str) -> bool:
|
||||
row = conn.execute(
|
||||
sa.text(
|
||||
"SELECT 1 FROM information_schema.columns "
|
||||
"WHERE table_name = :t AND column_name = :c"
|
||||
),
|
||||
{"t": table, "c": column},
|
||||
).first()
|
||||
return row is not None
|
||||
|
||||
|
||||
def upgrade():
|
||||
conn = op.get_bind()
|
||||
|
||||
if not _col_exists(conn, "organizations", "zt_api_token"):
|
||||
op.add_column(
|
||||
"organizations",
|
||||
sa.Column("zt_api_token", sa.String(512), nullable=True),
|
||||
)
|
||||
|
||||
if not _col_exists(conn, "organizations", "zt_api_url"):
|
||||
op.add_column(
|
||||
"organizations",
|
||||
sa.Column("zt_api_url", sa.String(512), nullable=True),
|
||||
)
|
||||
|
||||
if not _col_exists(conn, "organizations", "zt_api_mode"):
|
||||
op.add_column(
|
||||
"organizations",
|
||||
sa.Column("zt_api_mode", sa.String(32), nullable=True),
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
conn = op.get_bind()
|
||||
|
||||
if _col_exists(conn, "organizations", "zt_api_mode"):
|
||||
op.drop_column("organizations", "zt_api_mode")
|
||||
|
||||
if _col_exists(conn, "organizations", "zt_api_url"):
|
||||
op.drop_column("organizations", "zt_api_url")
|
||||
|
||||
if _col_exists(conn, "organizations", "zt_api_token"):
|
||||
op.drop_column("organizations", "zt_api_token")
|
||||
Reference in New Issue
Block a user