Newer
Older
package api
import (
"context"
"errors"
"io"
"time"
ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd"
spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
"github.com/google/uuid"
"github.com/openconfig/goyang/pkg/yang"
"github.com/openconfig/ygot/ygot"
log "github.com/sirupsen/logrus"
)
// AddNetworkElement adds a new network element to the controller. The network element name is optional.
// If no name is provided a name will be generated upon network element creation.
func AddNetworkElement(ctx context.Context, addr, mneName string, opt *tpb.TransportOption, sid, pid uuid.UUID) (*ppb.SetMneListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SetMneListRequest{
Timestamp: time.Now().UnixNano(),
Mne: []*ppb.SetMne{
{
Address: opt.GetAddress(),
Sbi: &spb.SouthboundInterface{
Id: sid.String(),
},
MneName: mneName,
TransportOption: opt,
},
},
Pid: pid.String(),
}
switch t := opt.Type; t {
case spb.Type_TYPE_CONTAINERISED, spb.Type_TYPE_PLUGIN:
req.Mne[0].Sbi.Id = uuid.Nil.String()
req.Mne[0].Sbi.Type = t
req.Mne[0].TransportOption.Type = t
default:
}
return pndClient.SetMneList(ctx, req)
// GetNetworkElement requests one network element belonging to a given
// PrincipalNetworkDomain from the controller. If no network element identifier
// is provided, an error is thrown.
func GetNetworkElement(ctx context.Context, addr, pid string, mneid string) (*ppb.GetMneResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
if len(mneid) == 0 {
return nil, err
}
req := &ppb.GetMneRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
}
return pndClient.GetMne(ctx, req)
// GetSbiSchemaTree gets the sbi tree for a sbi.
func GetSbiSchemaTree(ctx context.Context, addr string, pid, sid uuid.UUID) (map[string]*yang.Entry, error) {
sbiClient, err := nbi.SbiClient(addr, dialOptions...)
if err != nil {
return map[string]*yang.Entry{}, err
}
req := &spb.GetSchemaRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid.String(),
Sid: sid.String(),
}
ctx, cancel := context.WithTimeout(ctx, time.Minute*10)
defer cancel()
sClient, err := sbiClient.GetSchema(ctx, req)
if err != nil {
return map[string]*yang.Entry{}, err
}
sTreeBytes := []byte{}
for {
payload, err := sClient.Recv()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
log.Error(err)
closeErr := sClient.CloseSend()
if closeErr != nil {
return nil, err
}
return map[string]*yang.Entry{}, err
}
sTreeBytes = append(sTreeBytes, payload.Chunk...)
}
sTreeMap, err := ygot.GzipToSchema(sTreeBytes)
if err != nil {
return map[string]*yang.Entry{}, err
}
return sTreeMap, nil
}
// GetFlattenedNetworkElements requests all network elements belonging to a given
// PrincipalNetworkDomain from the controller.
func GetFlattenedNetworkElements(ctx context.Context, addr, pid string) (*ppb.GetFlattenedMneListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.GetMneListRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid,
}
return pndClient.GetFlattenedMneList(ctx, req)
// GetPath requests a specific path.
func GetPath(ctx context.Context, addr, pid, mneid, path string) (*ppb.GetPathResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.GetPathRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
Path: path,
}
return pndClient.GetPath(ctx, req)
}
// SubscribePath subscribes to paths on a network element.
func SubscribePath(ctx context.Context, addr, pid, mneid string, slist *ppb.SubscriptionList) (ppb.PndService_SubscribePathClient, error) {
log.Println("subscribePath called")
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SubscribePathRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
Sublist: slist,
}
return pndClient.SubscribePath(ctx, req)
}
// DeleteNetworkElement deletes a network element.
func DeleteNetworkElement(ctx context.Context, addr, pid, mneid string) (*ppb.DeleteMneResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.DeleteMneRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
}
return pndClient.DeleteMne(ctx, req)