diff --git a/controller/api/initialise_test.go b/controller/api/initialise_test.go index 004fc7af94b6562d451e4f905e1b2ba50eaae200..c9363a7f44540d527caa8c04cfcc441645307752 100644 --- a/controller/api/initialise_test.go +++ b/controller/api/initialise_test.go @@ -92,15 +92,15 @@ func bootstrapUnitTest() { mockPnd.On("GetChange", mock.Anything).Return(mockChange, nil) mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil) mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.CommonDevice{ - UUID: deviceUUID, - GoStruct: &openconfig.Device{}, + UUID: deviceUUID, + Model: &openconfig.Device{}, }, nil) mockPnd.On("Commit", mock.Anything).Return(nil) mockPnd.On("Confirm", mock.Anything).Return(nil) mockPnd.On("Devices").Return([]device.Device{ &nucleus.CommonDevice{ - UUID: deviceUUID, - GoStruct: &openconfig.Device{}, + UUID: deviceUUID, + Model: &openconfig.Device{}, }, }) mockPnd.On("GetSBIs").Return([]mocks.SouthboundInterface{}) diff --git a/controller/interfaces/device/device.go b/controller/interfaces/device/device.go index 318c0a79fe56b0badb67ce66d5fbff4c4955808a..55481cad37415c98335fe23ade9d29e70a0a3767 100644 --- a/controller/interfaces/device/device.go +++ b/controller/interfaces/device/device.go @@ -14,7 +14,7 @@ import ( // nucleus type Device interface { ID() uuid.UUID - Model() ygot.GoStruct + GetModel() ygot.ValidatedGoStruct Transport() transport.Transport Name() string SBI() southbound.SouthboundInterface diff --git a/controller/northbound/server/pnd.go b/controller/northbound/server/pnd.go index 4949a229285c38ec2b7593a4f5fa052ae535010d..6d53008450b78c502f81a6bf5ace70a8c367d0c4 100644 --- a/controller/northbound/server/pnd.go +++ b/controller/northbound/server/pnd.go @@ -122,7 +122,7 @@ func fillOnds(pnd networkdomain.NetworkDomain, all bool, did ...string) ([]*ppb. return nil, status.Errorf(codes.Aborted, "%v", err) } cfg := ygot.GNMINotificationsConfig{} - dev, err := ygot.TogNMINotifications(d.Model(), time.Now().UnixNano(), cfg) + dev, err := ygot.TogNMINotifications(d.GetModel(), time.Now().UnixNano(), cfg) if err != nil { log.Error(err) return nil, status.Errorf(codes.Aborted, "%v", err) @@ -159,7 +159,7 @@ func fillOndBySpecificPath(pnd networkdomain.NetworkDomain, did string, path str } opts := []ytypes.GetNodeOpt{&ytypes.GetHandleWildcards{}} - nodes, err := ytypes.GetNode(d.SBI().Schema().RootSchema(), d.Model(), gnmiPath, opts...) + nodes, err := ytypes.GetNode(d.SBI().Schema().RootSchema(), d.GetModel(), gnmiPath, opts...) if err != nil { log.Error(err) return nil, status.Errorf(codes.Aborted, "%v", err) diff --git a/controller/northbound/server/pnd_test.go b/controller/northbound/server/pnd_test.go index bd2c753880722c038c4a9ffc5efda1397576d956..f95be5acc5af3975b87e3dd3d8151a57c5181466 100644 --- a/controller/northbound/server/pnd_test.go +++ b/controller/northbound/server/pnd_test.go @@ -98,7 +98,7 @@ func TestMain(m *testing.M) { } mockDevice = &nucleus.CommonDevice{ - GoStruct: &openconfig.Device{ + Model: &openconfig.Device{ System: &openconfig.OpenconfigSystem_System{ Config: &openconfig.OpenconfigSystem_System_Config{ Hostname: &hostname, diff --git a/controller/nucleus/databaseDeviceStore.go b/controller/nucleus/databaseDeviceStore.go index 64f31bd364cf3bea59704e2228d7e54506f70b63..0d108f29561db10844edadfdf161f8c2fc281ace 100644 --- a/controller/nucleus/databaseDeviceStore.go +++ b/controller/nucleus/databaseDeviceStore.go @@ -15,6 +15,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" log "github.com/sirupsen/logrus" ) @@ -53,39 +54,22 @@ func (s *DatabaseDeviceStore) Get(query store.Query) (device.Device, error) { collection := db.Collection(s.storeName) result := collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: query.Name}}) if result == nil { - return nil, errors.ErrCouldNotFind{StoreName: pndStoreName} + return nil, errors.ErrCouldNotFind{StoreName: deviceStoreName} } err := result.Decode(&loadedDevice) if err != nil { log.Printf("Failed marshalling %v", err) - return nil, errors.ErrCouldNotFind{StoreName: pndStoreName} + return nil, errors.ErrCouldNotFind{StoreName: deviceStoreName} } } - sbiForDevice, err := s.sbiStore.Get(store.Query{ID: uuid.MustParse(loadedDevice.SBI)}) + device, err := s.createDeviceFromStore(loadedDevice) if err != nil { return nil, err } - d, err := NewDevice( - loadedDevice.Name, - uuid.MustParse(loadedDevice.DeviceID), - &tpb.TransportOption{ - Address: loadedDevice.TransportAddress, - Username: loadedDevice.TransportUsername, - Password: loadedDevice.TransportPassword, - TransportOption: &tpb.TransportOption_GnmiTransportOption{ - GnmiTransportOption: &tpb.GnmiTransportOption{}, - }, - Type: spb.Type_TYPE_OPENCONFIG, - }, sbiForDevice) - - if err != nil { - return nil, err - } - - return d, nil + return device, nil } // GetAll returns all stored devices. @@ -112,25 +96,13 @@ func (s *DatabaseDeviceStore) GetAll() ([]device.Device, error) { return nil, errors.ErrCouldNotMarshall{StoreName: pndStoreName} } - for _, device := range loadedDevices { - sbiForDevice, err := s.sbiStore.Get(store.Query{ID: uuid.MustParse(device.SBI)}) - d, err := NewDevice( - device.Name, - uuid.MustParse(device.DeviceID), - &tpb.TransportOption{ - Address: device.TransportAddress, - Username: device.TransportUsername, - Password: device.TransportPassword, - TransportOption: &tpb.TransportOption_GnmiTransportOption{ - GnmiTransportOption: &tpb.GnmiTransportOption{}, - }, - Type: spb.Type_TYPE_OPENCONFIG, - }, sbiForDevice) + for _, loadedDevice := range loadedDevices { + device, err := s.createDeviceFromStore(loadedDevice) if err != nil { return nil, err } - devices = append(devices, d) + devices = append(devices, device) } return devices, nil @@ -155,15 +127,13 @@ func (s *DatabaseDeviceStore) Add(deviceToAdd device.Device) error { // Update updates a existing device. func (s *DatabaseDeviceStore) Update(deviceToUpdate device.Device) error { - var updatedDevice device.Device + var updatedLoadedDevice LoadedDevice client, ctx, cancel := database.GetMongoConnection() defer cancel() defer client.Disconnect(ctx) - update := bson.M{ - "$set": deviceToUpdate, - } + update := bson.D{primitive.E{Key: "$set", Value: deviceToUpdate}} upsert := false after := options.After @@ -175,8 +145,8 @@ func (s *DatabaseDeviceStore) Update(deviceToUpdate device.Device) error { err := client.Database(database.DatabaseName). Collection(s.storeName). FindOneAndUpdate( - ctx, bson.M{"id": deviceToUpdate.ID}, update, &opt). - Decode(&updatedDevice) + ctx, bson.M{"_id": deviceToUpdate.ID().String()}, update, &opt). + Decode(&updatedLoadedDevice) if err != nil { log.Printf("Could not update Device: %v", err) @@ -201,3 +171,41 @@ func (s *DatabaseDeviceStore) Delete(deviceToDelete device.Device) error { return nil } + +func (s *DatabaseDeviceStore) createDeviceFromStore(loadedDevice LoadedDevice) (device.Device, error) { + sbiForDevice, err := s.sbiStore.Get(store.Query{ID: uuid.MustParse(loadedDevice.SBI)}) + if err != nil { + return nil, err + } + + d, err := NewDevice( + loadedDevice.Name, + uuid.MustParse(loadedDevice.DeviceID), + &tpb.TransportOption{ + Address: loadedDevice.TransportAddress, + Username: loadedDevice.TransportUsername, + Password: loadedDevice.TransportPassword, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + Type: spb.Type_TYPE_OPENCONFIG, + }, sbiForDevice) + + if err != nil { + return nil, err + } + + // Create 'root' path to be able to load the whole model from the store. + path, err := ygot.StringToPath("/", ygot.StructuredPath) + if err != nil { + return nil, err + } + + // Use unmarshall from the devices SBI to unmarshall ygot json in go struct. + err = d.SBI().Unmarshal([]byte(loadedDevice.Model), path, d.GetModel()) + if err != nil { + return nil, err + } + + return d, nil +} diff --git a/controller/nucleus/databasePndStore.go b/controller/nucleus/databasePndStore.go index 8eaef9e005f2a1cbe427d2a30f70f2d7780291f7..5e021277149b31df0b35c653e2fa565f934a697c 100644 --- a/controller/nucleus/databasePndStore.go +++ b/controller/nucleus/databasePndStore.go @@ -1,21 +1,29 @@ package nucleus import ( + "fmt" + "code.fbi.h-da.de/danet/gosdn/controller/interfaces/device" "code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain" + + cpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/csbi" "code.fbi.h-da.de/danet/gosdn/controller/nucleus/database" errors "code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors" "code.fbi.h-da.de/danet/gosdn/controller/store" "github.com/google/uuid" log "github.com/sirupsen/logrus" + "github.com/spf13/viper" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) // DatabasePndStore is used to store PrincipalNetworkDomains type DatabasePndStore struct { pndStoreName string pendingChannels map[uuid.UUID]chan device.Details + csbiClient cpb.CsbiServiceClient } // Get takes a PrincipalNetworkDomain's UUID or name and returns the PrincipalNetworkDomain. If the requested @@ -41,11 +49,16 @@ func (s *DatabasePndStore) Get(query store.Query) (networkdomain.NetworkDomain, return nil, errors.ErrCouldNotMarshall{StoreName: pndStoreName} } + csbiClient, err := s.getCsbiClient() + if err != nil { + return nil, err + } + newPnd, err := NewPND( loadedPND.Name, loadedPND.Description, uuid.MustParse(loadedPND.ID), - nil, + csbiClient, s.callback, ) if err != nil { @@ -79,13 +92,18 @@ func (s *DatabasePndStore) GetAll() ([]networkdomain.NetworkDomain, error) { return nil, errors.ErrCouldNotMarshall{StoreName: pndStoreName} } + csbiClient, err := s.getCsbiClient() + if err != nil { + return nil, err + } + for _, loadedPND := range loadedPnds { newPnd, err := NewPND( loadedPND.Name, loadedPND.Description, uuid.MustParse(loadedPND.ID), - nil, - nil, + csbiClient, + s.callback, ) if err != nil { return nil, err @@ -161,3 +179,19 @@ func (s *DatabasePndStore) callback(id uuid.UUID, ch chan device.Details) { log.Infof("pending channel %v removed", id) } } + +func (s *DatabasePndStore) getCsbiClient() (cpb.CsbiServiceClient, error) { + if s.csbiClient == nil { + orchestrator := viper.GetString("csbi-orchestrator") + conn, err := grpc.Dial(orchestrator, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, err + } + + s.csbiClient = cpb.NewCsbiServiceClient(conn) + + fmt.Println("creating new csbi client") + } + + return s.csbiClient, nil +} diff --git a/controller/nucleus/device.go b/controller/nucleus/device.go index 6db1d6f6e8071146e77dc7876d0bf3f6ee201bd0..100666727f4ebb154b386bd604c037367199a067 100644 --- a/controller/nucleus/device.go +++ b/controller/nucleus/device.go @@ -8,6 +8,7 @@ import ( "code.fbi.h-da.de/danet/gosdn/controller/interfaces/device" "code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound" "code.fbi.h-da.de/danet/gosdn/controller/interfaces/transport" + "code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors" "github.com/docker/docker/pkg/namesgenerator" "github.com/google/uuid" "github.com/openconfig/ygot/ygot" @@ -32,15 +33,26 @@ func NewDevice(name string, uuidInput uuid.UUID, opt *tpb.TransportOption, sbi s name = namesgenerator.GetRandomName(0) } + // We want a representation of the OND's config (the SBI-schema's root created through ygot), + // but do not want to work on the sbi.Schema() directly. + // So the root of sbi.Schema() is never changed when a set or get on a device will be called. root, err := ygot.DeepCopy(sbi.Schema().Root) if err != nil { return nil, err } + validatedDeepCopy, ok := root.(ygot.ValidatedGoStruct) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: root, + Type: (*ygot.ValidatedGoStruct)(nil), + } + } + if opt.Type == spb.Type_TYPE_CONTAINERISED { return &CsbiDevice{ CommonDevice: CommonDevice{ UUID: uuidInput, - GoStruct: root, + Model: validatedDeepCopy, sbi: sbi, transport: t, name: name, @@ -51,7 +63,7 @@ func NewDevice(name string, uuidInput uuid.UUID, opt *tpb.TransportOption, sbi s return &CommonDevice{ UUID: uuidInput, - GoStruct: root, + Model: validatedDeepCopy, sbi: sbi, transport: t, name: name, @@ -65,7 +77,7 @@ type CommonDevice struct { UUID uuid.UUID // Device embeds a ygot.GoStruct containing the device details - ygot.GoStruct + Model ygot.ValidatedGoStruct // SBI is the device's southbound interface implementation sbi southbound.SouthboundInterface @@ -84,9 +96,9 @@ func (d *CommonDevice) ID() uuid.UUID { return d.UUID } -// Model returns the ygot representation of the Device -func (d *CommonDevice) Model() ygot.GoStruct { - return d.GoStruct +// GetModel returns the ygot representation of the Device +func (d *CommonDevice) GetModel() ygot.ValidatedGoStruct { + return d.Model } // Transport returns the Transport of the device @@ -121,7 +133,7 @@ func (d *CommonDevice) SetSBI(sbi southbound.SouthboundInterface) { // ProcessResponse processes a response for the Device func (d *CommonDevice) ProcessResponse(resp proto.Message) error { - return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema()) + return d.transport.ProcessResponse(resp, d.Model, d.sbi.Schema()) } // CsbiDevice is used for the cSBI functionality. @@ -134,9 +146,9 @@ func (d *CsbiDevice) ID() uuid.UUID { return d.UUID } -// Model returns the ygot representation of the Device -func (d *CsbiDevice) Model() ygot.GoStruct { - return d.GoStruct +// GetModel returns the ygot representation of the Device +func (d *CsbiDevice) GetModel() ygot.ValidatedGoStruct { + return d.Model } // Transport returns the Transport of the device @@ -157,7 +169,7 @@ func (d *CsbiDevice) SBI() southbound.SouthboundInterface { // ProcessResponse processes a response for the Device func (d *CsbiDevice) ProcessResponse(resp proto.Message) error { // TODO: callback to send response to caller - return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema()) + return d.transport.ProcessResponse(resp, d.Model, d.sbi.Schema()) } // MarshalJSON implements the MarshalJSON interface to store a device as JSON @@ -193,6 +205,11 @@ func (d *CommonDevice) MarshalJSON() ([]byte, error) { sbiUUID = d.sbi.ID() } + modelAsString, err := ygot.EmitJSON(d.Model, d.getYgotEmitJSONConfig()) + if err != nil { + return []byte{}, err + } + return json.Marshal(&struct { DeviceID uuid.UUID `json:"id,omitempty"` Name string `json:"name,omitempty"` @@ -202,6 +219,7 @@ func (d *CommonDevice) MarshalJSON() ([]byte, error) { TransportPassword string `json:"transport_password,omitempty"` TransportOptionType spb.Type `json:"transport_option"` SBI uuid.UUID `json:"sbi,omitempty"` + Model string `bson:"model,omitempty"` }{ DeviceID: d.ID(), Name: d.Name(), @@ -211,6 +229,7 @@ func (d *CommonDevice) MarshalJSON() ([]byte, error) { TransportPassword: transportPassword, TransportOptionType: transportOptionType, SBI: sbiUUID, + Model: modelAsString, }) } @@ -239,6 +258,11 @@ func (d *CommonDevice) MarshalBSON() ([]byte, error) { transportOptionType = d.transportOptions.Type } + modelAsString, err := ygot.EmitJSON(d.Model, d.getYgotEmitJSONConfig()) + if err != nil { + return []byte{}, err + } + return bson.Marshal(&struct { DeviceID string `bson:"_id,omitempty"` Name string `bson:"name,omitempty"` @@ -248,6 +272,7 @@ func (d *CommonDevice) MarshalBSON() ([]byte, error) { TransportPassword string `bson:"transport_password,omitempty"` TransportOptionType spb.Type `bson:"transport_option"` SBI string `bson:"sbi,omitempty"` + Model string `bson:"model,omitempty"` }{ DeviceID: d.ID().String(), Name: d.Name(), @@ -257,5 +282,15 @@ func (d *CommonDevice) MarshalBSON() ([]byte, error) { TransportPassword: transportPassword, TransportOptionType: transportOptionType, SBI: d.sbi.ID().String(), + Model: modelAsString, }) } + +func (d *CommonDevice) getYgotEmitJSONConfig() *ygot.EmitJSONConfig { + return &ygot.EmitJSONConfig{ + Format: ygot.RFC7951, + Indent: "", + RFC7951Config: &ygot.RFC7951JSONConfig{ + AppendModuleName: true, + }} +} diff --git a/controller/nucleus/deviceStore.go b/controller/nucleus/deviceStore.go index 7764e0317f1612b38ca67115941f5da170fbf757..d47f4527e0b9e1e88800a8f3127430a651fc0665 100644 --- a/controller/nucleus/deviceStore.go +++ b/controller/nucleus/deviceStore.go @@ -29,16 +29,18 @@ type LoadedDevice struct { // Name represents the name of the LoadedDevice. Name string `json:"name,omitempty"` // TransportType represent the type of the transport in use of the LoadedDevice. - TransportType string `json:"transport_type,omitempty"` + TransportType string `json:"transport_type,omitempty" bson:"transport_type,omitempty"` // TransportAddress represents the address from which the device can be reached via the transport method. - TransportAddress string `json:"transport_address,omitempty"` + TransportAddress string `json:"transport_address,omitempty" bson:"transport_address,omitempty"` // TransportUsername is used for authentication via the transport method in use. - TransportUsername string `json:"transport_username,omitempty"` + TransportUsername string `json:"transport_username,omitempty" bson:"transport_username,omitempty"` // TransportPassword is used for authentication via the transport method in use. - TransportPassword string `json:"transport_password,omitempty"` - TransportOptionCsbi bool `json:"transport_option_csbi,omitempty"` + TransportPassword string `json:"transport_password,omitempty" bson:"transport_password,omitempty"` + TransportOptionCsbi bool `json:"transport_option_csbi,omitempty" bson:"transport_option_csbi,omitempty"` + // SBI indicates the southbound interface, which is used by this device as UUID. - SBI string `json:"sbi,omitempty"` + SBI string `json:"sbi,omitempty"` + Model string `json:"model,omitempty" bson:"model,omitempty"` } // ID returns the ID of the LoadedDevice as UUID. diff --git a/controller/nucleus/device_test.go b/controller/nucleus/device_test.go index fd2fa1d0c0780b4c582be5b5026d46737c68d3cc..0fdf5a6613d5717796453285e81b0d1ebdb9654e 100644 --- a/controller/nucleus/device_test.go +++ b/controller/nucleus/device_test.go @@ -16,7 +16,7 @@ import ( func TestDevice_Id(t *testing.T) { type fields struct { - GoStruct ygot.GoStruct + Model ygot.ValidatedGoStruct SBI southbound.SouthboundInterface Transport transport.Transport UUID uuid.UUID @@ -38,7 +38,7 @@ func TestDevice_Id(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { d := &CommonDevice{ - GoStruct: tt.fields.GoStruct, + Model: tt.fields.Model, sbi: tt.fields.SBI, transport: tt.fields.Transport, UUID: tt.fields.UUID, @@ -105,7 +105,7 @@ func TestNewDevice(t *testing.T) { return } if resp != nil { - if reflect.TypeOf(resp.Model()) != reflect.TypeOf(&openconfig.Device{}) { + if reflect.TypeOf(resp.GetModel()) != reflect.TypeOf(&openconfig.Device{}) { t.Error("NewDevice() returned invalid GoStruct") } if reflect.TypeOf(resp.Transport()) != reflect.TypeOf(&Gnmi{}) { diff --git a/controller/nucleus/initialise_test.go b/controller/nucleus/initialise_test.go index 8233c5a644593125a24b95b347111b0489c9ed0a..9f9146a1ff9c3fc4b58927480679c4d984092735 100644 --- a/controller/nucleus/initialise_test.go +++ b/controller/nucleus/initialise_test.go @@ -143,7 +143,7 @@ func mockDevice() device.Device { sbi := &OpenConfig{} return &CommonDevice{ UUID: mdid, - GoStruct: sbi.Schema().Root, + Model: sbi.Schema().Root, sbi: sbi, transport: &mocks.Transport{}, } diff --git a/controller/nucleus/principalNetworkDomain.go b/controller/nucleus/principalNetworkDomain.go index 6b072dc2ae68d02e527408c17e55a275f83b7048..54a04a44759e2c1450714f370ae08ff4065ee7e3 100644 --- a/controller/nucleus/principalNetworkDomain.go +++ b/controller/nucleus/principalNetworkDomain.go @@ -244,13 +244,14 @@ func (pnd *pndImplementation) GetDevice(identifier string) (device.Device, error return nil, err } - copiedGoStruct, err := ygot.DeepCopy(d.Model()) - if err != nil { - return nil, err + // TODO: We should investigate why we copy the device here. + copiedDevice := &CommonDevice{ + name: d.Name(), + UUID: d.ID(), + Model: d.GetModel(), + sbi: d.SBI(), } - copiedDevice := &CommonDevice{name: d.Name(), UUID: d.ID(), GoStruct: copiedGoStruct, sbi: d.SBI()} - return copiedDevice, nil } @@ -325,7 +326,7 @@ func (pnd *pndImplementation) MarshalDevice(identifier string) (string, error) { return "", err } - jsonTree, err := json.MarshalIndent(foundDevice.Model(), "", "\t") + jsonTree, err := json.MarshalIndent(foundDevice.GetModel(), "", "\t") if err != nil { return "", err } @@ -366,6 +367,12 @@ func (pnd *pndImplementation) Request(uuid uuid.UUID, path string) (proto.Messag if err != nil { return nil, err } + + err = pnd.devices.Update(d) + if err != nil { + return nil, err + } + return resp, nil } @@ -396,7 +403,7 @@ func (pnd *pndImplementation) ChangeOND(duid uuid.UUID, operation ppb.ApiOperati ID: duid, Name: "", })) - cpy, err := ygot.DeepCopy(d.Model()) + cpy, err := ygot.DeepCopy(d.GetModel()) ygot.BuildEmptyTree(cpy) if err != nil { return uuid.Nil, err @@ -433,7 +440,7 @@ func (pnd *pndImplementation) ChangeOND(duid uuid.UUID, operation ppb.ApiOperati payload := change.Payload{Original: original, Modified: modified} return d.Transport().Set(ctx, payload) } - ch := NewChange(duid, d.Model(), cpy, callback) + ch := NewChange(duid, d.GetModel(), cpy, callback) if err := pnd.changes.Add(ch); err != nil { return uuid.Nil, err } diff --git a/controller/nucleus/principalNetworkDomain_test.go b/controller/nucleus/principalNetworkDomain_test.go index 7fc4768c74ecbf3879ff27d604180f8f8640629b..f6d58d02dab9cb0ebeb4c3a547a75f03242bcd08 100644 --- a/controller/nucleus/principalNetworkDomain_test.go +++ b/controller/nucleus/principalNetworkDomain_test.go @@ -294,7 +294,7 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) { pnd := newPnd() d := &CommonDevice{ UUID: tt.args.uuid, - GoStruct: &openconfig.Device{}, + Model: &openconfig.Device{}, sbi: nil, transport: nil, } @@ -711,8 +711,8 @@ func Test_pndImplementation_GetDevice(t *testing.T) { return } if foundDevice != nil { - if !reflect.DeepEqual(foundDevice.(device.Device).Model(), tt.want) { - t.Errorf("GetDevice() got = %v, want %v", foundDevice.(device.Device).Model(), tt.want) + if !reflect.DeepEqual(foundDevice.(device.Device).GetModel(), tt.want) { + t.Errorf("GetDevice() got = %v, want %v", foundDevice.(device.Device).GetModel(), tt.want) } } }) @@ -765,8 +765,8 @@ func Test_pndImplementation_GetDeviceByName(t *testing.T) { return } if foundDevice != nil { - if !reflect.DeepEqual(foundDevice.(device.Device).Model(), tt.want) { - t.Errorf("GetDeviceByName() got = %v, want %v", foundDevice.(device.Device).Model(), tt.want) + if !reflect.DeepEqual(foundDevice.(device.Device).GetModel(), tt.want) { + t.Errorf("GetDeviceByName() got = %v, want %v", foundDevice.(device.Device).GetModel(), tt.want) } } }) diff --git a/controller/nucleus/southbound.go b/controller/nucleus/southbound.go index 8bff4dd7f8871e8056233ae8f1a4256e10344b65..2c18dd0922a9ed401f16782e2c4a7715eb3bbe60 100644 --- a/controller/nucleus/southbound.go +++ b/controller/nucleus/southbound.go @@ -294,6 +294,17 @@ func (p *SouthboundPlugin) Update() error { return nil } +// MarshalBSON implements the MarshalBSON interface to store a device as BSON +func (p *SouthboundPlugin) MarshalBSON() ([]byte, error) { + return bson.Marshal(&struct { + ID string `bson:"_id"` + Type spb.Type `bson:"type"` + }{ + ID: p.sbi.ID().String(), + Type: p.Type(), + }) +} + // MarshalBSON implements the MarshalBSON interface to store a device as BSON func (oc *OpenConfig) MarshalBSON() ([]byte, error) { return bson.Marshal(&struct { diff --git a/csbi/templates.go b/csbi/templates.go index d7e9727329853d3e1928163b82aed83c86ebdd05..d978296bc6278b4f3f89e2cd6ba7fa798f3030f5 100644 --- a/csbi/templates.go +++ b/csbi/templates.go @@ -89,6 +89,11 @@ const southboundStructCsbiAmendmend = ` func (csbi *Csbi) Type() spb.Type { return spb.Type_TYPE_CONTAINERISED } + +// Name returns the Name of the Southbound +func (csbi *Csbi) Name() string { + return "csbi" +} ` const southboundStructPluginAmendmend = ` @@ -97,6 +102,12 @@ const southboundStructPluginAmendmend = ` func (csbi *Csbi) Type() spb.Type { return spb.Type_TYPE_PLUGIN } + +// Name returns the Name of the Southbound +func (csbi *Csbi) Name() string { + return "plugin" +} + ` const southboundImportAmendmend = `