Skip to content
Snippets Groups Projects
Commit 4f098234 authored by Manuel Kieweg's avatar Manuel Kieweg
Browse files

Merge branch 'api-adapter' into 'develop'

pnd adapter skeleton

See merge request cocsn/gosdn!168
parents 79d7afb0 8f01fc9c
No related branches found
No related tags found
No related merge requests found
Pipeline #75843 passed with warnings
......@@ -4,6 +4,7 @@ import (
"os"
"testing"
"code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
"code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto"
guuid "github.com/google/uuid"
......@@ -110,7 +111,7 @@ func TestApiIntegration(t *testing.T) {
cliPnd := viper.GetString("CLI_PND")
cliSbi := viper.GetString("CLI_SBI")
if _, err := AddDevice(
if _, err := addDevice(
testAPIEndpoint,
testUsername,
testPassword,
......@@ -124,7 +125,7 @@ func TestApiIntegration(t *testing.T) {
}
did := viper.GetString("LAST_DEVICE_UUID")
_, err := GetDevice(
_, err := getDevice(
testAPIEndpoint,
cliPnd,
testPath,
......@@ -135,7 +136,7 @@ func TestApiIntegration(t *testing.T) {
return
}
_, err = GetDevice(
_, err = getDevice(
testAPIEndpoint,
cliPnd,
"",
......@@ -147,19 +148,20 @@ func TestApiIntegration(t *testing.T) {
}
hostname := guuid.New().String()
_, err = Update(
_, err = changeRequest(
testAPIEndpoint,
did,
cliPnd,
testPath,
hostname,
pnd.ApiOperation_UPDATE,
)
if (err != nil) != tt.wantErr {
t.Errorf("gosdn cli set error = %v, wantErr %v", err, tt.wantErr)
return
}
resp, err := GetDevice(testAddress, testUsername, testPassword, testPath)
resp, err := getDevice(testAddress, testUsername, testPassword, testPath)
if err != nil {
if !tt.wantErr {
t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
......
......@@ -154,7 +154,7 @@ func Test_CommitConfirm(t *testing.T) {
}
func Test_AddDevice(t *testing.T) {
resp, err := AddDevice(bufnet, "test", "test", sbiID, pndID, "test", "test")
resp, err := addDevice(bufnet, "test", "test", sbiID, pndID, "test", "test")
if err != nil {
t.Error(err)
return
......@@ -163,7 +163,7 @@ func Test_AddDevice(t *testing.T) {
}
func Test_GetDevice(t *testing.T) {
resp, err := GetDevice(bufnet, pndID, "", ondID)
resp, err := getDevice(bufnet, pndID, "", ondID)
if err != nil {
t.Error(err)
return
......@@ -175,7 +175,7 @@ func Test_GetDevice(t *testing.T) {
}
func Test_Update(t *testing.T) {
resp, err := Update(bufnet, ondID, pndID, "", "")
resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_UPDATE)
if err != nil {
t.Error(err)
return
......@@ -184,7 +184,7 @@ func Test_Update(t *testing.T) {
}
func Test_Replace(t *testing.T) {
resp, err := Replace(bufnet, ondID, pndID, "", "")
resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_REPLACE)
if err != nil {
t.Error(err)
return
......@@ -193,7 +193,7 @@ func Test_Replace(t *testing.T) {
}
func Test_Delete(t *testing.T) {
resp, err := Delete(bufnet, ondID, pndID, "")
resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_DELETE)
if err != nil {
t.Error(err)
return
......
......@@ -5,14 +5,12 @@ import (
"errors"
"time"
pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core"
ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
nbi "code.fbi.h-da.de/cocsn/gosdn/northbound/client"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core"
"google.golang.org/grpc"
)
......@@ -106,172 +104,3 @@ func GetPnd(addr string, args ...string) (*pb.GetResponse, error) {
}
return coreClient.Get(ctx, req)
}
// GetChanges requests all pending and unconfirmed changes from the controller
func GetChanges(addr, pnd string) (*ppb.GetResponse, error) {
ctx := context.Background()
client, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.GetRequest{
Timestamp: time.Now().UnixNano(),
Request: &ppb.GetRequest_Change{
Change: &ppb.GetChange{
All: true,
},
},
Pid: pnd,
}
return client.Get(ctx, req)
}
// Commit sends a commit request for one or multiple changes to the
// controller.
func Commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) {
changes := make([]*ppb.SetChange, len(cuids))
for i, arg := range cuids {
changes[i] = &ppb.SetChange{
Cuid: arg,
Op: ppb.SetChange_COMMIT,
}
}
return commitConfirm(addr, pnd, changes)
}
// Confirm sends a confirm request for one or multiple changes to the
// controller
func Confirm(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) {
changes := make([]*ppb.SetChange, len(cuids))
for i, arg := range cuids {
changes[i] = &ppb.SetChange{
Cuid: arg,
Op: ppb.SetChange_CONFIRM,
}
}
return commitConfirm(addr, pnd, changes)
}
func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetResponse, error) {
ctx := context.Background()
client, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SetRequest{
Timestamp: time.Now().UnixNano(),
Change: changes,
Pid: pnd,
}
return client.Set(ctx, req)
}
// AddDevice adds a new device to the controller. The device name is optional.
// If no name is provided a name will be generated upon device creation.
func AddDevice(addr, username, password, sbi, pnd, deviceAddress, deviceName string) (*ppb.SetResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SetRequest{
Timestamp: time.Now().UnixNano(),
Ond: []*ppb.SetOnd{
{
Address: deviceAddress,
Sbi: &spb.SouthboundInterface{
Id: sbi,
},
DeviceName: deviceName,
TransportOption: &tpb.TransportOption{
Address: addr,
Username: username,
Password: password,
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
},
},
},
Pid: pnd,
}
ctx := context.Background()
return pndClient.Set(ctx, req)
}
// GetDevice requests one or multiple devices belonging to a given
// PrincipalNetworkDomain from the controller. If no device identifier
// is provided, all devices are requested.
func GetDevice(addr, pid, path string, did ...string) (*ppb.GetResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
var all bool
if len(did) == 0 {
all = true
}
req := &ppb.GetRequest{
Timestamp: time.Now().UnixNano(),
Request: &ppb.GetRequest_Ond{
Ond: &ppb.GetOnd{
All: all,
Did: did,
},
},
Pid: pid,
}
ctx := context.Background()
return pndClient.Get(ctx, req)
}
// Update creates a ChangeRequest to update the given path with the given value
// at the given OND on the controller.
func Update(addr, did, pid, path, value string) (*ppb.SetResponse, error) {
req := &ppb.ChangeRequest{
Id: did,
Path: path,
Value: value,
ApiOp: ppb.ApiOperation_UPDATE,
}
return sendChangeRequest(addr, pid, req)
}
// Replace creates a ChangeRequest to replace the given path with the given value
// at the given OND on the controller.
func Replace(addr, did, pid, path, value string) (*ppb.SetResponse, error) {
req := &ppb.ChangeRequest{
Id: did,
Path: path,
Value: value,
ApiOp: ppb.ApiOperation_REPLACE,
}
return sendChangeRequest(addr, pid, req)
}
// Delete creates a ChangeRequest to delete the given path node
// at the given OND on the controller.
func Delete(addr, did, pid, path string) (*ppb.SetResponse, error) {
req := &ppb.ChangeRequest{
Id: did,
Path: path,
ApiOp: ppb.ApiOperation_DELETE,
}
return sendChangeRequest(addr, pid, req)
}
func sendChangeRequest(addr, pid string, req *ppb.ChangeRequest) (*ppb.SetResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
ctx := context.Background()
r := &ppb.SetRequest{
Timestamp: time.Now().UnixNano(),
ChangeRequest: []*ppb.ChangeRequest{req},
Pid: pid,
}
return pndClient.Set(ctx, r)
}
package api
import (
"context"
"time"
ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
"code.fbi.h-da.de/cocsn/gosdn/interfaces/change"
"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
"code.fbi.h-da.de/cocsn/gosdn/interfaces/southbound"
"code.fbi.h-da.de/cocsn/gosdn/interfaces/store"
nbi "code.fbi.h-da.de/cocsn/gosdn/northbound/client"
"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
"github.com/google/uuid"
)
type PrincipalNetworkDomainAdapter struct {
id uuid.UUID
endpoint string
}
func (p *PrincipalNetworkDomainAdapter) Destroy() error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) AddSbi(s southbound.SouthboundInterface) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) RemoveSbi(uuid.UUID) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) GetDevice(identifier string) (device.Device, error) {
return nil, &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) RemoveDevice(uuid.UUID) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) Devices() []uuid.UUID {
return nil
}
func (p *PrincipalNetworkDomainAdapter) ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) Request(uuid.UUID, string) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) RequestAll(string) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) GetName() string {
return ""
}
func (p *PrincipalNetworkDomainAdapter) GetDescription() string {
return ""
}
func (p *PrincipalNetworkDomainAdapter) MarshalDevice(string) (string, error) {
return "", &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) ContainsDevice(uuid.UUID) bool {
return false
}
func (p *PrincipalNetworkDomainAdapter) GetSBIs() store.Store {
return nil
}
func (p *PrincipalNetworkDomainAdapter) ID() uuid.UUID {
return p.id
}
func (p *PrincipalNetworkDomainAdapter) PendingChanges() []uuid.UUID {
return nil
}
func (p *PrincipalNetworkDomainAdapter) CommittedChanges() []uuid.UUID {
return nil
}
func (p *PrincipalNetworkDomainAdapter) GetChange(uuid.UUID, ...int) (change.Change, error) {
return nil, &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) Commit(uuid.UUID) error {
return &errors.ErrNotYetImplemented{}
}
func (p *PrincipalNetworkDomainAdapter) Confirm(uuid.UUID) error {
return &errors.ErrNotYetImplemented{}
}
// GetChanges requests all pending and unconfirmed changes from the controller
func GetChanges(addr, pnd string) (*ppb.GetResponse, error) {
ctx := context.Background()
client, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.GetRequest{
Timestamp: time.Now().UnixNano(),
Request: &ppb.GetRequest_Change{
Change: &ppb.GetChange{
All: true,
},
},
Pid: pnd,
}
return client.Get(ctx, req)
}
// Commit sends a commit request for one or multiple changes to the
// controller.
func Commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) {
changes := make([]*ppb.SetChange, len(cuids))
for i, arg := range cuids {
changes[i] = &ppb.SetChange{
Cuid: arg,
Op: ppb.SetChange_COMMIT,
}
}
return commitConfirm(addr, pnd, changes)
}
// Confirm sends a confirm request for one or multiple changes to the
// controller
func Confirm(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) {
changes := make([]*ppb.SetChange, len(cuids))
for i, arg := range cuids {
changes[i] = &ppb.SetChange{
Cuid: arg,
Op: ppb.SetChange_CONFIRM,
}
}
return commitConfirm(addr, pnd, changes)
}
func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetResponse, error) {
ctx := context.Background()
client, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SetRequest{
Timestamp: time.Now().UnixNano(),
Change: changes,
Pid: pnd,
}
return client.Set(ctx, req)
}
// addDevice adds a new device to the controller. The device name is optional.
// If no name is provided a name will be generated upon device creation.
func addDevice(addr, username, password, sbi, pnd, deviceAddress, deviceName string) (*ppb.SetResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &ppb.SetRequest{
Timestamp: time.Now().UnixNano(),
Ond: []*ppb.SetOnd{
{
Address: deviceAddress,
Sbi: &spb.SouthboundInterface{
Id: sbi,
},
DeviceName: deviceName,
TransportOption: &tpb.TransportOption{
Address: deviceAddress,
Username: username,
Password: password,
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
},
},
},
Pid: pnd,
}
if sbi == "csbi" {
req.Ond[0].Sbi.Id = uuid.Nil.String()
req.Ond[0].Sbi.Type = spb.Type_CONTAINERISED
req.Ond[0].TransportOption.Csbi = true
}
ctx := context.Background()
return pndClient.Set(ctx, req)
}
// getDevice requests one or multiple devices belonging to a given
// PrincipalNetworkDomain from the controller. If no device identifier
// is provided, all devices are requested.
func getDevice(addr, pid, path string, did ...string) (*ppb.GetResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
var all bool
if len(did) == 0 {
all = true
}
req := &ppb.GetRequest{
Timestamp: time.Now().UnixNano(),
Request: &ppb.GetRequest_Ond{
Ond: &ppb.GetOnd{
All: all,
Did: did,
},
},
Pid: pid,
}
ctx := context.Background()
return pndClient.Get(ctx, req)
}
// change creates a ChangeRequest for the specified OND. ApiOperations are
// used to specify the type of the change (update, replace, delete as specified
// in https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#34-modifying-state)
// For delete operations the value field needs to contain an empty string.
func changeRequest(addr, did, pid, path, value string, op ppb.ApiOperation) (*ppb.SetResponse, error) {
req := &ppb.ChangeRequest{
Id: did,
Path: path,
Value: value,
ApiOp: op,
}
return sendChangeRequest(addr, pid, req)
}
func sendChangeRequest(addr, pid string, req *ppb.ChangeRequest) (*ppb.SetResponse, error) {
pndClient, err := nbi.PndClient(addr, dialOptions...)
if err != nil {
return nil, err
}
ctx := context.Background()
r := &ppb.SetRequest{
Timestamp: time.Now().UnixNano(),
ChangeRequest: []*ppb.ChangeRequest{req},
Pid: pid,
}
return pndClient.Set(ctx, r)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment