Files
mantrae/internal/api/handler/profiles.go
2025-06-16 16:26:55 +02:00

144 lines
4.0 KiB
Go

package handler
import (
"encoding/json"
"log/slog"
"net/http"
"strconv"
"github.com/mizuchilabs/mantrae/internal/config"
"github.com/mizuchilabs/mantrae/internal/db"
"github.com/mizuchilabs/mantrae/internal/source"
"github.com/mizuchilabs/mantrae/internal/traefik"
"github.com/mizuchilabs/mantrae/internal/util"
)
func ListProfiles(a *config.App) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
q := a.Conn.GetQuery()
profiles, err := q.ListProfiles(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(profiles); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}
func GetProfile(a *config.App) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
q := a.Conn.GetQuery()
profile_id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
profile, err := q.GetProfile(r.Context(), profile_id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(profile); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}
func CreateProfile(a *config.App) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
q := a.Conn.GetQuery()
var params db.CreateProfileParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
profileID, err := q.CreateProfile(r.Context(), params)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Create default local config
if err = q.UpsertTraefikConfig(r.Context(), db.UpsertTraefikConfigParams{
ProfileID: profileID,
Source: source.Local,
}); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
profile, err := q.GetProfile(r.Context(), profileID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
go func() {
if err := traefik.UpdateTraefikAPI(a.Conn.Get(), profile); err != nil {
slog.Error("Failed to update api data", "error", err)
}
}()
util.Broadcast <- util.EventMessage{
Type: util.EventTypeCreate,
Category: util.EventCategoryProfile,
}
w.WriteHeader(http.StatusNoContent)
}
}
func UpdateProfile(a *config.App) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
q := a.Conn.GetQuery()
var params db.UpdateProfileParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err := q.UpdateProfile(r.Context(), params); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
profile, err := q.GetProfile(r.Context(), params.ID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
go func() {
if err := traefik.UpdateTraefikAPI(a.Conn.Get(), profile); err != nil {
slog.Error("Failed to update api data", "error", err)
}
}()
util.Broadcast <- util.EventMessage{
Type: util.EventTypeUpdate,
Category: util.EventCategoryProfile,
}
w.WriteHeader(http.StatusNoContent)
}
}
func DeleteProfile(a *config.App) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
q := a.Conn.GetQuery()
profile_id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err := q.DeleteProfile(r.Context(), profile_id); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
util.Broadcast <- util.EventMessage{
Type: util.EventTypeDelete,
Category: util.EventCategoryProfile,
}
w.WriteHeader(http.StatusNoContent)
}
}