diff --git a/config/goKMS/example01.yaml b/config/goKMS/example01.yaml index f67e8453dd340cadea642a8ae81c8b6403d58aca..a7360a200c7bef16e68c89a8c663c46ca6415c21 100644 --- a/config/goKMS/example01.yaml +++ b/config/goKMS/example01.yaml @@ -34,3 +34,5 @@ Peers: QuantumModule: Type: emulated Address: 172.100.20.18 +QkdnManagerServer: + Address: ":8090" diff --git a/goKMS/config/config.go b/goKMS/config/config.go index d80d67e7ac379bec0f2ce08ef8f59ed00038d9e9..f36739f27d1975ef0825c2df58c490ba468e344b 100644 --- a/goKMS/config/config.go +++ b/goKMS/config/config.go @@ -3,19 +3,20 @@ package config import "github.com/google/uuid" type Config struct { - Id string `yaml:"Id"` - Name string `yaml:"Name"` - InterComAddr string `yaml:"InterComAddr"` - QuantumAddr string `yaml:"QuantumAddr"` - GRPCAddr string `yaml:"GRPCAddr"` - AkmsURL string `yaml:"AkmsURL"` - AkmsCkmsServerPort string `yaml:"AkmsCkmsServerPort"` - GnmiBindAddress string `yaml:"GnmiBindAddress"` - Peers []Peer `yaml:"Peers"` - GnmiTLS TLSConfig `yaml:"GnmiTLS"` - KmsTLS TLSConfig `yaml:"KmsTLS"` - QuantumModuleTLS TLSConfig `yaml:"QuantumModuleTLS"` - AkmsCkmsTLS TLSConfig `yaml:"AkmsCkmsTLS"` + Id string `yaml:"Id"` + Name string `yaml:"Name"` + InterComAddr string `yaml:"InterComAddr"` + QuantumAddr string `yaml:"QuantumAddr"` + GRPCAddr string `yaml:"GRPCAddr"` + AkmsURL string `yaml:"AkmsURL"` + AkmsCkmsServerPort string `yaml:"AkmsCkmsServerPort"` + GnmiBindAddress string `yaml:"GnmiBindAddress"` + Peers []Peer `yaml:"Peers"` + GnmiTLS TLSConfig `yaml:"GnmiTLS"` + KmsTLS TLSConfig `yaml:"KmsTLS"` + QuantumModuleTLS TLSConfig `yaml:"QuantumModuleTLS"` + AkmsCkmsTLS TLSConfig `yaml:"AkmsCkmsTLS"` + QkdnManagerServer *QkdnManagerServer `yaml:"QkdnManagerServer,omitempty"` } type Peer struct { @@ -42,6 +43,10 @@ type QuantumModule struct { MasterMode bool `yaml:"MasterMode"` } +type QkdnManagerServer struct { + Address string `yaml:"Address"` +} + func NewKMSInfo(id uuid.UUID, version *kmsVersionInformation, channel chan string) *KMSInfo { return &KMSInfo{ id: id, diff --git a/goKMS/kms/kms.go b/goKMS/kms/kms.go index 6440aeb09043827875e080e1b4f1706da227f865..050fe7fcc07e84487b698e7c8671fa41d0f64f88 100644 --- a/goKMS/kms/kms.go +++ b/goKMS/kms/kms.go @@ -625,3 +625,7 @@ func (kms *KMS) sendKSAKeysToPlatformKmsPeer(kmsPeerAddress, platformKeyID, requ return nil } + +func (kms *KMS) GetID() uuid.UUID { + return kms.kmsUUID +} diff --git a/goKMS/main.go b/goKMS/main.go index 685c82d7ba8de772b5051a55461b27c688717a0a..7d00b3c9bcc0eeea583f731410f3313b06dc5f3e 100644 --- a/goKMS/main.go +++ b/goKMS/main.go @@ -31,8 +31,11 @@ POSSIBILITY OF SUCH DAMAGE. package main import ( + "context" "flag" "os" + "os/signal" + "syscall" gnmitarget "code.fbi.h-da.de/danet/gnmi-target" "code.fbi.h-da.de/danet/gnmi-target/handler" @@ -41,6 +44,7 @@ import ( "code.fbi.h-da.de/danet/quant/goKMS/gnmiHandlers/system" "code.fbi.h-da.de/danet/quant/goKMS/kms" gnmitargetygot "code.fbi.h-da.de/danet/quant/goKMS/model" + qkdnmanager "code.fbi.h-da.de/danet/quant/goKMS/qkdnManager" "github.com/google/uuid" log "github.com/sirupsen/logrus" "google.golang.org/grpc/resolver" @@ -104,6 +108,13 @@ func main() { kms := kms.NewKMS(kmsId, os.Stdout, log.GetLevel(), false, kmsConfig) + // start Qkdn Manager server, if there is info about it in the config + if kmsConfig.QkdnManagerServer != nil { + go setupQkdnManagerServer(kms, *kmsConfig.QkdnManagerServer) + } else { + log.Info("No server for QkdnManager running.") + } + schema, err := gnmitargetygot.Schema() if err != nil { log.Fatal(err) @@ -194,3 +205,27 @@ func generateKMSInfo(id uuid.UUID) *config.KMSInfo { return config.NewKMSInfo(id, kmsVersionInformation, make(chan string)) } + +func setupQkdnManagerServer(kms *kms.KMS, config config.QkdnManagerServer) { + qkdnManagerServer := qkdnmanager.NewQkdnManagerServer(kms) + + qkdnManagerServer.InitHTTPServer(config) + + ctx, cancel := context.WithCancel(context.Background()) + stopChannel := make(chan os.Signal, 1) + signal.Notify(stopChannel, syscall.SIGINT) + + defer func() { + log.Info("Shutting down server...") + if err := qkdnManagerServer.Server.Shutdown(ctx); err != nil { + log.Errorf("Error shutting down server: %v", err) + _ = qkdnManagerServer.Server.Close() + return + } + log.Info("Gracefully shutdown server completed.") + }() + + <-stopChannel + + cancel() +} diff --git a/goKMS/qkdnManager/server.go b/goKMS/qkdnManager/server.go new file mode 100644 index 0000000000000000000000000000000000000000..8d496bc54dcbbe5a8d8e6093dd55865cb0bcfa90 --- /dev/null +++ b/goKMS/qkdnManager/server.go @@ -0,0 +1,174 @@ +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" + +var endpoints = map[string]string{ + operationalState: "/operationalState", + qkdInterface: "/qkdInterface", + interCKMSInterface: "/interCKMSInterface", + akmsInterface: "/akmsInterface", +} + +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) +} + +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 + for _, peer := range qs.kms.KmsPeers { + 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 requestfrom: %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) + } +}