Add ServiceCatalogItem type and services CRUD API endpoints (list, create, update, delete). Extend Policy type to include services array with domain, upstream_ip, proxy_ip, and ports metadata. Add ServicesPage component with table view and create/edit modals for managing service definitions. Include service name, domain, proxy, and upstream columns with port parsing logic. Integrate service selection
79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
package servicecatalog
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/google/uuid"
|
|
|
|
"nexavpn/backend/internal/apiutil"
|
|
)
|
|
|
|
type Handler struct {
|
|
service *CatalogService
|
|
}
|
|
|
|
func NewHandler(service *CatalogService) *Handler {
|
|
return &Handler{service: service}
|
|
}
|
|
|
|
func (h *Handler) List(w http.ResponseWriter, r *http.Request) {
|
|
items, err := h.service.List(r.Context())
|
|
if err != nil {
|
|
apiutil.Error(w, http.StatusInternalServerError, "services_list_failed", "unable to list services")
|
|
return
|
|
}
|
|
apiutil.JSON(w, http.StatusOK, items)
|
|
}
|
|
|
|
func (h *Handler) Create(w http.ResponseWriter, r *http.Request) {
|
|
var input CreateRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
|
|
apiutil.Error(w, http.StatusBadRequest, "invalid_json", "invalid request body")
|
|
return
|
|
}
|
|
|
|
item, err := h.service.Create(r.Context(), input)
|
|
if err != nil {
|
|
apiutil.Error(w, http.StatusInternalServerError, "service_create_failed", "unable to create service")
|
|
return
|
|
}
|
|
apiutil.JSON(w, http.StatusCreated, item)
|
|
}
|
|
|
|
func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
|
|
serviceID, err := uuid.Parse(chi.URLParam(r, "id"))
|
|
if err != nil {
|
|
apiutil.Error(w, http.StatusBadRequest, "invalid_service_id", "invalid service id")
|
|
return
|
|
}
|
|
|
|
var input UpdateRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
|
|
apiutil.Error(w, http.StatusBadRequest, "invalid_json", "invalid request body")
|
|
return
|
|
}
|
|
|
|
item, err := h.service.Update(r.Context(), serviceID, input)
|
|
if err != nil {
|
|
apiutil.Error(w, http.StatusInternalServerError, "service_update_failed", "unable to update service")
|
|
return
|
|
}
|
|
apiutil.JSON(w, http.StatusOK, item)
|
|
}
|
|
|
|
func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
|
|
serviceID, err := uuid.Parse(chi.URLParam(r, "id"))
|
|
if err != nil {
|
|
apiutil.Error(w, http.StatusBadRequest, "invalid_service_id", "invalid service id")
|
|
return
|
|
}
|
|
|
|
if err := h.service.Delete(r.Context(), serviceID); err != nil {
|
|
apiutil.Error(w, http.StatusInternalServerError, "service_delete_failed", "unable to delete service")
|
|
return
|
|
}
|
|
apiutil.JSON(w, http.StatusOK, map[string]any{"ok": true})
|
|
}
|