Skip to content
Snippets Groups Projects
server.go 6.07 KiB
Newer Older
  • Learn to ignore specific revisions
  • package qkdnmanager
    
    import (
    	"encoding/json"
    	"errors"
    
    	"net/http"
    	"time"
    
    	"code.fbi.h-da.de/danet/quant/goKMS/config"
    	"code.fbi.h-da.de/danet/quant/goKMS/kms"
    	"github.com/google/uuid"
    	"github.com/sirupsen/logrus"
    )
    
    const APIPrefix = "/api/v1"
    
    const operationalState = "operationalState"
    const qkdInterface = "qkdInterface"
    const interCKMSInterface = "interCKMSInterface"
    const akmsInterface = "akmsInterface"
    
    const setKeyStore = "setKeyStore"
    
    
    var endpoints = map[string]string{
    	operationalState:   "/operationalState",
    	qkdInterface:       "/qkdInterface",
    	interCKMSInterface: "/interCKMSInterface",
    	akmsInterface:      "/akmsInterface",
    
    	setKeyStore:        "/set_key_store",
    
    }
    
    type QkdnManagerServer struct {
    	Server *http.Server
    	kms    *kms.KMS
    }
    
    type KmsData struct {
    	KMS_ID  uuid.UUID `json:"KMS_ID"`
    	Peers   []Peer    `json:"peers,omitempty"`
    	Running bool      `json:"running,omitempty"`
    }
    
    type Peer struct {
    	Peer_ID uuid.UUID `json:"peer_ID"`
    	Running bool      `json:"running"`
    }
    
    func NewQkdnManagerServer(kms *kms.KMS) *QkdnManagerServer {
    	return &QkdnManagerServer{
    		Server: &http.Server{
    			ReadHeaderTimeout: 15 * time.Second,
    			ReadTimeout:       15 * time.Second,
    			WriteTimeout:      10 * time.Second,
    			IdleTimeout:       30 * time.Second,
    		},
    		kms: kms,
    	}
    }
    
    func (qs *QkdnManagerServer) InitHTTPServer(conf config.QkdnManagerServer) {
    	logrus.Info("Setting up server for management information...")
    	mux := http.NewServeMux()
    	qs.addHandlersToMux(mux)
    
    	qs.Server.Addr = conf.Address
    	qs.Server.Handler = mux
    
    	go qs.startServer()
    	logrus.Infof("QKDN manager server running on %s ...", conf.Address)
    }
    
    func (qs *QkdnManagerServer) addHandlersToMux(mux *http.ServeMux) {
    	// add additional handlers if necessary
    	mux.HandleFunc(APIPrefix+endpoints[operationalState], qs.handleHttpOperationalState)
    	mux.HandleFunc(APIPrefix+endpoints[qkdInterface], qs.handleHttpQkdInterface)
    	mux.HandleFunc(APIPrefix+endpoints[interCKMSInterface], qs.handleHttpInterCKMSInterface)
    	mux.HandleFunc(APIPrefix+endpoints[akmsInterface], qs.handleHttpAkmsInterface)
    
    	mux.HandleFunc(APIPrefix+endpoints[setKeyStore], qs.handleSetKeyStore)
    
    }
    
    func (qs *QkdnManagerServer) startServer() {
    	if err := qs.Server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
    		logrus.Error(err)
    	}
    	logrus.Info("Stopped serving new connections.")
    }
    
    func (qs *QkdnManagerServer) handleHttpOperationalState(w http.ResponseWriter, r *http.Request) {
    	logrus.Debugf("Handler for OperationalState got request from: %s", r.RemoteAddr)
    
    	data := &KmsData{
    		KMS_ID:  qs.kms.GetID(),
    		Running: true,
    	}
    
    	jsonData, err := json.Marshal(data)
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    	}
    
    	w.WriteHeader(http.StatusOK)
    	w.Header().Set("Content-Type", "application/json")
    	_, err = w.Write(jsonData)
    	if err != nil {
    		logrus.Error(err)
    	}
    }
    
    func (qs *QkdnManagerServer) handleHttpQkdInterface(w http.ResponseWriter, r *http.Request) {
    	logrus.Debugf("Handler for QkdInterface got request from: %s", r.RemoteAddr)
    
    	data := &KmsData{
    		KMS_ID:  qs.kms.GetID(),
    		Running: true,
    	}
    
    	jsonData, err := json.Marshal(data)
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    	}
    
    	w.WriteHeader(http.StatusOK)
    	w.Header().Set("Content-Type", "application/json")
    	_, err = w.Write(jsonData)
    	if err != nil {
    		logrus.Error(err)
    	}
    }
    
    func (qs *QkdnManagerServer) handleHttpInterCKMSInterface(w http.ResponseWriter, r *http.Request) {
    	logrus.Debugf("Handler for InterCKMSInterface got request from: %s", r.RemoteAddr)
    
    	var peers []Peer
    
    	peerMapCopy := qs.kms.PeersDeepCopy()
    	for _, peer := range peerMapCopy {
    
    		peers = append(peers, Peer{
    			Peer_ID: peer.GetKmsPeerId(),
    			Running: true,
    		})
    	}
    
    	data := &KmsData{
    		KMS_ID: qs.kms.GetID(),
    		Peers:  peers,
    	}
    
    	jsonData, err := json.Marshal(data)
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    	}
    
    	w.WriteHeader(http.StatusOK)
    	w.Header().Set("Content-Type", "application/json")
    	_, err = w.Write(jsonData)
    	if err != nil {
    		logrus.Error(err)
    	}
    }
    
    func (qs *QkdnManagerServer) handleHttpAkmsInterface(w http.ResponseWriter, r *http.Request) {
    
    	logrus.Debugf("Handler for AkmsInterface got request from: %s", r.RemoteAddr)
    
    
    	data := &KmsData{
    		KMS_ID:  qs.kms.GetID(),
    		Running: true,
    	}
    
    	jsonData, err := json.Marshal(data)
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusInternalServerError)
    	}
    
    	w.WriteHeader(http.StatusOK)
    	w.Header().Set("Content-Type", "application/json")
    	_, err = w.Write(jsonData)
    	if err != nil {
    		logrus.Error(err)
    	}
    }
    
    
    func (qs *QkdnManagerServer) handleSetKeyStore(w http.ResponseWriter, r *http.Request) {
    	logrus.Debugf("Handler for SetKeyStore got request from: %s", r.RemoteAddr)
    
    
    	var parsedRequest struct {
    		KeyFillLevel int      `json:"key_fill_level"`
    		PeerIDs      []string `json:"peer_ids"`
    		Fetch        bool     `json:"fetch"`
    
    	err := json.NewDecoder(r.Body).Decode(&parsedRequest)
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusBadRequest)
    
    	logrus.Debugf("KeyFillLevel: %d, PeerIDs: %v, Fetch: %t", parsedRequest.KeyFillLevel, parsedRequest.PeerIDs, parsedRequest.Fetch)
    
    	for _, peerID := range parsedRequest.PeerIDs {
    
    		peerUUID, err := uuid.Parse(peerID)
    		if err != nil {
    			http.Error(w, err.Error(), http.StatusBadRequest)
    			return
    		}
    		peer, err := qs.kms.FindPeerById(peerUUID.String())
    		if err != nil {
    			http.Error(w, err.Error(), http.StatusBadRequest)
    			return
    		}
    
    		eqm := peer.QuantumModule()
    		if parsedRequest.Fetch == true {
    
    			if err := eqm.Initialize(); err != nil {
    				http.Error(w, fmt.Sprintf("Failed to restart fetching for quantum module of peer: %s", peerID), http.StatusBadRequest)
    				return
    			}
    
    		} else if parsedRequest.Fetch == false {
    
    			eqm.SetActive(false)
    			if err := peer.ResetKeyStore(qs.kms.GetID().String()); err != nil {
    				eqm.SetActive(true)
    				http.Error(w, fmt.Sprintf("Failed to reset keystore for quantum module of peer: %s", peerID), http.StatusBadRequest)
    				return
    			}
    
    			eqm.Reset()
    		}
    	}
    
    	w.WriteHeader(http.StatusOK)
    	_, err = w.Write([]byte("OK\n"))
    	if err != nil {
    		logrus.Error(err)
    	}
    }