Skip to content
Snippets Groups Projects
Commit 66ac272b authored by Fabian Seidl's avatar Fabian Seidl
Browse files

Resolve "Update gRPC abstraction API with missing calls and refactoring"

See merge request !790
parent c026ea5b
No related branches found
No related tags found
1 merge request!790Resolve "Update gRPC abstraction API with missing calls and refactoring"
Pipeline #188423 passed
...@@ -50,7 +50,7 @@ A description must be passed as positional argument.`, ...@@ -50,7 +50,7 @@ A description must be passed as positional argument.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
spinner, _ := pterm.DefaultSpinner.Start("Creating new PND") spinner, _ := pterm.DefaultSpinner.Start("Creating new PND")
_, err := api.AddPnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), pndName, pndDescription) _, err := api.CreatePnd(createContextWithAuthorization(), viper.GetString("controllerApiEndpoint"), pndName, pndDescription)
if err != nil { if err != nil {
spinner.Fail("Failed creating the PND with name: ", pndName) spinner.Fail("Failed creating the PND with name: ", pndName)
spinner.Fail(err) spinner.Fail(err)
......
...@@ -47,7 +47,7 @@ var pndListCmd = &cobra.Command{ ...@@ -47,7 +47,7 @@ var pndListCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
spinner, _ := pterm.DefaultSpinner.Start("Fetching PND list from controller") spinner, _ := pterm.DefaultSpinner.Start("Fetching PND list from controller")
resp, err := api.GetPnds(createContextWithAuthorization(), pndAdapter.Endpoint()) resp, err := api.GetPndList(createContextWithAuthorization(), pndAdapter.Endpoint())
if err != nil { if err != nil {
spinner.Fail(err) spinner.Fail(err)
return return
......
...@@ -55,7 +55,7 @@ func ensureStoreFileForTestsIsRemoved(storeName string) { ...@@ -55,7 +55,7 @@ func ensureStoreFileForTestsIsRemoved(storeName string) {
func Test_AddPnd(t *testing.T) { func Test_AddPnd(t *testing.T) {
defer ensureFilesForTestsAreRemoved() defer ensureFilesForTestsAreRemoved()
resp, err := AddPnd(context.TODO(), bufnet, "test", "test pnd") resp, err := CreatePnd(context.TODO(), bufnet, "test", "test pnd")
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
......
package api
import (
"context"
"time"
apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/app"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
)
// Register checks if the app already exists and if not creates a new one.
func Register(ctx context.Context, addr, appname, token string) (*apb.AppRegisterResponse, error) {
appClient, err := nbi.AppClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &apb.AppRegisterRequest{
Timestamp: time.Now().UnixNano(),
Appname: appname,
Token: token,
}
return appClient.Register(ctx, req)
}
// Deregister deregisters an app.
func Deregister(ctx context.Context, addr, appname, token string) (*apb.AppDeregisterResponse, error) {
appClient, err := nbi.AppClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &apb.AppDeregisterRequest{
Timestamp: time.Now().UnixNano(),
Appname: appname,
}
return appClient.Deregister(ctx, req)
}
package api
import (
"context"
"time"
cpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/configurationmanagement"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
)
// ExportSDNConfig returns the SDN configuration.
func ExportSDNConfig(ctx context.Context, addr, pid string) (*cpb.ExportSDNConfigResponse, error) {
configClient, err := nbi.ConfigurationManagementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &cpb.ExportSDNConfigRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid,
}
return configClient.ExportSDNConfig(ctx, req)
}
// ImportSDNConfig receives an SDN configuration and imports it.
func ImportSDNConfig(ctx context.Context, addr, pid, sdnConfigData string) (*cpb.ImportSDNConfigResponse, error) {
configClient, err := nbi.ConfigurationManagementClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &cpb.ImportSDNConfigRequest{
Timestamp: time.Now().UnixNano(),
Pid: pid,
SdnConfigData: sdnConfigData,
}
return configClient.ImportSDNConfig(ctx, req)
}
...@@ -2,19 +2,15 @@ package api ...@@ -2,19 +2,15 @@ package api
import ( import (
"context" "context"
"errors"
"io"
"time" "time"
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
mnepb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement" 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" spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport" tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client" nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/openconfig/goyang/pkg/yang"
"github.com/openconfig/ygot/ygot"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
...@@ -50,6 +46,23 @@ func AddNetworkElement(ctx context.Context, addr, mneName, mneUUID string, opt * ...@@ -50,6 +46,23 @@ func AddNetworkElement(ctx context.Context, addr, mneName, mneUUID string, opt *
return client.AddList(ctx, req) 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 // GetNetworkElement requests one network element belonging to a given
// PrincipalNetworkDomain from the controller. If no network element identifier // PrincipalNetworkDomain from the controller. If no network element identifier
// is provided, an error is thrown. // is provided, an error is thrown.
...@@ -72,51 +85,19 @@ func GetNetworkElement(ctx context.Context, addr, pid string, mneid string) (*mn ...@@ -72,51 +85,19 @@ func GetNetworkElement(ctx context.Context, addr, pid string, mneid string) (*mn
return client.Get(ctx, req) return client.Get(ctx, req)
} }
// GetPluginSchemaTree gets the schema tree for a plugin. // GetNetworkElements requests all available network elements related to one PND.
func GetPluginSchemaTree(ctx context.Context, addr string, pluginID uuid.UUID) (map[string]*yang.Entry, error) { func GetNetworkElements(ctx context.Context, addr, pid string) (*mnepb.GetAllResponse, error) {
pluginClient, err := nbi.PluginClient(addr, dialOptions...) client, err := nbi.NetworkElementClient(addr, dialOptions...)
if err != nil { if err != nil {
return map[string]*yang.Entry{}, err return nil, err
} }
req := &pipb.GetPluginSchemaRequest{ req := &mnepb.GetAllRequest{
Timestamp: time.Now().UnixNano(), Timestamp: time.Now().UnixNano(),
Pid: pluginID.String(), Pid: pid,
}
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 return client.GetAll(ctx, req)
} }
// GetFlattenedNetworkElement requests a network elements belonging to a given // GetFlattenedNetworkElement requests a network elements belonging to a given
...@@ -218,3 +199,28 @@ func DeleteNetworkElement(ctx context.Context, addr, pid, mneid string) (*mnepb. ...@@ -218,3 +199,28 @@ func DeleteNetworkElement(ctx context.Context, addr, pid, mneid string) (*mnepb.
return client.Delete(ctx, req) return client.Delete(ctx, req)
} }
// 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
}
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)
}
...@@ -2,11 +2,18 @@ package api ...@@ -2,11 +2,18 @@ package api
import ( import (
"context" "context"
"errors"
"io"
"time" "time"
pib "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-internal" pib "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-internal"
pipb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-internal"
prb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-registry" prb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-registry"
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client" 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"
"github.com/sirupsen/logrus"
) )
// GetAvailablePlugins requests all available plugins that can be registered // GetAvailablePlugins requests all available plugins that can be registered
...@@ -24,3 +31,50 @@ func GetAvailablePlugins(ctx context.Context, addr string) (*prb.GetResponse, er ...@@ -24,3 +31,50 @@ func GetAvailablePlugins(ctx context.Context, addr string) (*prb.GetResponse, er
return pluginRegistryClient.AvailablePlugins(ctx, req) return pluginRegistryClient.AvailablePlugins(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
}
logrus.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
}
...@@ -9,9 +9,9 @@ import ( ...@@ -9,9 +9,9 @@ import (
nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client" nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
) )
// AddPnd takes a name, description and SBI UUID to create a new // CreatePnd takes an address, a name and a description to create a new
// PrincipalNetworkDomain on the controller. // PrincipalNetworkDomain on the controller.
func AddPnd(ctx context.Context, addr, name, description string) (*ppb.CreatePndListResponse, error) { func CreatePnd(ctx context.Context, addr, name, description string) (*ppb.CreatePndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...) pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -30,6 +30,21 @@ func AddPnd(ctx context.Context, addr, name, description string) (*ppb.CreatePnd ...@@ -30,6 +30,21 @@ func AddPnd(ctx context.Context, addr, name, description string) (*ppb.CreatePnd
return pndClient.CreatePndList(ctx, req) return pndClient.CreatePndList(ctx, req)
} }
// CreatePndList uses the provided creation properties to add all the PNDs to the controller.
func CreatePndList(ctx context.Context, addr string, pnds []*ppb.PndCreateProperties) (*ppb.CreatePndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.CreatePndListRequest{
Timestamp: time.Now().UnixNano(),
Pnd: pnds,
}
return pndClient.CreatePndList(ctx, req)
}
// GetPnd requests one PrincipalNetworkDomain from the // GetPnd requests one PrincipalNetworkDomain from the
// controller. // controller.
func GetPnd(ctx context.Context, addr string, args string) (*ppb.GetPndResponse, error) { func GetPnd(ctx context.Context, addr string, args string) (*ppb.GetPndResponse, error) {
...@@ -48,9 +63,9 @@ func GetPnd(ctx context.Context, addr string, args string) (*ppb.GetPndResponse, ...@@ -48,9 +63,9 @@ func GetPnd(ctx context.Context, addr string, args string) (*ppb.GetPndResponse,
return pndClient.GetPnd(ctx, req) return pndClient.GetPnd(ctx, req)
} }
// GetPnds requests all PrincipalNetworkDomains from the // GetPndList requests all PrincipalNetworkDomains from the
// controller. // controller.
func GetPnds(ctx context.Context, addr string, args ...string) (*ppb.GetPndListResponse, error) { func GetPndList(ctx context.Context, addr string, args ...string) (*ppb.GetPndListResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...) pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil { if err != nil {
return nil, err return nil, err
......
package client
import (
apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/app"
"google.golang.org/grpc"
)
// AppClient returns a client for the gRPC App service. It takes
// the address of the gRPC endpoint and optional grpc.DialOption
// as argument.
func AppClient(addr string, opts ...grpc.DialOption) (apb.AppServiceClient, error) {
conn, err := grpc.Dial(addr, opts...)
if err != nil {
return nil, err
}
return apb.NewAppServiceClient(conn), nil
}
package client
import (
cpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/configurationmanagement"
"google.golang.org/grpc"
)
// ConfigurationManagementClient returns a client for the gRPC ConfigurationManagement service. It takes
// the address of the gRPC endpoint and optional grpc.DialOption
// as argument.
func ConfigurationManagementClient(addr string, opts ...grpc.DialOption) (cpb.ConfigurationManagementServiceClient, error) {
conn, err := grpc.Dial(addr, opts...)
if err != nil {
return nil, err
}
return cpb.NewConfigurationManagementServiceClient(conn), nil
}
...@@ -663,7 +663,7 @@ func (n *NetworkElementServer) addMne(ctx context.Context, ...@@ -663,7 +663,7 @@ func (n *NetworkElementServer) addMne(ctx context.Context,
} }
if mne.IsTransportValid() { if mne.IsTransportValid() {
err = n.initialNetworkElementRootPathRequest(ctx, mne, plugin) err = n.initialNetworkElementRootPathRequest(ctx, mne)
if err != nil { if err != nil {
return uuid.Nil, err return uuid.Nil, err
} }
...@@ -692,7 +692,7 @@ func (n *NetworkElementServer) addMne(ctx context.Context, ...@@ -692,7 +692,7 @@ func (n *NetworkElementServer) addMne(ctx context.Context,
return mne.ID(), nil return mne.ID(), nil
} }
func (n *NetworkElementServer) initialNetworkElementRootPathRequest(ctx context.Context, mne networkelement.NetworkElement, plugin plugin.Plugin) error { func (n *NetworkElementServer) initialNetworkElementRootPathRequest(ctx context.Context, mne networkelement.NetworkElement) error {
resp, err := n.getPath(ctx, mne, "/") resp, err := n.getPath(ctx, mne, "/")
if err != nil { if err != nil {
return err return err
......
...@@ -59,14 +59,15 @@ func (t *FilesystemPndStore) readAllPndsFromFile() ([]networkdomain.LoadedPnd, e ...@@ -59,14 +59,15 @@ func (t *FilesystemPndStore) readAllPndsFromFile() ([]networkdomain.LoadedPnd, e
// } // }
for i, loadedPND := range loadedPnds { for i, loadedPND := range loadedPnds {
pndUUID, err := uuid.Parse(loadedPND.ID)
if err != nil {
return nil, err
}
newPnd := NewPND( newPnd := NewPND(
uuid.MustParse(loadedPND.ID), pndUUID,
loadedPND.Name, loadedPND.Name,
loadedPND.Description, loadedPND.Description,
) )
if err != nil {
return nil, err
}
pnds[i] = newPnd pnds[i] = newPnd
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment