backend structure build

This commit is contained in:
2025-12-23 18:38:44 +00:00
parent 861e0f65c3
commit e7f55839eb
8 changed files with 702 additions and 27 deletions

View File

@@ -2,6 +2,7 @@ package api
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
@@ -102,6 +103,28 @@ func handleCreateRepository(sm *services.ServiceManager) http.HandlerFunc {
return
}
// Validate input
if err := validateRepositoryName(req.Name); err != nil {
jsonError(w, http.StatusBadRequest, err.Error())
return
}
if err := validateSize(req.Size); err != nil {
jsonError(w, http.StatusBadRequest, err.Error())
return
}
if req.Type != "lvm" && req.Type != "zfs" {
jsonError(w, http.StatusBadRequest, "type must be 'lvm' or 'zfs'")
return
}
if req.Type == "lvm" && req.VGName == "" {
jsonError(w, http.StatusBadRequest, "vg_name is required for LVM repositories")
return
}
if req.Type == "zfs" && req.PoolName == "" {
jsonError(w, http.StatusBadRequest, "pool_name is required for ZFS repositories")
return
}
repo, err := sm.Disk.CreateRepository(req.Name, req.Size, req.Type, req.VGName, req.PoolName)
if err != nil {
jsonError(w, http.StatusInternalServerError, err.Error())
@@ -240,6 +263,22 @@ func handleCreateTarget(sm *services.ServiceManager) http.HandlerFunc {
return
}
// Validate input
if err := validateIQN(req.IQN); err != nil {
jsonError(w, http.StatusBadRequest, err.Error())
return
}
if len(req.Portals) == 0 {
jsonError(w, http.StatusBadRequest, "at least one portal is required")
return
}
for _, portal := range req.Portals {
if err := validatePortal(portal); err != nil {
jsonError(w, http.StatusBadRequest, err.Error())
return
}
}
target, err := sm.ISCSI.CreateTarget(req.IQN, req.Portals, req.Initiators)
if err != nil {
jsonError(w, http.StatusInternalServerError, err.Error())
@@ -315,6 +354,63 @@ func handleListSessions(sm *services.ServiceManager) http.HandlerFunc {
}
}
func handleAddLUN(sm *services.ServiceManager) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var req struct {
LUNNumber int `json:"lun_number"`
DevicePath string `json:"device_path"`
Type string `json:"type"` // "disk" or "tape"
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
jsonError(w, http.StatusBadRequest, "Invalid request body")
return
}
if req.Type != "disk" && req.Type != "tape" {
jsonError(w, http.StatusBadRequest, "type must be 'disk' or 'tape'")
return
}
if err := sm.ISCSI.AddLUN(vars["id"], req.LUNNumber, req.DevicePath, req.Type); err != nil {
jsonError(w, http.StatusInternalServerError, err.Error())
return
}
// Return updated target
target, err := sm.ISCSI.GetTarget(vars["id"])
if err != nil {
jsonError(w, http.StatusInternalServerError, err.Error())
return
}
jsonResponse(w, http.StatusOK, target)
}
}
func handleRemoveLUN(sm *services.ServiceManager) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
lunNumber := 0
if _, err := fmt.Sscanf(vars["lun"], "%d", &lunNumber); err != nil {
jsonError(w, http.StatusBadRequest, "invalid LUN number")
return
}
if err := sm.ISCSI.RemoveLUN(vars["id"], lunNumber); err != nil {
jsonError(w, http.StatusInternalServerError, err.Error())
return
}
// Return updated target
target, err := sm.ISCSI.GetTarget(vars["id"])
if err != nil {
jsonError(w, http.StatusInternalServerError, err.Error())
return
}
jsonResponse(w, http.StatusOK, target)
}
}
// Bacula handlers
func handleBaculaStatus(sm *services.ServiceManager) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {