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

Northbound Interface

parent 50722ba9
No related branches found
No related tags found
9 merge requests!246Develop,!245Develop into Master,!244Master into develop2 into master,!219Draft: Testing,!214Test pipelines,!195DO NOT MERGE 2,!194DO NOT MERGE! just for testing,!155Northbound Interface,!138Develop
......@@ -144,9 +144,9 @@ func update(clientset *kubernetes.Clientset, resource metav1.Common, env string)
opts := metav1.UpdateOptions{}
getOpts := metav1.GetOptions{}
ctx := context.Background()
switch resource.(type) {
switch resource := resource.(type) {
case *corev1.Service:
service := resource.(*corev1.Service)
service := resource
s, err := clientset.CoreV1().Services("cocsn").Get(ctx, env, getOpts)
if err != nil {
return err
......@@ -158,7 +158,7 @@ func update(clientset *kubernetes.Clientset, resource metav1.Common, env string)
}
log.Printf("service %v updated", service.Name)
case *netv1.Ingress:
ingress := resource.(*netv1.Ingress)
ingress := resource
i, err := clientset.NetworkingV1beta1().Ingresses("cocsn").Get(ctx, env, getOpts)
if err != nil {
return err
......@@ -170,7 +170,7 @@ func update(clientset *kubernetes.Clientset, resource metav1.Common, env string)
}
log.Printf("ingress %v updated", ingress.Name)
case *corev1.ConfigMap:
config := resource.(*corev1.ConfigMap)
config := resource
c, err := clientset.CoreV1().ConfigMaps("cocsn").Get(ctx, env+"-config", getOpts)
if err != nil {
return err
......@@ -182,7 +182,7 @@ func update(clientset *kubernetes.Clientset, resource metav1.Common, env string)
}
log.Printf("configMap %v updated", config.Name)
case *appv1.Deployment:
deployment := resource.(*appv1.Deployment)
deployment := resource
d, err := clientset.AppsV1().Deployments("cocsn").Get(ctx, env, getOpts)
if err != nil {
return err
......
......@@ -5,7 +5,9 @@ import (
"fmt"
"strings"
"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
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/nucleus"
gpb "github.com/openconfig/gnmi/proto/gnmi"
)
......@@ -13,14 +15,12 @@ import (
// Capabilities sends a gNMI Capabilities request to the specified target
// and prints the supported models to stdout
func Capabilities(a, u, p string) error {
cfg := gnmi.Config{
Addr: a,
opts := &tpb.TransportOption{
Address: a,
Username: u,
Password: p,
Encoding: gpb.Encoding_JSON_IETF,
}
opts := &nucleus.GnmiTransportOptions{Config: cfg}
transport, err := nucleus.NewGnmiTransport(opts)
transport, err := nucleus.NewGnmiTransport(opts, nucleus.NewSBI(spb.Type_OPENCONFIG))
if err != nil {
return err
}
......
package cli
import (
"context"
"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
"code.fbi.h-da.de/cocsn/gosdn/nucleus"
gpb "github.com/openconfig/gnmi/proto/gnmi"
log "github.com/sirupsen/logrus"
)
// Get sends a gNMI Get request to the specified target and prints the response to stdout
func Get(a, u, p string, args ...string) (*gpb.GetResponse, error) {
sbi := &nucleus.OpenConfig{}
opts := &nucleus.GnmiTransportOptions{
Config: gnmi.Config{
Addr: a,
Username: u,
Password: p,
Encoding: gpb.Encoding_JSON_IETF,
},
SetNode: sbi.SetNode(),
}
t, err := nucleus.NewGnmiTransport(opts)
if err != nil {
return nil, err
}
resp, err := t.Get(context.Background(), args...)
if err != nil {
return nil, err
}
log.Debug(resp)
r, ok := resp.(*gpb.GetResponse)
if !ok {
return nil, &errors.ErrInvalidTypeAssertion{}
}
return r, nil
}
package cli
import (
"context"
"errors"
"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"
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"
)
var dialOptions []grpc.DialOption
func init() {
dialOptions = []grpc.DialOption{
grpc.WithInsecure(),
}
}
// Init initialises the CLI client.
func Init(addr string) error {
ctx := context.Background()
resp, err := getAllCore(ctx, addr)
if err != nil {
return err
}
if len(resp.Pnd) > 0 {
pid := resp.Pnd[0].Id
viper.Set("CLI_PND", pid)
log.Infof("PND: %v", pid)
if len(resp.Pnd[0].Sbi) != 0 {
sbi := resp.Pnd[0].Sbi[0].Id
viper.Set("CLI_SBI", sbi)
log.Infof("SBI: %v", sbi)
}
}
return nil
}
// GetIds requests all UUID information from the controller
func GetIds(addr string) ([]*ppb.PrincipalNetworkDomain, error) {
ctx := context.Background()
resp, err := getAllCore(ctx, addr)
if err != nil {
return nil, err
}
return resp.Pnd, nil
}
func getAllCore(ctx context.Context, addr string) (*pb.GetResponse, error) {
coreClient, err := nbi.CoreClient(addr, dialOptions...)
if err != nil {
return nil, err
}
req := &pb.GetRequest{
Timestamp: time.Now().UnixNano(),
All: true,
}
return coreClient.Get(ctx, req)
}
// AddPnd takes a name, description and SBI UUID to create a new
// PrincipalNetworkDomain on the controller
func AddPnd(addr, name, description, sbi string) (*pb.SetResponse, error) {
coreClient, err := nbi.CoreClient(addr, dialOptions...)
if err != nil {
return nil, err
}
ctx := context.Background()
req := &pb.SetRequest{
Timestamp: time.Now().UnixNano(),
Pnd: []*pb.SetPnd{
{
Name: name,
Description: description,
Sbi: sbi,
},
},
}
return coreClient.Set(ctx, req)
}
// GetPnd requests one or several PrincipalNetworkDomains from the
// controller. To request all PrincipalNetworkDomains without providing
// names or UUIDs use GetIds()
func GetPnd(addr string, args ...string) (*pb.GetResponse, error) {
coreClient, err := nbi.CoreClient(addr, dialOptions...)
if err != nil {
return nil, err
}
if len(args) <= 0 {
return nil, errors.New("not enough arguments")
}
ctx := context.Background()
req := &pb.GetRequest{
Timestamp: time.Now().UnixNano(),
Pid: args,
}
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 cli
import (
"context"
"net"
"testing"
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"
"code.fbi.h-da.de/cocsn/gosdn/mocks"
nbi "code.fbi.h-da.de/cocsn/gosdn/northbound/server"
"code.fbi.h-da.de/cocsn/gosdn/nucleus"
"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
)
/*
Based on this StackOverflow answer: https://stackoverflow.com/a/52080545/4378176
*/
const bufSize = 1024 * 1024
const bufnet = "bufnet"
const pndID = "2043519e-46d1-4963-9a8e-d99007e104b8"
const changeID = "0992d600-f7d4-4906-9559-409b04d59a5f"
const sbiID = "f6fd4b35-f039-4111-9156-5e4501bb8a5a"
const ondID = "7e0ed8cc-ebf5-46fa-9794-741494914883"
var pndStore *nucleus.PndStore
var lis *bufconn.Listener
func init() {
dialOptions = []grpc.DialOption{
grpc.WithContextDialer(bufDialer),
grpc.WithInsecure(),
}
lis = bufconn.Listen(bufSize)
s := grpc.NewServer()
pndStore = nucleus.NewPndStore()
pndUUID, err := uuid.Parse(pndID)
if err != nil {
log.Fatal(err)
}
changeUUID, err := uuid.Parse(changeID)
if err != nil {
log.Fatal(err)
}
deviceUUID, err := uuid.Parse(ondID)
if err != nil {
log.Fatal(err)
}
mockPnd := mocks.PrincipalNetworkDomain{}
mockPnd.On("ID").Return(pndUUID)
mockPnd.On("GetName").Return("test")
mockPnd.On("GetDescription").Return("test")
mockPnd.On("PendingChanges").Return([]uuid.UUID{changeUUID})
mockPnd.On("CommittedChanges").Return([]uuid.UUID{changeUUID})
mockPnd.On("GetChange", mock.Anything).Return(&nucleus.Change{}, nil)
mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil)
mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.Device{
UUID: deviceUUID,
GoStruct: &openconfig.Device{},
}, nil)
mockPnd.On("Commit", mock.Anything).Return(nil)
mockPnd.On("Confirm", mock.Anything).Return(nil)
mockPnd.On("ChangeOND", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
if err := pndStore.Add(&mockPnd); err != nil {
log.Fatal(err)
}
northbound := nbi.NewNBI(pndStore)
pb.RegisterCoreServer(s, northbound.Core)
ppb.RegisterPndServer(s, northbound.Pnd)
go func() {
if err := s.Serve(lis); err != nil {
log.Fatalf("Server exited with error: %v", err)
}
}()
}
func bufDialer(context.Context, string) (net.Conn, error) {
return lis.Dial()
}
func Test_Init(t *testing.T) {
if err := Init(bufnet); err != nil {
t.Error(err)
}
}
func Test_GetIds(t *testing.T) {
resp, err := GetIds(bufnet)
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
func Test_AddPnd(t *testing.T) {
sbi := nucleus.NewSBI(spb.Type_OPENCONFIG)
resp, err := AddPnd(bufnet, "test", "test pnd", sbi.ID().String())
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
func Test_GetPnd(t *testing.T) {
resp, err := GetPnd(bufnet, pndID)
if err != nil {
t.Error(err)
return
}
got := resp.Pnd[0].Id
if got != pndID {
t.Errorf("PND ID is %v, expected %v", got, pndID)
}
}
func Test_GetChanges(t *testing.T) {
resp, err := GetChanges(bufnet, pndID)
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
func Test_CommitConfirm(t *testing.T) {
resp, err := Commit(bufnet, pndID, changeID)
if err != nil {
t.Error(err)
return
}
log.Info(resp)
resp, err = Confirm(bufnet, pndID, changeID)
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
func Test_AddDevice(t *testing.T) {
resp, err := AddDevice(bufnet, "test", "test", sbiID, pndID, "test", "test")
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
func Test_GetDevice(t *testing.T) {
resp, err := GetDevice(bufnet, pndID, "", ondID)
if err != nil {
t.Error(err)
return
}
got := resp.Ond[0].Id
if got != ondID {
t.Errorf("PND ID is %v, expected %v", got, ondID)
}
}
func Test_Update(t *testing.T) {
resp, err := Update(bufnet, ondID, pndID, "", "")
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
func Test_Replace(t *testing.T) {
resp, err := Replace(bufnet, ondID, pndID, "", "")
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
func Test_Delete(t *testing.T) {
resp, err := Delete(bufnet, ondID, pndID, "")
if err != nil {
t.Error(err)
return
}
log.Info(resp)
}
package cli
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"strings"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
const apiRoot = "?"
var builder *strings.Builder
func init() {
builder = &strings.Builder{}
}
// HTTPGet sends sends requests from the CLI to the gosdn HTTP API and processes any response data
func HTTPGet(apiEndpoint, f string, args ...string) error {
for _, p := range args {
builder.WriteString("&")
builder.WriteString(p)
}
resp, err := http.Get(apiEndpoint + apiRoot + "q=" + f + builder.String())
if err != nil {
log.Info(fmt.Sprintf("Err: %s", err))
return err
}
builder.Reset()
switch resp.StatusCode {
case http.StatusOK:
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
switch f {
case "init":
pnd := string(bytes[9:45])
sbi := string(bytes[55:91])
viper.Set("CLI_PND", pnd)
viper.Set("CLI_SBI", sbi)
err := viper.WriteConfig()
if err != nil {
log.Error(err)
}
default:
fmt.Println(string(bytes))
}
case http.StatusCreated:
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
uuid := string(bytes[19:55])
viper.Set("LAST_DEVICE_UUID", uuid)
fmt.Println(string(bytes))
case http.StatusAccepted:
default:
log.WithFields(log.Fields{
"status code": resp.StatusCode,
}).Error("operation unsuccessful")
return errors.New(resp.Status)
}
return nil
}
package cli
import (
model "code.fbi.h-da.de/cocsn/yang-models/generated/arista"
"github.com/openconfig/ygot/ytypes"
log "github.com/sirupsen/logrus"
)
var testSchema *ytypes.Schema
func init() {
var err error
testSchema, err = model.Schema()
if err != nil {
log.Fatal(err)
}
}
package cli
import (
"context"
"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
"code.fbi.h-da.de/cocsn/gosdn/nucleus"
)
// Set sends a gNMI Set request to the specified target. Only one
// request per invocation supported.
func Set(a, u, p, typ string, args ...string) error {
opts := &nucleus.GnmiTransportOptions{
Config: gnmi.Config{
Addr: a,
Username: u,
Password: p,
},
}
t, err := nucleus.NewGnmiTransport(opts)
if err != nil {
return err
}
return t.Set(context.Background(), args)
}
......@@ -8,11 +8,11 @@ import (
"syscall"
"time"
tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport"
"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
"code.fbi.h-da.de/cocsn/gosdn/nucleus"
gpb "github.com/openconfig/gnmi/proto/gnmi"
log "github.com/sirupsen/logrus"
)
......@@ -20,18 +20,22 @@ import (
// logs the response to stdout. Only 'stream' mode with 'sample' operation supported.
func Subscribe(address, username, password, deviceName string, sample, heartbeat int64, args ...string) error {
sbi := &nucleus.OpenConfig{}
tOpts := &nucleus.GnmiTransportOptions{
Config: gnmi.Config{
Addr: address,
Username: username,
Password: password,
Encoding: gpb.Encoding_JSON_IETF,
tOpts := &tpb.TransportOption{
Address: address,
Username: username,
Password: password,
Tls: false,
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{
Compression: "",
GrpcDialOptions: nil,
Token: "",
Encoding: 0,
},
},
SetNode: sbi.SetNode(),
RespChan: make(chan *gpb.SubscribeResponse),
}
device, err := nucleus.NewDevice(sbi, tOpts, deviceName)
device, err := nucleus.NewDevice(deviceName, tOpts, sbi)
if err != nil {
return err
}
......
......@@ -34,9 +34,9 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
)
var deviceName string
log "github.com/sirupsen/logrus"
)
// addDeviceCmd represents the addDevice command
var addDeviceCmd = &cobra.Command{
......@@ -47,21 +47,27 @@ var addDeviceCmd = &cobra.Command{
Device address and user credentials need to be provided
if they diverge from the default credentials.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(
resp, err := cli.AddDevice(
apiEndpoint,
"addDevice",
"address="+address,
"password="+password,
"username="+username,
"sbi="+cliSbi,
"pnd="+cliPnd,
"name="+deviceName,
username,
password,
cliSbi,
cliPnd,
address,
deviceName,
)
if err != nil {
return err
}
log.Info(resp)
return nil
},
}
var deviceName string
func init() {
cliCmd.AddCommand(addDeviceCmd)
addDeviceCmd.PersistentFlags().StringVarP(&deviceName, "device-name", "n", "", "Human readable device name.")
addDeviceCmd.Flags().StringVar(&deviceName, "name", "", "add a device name (optional)")
}
......@@ -34,24 +34,37 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
log "github.com/sirupsen/logrus"
)
var typ string
// addCmd represents the add command
var addCmd = &cobra.Command{
Use: "add",
Short: "adds a new principal network domain to the controller",
Long: `A principal network domain is a main networking entity. This can be a
campus building or site.
// setCmd represents the set command
var setCmd = &cobra.Command{
Use: "set",
Short: "set request",
Long: `Sends a gNMI Set request to the specified target. Only one
request per invocation supported.`,
A description must be passed as positional argument. A name and default SBI can be
passed using flags`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return cli.Set(address, username, password, typ, args...)
resp, err := cli.AddPnd(apiEndpoint, pndName, args[0], pndDefaultSbi)
if err != nil {
return err
}
log.Info(resp)
return nil
},
}
var pndName string
var pndDefaultSbi string
func init() {
rootCmd.AddCommand(setCmd)
pndCmd.AddCommand(addCmd)
addCmd.Flags().StringVar(&pndName, "name", "", "the name of the pnd")
addCmd.Flags().StringVar(&pndDefaultSbi, "sbi", "openconfig", "the default SBI of the pnd")
setCmd.Flags().StringVarP(&typ, "type", "t", "update", "Type of the set request. "+
"Possible values: 'update', 'replace', and 'delete'")
}
......@@ -46,13 +46,15 @@ var cliCmd = &cobra.Command{
Long: `Initialises the CLI. The first PND UUID and SBI UUID
are written to the config file for subsequent requests.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(apiEndpoint, "init")
return cli.Init(apiEndpoint)
},
}
var verbose bool
func init() {
rootCmd.AddCommand(cliCmd)
cliCmd.PersistentFlags().StringVar(&apiEndpoint, "controller", "http://gosdn-develop.apps.ocp.fbi.h-da.de/api", "address of the controller")
pndCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "show ond and sbi info")
}
......@@ -33,6 +33,7 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
......@@ -46,16 +47,18 @@ only one value supported for now.
Use "set replace" or "set delete" respectively`,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(
resp, err := cli.Update(
apiEndpoint,
"update",
"uuid="+uuid,
"cliSbi="+cliSbi,
"cliPnd="+cliPnd,
"path="+args[0],
"address="+address,
"value="+args[1],
uuid,
cliPnd,
args[0],
args[1],
)
if err != nil {
return err
}
log.Info(resp)
return nil
},
}
......
......@@ -33,6 +33,7 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
......@@ -42,13 +43,12 @@ var commitCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Short: "Commit the given change for the active PND",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(
Run: func(cmd *cobra.Command, args []string) {
log.Info(cli.Commit(
apiEndpoint,
"change-commit",
"pnd="+cliPnd,
"cuid="+args[0],
)
cliPnd,
args[0],
))
},
}
......
......@@ -33,6 +33,7 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
......@@ -42,13 +43,12 @@ var confirmCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Short: "Confirms the given change for the active PND",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(
Run: func(cmd *cobra.Command, args []string) {
log.Info(cli.Confirm(
apiEndpoint,
"change-confirm",
"pnd="+cliPnd,
"cuid="+args[0],
)
cliPnd,
args[0],
))
},
}
......
......@@ -33,6 +33,7 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
......@@ -43,16 +44,13 @@ var deleteCmd = &cobra.Command{
Short: "set a value on a device",
Long: `Set a path value for a given device. Only one path and
only one value supported for now`,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(
Run: func(cmd *cobra.Command, args []string) {
log.Info(cli.Delete(
apiEndpoint,
"delete",
"uuid="+uuid,
"cliSbi="+cliSbi,
"cliPnd="+cliPnd,
"path="+args[0],
"address="+address,
)
uuid,
cliPnd,
args[0],
))
},
}
......
......@@ -33,6 +33,7 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
......@@ -45,13 +46,17 @@ var getDeviceCmd = &cobra.Command{
Device UUID or name needs to be specified as positional argument.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(
resp, err := cli.GetDevice(
apiEndpoint,
"getDevice",
"identifier="+args[0],
"sbi="+cliSbi,
"pnd="+cliPnd,
cliPnd,
cliSbi,
args[0],
)
if err != nil {
return err
}
log.Info(resp)
return nil
},
}
......
......@@ -33,6 +33,7 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
......@@ -42,7 +43,20 @@ var getIdsCmd = &cobra.Command{
Short: "gets device IDs from the controller",
Long: `Gets device IDs from the controller and lists them.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(apiEndpoint, "getIDs")
resp, err := cli.GetIds(apiEndpoint)
if err != nil {
return err
}
for i, pnd := range resp {
log.Infof("PND %v: %v\n\tuuid: %v", i+1, pnd.Name, pnd.Id)
for j, ond := range pnd.Ond {
log.Infof("\tSBI %v: %v\n\tuuid: %v", j+1, ond.Name, ond.Id)
}
for k, sbi := range pnd.Sbi {
log.Infof("\tSBI %v: %v", k+1, sbi.Id)
}
}
return nil
},
}
......
......@@ -33,21 +33,35 @@ package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
// getCmd represents the get command
var getCmd = &cobra.Command{
Use: "gosdn get",
Short: "get request",
Long: `Sends a gNMI Get request to the specified target and
prints the response to stdout`,
Use: "get",
Short: "get one or multiple pnds by uuid or name and print them to stdout",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
_, err := cli.Get(address, username, password, args...)
return err
resp, err := cli.GetPnd(apiEndpoint, args...)
if err != nil {
return err
}
for i, pnd := range resp.Pnd {
log.Infof("PND %v: %v\n\tuuid: %v", i+1, pnd.Name, pnd.Id)
if verbose {
for j, ond := range pnd.Ond {
log.Infof("\tSBI %v: %v\n\tuuid: %v", j+1, ond.Name, ond.Id)
}
for k, sbi := range pnd.Sbi {
log.Infof("\tSBI %v: %v", k+1, sbi.Id)
}
}
}
return nil
},
}
func init() {
rootCmd.AddCommand(getCmd)
pndCmd.AddCommand(getCmd)
}
......@@ -44,7 +44,7 @@ var initCmd = &cobra.Command{
Same as invoking "gosdn cli" without any arguments`,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HTTPGet(apiEndpoint, "init")
return cli.Init(apiEndpoint)
},
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment