Skip to content
Snippets Groups Projects
model-handling.go 2.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • package models
    
    import (
    	gpb "github.com/openconfig/gnmi/proto/gnmi"
    	"github.com/openconfig/ygot/ygot"
    	"github.com/openconfig/ygot/ytypes"
    	log "github.com/sirupsen/logrus"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
    	"code.fbi.h-da.de/danet/gosdn/models/generated/arista"
    )
    
    func getYgotEmitJSONConfig() *ygot.EmitJSONConfig {
    	return &ygot.EmitJSONConfig{
    		Format:         ygot.RFC7951,
    		Indent:         "",
    		SkipValidation: true,
    		RFC7951Config: &ygot.RFC7951JSONConfig{
    			AppendModuleName: true,
    		}}
    }
    
    
    // GetModelAsString returns the YANG model of a network element as string.
    
    func GetModelAsString(model ygot.GoStruct) (string, error) {
    	modelAsString, err := ygot.EmitJSON(model, getYgotEmitJSONConfig())
    	if err != nil {
    		return "", err
    	}
    
    	return modelAsString, nil
    }
    
    // Unmarshal injects OpenConfig specific model representation to the transport.
    // Needed for type assertion.
    func Unmarshal(bytes []byte, path *gpb.Path, goStruct ygot.GoStruct, opt ...ytypes.UnmarshalOpt) error {
    	schema, err := arista.Schema()
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	return unmarshal(schema, bytes, path, goStruct, opt...)
    }
    
    // unmarshal parses a gNMI response to a go struct.
    func unmarshal(schema *ytypes.Schema, bytes []byte, path *gpb.Path, goStruct ygot.GoStruct, opt ...ytypes.UnmarshalOpt) error {
    	defer func() {
    		if r := recover(); r != nil {
    
    			log.Error(r.(error)) //nolint:errcheck
    
    		}
    	}()
    
    	// Load SBI definition
    	root, err := ygot.DeepCopy(schema.Root)
    	if err != nil {
    		return err
    	}
    	validatedDeepCopy, ok := root.(ygot.ValidatedGoStruct)
    	if !ok {
    		return &customerrs.InvalidTypeAssertionError{
    			Value: root,
    			Type:  (*ygot.ValidatedGoStruct)(nil),
    		}
    	}
    
    	// returns the node we want to fill with the data contained in 'bytes',
    	// using the specified 'path'.
    	createdNode, _, err := ytypes.GetOrCreateNode(schema.RootSchema(), validatedDeepCopy, path)
    	if err != nil {
    		return err
    	}
    	validatedCreatedNode, ok := createdNode.(ygot.ValidatedGoStruct)
    	if !ok {
    		return &customerrs.InvalidTypeAssertionError{
    			Value: createdNode,
    			Type:  (*ygot.ValidatedGoStruct)(nil),
    		}
    	}
    
    	if err := arista.Unmarshal(bytes, validatedCreatedNode, opt...); err != nil {
    		return err
    	}
    
    	opts := []ygot.MergeOpt{&ygot.MergeOverwriteExistingFields{}}
    	return ygot.MergeStructInto(goStruct, validatedDeepCopy, opts...)
    }