Fediversity/panel/src/panel/views.py

110 lines
3.2 KiB
Python

from enum import Enum
import json
import subprocess
import os
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.views.generic import TemplateView, DetailView
from django.views.generic.edit import FormView
from django.shortcuts import render, redirect
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from pydantic import BaseModel
from panel import models, settings
from panel.configuration import schema
class Index(TemplateView):
template_name = 'index.html'
class AccountDetail(LoginRequiredMixin, DetailView):
model = User
template_name = 'account_detail.html'
def get_object(self):
return self.request.user
class ServiceList(TemplateView):
template_name = 'service_list.html'
class ConfigurationForm(LoginRequiredMixin, APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'configuration_form.html'
success_url = reverse_lazy('configuration_form')
def get_object(self):
obj, created = models.Configuration.objects.get_or_create(
operator=self.request.user,
)
return obj
def get(self, request):
config = self.get_object()
serializer = schema.Model.drf_serializer(instance=config.parsed_value)
return Response({'serializer': serializer})
def post(self, request):
config = self.get_object()
serializer = schema.Model.drf_serializer(
instance=config.parsed_value,
data=request.data
)
if not serializer.is_valid():
return Response({'serializer': serializer})
config.value = json.dumps(serializer.validated_data)
config.save()
return redirect(self.success_url)
class DeploymentStatus(ConfigurationForm):
def post(self, request):
config = self.get_object()
serializer = schema.Model.drf_serializer(
instance=config.parsed_value,
data=request.data
)
if not serializer.is_valid():
return Response({'serializer': serializer})
config.value = json.dumps(serializer.validated_data)
config.save()
deployment_result, deployment_params = self.deployment(config.parsed_value)
return render(self.request, "partials/deployment_result.html", {
"deployment_succeeded": (deployment_result.returncode == 0),
"services": deployment_params.json(),
})
def deployment(self, config: BaseModel):
env = {
"PATH": os.environ['PATH'] + ":" + settings.bin_path,
"HOME": '/run/fedipanel',
# pass in form info to our deployment
"DEPLOYMENT": config.json()
}
cmd = [
"nixops4",
"apply",
"check-deployment-panel",
"--show-trace",
"--no-interactive",
]
deployment_result = subprocess.run(
cmd,
cwd = settings.repo_dir,
env = env,
stderr = subprocess.STDOUT,
)
return deployment_result, config