diff --git a/cmd/addDevice.go b/cmd/addDevice.go index 364cb833f864db255930a0f630830005e3e5686e..d551c4c1013a2718792a2ffb71fc4c6a69cc5b37 100644 --- a/cmd/addDevice.go +++ b/cmd/addDevice.go @@ -47,11 +47,11 @@ if they diverge from the default credentials.`, RunE: func(cmd *cobra.Command, args []string) error { return cli.AddDevice( apiEndpoint, - "username="+username, - "password="+password, - "pnd="+cliPnd, - "sbi="+cliSbi, - "address="+address, + username, + password, + cliPnd, + cliSbi, + address, ) }, } diff --git a/cmd/requestAll.go b/cmd/requestAll.go index 84c31154e6f5cee824e83d65b210ad72b76a4c86..1f753c7296a45ef80d01c060a949f7f33b648541 100644 --- a/cmd/requestAll.go +++ b/cmd/requestAll.go @@ -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,11 +47,16 @@ the controller. The request path is passed as positional argument.`, RunE: func(cmd *cobra.Command, args []string) error { - return cli.GetDevice( + resp, err := cli.GetDevice( apiEndpoint, cliPnd, args[0], ) + if err != nil { + return err + } + log.Info(resp) + return nil }, } diff --git a/go.mod b/go.mod index d85a5817c8d4d1aea976f6e8d46a81f89687b128..f88510f7a60e128b91e476859337f4f16a4ce8d6 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,10 @@ module code.fbi.h-da.de/cocsn/gosdn -go 1.14 +go 1.16 + +replace ( + code.fbi.h-da.de/cocsn/api/go v0.0.0-20210526102447-811b12caa119 => ../api/go +) require ( code.fbi.h-da.de/cocsn/api/go v0.0.0-20210526102447-811b12caa119 diff --git a/nucleus/device.go b/nucleus/device.go index 0c03706fc2c1866784b58d9689b25283f70f5465..58c62f539bab082e0fa7d98c003f0698775ff5a5 100644 --- a/nucleus/device.go +++ b/nucleus/device.go @@ -1,7 +1,7 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/nucleus/errors" + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" "github.com/google/uuid" "github.com/openconfig/ygot/ygot" ) @@ -12,7 +12,7 @@ type Device struct { // UUID represents the Devices UUID UUID uuid.UUID - // Device inherits properties of ygot.GoStruct + // Device embeds a ygot.GoStruct containing the device details ygot.GoStruct // SBI is the device's southbound interface implementation @@ -23,25 +23,17 @@ type Device struct { } // NewDevice creates a Device -func NewDevice(sbi SouthboundInterface, opts TransportOptions) (*Device, error) { - var transport Transport - var err error - switch o := opts.(type) { - case *GnmiTransportOptions: - transport, err = NewGnmiTransport(o) - if err != nil { - return nil, err - } - default: - return nil, &errors.ErrInvalidTransportOptions{Opt: o} - +func NewDevice(name string, opt *tpb.TransportOption, sbi SouthboundInterface) (*Device, error) { + t, err := NewTransport(opt, sbi) + if err != nil { + return nil, err } return &Device{ UUID: uuid.New(), GoStruct: sbi.Schema().Root, SBI: sbi, - Transport: transport, - }, nil + Transport: t, + }, err } // ID returns the UUID of the Device diff --git a/nucleus/device_test.go b/nucleus/device_test.go index 829c60c5d53f53611d8dfb72f411145769fca58b..6e3cb98f389f248c6a53e61ef12d0b56a4386b36 100644 --- a/nucleus/device_test.go +++ b/nucleus/device_test.go @@ -1,10 +1,10 @@ package nucleus import ( + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" "reflect" "testing" - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" "github.com/google/uuid" "github.com/openconfig/ygot/ygot" @@ -49,7 +49,7 @@ func TestNewDevice(t *testing.T) { sbi := &OpenConfig{} type args struct { sbi SouthboundInterface - opts TransportOptions + opts *tpb.TransportOption } tests := []struct { name string @@ -61,11 +61,17 @@ func TestNewDevice(t *testing.T) { name: "default", args: args{ sbi: sbi, - opts: &GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "test:///", - Username: "test", - Password: "test", + opts: &tpb.TransportOption{ + Address: "test:///", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + Compression: "", + GrpcDialOptions: nil, + Token: "", + Encoding: 0, + }, }, }, }, @@ -73,30 +79,33 @@ func TestNewDevice(t *testing.T) { GoStruct: &openconfig.Device{}, SBI: sbi, UUID: uuid.New(), - Transport: &Gnmi{ - Options: &GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "test:///", - Username: "test", - Password: "test", - }, - }, + }, + }, + { + name: "invalid options", + args: args{ + sbi: sbi, + opts: &tpb.TransportOption{ + Address: "test:///", + Username: "test", + Password: "test", }, }, + want: nil, + wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewDevice(tt.args.sbi, tt.args.opts) - if err != nil { - t.Error(err) - } - tt.want.Transport.(*Gnmi).client = got.Transport.(*Gnmi).client - tt.want.UUID = got.ID() + got, err := NewDevice("", tt.args.opts, tt.args.sbi) if (err != nil) != tt.wantErr { t.Errorf("NewDevice() error = %v, wantErr %v", err, tt.wantErr) return } + if got != nil { + tt.want.Transport = got.Transport + tt.want.UUID = got.ID() + } if !reflect.DeepEqual(got, tt.want) { t.Errorf("NewDevice() got = %v, want %v", got, tt.want) } diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go index 2ba89bf6fe2fc02c01124efb6d63e7d457ffd92a..87adff39e75dc393815606542117648ca08134f2 100644 --- a/nucleus/gnmi_transport.go +++ b/nucleus/gnmi_transport.go @@ -2,6 +2,7 @@ package nucleus import ( "context" + "google.golang.org/grpc" "reflect" "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" @@ -14,6 +15,8 @@ import ( "github.com/openconfig/ygot/ygot" "github.com/openconfig/ygot/ytypes" log "github.com/sirupsen/logrus" + + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" ) var opmap = map[types.Operation]string{ @@ -28,38 +31,44 @@ type Gnmi struct { SetNode func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error RespChan chan *gpb.SubscribeResponse Unmarshal func([]byte, []string, interface{}, ...ytypes.UnmarshalOpt) error - Options *GnmiTransportOptions + Options *tpb.TransportOption client gpb.GNMIClient + config *gnmi.Config } // NewGnmiTransport takes a struct of GnmiTransportOptions and returns a Gnmi // transport based on the values of it. -func NewGnmiTransport(opts *GnmiTransportOptions) (*Gnmi, error) { - c, err := gnmi.Dial(&opts.Config) +func NewGnmiTransport(opts *tpb.TransportOption, sbi SouthboundInterface) (*Gnmi, error) { + gnmiConfig := &gnmi.Config{ + Addr: opts.Address, + Password: opts.Password, + Username: opts.Username, + TLS: opts.Tls, + Compression: opts.GetGnmiTransportOption().Compression, + DialOptions: parseDialOptions(opts.GetGnmiTransportOption().GrpcDialOptions), + Token: "", + Encoding: 0, + } + c, err := gnmi.Dial(gnmiConfig) if err != nil { return nil, err } log.WithFields(log.Fields{ - "target": opts.Addr, - "tls": opts.TLS, - "encoding": opts.Encoding, + "target": opts.Address, + "tls": opts.Tls, + "encoding": opts.GetGnmiTransportOption().Encoding, }).Info("building new gNMI transport") return &Gnmi{ - SetNode: opts.SetNode, - RespChan: opts.RespChan, + SetNode: sbi.SetNode(), + RespChan: make(chan *gpb.SubscribeResponse), Options: opts, client: c, + config: gnmiConfig, }, nil } -//SetOptions sets Gnmi Options -func (g *Gnmi) SetOptions(to TransportOptions) { - g.Options = to.(*GnmiTransportOptions) -} - -//GetOptions returns the Gnmi options -func (g *Gnmi) GetOptions() interface{} { - return g.Options +func parseDialOptions(opts map[string]string) []grpc.DialOption { + return nil } // Get takes a slice of gnmi paths, splits them and calls get for each one of them. @@ -126,7 +135,7 @@ func (g *Gnmi) Set(ctx context.Context, args ...interface{}) error { case *gnmi.Operation: op := p.(*gnmi.Operation) if op.Target == "" { - op.Target = g.Options.Addr + op.Target = g.Options.Address } ops = append(ops, op) case *gnmi_ext.Extension: @@ -238,10 +247,10 @@ func (g *Gnmi) ProcessResponse(resp interface{}, root interface{}, s *ytypes.Sch // Capabilities calls GNMI capabilities func (g *Gnmi) Capabilities(ctx context.Context) (interface{}, error) { log.WithFields(log.Fields{ - "target": g.Options.Addr, + "target": g.Options.Address, }).Info("sending gNMI capabilities request") - ctx = gnmi.NewContext(ctx, &g.Options.Config) - ctx = context.WithValue(ctx, types.CtxKeyConfig, &g.Options.Config) //nolint + ctx = gnmi.NewContext(ctx, g.config) + ctx = context.WithValue(ctx, types.CtxKeyConfig, g.config) //nolint resp, err := g.client.Capabilities(ctx, &gpb.CapabilityRequest{}) if err != nil { return nil, err @@ -252,8 +261,8 @@ func (g *Gnmi) Capabilities(ctx context.Context) (interface{}, error) { // get calls GNMI get func (g *Gnmi) get(ctx context.Context, paths [][]string, origin string) (interface{}, error) { - ctx = gnmi.NewContext(ctx, &g.Options.Config) - ctx = context.WithValue(ctx, types.CtxKeyConfig, &g.Options.Config) //nolint + ctx = gnmi.NewContext(ctx, g.config) + ctx = context.WithValue(ctx, types.CtxKeyConfig, g.config) //nolint req, err := gnmi.NewGetRequest(ctx, paths, origin) if err != nil { return nil, err @@ -268,7 +277,7 @@ func (g *Gnmi) getWithRequest(ctx context.Context, req *gpb.GetRequest) (interfa return nil, &errors.ErrNil{} } log.WithFields(log.Fields{ - "target": g.Options.Addr, + "target": g.Options.Address, "path": req.Path, }).Info("sending gNMI get request") @@ -282,7 +291,7 @@ func (g *Gnmi) getWithRequest(ctx context.Context, req *gpb.GetRequest) (interfa // Set calls GNMI set func (g *Gnmi) set(ctx context.Context, setOps []*gnmi.Operation, exts ...*gnmi_ext.Extension) (*gpb.SetResponse, error) { - ctx = gnmi.NewContext(ctx, &g.Options.Config) + ctx = gnmi.NewContext(ctx, g.config) targets := make([]string, len(setOps)) paths := make([][]string, len(setOps)) values := make([]string, len(setOps)) @@ -301,7 +310,7 @@ func (g *Gnmi) set(ctx context.Context, setOps []*gnmi.Operation, // Subscribe calls GNMI subscribe func (g *Gnmi) subscribe(ctx context.Context) error { - ctx = gnmi.NewContext(ctx, &g.Options.Config) + ctx = gnmi.NewContext(ctx, g.config) opts, ok := ctx.Value(types.CtxKeyOpts).(*gnmi.SubscribeOptions) if !ok { return &errors.ErrInvalidTypeAssertion{ @@ -332,38 +341,3 @@ func (g *Gnmi) subscribe(ctx context.Context) error { func (g *Gnmi) Close() error { return nil } - -// GnmiTransportOptions implements the TransportOptions interface. -// GnmiTransportOptions contains all needed information to setup a Gnmi -// transport and therefore inherits gnmi.Config. -type GnmiTransportOptions struct { - // all needed gnmi transport parameters - gnmi.Config - - SetNode func(schema *yang.Entry, root interface{}, path *gpb.Path, - val interface{}, opts ...ytypes.SetNodeOpt) error - Unmarshal func([]byte, []string, interface{}, ...ytypes.UnmarshalOpt) error - RespChan chan *gpb.SubscribeResponse -} - -// GetAddress returns the address used by the transport to connect to a -// gRPC endpoint. -func (gto *GnmiTransportOptions) GetAddress() string { - return gto.Config.Addr -} - -// GetUsername returns the username used by the transport to connect to a -// gRPC endpoint. -func (gto *GnmiTransportOptions) GetUsername() string { - return gto.Config.Username -} - -// GetPassword returns the password used by the transport to connect to a -// gRPC endpoint. -func (gto *GnmiTransportOptions) GetPassword() string { - return gto.Config.Password -} - -// IsTransportOption is needed to fulfill the requirements of the -// TransportOptions interface. It does not need any further implementation. -func (gto *GnmiTransportOptions) IsTransportOption() {} diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go index 17389b1bf30d9a3e8579253801e8fbe5039408f7..06ca5fdb1bf2beed46d73940e361ab2fafcd4cbc 100644 --- a/nucleus/gnmi_transport_test.go +++ b/nucleus/gnmi_transport_test.go @@ -1,6 +1,7 @@ package nucleus import ( + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" "context" "errors" "reflect" @@ -191,7 +192,7 @@ func TestGnmi_Get(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.args.runEndpoint { - startGnmiTarget <- tt.fields.transport.Options.Addr + startGnmiTarget <- tt.fields.transport.config.Addr } got, err := tt.fields.transport.Get(context.Background(), tt.args.params...) if (err != nil) != tt.wantErr { @@ -431,7 +432,7 @@ func TestGnmi_getWithRequest(t *testing.T) { func TestNewGnmiTransport(t *testing.T) { type args struct { - opts *GnmiTransportOptions + opts *tpb.TransportOption } tests := []struct { name string @@ -441,21 +442,21 @@ func TestNewGnmiTransport(t *testing.T) { }{ { name: "default", - args: args{opts: &GnmiTransportOptions{ - Config: gnmi.Config{ - Username: "test", - Password: "test", - Addr: "localhost:13371", - Encoding: gpb.Encoding_PROTO, + args: args{opts: &tpb.TransportOption{ + Address: "localhost:13371", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, }, }}, want: &Gnmi{ - Options: &GnmiTransportOptions{ - Config: gnmi.Config{ - Username: "test", - Password: "test", - Addr: "localhost:13371", - Encoding: gpb.Encoding_PROTO, + Options: &tpb.TransportOption{ + Address: "localhost:13371", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, }, }, client: nil, @@ -463,20 +464,42 @@ func TestNewGnmiTransport(t *testing.T) { wantErr: false, }, { - name: "unsupported compression", - args: args{opts: &GnmiTransportOptions{Config: gnmi.Config{Compression: "brotli"}}}, + name: "unsupported compression", + args: args{ + opts: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + Compression: "brotli", + }, + }}}, want: nil, wantErr: true, }, { - name: "certificate error no key file", - args: args{opts: &GnmiTransportOptions{Config: gnmi.Config{TLS: true, CertFile: "invalid", KeyFile: ""}}}, + name: "certificate error no key file", + args: args{ + opts: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + GrpcDialOptions: map[string]string{ + "cert-file":"invalid", + }, + }, + }}}, want: nil, wantErr: true, }, { name: "certificate error no ca file", - args: args{opts: &GnmiTransportOptions{Config: gnmi.Config{TLS: true, CAFile: "invalid"}}}, + args: args{ + opts: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + GrpcDialOptions: map[string]string{ + "ca-file":"invalid", + }, + }, + }}}, want: nil, wantErr: true, }, @@ -486,7 +509,7 @@ func TestNewGnmiTransport(t *testing.T) { if tt.name == "default" { startGnmiTarget <- gnmiConfig.Addr } - got, err := NewGnmiTransport(tt.args.opts) + got, err := NewGnmiTransport(tt.args.opts, &OpenConfig{}) if (err != nil) != tt.wantErr { t.Errorf("NewGnmiTransport() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/nucleus/initialise_test.go b/nucleus/initialise_test.go index 85b938a0d14aa442c196e020b9f413b8095bb9bb..a241dec130ddbd6eba2ff1de67fbf0b3b51cde2d 100644 --- a/nucleus/initialise_test.go +++ b/nucleus/initialise_test.go @@ -1,6 +1,7 @@ package nucleus import ( + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" "context" "os" "testing" @@ -86,16 +87,14 @@ func mockTransport() Gnmi { } } -func newGnmiTransportOptions() *GnmiTransportOptions { - return &GnmiTransportOptions{ - Config: gnmi.Config{ - Username: "test", - Password: "test", - Addr: "localhost:13371", - Encoding: gpb.Encoding_PROTO, +func newGnmiTransportOptions() *tpb.TransportOption { + return &tpb.TransportOption{ + Address: "localhost:13371", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, }, - SetNode: nil, - RespChan: make(chan *gpb.SubscribeResponse), } } diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go index e3d535d81d7dfee3557f6ce2f7d7bdd94ab7f6f1..4b9976a6d6543372ad8705fa43e6e081713e854a 100644 --- a/nucleus/principalNetworkDomain.go +++ b/nucleus/principalNetworkDomain.go @@ -1,10 +1,10 @@ package nucleus import ( - "context" - + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" "code.fbi.h-da.de/cocsn/gosdn/nucleus/errors" "code.fbi.h-da.de/cocsn/gosdn/nucleus/types" + "context" "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" "github.com/openconfig/ygot/ygot" @@ -22,7 +22,7 @@ type PrincipalNetworkDomain interface { Destroy() error AddSbi(interface{}) error RemoveSbi(uuid.UUID) error - AddDevice(interface{}) error + AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error GetDevice(uuid uuid.UUID) (ygot.GoStruct, error) RemoveDevice(uuid.UUID) error Devices() []uuid.UUID @@ -35,8 +35,8 @@ type PrincipalNetworkDomain interface { ContainsDevice(uuid.UUID) bool GetSBIs() interface{} ID() uuid.UUID - Pending() []uuid.UUID - Committed() []uuid.UUID + PendingChanges() []uuid.UUID + CommittedChanges() []uuid.UUID Commit(uuid.UUID) error Confirm(uuid.UUID) error } @@ -72,11 +72,11 @@ type pndImplementation struct { errChans map[uuid.UUID]chan error } -func (pnd *pndImplementation) Pending() []uuid.UUID { +func (pnd *pndImplementation) PendingChanges() []uuid.UUID { return pnd.pendingChanges.UUIDs() } -func (pnd *pndImplementation) Committed() []uuid.UUID { +func (pnd *pndImplementation) CommittedChanges() []uuid.UUID { return pnd.committedChanges.UUIDs() } @@ -173,13 +173,15 @@ func (pnd *pndImplementation) RemoveSbi(id uuid.UUID) error { } //AddDevice adds a new device to the PND -func (pnd *pndImplementation) AddDevice(device interface{}) error { - d, ok := device.(*Device) - if !ok { - return &errors.ErrInvalidTypeAssertion{ - Value: device, - Type: "Device", - } +func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, sid uuid.UUID) error { + sbi, err := pnd.sbic.Get(sid) + if err != nil { + return err + } + + d, err := NewDevice(name, opt, sbi) + if err != nil { + return err } return pnd.addDevice(d) } diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go index 17d5c0a30232b69ec82e180fc2fa75706d3d66c5..8edd68c2e0e2219666f77eb48ac1d07b291fc08a 100644 --- a/nucleus/principalNetworkDomain_test.go +++ b/nucleus/principalNetworkDomain_test.go @@ -114,7 +114,7 @@ func Test_pndImplementation_AddDevice(t *testing.T) { if tt.name == "already exists" { pnd.devices.store[did] = &Device{UUID: did} } - err := pnd.AddDevice(tt.args.device) + err := pnd.AddDevice("", nil, defaultSbiID) if (err != nil) != tt.wantErr { t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr) } @@ -640,8 +640,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := newPnd() - d := mockDevice() - if err := p.AddDevice(&d); err != nil { + if err := p.AddDevice("", nil, defaultSbiID); err != nil { t.Error(err) return } @@ -661,7 +660,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) { func Test_pndImplementation_GetDevice(t *testing.T) { pnd := newPnd() sbi := NewSBI(types.Openconfig) - d, err := NewDevice(sbi, &GnmiTransportOptions{}) + d, err := NewDevice("", newGnmiTransportOptions(), sbi) if err != nil { t.Error(err) return @@ -734,7 +733,7 @@ func Test_pndImplementation_Confirm(t *testing.T) { t.Error(err) return } - u := pnd.Pending()[0] + u := pnd.PendingChanges()[0] if tt.name != "uncommitted" { if err := pnd.Commit(u); (err != nil) != tt.wantErr { t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr) diff --git a/nucleus/transport.go b/nucleus/transport.go index 4a1764e42a37f2724083a5d260c9bdee23f41a43..7d7fdf260bb22de35812de2dce960a7cf639ec90 100644 --- a/nucleus/transport.go +++ b/nucleus/transport.go @@ -1,9 +1,9 @@ package nucleus import ( - "bytes" + tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" + "code.fbi.h-da.de/cocsn/gosdn/nucleus/errors" "context" - "io" "github.com/openconfig/ygot/ytypes" ) @@ -15,27 +15,17 @@ type Transport interface { Set(ctx context.Context, params ...interface{}) error Subscribe(ctx context.Context, params ...string) error Type() string - GetOptions() interface{} ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error } -// YANGConsumer is a auxillary type to redirect the response -// of an RESTCONF call to a ygot YANG unmarshaler -type YANGConsumer struct { - Data *bytes.Buffer -} - -// Consume reads the received data into a byte buffer -func (yc YANGConsumer) Consume(reader io.Reader, _ interface{}) error { - _, err := yc.Data.ReadFrom(reader) - return err -} +// NewTransport receives TransportOptions and returns an appropriate Transport +// implementation +func NewTransport(opts *tpb.TransportOption, sbi SouthboundInterface) (Transport, error) { + switch o := opts.TransportOption.(type) { + case *tpb.TransportOption_GnmiTransportOption: + return NewGnmiTransport(opts, sbi) + default: + return nil, &errors.ErrInvalidTransportOptions{Opt: o} -// TransportOptions provides an interface for TransportOptions implementations -// for Transports like RESTCONF or gNMI -type TransportOptions interface { - GetAddress() string - GetUsername() string - GetPassword() string - IsTransportOption() + } }