Skip to content
Snippets Groups Projects
target.go 2.21 KiB
Newer Older
  • Learn to ignore specific revisions
  • Manuel Kieweg's avatar
    Manuel Kieweg committed
    package api
    
    
    import (
    
    Andre Sterba's avatar
    Andre Sterba committed
    	"context"
    	"net"
    	"reflect"
    
    
    	"code.fbi.h-da.de/cocsn/gosdn/forks/google/gnmi"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	oc "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
    
    	pb "github.com/openconfig/gnmi/proto/gnmi"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"github.com/openconfig/goyang/pkg/yang"
    	"github.com/openconfig/ygot/util"
    
    	"github.com/openconfig/ygot/ygot"
    	log "github.com/sirupsen/logrus"
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/reflection"
    )
    
    type server struct {
    	*gnmi.Server
    }
    
    func callback(newConfig ygot.ValidatedGoStruct) error {
    	// Apply the config to your device and return nil if success. return error if fails.
    	//
    	// Do something ...
    	return nil
    }
    
    func newServer(model *gnmi.Model, config []byte) (*server, error) {
    	s, err := gnmi.NewServer(model, config, callback)
    	if err != nil {
    		return nil, err
    	}
    	return &server{Server: s}, nil
    }
    
    // Get overrides the Get func of gnmi.Target to provide user auth.
    func (s *server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) {
    	return s.Server.Get(ctx, req)
    }
    
    // Set overrides the Set func of gnmi.Target to provide user auth.
    /*
    func (s *server) Set(ctx context.Context, req *pb.SetRequest) (*pb.SetResponse, error) {
    	msg, ok := credentials.AuthorizeUser(ctx)
    	if !ok {
    		log.Infof("denied a Set request: %v", msg)
    		return nil, status.Error(codes.PermissionDenied, msg)
    	}
    	log.Infof("allowed a Set request: %v", msg)
    	return s.Server.Set(ctx, req)
    }
    */
    
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    // Target starts a gNMI target listening on the specified port.
    func Target(bindAddr string) error {
    	entries := make([]*yang.Entry, 0)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	for _, e := range oc.SchemaTree {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		entries = append(entries, e)
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	modelData, err := util.FindModelData(entries)
    	if err != nil {
    		return err
    	}
    
    	// Google stuff from here
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	model := gnmi.NewModel(
    		modelData,
    
    		reflect.TypeOf((*oc.Device)(nil)),
    		oc.SchemaTree["Device"],
    		oc.Unmarshal,
    		oc.ΛEnum)
    
    	g := grpc.NewServer()
    
    	var configData []byte
    	s, err := newServer(model, configData)
    	if err != nil {
    		return err
    	}
    	pb.RegisterGNMIServer(g, s)
    	reflection.Register(g)
    
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	log.Infof("starting to listen on %s", bindAddr)
    	listen, err := net.Listen("tcp", bindAddr)
    
    	if err != nil {
    		return err
    	}
    
    	log.Info("starting to serve")
    	if err := g.Serve(listen); err != nil {
    		return err
    	}
    	return nil
    }