Skip to content
Snippets Groups Projects
networkInstanceHandler.go 4.84 KiB
Newer Older
  • Learn to ignore specific revisions
  • package networkinstances
    
    import (
    	"fmt"
    
    	gnmitargetygot "code.fbi.h-da.de/danet/gnmi-target/examples/example01/model"
    	"code.fbi.h-da.de/danet/gnmi-target/examples/example01/osclient"
    	"code.fbi.h-da.de/danet/gnmi-target/examples/example01/osclient/additions"
    	"github.com/openconfig/gnmi/proto/gnmi"
    	"github.com/openconfig/ygot/ygot"
    	log "github.com/sirupsen/logrus"
    )
    
    // NetworkInstanceHandler is the implementation of a gnmitarget.PathHandler.
    type NetworkInstanceHandler struct {
    	name     string
    	paths    map[string]struct{}
    	osClient osclient.Osclient
    }
    
    func NewNetworkInstanceHandler() *NetworkInstanceHandler {
    	return &NetworkInstanceHandler{
    		name: "openconfig-network-instance-handler",
    		paths: map[string]struct{}{
    			"/network-instances": struct{}{},
    		},
    		osClient: osclient.NewOsClient(),
    	}
    }
    
    func (yh *NetworkInstanceHandler) Name() string {
    	return yh.name
    }
    
    func (yh *NetworkInstanceHandler) Paths() map[string]struct{} {
    	return yh.paths
    }
    
    func (yh *NetworkInstanceHandler) Init(c ygot.ValidatedGoStruct) error {
    	config, ok := c.(*gnmitargetygot.Gnmitarget)
    	if !ok {
    		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
    	}
    
    	// needed for interfaces and network instances
    	localInterfaces, err := yh.osClient.GetInterfaces()
    	if err != nil {
    		return err
    	}
    
    	confNetworkInstances := config.GetOrCreateNetworkInstances()
    
    	for _, localInterface := range localInterfaces {
    		staticRoutes, err := yh.osClient.GetStaticRoutes(*localInterface.Name)
    		if err != nil {
    			return err
    		}
    
    		for _, staticRoute := range staticRoutes {
    			if err := updateOrCreateNetworkInstance(confNetworkInstances, staticRoute); err != nil {
    				return err
    			}
    		}
    	}
    
    	return nil
    }
    
    func (yh *NetworkInstanceHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update) error {
    	fmt.Println("Update request received for ", yh.name)
    	config, ok := c.(*gnmitargetygot.Gnmitarget)
    	if !ok {
    		return fmt.Errorf("failed type assertion for config %T", (*gnmitargetygot.Gnmitarget)(nil))
    	}
    
    	networkInstances := config.GetNetworkInstances()
    
    	if networkInstances != nil {
    		if networkInstanceMap := networkInstances.NetworkInstance; networkInstanceMap != nil {
    			for _, networkInstance := range networkInstanceMap {
    				if protocols := networkInstance.Protocols; protocols != nil {
    					if protocolMap := protocols.Protocol; protocolMap != nil {
    						// NOTE: since these are dependent on ip addresses
    						// being already set; they should probably wait for the
    						// completion of that task
    						for _, protocol := range protocolMap {
    							if staticRoutes := protocol.StaticRoutes; staticRoutes != nil {
    								for _, staticRoute := range staticRoutes.Static {
    									osStaticRoute := &additions.StaticRoute{}
    									osStaticRoute.Prefix = staticRoute.Prefix
    									for _, hop := range staticRoute.NextHops.NextHop {
    										osStaticRoute.Hops = append(osStaticRoute.Hops, additions.Hop{
    											InterfaceRef: hop.GetInterfaceRef().GetConfig().Interface,
    											Index:        hop.Index,
    											NextHop:      hop.GetConfig().GetNextHop(),
    										})
    									}
    									if err := yh.osClient.SetStaticRoute(osStaticRoute); err != nil {
    										log.Debug("Failed to set static route: ", err)
    										return err
    									}
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    
    	return nil
    }
    
    func updateOrCreateNetworkInstance(confNetworkInstances *gnmitargetygot.OpenconfigNetworkInstance_NetworkInstances, localStaticRoute *additions.StaticRoute) error {
    	if networkInstances := confNetworkInstances.GetOrCreateNetworkInstance("DEFAULT"); networkInstances != nil && localStaticRoute != nil {
    		if protocols := networkInstances.GetOrCreateProtocols(); protocols != nil {
    			staticProtocol := protocols.GetOrCreateProtocol(gnmitargetygot.OpenconfigPolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, "STATIC")
    
    			staticConfig := staticProtocol.GetOrCreateConfig()
    			staticConfig.Identifier = gnmitargetygot.OpenconfigPolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC
    			staticConfig.Name = staticProtocol.Name
    
    			staticRoutes := staticProtocol.GetOrCreateStaticRoutes()
    			staticRoute := staticRoutes.GetOrCreateStatic(*localStaticRoute.Prefix)
    
    			staticRouteConfig := staticRoute.GetOrCreateConfig()
    			staticRouteConfig.Prefix = localStaticRoute.Prefix
    
    			staticRouteHops := staticRoute.GetOrCreateNextHops()
    			for _, hop := range localStaticRoute.Hops {
    				staticRouteHop := staticRouteHops.GetOrCreateNextHop(*hop.Index)
    				staticRouteHopConfig := staticRouteHop.GetOrCreateConfig()
    				if hop.Index != nil {
    					staticRouteHopConfig.Index = hop.Index
    				}
    				if hop.NextHop != nil {
    					staticRouteHopConfig.NextHop = hop.NextHop
    				}
    
    				interfaceRef := staticRouteHop.GetOrCreateInterfaceRef()
    				interfaceRefConfig := interfaceRef.GetOrCreateConfig()
    				if hop.InterfaceRef != nil {
    					interfaceRefConfig.Interface = hop.InterfaceRef
    				}
    			}
    		}
    	}
    	return nil
    }