2023-07-24 20:56:10 +00:00
|
|
|
package client
|
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
"git.faercol.me/faercol/http-boot-server/bootserver/helpers"
|
|
|
|
"git.faercol.me/faercol/http-boot-server/bootserver/services"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
)
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
const SetBootRoute = "/config/boot"
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
type setBootOptionPayload struct {
|
|
|
|
ClientID string `json:"client_id"`
|
|
|
|
OptionID string `json:"option_id"`
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
type BootController struct {
|
|
|
|
clientService *services.ClientHandlerService
|
|
|
|
l *logrus.Logger
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
func NewBootController(logger *logrus.Logger, service *services.ClientHandlerService) *BootController {
|
|
|
|
return &BootController{
|
|
|
|
clientService: service,
|
|
|
|
l: logger,
|
|
|
|
}
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
func (bc *BootController) setBootOption(w http.ResponseWriter, r *http.Request) (int, []byte, error) {
|
|
|
|
dat, err := io.ReadAll(r.Body)
|
|
|
|
if err != nil {
|
|
|
|
return http.StatusInternalServerError, nil, fmt.Errorf("failed to read body: %w", err)
|
|
|
|
}
|
|
|
|
var payload setBootOptionPayload
|
|
|
|
if err := json.Unmarshal(dat, &payload); err != nil {
|
|
|
|
return http.StatusBadRequest, nil, fmt.Errorf("failed to parse body: %w", err)
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
clientID, err := uuid.Parse(payload.ClientID)
|
|
|
|
if err != nil {
|
|
|
|
return http.StatusBadRequest, []byte("bad client ID"), fmt.Errorf("invalid format for client ID: %w", err)
|
|
|
|
}
|
|
|
|
optionID, err := uuid.Parse(payload.OptionID)
|
|
|
|
if err != nil {
|
|
|
|
return http.StatusBadRequest, []byte("bad option ID"), fmt.Errorf("invalid format for option ID: %w", err)
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
if err := bc.clientService.SetClientBootOption(clientID, optionID.String()); err != nil {
|
|
|
|
if errors.Is(err, services.ErrUnknownClient) {
|
|
|
|
return http.StatusNotFound, []byte("unknown client"), err
|
|
|
|
}
|
|
|
|
if errors.Is(err, services.ErrUnknownBootOption) {
|
|
|
|
return http.StatusNotFound, []byte("unknown boot option"), err
|
|
|
|
}
|
|
|
|
return http.StatusInternalServerError, nil, fmt.Errorf("failed to set boot option for client: %w", err)
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
return http.StatusAccepted, nil, nil
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-09-16 11:52:12 +00:00
|
|
|
func (bc *BootController) deleteClient(w http.ResponseWriter, r *http.Request) (int, []byte, error) {
|
|
|
|
dat, err := io.ReadAll(r.Body)
|
|
|
|
if err != nil {
|
|
|
|
return http.StatusInternalServerError, nil, fmt.Errorf("failed to read body: %w", err)
|
|
|
|
}
|
|
|
|
var payload setBootOptionPayload
|
|
|
|
if err := json.Unmarshal(dat, &payload); err != nil {
|
|
|
|
return http.StatusBadRequest, nil, fmt.Errorf("failed to parse body: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
clientID, err := uuid.Parse(payload.ClientID)
|
|
|
|
if err != nil {
|
|
|
|
return http.StatusBadRequest, []byte("bad client ID"), fmt.Errorf("invalid format for client ID: %w", err)
|
|
|
|
}
|
|
|
|
if err := bc.clientService.DeleteClient(clientID); err != nil {
|
|
|
|
return http.StatusInternalServerError, []byte("failed to delete client"), fmt.Errorf("failed to delete client: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return http.StatusOK, nil, nil
|
|
|
|
}
|
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
func (bc *BootController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
2023-09-16 11:52:12 +00:00
|
|
|
var returncode int
|
|
|
|
var content []byte
|
|
|
|
var err error
|
|
|
|
|
|
|
|
switch r.Method {
|
|
|
|
case http.MethodPut:
|
|
|
|
returncode, content, err = bc.setBootOption(w, r)
|
|
|
|
if err != nil {
|
|
|
|
bc.l.Errorf("Error setting boot option for client: %s", err.Error())
|
|
|
|
}
|
|
|
|
case http.MethodDelete:
|
|
|
|
returncode, content, err = bc.deleteClient(w, r)
|
|
|
|
if err != nil {
|
|
|
|
bc.l.Errorf("Error setting boot option for client: %s", err.Error())
|
|
|
|
}
|
|
|
|
default:
|
2023-08-19 11:49:13 +00:00
|
|
|
helpers.HandleResponse(w, r, http.StatusMethodNotAllowed, nil, bc.l)
|
|
|
|
return
|
|
|
|
}
|
2023-07-24 20:56:10 +00:00
|
|
|
|
2023-08-19 11:49:13 +00:00
|
|
|
helpers.HandleResponse(w, r, returncode, content, bc.l)
|
|
|
|
}
|