From 99f67a7e790f81c9c0fcfbf923718e7dcb434cc6 Mon Sep 17 00:00:00 2001 From: Melora Hugues Date: Sun, 13 Aug 2023 20:40:22 +0200 Subject: [PATCH] add controller to get current client config --- bootserver/controllers/client/getconfig.go | 88 ++++++++++++++++++++++ bootserver/server/server.go | 1 + bootserver/services/services.go | 15 ++++ 3 files changed, 104 insertions(+) create mode 100644 bootserver/controllers/client/getconfig.go diff --git a/bootserver/controllers/client/getconfig.go b/bootserver/controllers/client/getconfig.go new file mode 100644 index 0000000..554228d --- /dev/null +++ b/bootserver/controllers/client/getconfig.go @@ -0,0 +1,88 @@ +package client + +import ( + "encoding/json" + "errors" + "net/http" + + "git.faercol.me/faercol/http-boot-server/bootserver/bootoption" + "git.faercol.me/faercol/http-boot-server/bootserver/config" + "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" +) + +const ConfigRoute = "/config" + +type clientNetConfig struct { + MulticastGroup string `json:"multicast_group"` + Port int `json:"port"` +} + +type clientConfig struct { + EFIConfig *bootoption.Client `json:"efi_config"` + NetConfig *clientNetConfig `json:"net_config"` +} + +type GetConfigController struct { + clientService *services.ClientHandlerService + config *config.AppConfig + l *logrus.Logger +} + +func NewGetConfigController(l *logrus.Logger, service *services.ClientHandlerService, config *config.AppConfig) *GetConfigController { + return &GetConfigController{ + clientService: service, + l: l, + config: config, + } +} + +func (cc *GetConfigController) getConfig(w http.ResponseWriter, r *http.Request) (int, []byte, error) { + if r.Method != http.MethodGet { + return http.StatusMethodNotAllowed, nil, nil + } + + id := r.URL.Query().Get("id") + parsedId, err := uuid.Parse(id) + if err != nil { + cc.l.Errorf("Invalid uuid %q", id) + return http.StatusBadRequest, []byte("invalid uuid format"), errors.New("invalid uuid format") + } + + efiConfig, err := cc.clientService.GetClientConfig(parsedId) + if err != nil { + if errors.Is(err, services.ErrUnknownClient) { + cc.l.Errorf("Unknown client %q", id) + return http.StatusNotFound, []byte("unknown client"), err + } else { + cc.l.Errorf("Unexpected error getting config for client: %s", err.Error()) + return http.StatusInternalServerError, nil, err + } + } + + cltConfig := clientConfig{ + EFIConfig: efiConfig, + NetConfig: &clientNetConfig{ + MulticastGroup: cc.config.UPDMcastGroup, + Port: cc.config.UDPPort, + }, + } + + jsonDat, err := json.Marshal(cltConfig) + if err != nil { + cc.l.Errorf("Failed to serialize EFI config: %s", err.Error()) + return http.StatusInternalServerError, nil, err + } + w.Header().Add("Content-Type", "application/json") + return http.StatusOK, jsonDat, nil +} + +func (cc *GetConfigController) ServeHTTP(w http.ResponseWriter, r *http.Request) { + returncode, content, err := cc.getConfig(w, r) + if err != nil { + cc.l.Errorf("Error getting client config: %s", err.Error()) + } + helpers.HandleResponse(w, r, returncode, content, cc.l) +} diff --git a/bootserver/server/server.go b/bootserver/server/server.go index a0b83f7..e4a216c 100644 --- a/bootserver/server/server.go +++ b/bootserver/server/server.go @@ -67,6 +67,7 @@ func New(appConf *config.AppConfig, logger *logrus.Logger) (*Server, error) { service := services.NewClientHandlerService(appConf.DataFilepath, logger) controllers := map[string]http.Handler{ client.EnrollRoute: middlewares.WithLogger(client.NewEnrollController(logger, service), logger), + client.ConfigRoute: middlewares.WithLogger(client.NewGetConfigController(logger, service, appConf), logger), } m := http.NewServeMux() diff --git a/bootserver/services/services.go b/bootserver/services/services.go index 0345466..2a2df32 100644 --- a/bootserver/services/services.go +++ b/bootserver/services/services.go @@ -99,6 +99,21 @@ func (chs *ClientHandlerService) AddClient(client *bootoption.Client) (uuid.UUID return client.ID, nil } +func (chs *ClientHandlerService) GetClientConfig(client uuid.UUID) (*bootoption.Client, error) { + clients, err := chs.load() + if err != nil { + return nil, fmt.Errorf("failed to load current config %w", err) + } + defer chs.unloadNoCommmit(clients) + + clientDetails, ok := clients[client] + if !ok { + return nil, ErrUnknownClient + } + clientDetails.ID = client + return clientDetails, nil +} + func (chs *ClientHandlerService) GetClientSelectedBootOption(client uuid.UUID) (*bootoption.EFIApp, error) { clients, err := chs.load() if err != nil {