Newer
Older
spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound"
"code.fbi.h-da.de/danet/gosdn/interfaces/southbound"
"code.fbi.h-da.de/danet/yang-models/generated/openconfig"
gpb "github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/goyang/pkg/yang"
"github.com/openconfig/ygot/util"
"github.com/openconfig/ygot/ygot"
log "github.com/sirupsen/logrus"
var csbi *Csbi
func init() {
csbi = &Csbi{id: uuid.New()}
}
// NewSBI creates a SouthboundInterface of a given type.
func NewSBI(southbound spb.Type, sbUUID ...uuid.UUID) southbound.SouthboundInterface {
var id uuid.UUID
if len(sbUUID) == 0 {
id = uuid.New()
} else {
id = sbUUID[0]
}
// OpenConfig is the implementation of an OpenConfig SBI.
// The struct holds the YANG schema and a function that
// returns an SBI specific SetNode function.
// SbiIdentifier returns the string representation of
// the SBI
// deprecated
// Schema returns a ygot generated openconfig Schema as ytypes.Schema
func (oc *OpenConfig) Schema() *ytypes.Schema {
schema, err := openconfig.Schema()
Manuel Kieweg
committed
if err != nil {
Manuel Kieweg
committed
// SetNode injects OpenConfig specific model representation to the transport.
func (oc *OpenConfig) SetNode(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error {
return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...)
// Unmarshal injects OpenConfig specific model representation to the transport.
// Needed for type assertion.
func (oc *OpenConfig) Unmarshal(bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error {
return unmarshal(oc.Schema(), bytes, fields, goStruct, opt...)
// unmarshal parses gNMI response to a go struct. If it's a root level response
// it uses
func unmarshal(schema *ytypes.Schema, bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error {
defer func() {
if r := recover(); r != nil {
}()
// Load SBI definition
validatedDeepCopy, ok := root.(ygot.ValidatedGoStruct)
if !ok {
return &errors.ErrInvalidTypeAssertion{}
ygot.BuildEmptyTree(validatedDeepCopy)
var fieldStruct ygot.ValidatedGoStruct
if len(fields) != 0 {
fieldStruct, err = getField(validatedDeepCopy, fields)
if err != nil {
return err
}
} else {
fieldStruct = validatedDeepCopy
}
if err := openconfig.Unmarshal(bytes, fieldStruct, opt...); err != nil {
return err
}
ygot.PruneEmptyBranches(validatedDeepCopy)
opts := []ygot.MergeOpt{&ygot.MergeOverwriteExistingFields{}}
return ygot.MergeStructInto(goStruct, validatedDeepCopy, opts...)
// getField traverses the GoStruct and returns the field that represents the
// tail of the path
func getField(inStruct ygot.ValidatedGoStruct, fields []string) (ygot.ValidatedGoStruct, error) {
defer func() {
if r := recover(); r != nil {
f := fields[0]
s := reflect.ValueOf(inStruct)
h := reflect.Indirect(s).FieldByName(f).Interface()
outStruct, ok := h.(ygot.ValidatedGoStruct)
if !ok {
t := reflect.TypeOf(h)
if !(util.IsTypeStruct(t) || util.IsTypeStructPtr(t)) {
return nil, fmt.Errorf("cannot process entry of type %v, request longer or shorter path", t)
return nil, fmt.Errorf("expected ValidatedGoStruct got %v", t)
}
if len(fields) > 1 {
// ID returns the ID of the OpenConfig SBI
func (oc *OpenConfig) ID() uuid.UUID {
// Type returns the Southbound's type
func (oc *OpenConfig) Type() spb.Type { return spb.Type_OPENCONFIG }
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// Csbi is a stub for the containerised SBI functionality.
// It holds the standard goSDN OPENCONFIG schema for minimum
// compatibility
type Csbi struct {
schema *ytypes.Schema
id uuid.UUID
}
// SbiIdentifier returns the identifier as a
func (csbi *Csbi) SbiIdentifier() string {
return "csbi"
}
// SetNode injects schema specific model representation to the transport.
// Needed for type assertion.
func (csbi *Csbi) SetNode(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error {
return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...)
}
// Unmarshal injects schema specific model representation to the transport.
// Needed for type assertion.
func (csbi *Csbi) Unmarshal(bytes []byte, fields []string, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error {
oc := OpenConfig{}
return unmarshal(oc.Schema(), bytes, fields, goStruct, opt...)
}
// Schema is holding the default OpenConfig schema for minimal compatibility
// to gosdn interfaces
func (csbi *Csbi) Schema() *ytypes.Schema {
schema, err := openconfig.Schema()
csbi.schema = schema
if err != nil {
log.Fatal(err)
}
return schema
}
// ID returns the Southbound's UUID
func (csbi *Csbi) ID() uuid.UUID {
return csbi.id
}
// Type returns the Southbound's type
func (csbi *Csbi) Type() spb.Type {
return spb.Type_CONTAINERISED
}