diff --git a/config/config.json b/config/config.json index d7261397db3aac885b2f486c641f858444e6d9d1..27a28cd5efd25f8b7aefc21c42008ce31d4156cb 100644 --- a/config/config.json +++ b/config/config.json @@ -18,5 +18,58 @@ "state": { "software-version": "debian:12" } + }, + "temp:kms": { + "kms-id": "672f4f62-df26-40cc-b0ee-6248bcb3d8d0" + }, + "temp:key-stores": { + "key-store": [ + { + "key-store": { + "key-fill-level": "5", + "max-key-fill-level": "100" + }, + "kms-peer-id": "7fbc5517-44cb-4aab-a271-212f1df308c2" + }, + { + "key-store": { + "key-fill-level": "5", + "max-key-fill-level": "100" + }, + "kms-peer-id": "069f2897-83d7-4266-8f77-737e3cb23e1c" + } + ] + }, + "temp:kms-peer-table": { + "kms-peers": [ + { + "kms-peer-id": "7fbc5517-44cb-4aab-a271-212f1df308c2", + "peer-information": { + "negotiated-key-length": "256", + "op-status": "ESTABLISHED", + "peer-address": { + "hostname": "10.10.10.10:5000", + "ip-address": "10.10.10.10", + "node-id": "7fbc5517-44cb-4aab-a271-212f1df308c2", + "port": 5000 + }, + "qkd-module-id": "29ba40be-a72f-400b-a5b1-4b2c1cc2a38e" + } + }, + { + "kms-peer-id": "069f2897-83d7-4266-8f77-737e3cb23e1c", + "peer-information": { + "negotiated-key-length": "256", + "op-status": "ESTABLISHED", + "peer-address": { + "hostname": "10.10.10.11:5000", + "ip-address": "10.10.10.11", + "node-id": "069f2897-83d7-4266-8f77-737e3cb23e1c", + "port": 5000 + }, + "qkd-module-id": "d9099e5d-b4ba-4e6b-af59-c2ce89005b59" + } + } + ] } } diff --git a/examples/example01/cmd/start.go b/examples/example01/cmd/start.go index f7c6bc7950192164bcca22f6771381775bbb3130..e04629890de8fb09aea2b5310b911e3a51c69671 100644 --- a/examples/example01/cmd/start.go +++ b/examples/example01/cmd/start.go @@ -35,8 +35,10 @@ import ( "os" gnmitarget "code.fbi.h-da.de/danet/gnmi-target" + "code.fbi.h-da.de/danet/gnmi-target/examples/example01/handlers/keystore" gnmitargetygot "code.fbi.h-da.de/danet/gnmi-target/examples/example01/model" + "code.fbi.h-da.de/danet/gnmi-target/handler" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -95,7 +97,14 @@ var startCmd = &cobra.Command{ logrus.Fatal(err) } - gnmitTarget := gnmitarget.NewGnmiTarget(schema, model, gnmitargetygot.ΓModelData, gnmitargetygot.Unmarshal, gnmitargetygot.ΛEnum) + // The registered path handlers sorted by priority. If specific + // handlers should be able to process their workload before others, + // then they should be placed in the front of the slice. + handlers := []handler.PathHandler{ + keystore.NewKeyStoreHandler(), + } + + gnmitTarget := gnmitarget.NewGnmiTarget(schema, model, gnmitargetygot.ΓModelData, gnmitargetygot.Unmarshal, gnmitargetygot.ΛEnum, handlers...) if err := gnmitTarget.Start(viper.GetString("bindAddress"), viper.GetString("certFile"), viper.GetString("keyFile"), viper.GetString("caFile"), *insecure); err != nil { logrus.Fatal(err) } diff --git a/examples/example01/handlers/keystore/keyStoreHandler.go b/examples/example01/handlers/keystore/keyStoreHandler.go new file mode 100644 index 0000000000000000000000000000000000000000..5df8b2adfb62a74ab3bd4b570f63490ab155de72 --- /dev/null +++ b/examples/example01/handlers/keystore/keyStoreHandler.go @@ -0,0 +1,96 @@ +package keystore + +import ( + "fmt" + "math/rand/v2" + "time" + + gnmitargetygot "code.fbi.h-da.de/danet/gnmi-target/examples/example01/model" + "code.fbi.h-da.de/danet/gnmi-target/handler" + "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/ygot/ygot" + log "github.com/sirupsen/logrus" +) + +type KeyStoreHandler struct { + handler.DefaultPathHandler +} + +func NewKeyStoreHandler() *KeyStoreHandler { + return &KeyStoreHandler{ + DefaultPathHandler: handler.DefaultPathHandler{ + Name: "key-store-handler", + Paths: map[string]struct{}{ + "key-stores": {}, + }, + }, + } +} + +func (yh *KeyStoreHandler) Init(config *handler.Config, publishToSubsFunc func([]*gnmi.Notification) error) error { + yh.Config = config + yh.PublishToSubs = publishToSubsFunc + + go func() { + // update the keystore every 5 seconds + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() + + // TODO: add context/channel to stop + for range ticker.C { + diff, err := yh.updateOrCreateKeyStores() + if err != nil { + log.Errorf("Error within key stores subscription goroutine; %v", err) + break + } + if err := yh.PublishToSubs(diff); err != nil { + log.Errorf("Error within key stores subscription goroutine; %v", err) + } + } + }() + return nil +} + +func (yh *KeyStoreHandler) updateOrCreateKeyStores() ([]*gnmi.Notification, error) { + yh.Config.Lock() + defer yh.Config.Unlock() + + copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data) + if err != nil { + return nil, err + } + + newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget) + if !ok { + return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.Temp_KeyStores)(nil), copyCurrentConfig) + } + + confKeyStores := newConfig.GetOrCreateKeyStores() + + if confKeyStores.KeyStore != nil { + // This is used for demonstration: generate a random number in the + // range(min:95, max:100), this value is then used for all keystores. + randomKeyFillLevel := rand.IntN(100+1-95) + 95 + + for _, store := range confKeyStores.KeyStore { + confKeyStore := store.GetOrCreateKeyStore() + confKeyStore.KeyFillLevel = ygot.Uint64(uint64(randomKeyFillLevel)) + // set the max key fill level to 100 + confKeyStore.MaxKeyFillLevel = ygot.Uint64(100) + } + } + + // validate struct + if err := newConfig.Validate(); err != nil { + return nil, err + } + + notifications, err := ygot.DiffWithAtomic(yh.Config.Data, newConfig) + if err != nil { + return nil, err + } + + yh.Config.Data = newConfig + + return notifications, nil +}