forked from Fediversity/Fediversity
store versioned configurations
Test manually: ```shell-session $ manage shell >>> from panel.models import Configuration >>> Configuration().value '{"enable":false,"domain":"fediversity.eu"}' >>> Configuration().save() >>> Configuration.objects.first().parsed_value Configuration(enable=False, domain=<Domain.EU: 'fediversity.eu'>) ```
This commit is contained in:
parent
438f7d280a
commit
981ba011ab
5 changed files with 105 additions and 0 deletions
panel/src/panel
31
panel/src/panel/configuration/__init__.py
Normal file
31
panel/src/panel/configuration/__init__.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from importlib import import_module
|
||||
from importlib.util import find_spec
|
||||
from django.utils.functional import classproperty
|
||||
|
||||
from django.apps import apps
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Version():
|
||||
|
||||
model: models.Model
|
||||
|
||||
@classproperty
|
||||
def latest(cls):
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
version_pattern = re.compile(r'v(\d+)\.py$')
|
||||
versions = []
|
||||
for filename in os.listdir(current_dir):
|
||||
match = version_pattern.match(filename)
|
||||
if match:
|
||||
versions.append(int(match.group(1)))
|
||||
|
||||
return max(versions)
|
||||
|
||||
def __init__(self, version: int):
|
||||
module = import_module(f"{__name__}.v{version}")
|
||||
self.model = getattr(module, "Configuration")
|
19
panel/src/panel/configuration/v1.py
Normal file
19
panel/src/panel/configuration/v1.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from pydantic import BaseModel, Field
|
||||
from enum import Enum
|
||||
|
||||
class Configuration(BaseModel):
|
||||
enable: bool = Field(
|
||||
default=False,
|
||||
description="Enable the configuration",
|
||||
)
|
||||
|
||||
# XXX: hard-code available apex domains for now,
|
||||
# they will be prefixed by the user name
|
||||
class Domain(Enum):
|
||||
EU = "fediversity.eu"
|
||||
NET = "fediversity.net"
|
||||
|
||||
domain: Domain = Field(
|
||||
default=Domain.EU,
|
||||
description="DNS domain where to expose services"
|
||||
)
|
26
panel/src/panel/migrations/0001_initial.py
Normal file
26
panel/src/panel/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Generated by Django 4.2.16 on 2025-03-05 08:25
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Configuration',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('version', models.PositiveIntegerField(default=1, help_text='Configuration schema version')),
|
||||
('value', models.JSONField(help_text='Stored configuration value', null=True)),
|
||||
('operator', models.ForeignKey(help_text='Operator who owns the configuration', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='configurations', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
0
panel/src/panel/migrations/__init__.py
Normal file
0
panel/src/panel/migrations/__init__.py
Normal file
29
panel/src/panel/models.py
Normal file
29
panel/src/panel/models.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from panel.configuration import Version
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
class Configuration(models.Model):
|
||||
operator = models.ForeignKey(
|
||||
User,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
related_name="configurations",
|
||||
help_text="Operator who owns the configuration",
|
||||
)
|
||||
|
||||
version = models.PositiveIntegerField(
|
||||
help_text="Configuration schema version",
|
||||
default=Version.latest,
|
||||
)
|
||||
|
||||
value = models.JSONField(
|
||||
help_text="Stored configuration value",
|
||||
default=Version(Version.latest).model().model_dump_json,
|
||||
)
|
||||
|
||||
@property
|
||||
def parsed_value(self) -> BaseModel:
|
||||
return Version(self.version).model.model_validate_json(self.value)
|
Loading…
Add table
Reference in a new issue