Newer
Older
package api
import (
"context"
"errors"
"io"
"time"
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
mnepb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement"
pipb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-internal"
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, mneUUID string, opt *tpb.TransportOption, pluginID, pid uuid.UUID, gNMISubscribePaths []string) (*mnepb.AddListResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
Fabian Seidl
committed
req := &mnepb.AddListRequest{
Timestamp: time.Now().UnixNano(),
Mne: []*mnepb.SetMne{
Fabian Seidl
committed
Address: opt.GetAddress(),
MneName: mneName,
PluginId: pluginID.String(),
Pid: pid.String(),
TransportOption: opt,
GnmiSubscribePaths: gNMISubscribePaths,
},
},
Pid: pid.String(),
}
switch t := opt.Type; t {
case spb.Type_TYPE_CONTAINERISED, spb.Type_TYPE_PLUGIN:
req.Mne[0].TransportOption.Type = t
default:
}
Fabian Seidl
committed
return client.AddList(ctx, req)
// AddNetworkElementList adds all the network elements to the controller. The name of each network element is optional.
// If no name is provided a name will be generated upon network element creation.
func AddNetworkElementList(ctx context.Context, addr, pid string, mneList []*mnepb.SetMne) (*mnepb.AddListResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &mnepb.AddListRequest{
Timestamp: time.Now().UnixNano(),
Mne: mneList,
Pid: pid,
}
return client.AddList(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.
Fabian Seidl
committed
func GetNetworkElement(ctx context.Context, addr, pid string, mneid string) (*mnepb.GetResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
if len(mneid) == 0 {
return nil, err
}
Fabian Seidl
committed
req := &mnepb.GetRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
}
Fabian Seidl
committed
return client.Get(ctx, req)
// GetNetworkElements requests all available network elements related to one PND.
func GetNetworkElements(ctx context.Context, addr, pid string) (*mnepb.GetAllResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &mnepb.GetAllRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid,
}
return client.GetAll(ctx, req)
}
// GetPluginSchemaTree gets the schema tree for a plugin.
func GetPluginSchemaTree(ctx context.Context, addr string, pluginID uuid.UUID) (map[string]*yang.Entry, error) {
pluginClient, err := nbi.PluginClient(addr, dialOptions...)
if err != nil {
return map[string]*yang.Entry{}, err
}
req := &pipb.GetPluginSchemaRequest{
Timestamp: time.Now().UnixNano(),
Pid: pluginID.String(),
}
ctx, cancel := context.WithTimeout(ctx, time.Minute*10)
defer cancel()
sClient, err := pluginClient.GetPluginSchema(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
}
// GetFlattenedNetworkElement requests a network elements belonging to a given
// PrincipalNetworkDomain from the controller.
Fabian Seidl
committed
func GetFlattenedNetworkElement(ctx context.Context, addr, pid string, mneid string) (*mnepb.GetFlattenedResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
Fabian Seidl
committed
req := &mnepb.GetFlattenedRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
}
Fabian Seidl
committed
return client.GetFlattened(ctx, req)
}
// GetFlattenedNetworkElements requests all network elements belonging to a given
// PrincipalNetworkDomain from the controller.
Fabian Seidl
committed
func GetFlattenedNetworkElements(ctx context.Context, addr, pid string) (*mnepb.GetAllFlattenedResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
Fabian Seidl
committed
req := &mnepb.GetAllFlattenedRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid,
}
Fabian Seidl
committed
return client.GetAllFlattened(ctx, req)
// GetPath requests a specific path.
func GetPath(ctx context.Context, addr, pid, mneid, path string) (*mnepb.GetPathResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &mnepb.GetPathRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
Path: path,
}
return client.GetPath(ctx, req)
func GetIntendedPath(ctx context.Context, addr, pid, mneid, intendedPath string) (*mnepb.GetIntendedPathResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &mnepb.GetIntendedPathRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
IntendedPath: intendedPath,
}
return client.GetIntendedPath(ctx, req)
}
// SubscribePath subscribes to paths on a network element.
func SubscribePath(ctx context.Context, addr, pid, mneid string, slist *mnepb.SubscriptionList) (mnepb.NetworkElementService_SubscribePathClient, error) {
log.Println("subscribePath called")
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &mnepb.SubscribePathRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
Sublist: slist,
}
return client.SubscribePath(ctx, req)
// DeleteNetworkElement deletes a network element.
Fabian Seidl
committed
func DeleteNetworkElement(ctx context.Context, addr, pid, mneid string) (*mnepb.DeleteResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
Fabian Seidl
committed
req := &mnepb.DeleteRequest{
Timestamp: time.Now().UnixNano(),
Mneid: mneid,
Pid: pid,
}
Fabian Seidl
committed
return client.Delete(ctx, req)
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
// UpdateNetworkElement changes the metadata of the network element which is stored in the controller storage.
// Correct resource version needs to be provided to allow a change of the object in the storage.
func UpdateNetworkElement(ctx context.Context, addr, mneid, updatedName, updatedTransportAddress, updatedPid string, resourceVersion *conflict.Metadata) (*mnepb.UpdateNetworkElementResponse, error) {
client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
// Note: Consider changing what to update. Some values are quite iffy to change.
req := &mnepb.UpdateNetworkElementRequest{
Timestamp: time.Now().UnixNano(),
NetworkElement: &mnepb.ManagedNetworkElement{
Id: mneid,
Name: updatedName,
TransportAddress: updatedTransportAddress,
TransportOption: &tpb.TransportOption{
Address: updatedTransportAddress,
},
Metadata: resourceVersion,
AssociatedPnd: updatedPid,
},
}
return client.Update(ctx, req)
}