From b1b68b98c5f086b3d44c9a5ea0f7636423e7ac3e Mon Sep 17 00:00:00 2001 From: "S.H." <sebastian.heiss94@proton.me> Date: Tue, 22 Apr 2025 11:57:07 +0200 Subject: [PATCH] Introduce experimental mode which disables filtering for paths in callback. at the moment trying to sync every change blasts gNMI target because bug in interface handler, so limit it back to mtu for now --- applications/rtdt-manager/main.go | 9 ++- .../rtdt-manager/rtdt-manager/rtdt-manager.go | 81 ++++++++++++++----- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/applications/rtdt-manager/main.go b/applications/rtdt-manager/main.go index f95d64666..967d67c10 100644 --- a/applications/rtdt-manager/main.go +++ b/applications/rtdt-manager/main.go @@ -18,6 +18,10 @@ func main() { var clabConfigName string var benchmark bool var sdnConfigPath string + // The next flag is to disable path checking before applying received events. + //Interface handler in gNMI target is sort of broken and bombards you with events + // Trying to apply them all crashes the handler (? more research needed) + var experimentalMode bool flag.StringVar(&address, "address", "172.100.0.5:55055", "Address of the gosdn controller") flag.StringVar(&address, "a", "172.100.0.5:55055", "Address of the gosdn controller (shorthand)") @@ -29,6 +33,7 @@ func main() { flag.StringVar(&clabConfigName, "c", "data/clab.yaml", "Containerlab file with basic gosdn environment (shorthand)") flag.BoolVar(&benchmark, "benchmark", false, "Run performance tests (measure propagation delay)") flag.BoolVar(&benchmark, "b", false, "Run performance tests (measure propagation delay)") + flag.BoolVar(&experimentalMode, "experimental", false, "Enable experimental mode (spicy!)") flag.StringVar(&sdnConfigPath, "sdnconfig", "applications/rtdt-manager/data/sample_venv_sdnconfig.json", "SdnConfig file (json)") flag.Usage = func() { @@ -37,10 +42,12 @@ func main() { fmt.Println("--password, -p: Password for the user to log into realnet as (Try 'TestPassword')") fmt.Println("--topology, -t: Topology .yaml file with entries for the goSDN environment. Used to generate realnet and twins") fmt.Println("--sdnconfig: Path to the sdnconfig .json file that contains information about network elements and links") + fmt.Println("--experimental: WARNING! Passing this essentially disables paths filtering, trying to apply all changes of events, generally causing breakage because of bugs in gNMI-target") + } flag.Parse() // Register new RtdtManager - rtdtMan := RtdtMan.NewRtdtManager() + rtdtMan := RtdtMan.NewRtdtManager(experimentalMode) if rtdtMan == nil { fmt.Println("Couldn't initialize rtdt-manager, quitting!") return diff --git a/applications/rtdt-manager/rtdt-manager/rtdt-manager.go b/applications/rtdt-manager/rtdt-manager/rtdt-manager.go index 3fcf1e822..5f6236ed1 100644 --- a/applications/rtdt-manager/rtdt-manager/rtdt-manager.go +++ b/applications/rtdt-manager/rtdt-manager/rtdt-manager.go @@ -15,6 +15,7 @@ import ( "time" "code.fbi.h-da.de/danet/gosdn/application-framework/event" + "code.fbi.h-da.de/danet/gosdn/application-framework/registration" clabconfig "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/clab-config" "code.fbi.h-da.de/danet/gosdn/applications/rtdt-manager/sdnconfig" @@ -31,16 +32,18 @@ type RtdtManager struct { stopChan chan os.Signal baseClabConfig *clabconfig.ClabConfig benchmark0 bool + experimental bool } // needs to be passed a running realnet VEnv -func NewRtdtManager() *RtdtManager { +func NewRtdtManager(experimental bool) *RtdtManager { rMan := RtdtManager{ realnet: nil, waitGroup: sync.WaitGroup{}, stopChan: make(chan os.Signal, 1), baseClabConfig: nil, benchmark0: false, + experimental: experimental, } signal.Notify(rMan.stopChan, os.Interrupt) fmt.Println("Success: RtdtManager created") @@ -284,7 +287,7 @@ func (r *RtdtManager) Run() error { return nil } if len(r.rtdt_twins) < 1 { - fmt.Println("Warning: You did not start any twins") + fmt.Println("!! Warning: You did not start any twins, you can do so with 'launch-twin'") } // Run until SIGINT, SIGTERM is received @@ -399,9 +402,9 @@ func (r *RtdtManager) InitEventSystem() error { if !r.realnet.EventSystemStarted { fmt.Println("Starting Event System for realnet!") - // realnet_auth := r.realnet.GetAuth() - // ctx := realnet_auth.CreateContextWithAuthorization() - // queueCredentials, err := registration.Register(ctx, realnet_auth.GetAddress(), "basic-interface-monitoring", "SecurePresharedToken") + realnet_auth := r.realnet.GetAuth() + ctx := realnet_auth.CreateContextWithAuthorization() + _, err := registration.Register(ctx, realnet_auth.GetAddress(), "basic-interface-monitoring", "SecurePresharedToken") queueAddress, err := r.realnet.FindQueueAddress() if err != nil { return fmt.Errorf("Error in InitEventSystem(): %w", err) @@ -485,6 +488,16 @@ func (r *RtdtManager) updateMNECallbackTwin(event *event.Event) { } } +func printEvent(event *event.Event) { + + fmt.Println("--------------------------------") + fmt.Println("---------- MNE EVENT -----------") + fmt.Println("EventID: ", event.ID.ID()) + fmt.Println("Event Type: ", event.Type) + fmt.Println("PathsAndValuesMap: ", event.PathsAndValuesMap) + fmt.Println("EntityID", event.EntityID) +} + func (r *RtdtManager) updateMNECallbackRealnet(event *event.Event) { if !r.realnet.SyncBack { return @@ -493,24 +506,17 @@ func (r *RtdtManager) updateMNECallbackRealnet(event *event.Event) { benchmark.Current = benchmark.Benchmark0{} benchmark.Current.StartTimeRealnet = time.Now() } - fmt.Println("--------------------------------") - fmt.Println("---------- MNE EVENT -----------") - fmt.Println("EventID: ", event.ID.ID()) - fmt.Println("Event Type: ", event.Type) - fmt.Println("PathsAndValuesMap: ", event.PathsAndValuesMap) - fmt.Println("EntityID", event.EntityID) - // prefix := "/interfaces/interface[name=" - // prefixHostname := "/system/config/hostname" + prefixInterface := "/interfaces/interface[name=" + prefixHostname := "/system/config/hostname" //realnetClabData := r.realnet.GetClabData() // for i, node := range realnetClabData.Topology.Nodes { // // } - // suffixMTU := "]/config/mtu" + suffixMTU := "]/config/mtu" // Select a twin //TODO: This is where some selection process should happen to select the right twin based on the event var twin *venv.VEnv if len(r.rtdt_twins) > 0 { - fmt.Println("Found twin to apply change to:", r.rtdt_twins[0].Name) twin = r.rtdt_twins[0] // just support one twin for now r.rtdt_twins[0].SyncBack = false // Don't record this in twin } else { @@ -524,8 +530,8 @@ func (r *RtdtManager) updateMNECallbackRealnet(event *event.Event) { // First get hostname of realnet node realnetNode := r.realnet.GetSdnConfig().GetNodeByUUID(event.EntityID.String()) // LINK UP/DOWN - //interfaceRegex := regexp.MustCompile(`/interfaces/interface\[name=([^]]+)]/state/oper-status`) - // regexMatch := interfaceRegex.FindStringSubmatch(path) + interfaceRegex := regexp.MustCompile(`/interfaces/interface\[name=([^]]+)]/state/oper-status`) + regexMatchOperStatus := interfaceRegex.FindStringSubmatch(path) // Get the ID of parallel mne in twin network // parallel nodes are nodes that have the same name in twin and realnet @@ -536,8 +542,45 @@ func (r *RtdtManager) updateMNECallbackRealnet(event *event.Event) { } } - //var err error - twin.SetGnmiPath(path, value, twinEntityID, r.benchmark0) + // If experimental, just call it like this + if r.experimental { + fmt.Println("Found twin to apply change to:", r.rtdt_twins[0].Name) + twin.SetGnmiPath(path, value, twinEntityID, r.benchmark0) + // Else filter it first + } else if strings.HasPrefix(path, prefixInterface) && strings.HasSuffix(path, suffixMTU) { + fmt.Println("--- CHANGE MTU TRIGGERED ---") + printEvent(event) + + fmt.Println("Value of new MTU: ", value) + twin.SetGnmiPath(path, value, twinEntityID, r.benchmark0) + // Set Hostname + } else if strings.HasPrefix(path, prefixHostname) { + + fmt.Println("--- CHANGE HOSTNAME TRIGGERED ---") + printEvent(event) + for _, twin := range r.rtdt_twins { + if twin == nil { + fmt.Println("Encountered nil twin, skipping") + continue + } + fmt.Println("ENTERING SETGNMIPATH, value: ", value, "path:", path) + err := twin.SetGnmiPath(path, value, twinEntityID, r.benchmark0) + if err != nil { + fmt.Println("Callback failed:", err) + return + } + } + } else if regexMatchOperStatus != nil && len(r.rtdt_twins) > 0 { + fmt.Println("Setting interface", regexMatchOperStatus[1], "UP/DOWN") + fmt.Printf("match: %v\n", regexMatchOperStatus) + path := "/interfaces/interface[name=" + regexMatchOperStatus[1] + "]/config/enabled" + if value == "DOWN" { + value = "false" + } else { + value = "true" + } + twin.SetGnmiPath(path, value, twinEntityID, false) + } // Some explicitly supported paths // MTU Change -- GitLab