diff --git a/cli/subscribe.go b/cli/subscribe.go index 46e6529a2de18c8e969a7954b36ac94cf281d48e..5b3df54873ab56c0a7f16757daca943219e4cee1 100644 --- a/cli/subscribe.go +++ b/cli/subscribe.go @@ -18,12 +18,12 @@ import ( // Subscribe starts a gNMI subscriber requersting the specified paths on the target and // logs the response to stdout. Only 'stream' mode with 'sample' operation supported. -func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error { +func Subscribe(address, username, password, deviceName string, sample, heartbeat int64, args ...string) error { sbi := &nucleus.OpenConfig{} tOpts := &tpb.TransportOption{ - Address: a, - Username: u, - Password: p, + Addr: address, + Username: username, + Password: password, Tls: false, TransportOption: &tpb.TransportOption_GnmiTransportOption{ GnmiTransportOption: &tpb.GnmiTransportOption{ @@ -35,7 +35,7 @@ func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error { }, } - device, err := nucleus.NewDevice("", tOpts, sbi) + device, err := nucleus.NewDevice(deviceName, tOpts, sbi) if err != nil { return err } @@ -50,7 +50,7 @@ func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error { HeartbeatInterval: uint64(heartbeat * time.Second.Nanoseconds()), Paths: gnmi.SplitPaths(args), Origin: "", - Target: a, + Target: address, } done := make(chan os.Signal, 1) signal.Notify(done, syscall.SIGILL, syscall.SIGTERM) @@ -63,5 +63,6 @@ func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error { fmt.Println("awaiting signal") <-done fmt.Println("exiting") + return nil } diff --git a/cmd/addDevice.go b/cmd/addDevice.go index 797001949228d5608a619611e5ff5e50f978d9ed..53e0880010239fe9a0092d7e956da0ffa16aee24 100644 --- a/cmd/addDevice.go +++ b/cmd/addDevice.go @@ -36,12 +36,14 @@ import ( "github.com/spf13/cobra" ) +var deviceName string + // addDeviceCmd represents the addDevice command var addDeviceCmd = &cobra.Command{ Use: "add-device", Short: "adds a device to the controller", - Long: `Adds a device to the controller. - + Long: `Adds a device to the controller. + Device address and user credentials need to be provided if they diverge from the default credentials.`, RunE: func(cmd *cobra.Command, args []string) error { @@ -62,5 +64,9 @@ var deviceName string func init() { cliCmd.AddCommand(addDeviceCmd) +<<<<<<< HEAD addDeviceCmd.Flags().StringVar(&deviceName, "name", "", "add a device name (optional)") +======= + addDeviceCmd.PersistentFlags().StringVarP(&deviceName, "device-name", "n", "", "Human readable device name.") +>>>>>>> 8e2fe42b (Let user set a name for a device or autogenerate it) } diff --git a/cmd/getDevice.go b/cmd/getDevice.go index c51de68a5f1f94c7601998a84fc423c673f0545b..2f394f86e45efa91deaff069bf4bbabe4aa75153 100644 --- a/cmd/getDevice.go +++ b/cmd/getDevice.go @@ -43,8 +43,8 @@ var getDeviceCmd = &cobra.Command{ Args: cobra.ExactArgs(1), Short: "gets device information from the controller", Long: `Gets device information from the controller. - -Device UUID needs to be specified as positional argument.`, + +Device UUID or name needs to be specified as positional argument.`, RunE: func(cmd *cobra.Command, args []string) error { resp, err := cli.GetDevice( apiEndpoint, diff --git a/cmd/init.go b/cmd/init.go index 949e6996bdeab725de1103db08644ffaf92815ee..c45a03b217358be731977c4ad44ec094b2623c0b 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -41,7 +41,7 @@ var initCmd = &cobra.Command{ Use: "init", Short: "initialise SBI and PND", Long: `Initialise SBI and PND and saves values to config file. - + Same as invoking "gosdn cli" without any arguments`, RunE: func(cmd *cobra.Command, args []string) error { return cli.Init(apiEndpoint) diff --git a/cmd/request.go b/cmd/request.go index 88e6c974503553fb3449651f41383e92c70616d2..f70586dc7063f38f9b1a6c2f1b5f7348995e7dfd 100644 --- a/cmd/request.go +++ b/cmd/request.go @@ -43,7 +43,7 @@ var requestCmd = &cobra.Command{ Args: cobra.ExactArgs(1), Short: "requests a path from a specified device on the controller", Long: `Requests a path from a specified device on the controller. - + The request path is passed as positional argument.`, Run: func(cmd *cobra.Command, args []string) { log.Info(cli.GetDevice( diff --git a/cmd/requestAll.go b/cmd/requestAll.go index 1f753c7296a45ef80d01c060a949f7f33b648541..2fb8dbb1fa6b263fb746b7307a85439e977b8cfa 100644 --- a/cmd/requestAll.go +++ b/cmd/requestAll.go @@ -44,7 +44,7 @@ var requestAllCmd = &cobra.Command{ Short: "requests specified path from all devices on the controller", Long: `Requests a path from all devices on the controller known by the controller. - + The request path is passed as positional argument.`, RunE: func(cmd *cobra.Command, args []string) error { resp, err := cli.GetDevice( diff --git a/cmd/subscribe.go b/cmd/subscribe.go index a641b7fb4f4abffebd4e6848ae5cf6343644d276..63e7a9ac5c131d862253d34f7ba46e62cd5b2374 100644 --- a/cmd/subscribe.go +++ b/cmd/subscribe.go @@ -47,7 +47,7 @@ var subscribeCmd = &cobra.Command{ Only 'stream' mode with 'sample' operation supported.`, RunE: func(cmd *cobra.Command, args []string) error { - return cli.Subscribe(address, username, password, sampleInterval, heartbeatInterval, args...) + return cli.Subscribe(address, username, password, "", sampleInterval, heartbeatInterval, args...) }, } diff --git a/go.mod b/go.mod index 39cffc3c5f21376f875990d1b291c509b19e7ee0..883bcc2b4a4f41c5d16d45b27701bd45f6ab48df 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( code.fbi.h-da.de/cocsn/yang-models v0.0.7 github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a github.com/golang/protobuf v1.5.2 + github.com/docker/docker v1.13.1 github.com/google/gnxi v0.0.0-20201221102247-c26672548161 github.com/google/uuid v1.1.2 github.com/neo4j/neo4j-go-driver v1.8.3 diff --git a/go.sum b/go.sum index dc81570aab6ab4357bad19d9ecd4efe66c10ba2a..e54bdedadf898c8469cb319baf75c9436bf92a09 100644 --- a/go.sum +++ b/go.sum @@ -86,6 +86,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/initialise_test.go b/initialise_test.go index 828a27730795b46353d71825c605828ab3316023..85d5fb6f41a59247c12bc339f82768718f2166b8 100644 --- a/initialise_test.go +++ b/initialise_test.go @@ -30,6 +30,7 @@ var httpTestDevice nucleus.Device var args string var argsNotFound string +var argsNotFoundGetDevice string var mockContext = mock.MatchedBy(func(ctx context.Context) bool { return true }) diff --git a/nucleus/device.go b/nucleus/device.go index 58c62f539bab082e0fa7d98c003f0698775ff5a5..18c36a27d71f1412aadc18e0d0c30bcd8c014637 100644 --- a/nucleus/device.go +++ b/nucleus/device.go @@ -2,6 +2,7 @@ package nucleus import ( tpb "code.fbi.h-da.de/cocsn/api/go/gosdn/transport" + "github.com/docker/docker/pkg/namesgenerator" "github.com/google/uuid" "github.com/openconfig/ygot/ygot" ) @@ -20,20 +21,29 @@ type Device struct { // Transport is the device's Transport implementation Transport Transport + + // Name is the device's human readable name + Name string } // NewDevice creates a Device func NewDevice(name string, opt *tpb.TransportOption, sbi SouthboundInterface) (*Device, error) { - t, err := NewTransport(opt, sbi) + transport, err := NewTransport(opt, sbi) if err != nil { return nil, err } + + if name == "" { + name = namesgenerator.GetRandomName(0) + } + return &Device{ UUID: uuid.New(), GoStruct: sbi.Schema().Root, SBI: sbi, - Transport: t, - }, err + Transport: transport, + Name: name, + }, nil } // ID returns the UUID of the Device diff --git a/nucleus/device_test.go b/nucleus/device_test.go index ef04e4631ddce19a6c0f9e282d629db040145656..d3d2ae9831eda694f938c2c0485dacadd6d9367d 100644 --- a/nucleus/device_test.go +++ b/nucleus/device_test.go @@ -17,6 +17,7 @@ func TestDevice_Id(t *testing.T) { SBI SouthboundInterface Transport Transport UUID uuid.UUID + Name string } tests := []struct { name string @@ -38,6 +39,7 @@ func TestDevice_Id(t *testing.T) { SBI: tt.fields.SBI, Transport: tt.fields.Transport, UUID: tt.fields.UUID, + Name: tt.fields.Name, } if got := d.ID(); !reflect.DeepEqual(got, tt.want) { t.Errorf("ID() = %v, want %v", got, tt.want) @@ -51,6 +53,7 @@ func TestNewDevice(t *testing.T) { type args struct { sbi SouthboundInterface opts *tpb.TransportOption + name string } tests := []struct { name string @@ -75,6 +78,7 @@ func TestNewDevice(t *testing.T) { }, }, }, + name: "MyDevice", }, want: &Device{ GoStruct: &openconfig.Device{}, @@ -91,6 +95,7 @@ func TestNewDevice(t *testing.T) { Username: "test", Password: "test", }, + name: "MyDevice", }, want: nil, wantErr: true, @@ -98,7 +103,7 @@ func TestNewDevice(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewDevice("", tt.args.opts, tt.args.sbi) + got, err := NewDevice(tt.args.name, tt.args.opts, tt.args.sbi) if (err != nil) != tt.wantErr { t.Errorf("NewDevice() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/nucleus/errors/errors.go b/nucleus/errors/errors.go index 3aad202118e0bceb2b4e91dd34ce075c1ed454e5..4cc6ca1c61d8cb1d82d125030fabbc8840c74788 100644 --- a/nucleus/errors/errors.go +++ b/nucleus/errors/errors.go @@ -41,6 +41,15 @@ func (e *ErrAlreadyExists) Error() string { return fmt.Sprintf("%v already exists", e.Item) } +// ErrInvalidUUID implements the Error interface and is called if a UUID is not valid. +type ErrInvalidUUID struct { + DeviceName string +} + +func (e *ErrInvalidUUID) Error() string { + return fmt.Sprintf("UUID not valid") +} + // ErrInvalidTypeAssertion implements the Error interface and is called if the // type of a storable item does not correspond to the expected type. type ErrInvalidTypeAssertion struct { diff --git a/nucleus/initialise_test.go b/nucleus/initialise_test.go index d62e06d498f3e25fb6f25ca2943825f0f472e46f..e412a631d0ea6f43169842a1b924a3db4f85ab62 100644 --- a/nucleus/initialise_test.go +++ b/nucleus/initialise_test.go @@ -130,7 +130,7 @@ func newPnd() pndImplementation { name: "default", description: "default test pnd", sbic: SbiStore{store{}}, - devices: DeviceStore{store{}}, + devices: NewDeviceStore(), pendingChanges: ChangeStore{store{}}, committedChanges: ChangeStore{store{}}, confirmedChanges: ChangeStore{store{}}, diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go index 216be2b78d8241e642cc1e6f7750da0dc711be1d..afa6e36be051f50020bc3bad1a725902182ec374 100644 --- a/nucleus/principalNetworkDomain.go +++ b/nucleus/principalNetworkDomain.go @@ -25,7 +25,7 @@ type PrincipalNetworkDomain interface { AddSbi(interface{}) error RemoveSbi(uuid.UUID) error AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error - GetDevice(uuid uuid.UUID) (ygot.GoStruct, error) + GetDevice(identifier string) (*Device, error) RemoveDevice(uuid.UUID) error Devices() []uuid.UUID ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) error @@ -33,7 +33,7 @@ type PrincipalNetworkDomain interface { RequestAll(string) error GetName() string GetDescription() string - MarshalDevice(uuid.UUID) (string, error) + MarshalDevice(string) (string, error) ContainsDevice(uuid.UUID) bool GetSBIs() interface{} ID() uuid.UUID @@ -50,7 +50,7 @@ func NewPND(name, description string, id uuid.UUID, sbi SouthboundInterface) (Pr name: name, description: description, sbic: SbiStore{store{}}, - devices: DeviceStore{store{}}, + devices: NewDeviceStore(), pendingChanges: ChangeStore{store{}}, committedChanges: ChangeStore{store{}}, confirmedChanges: ChangeStore{store{}}, @@ -67,7 +67,7 @@ type pndImplementation struct { name string description string sbic SbiStore - devices DeviceStore + devices *DeviceStore pendingChanges ChangeStore committedChanges ChangeStore confirmedChanges ChangeStore @@ -229,12 +229,20 @@ func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, s return pnd.addDevice(d) } -func (pnd *pndImplementation) GetDevice(uuid uuid.UUID) (ygot.GoStruct, error) { - d, err := pnd.devices.Get(uuid) +func (pnd *pndImplementation) GetDevice(identifier string) (*Device, error) { + d, err := pnd.devices.Get(FromString(identifier)) + if err != nil { + return nil, err + } + + copiedGoStruct, err := ygot.DeepCopy(d.GoStruct) if err != nil { return nil, err } - return ygot.DeepCopy(d.GoStruct) + + copiedDevice := &Device{Name: d.Name, UUID: d.UUID, GoStruct: copiedGoStruct} + + return copiedDevice, nil } // RemoveDevice removes a device from the PND @@ -257,36 +265,40 @@ func (pnd *pndImplementation) removeSbi(id uuid.UUID) error { } func (pnd *pndImplementation) addDevice(device *Device) error { - return pnd.devices.Add(device) -} + err := pnd.devices.Add(device, device.Name) + if err != nil { + return err + } -func (pnd *pndImplementation) getDevice(id uuid.UUID) (*Device, error) { - return pnd.devices.Get(id) + return nil } func (pnd *pndImplementation) removeDevice(id uuid.UUID) error { return pnd.devices.Delete(id) } -func (pnd *pndImplementation) MarshalDevice(uuid uuid.UUID) (string, error) { - d, err := pnd.getDevice(uuid) +func (pnd *pndImplementation) MarshalDevice(identifier string) (string, error) { + foundDevice, err := pnd.devices.Get(FromString(identifier)) if err != nil { return "", err } - jsonTree, err := json.MarshalIndent(d.GoStruct, "", "\t") + + jsonTree, err := json.MarshalIndent(foundDevice.GoStruct, "", "\t") if err != nil { return "", err } log.WithFields(log.Fields{ - "pnd": pnd.id, - "device": uuid, + "pnd": pnd.id, + "Identifier": identifier, + "Name": foundDevice.Name, }).Info("marshalled device") + return string(jsonTree), nil } // Request sends a get request to a specific device func (pnd *pndImplementation) Request(uuid uuid.UUID, path string) error { - d, err := pnd.getDevice(uuid) + d, err := pnd.devices.Get(FromString(uuid.String())) if err != nil { return err } @@ -318,12 +330,15 @@ func (pnd *pndImplementation) RequestAll(path string) error { // ChangeOND creates a change from the provided Operation, path and value. The Change is Pending and func (pnd *pndImplementation) ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) error { - d, err := pnd.getDevice(uuid) + d, err := pnd.devices.Get(uuid) if err != nil { return err } cpy, err := ygot.DeepCopy(d.GoStruct) ygot.BuildEmptyTree(cpy) + if err != nil { + return err + } p, err := ygot.StringToStructuredPath(path) if err != nil { diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go index 8ab5b389d63b58fef06ae37264c6ce9e633b95f7..242ce6fad41ca4c84cf21ad1e599d4ad785a2a52 100644 --- a/nucleus/principalNetworkDomain_test.go +++ b/nucleus/principalNetworkDomain_test.go @@ -236,7 +236,7 @@ func Test_pndImplementation_ContainsDevice(t *testing.T) { t.Run(tt.name, func(t *testing.T) { pnd := newPnd() if tt.name != "fails empty" { - if err := pnd.devices.Add(tt.args.device); err != nil { + if err := pnd.devices.Add(tt.args.device, "test"); err != nil { t.Error(err) } } @@ -255,7 +255,7 @@ func Test_pndImplementation_Destroy(t *testing.T) { name string description string sbi SbiStore - devices DeviceStore + devices *DeviceStore } tests := []struct { name string @@ -359,7 +359,7 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) { if err := pnd.addDevice(d); err != nil { t.Error(err) } - got, err := pnd.MarshalDevice(tt.args.uuid) + got, err := pnd.MarshalDevice(tt.args.uuid.String()) if (err != nil) != tt.wantErr { t.Errorf("MarshalDevice() error = %v, wantErr %v", err, tt.wantErr) return @@ -425,7 +425,7 @@ func Test_pndImplementation_RemoveSbi(t *testing.T) { name: "test-remove-sbi", description: "test-remove-sbi", sbic: SbiStore{store{}}, - devices: DeviceStore{store{}}, + devices: NewDeviceStore(), id: defaultPndID, } if tt.name != "fails empty" { @@ -701,14 +701,68 @@ func Test_pndImplementation_GetDevice(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := pnd.GetDevice(tt.args.uuid) + foundDevice, err := pnd.GetDevice(tt.args.uuid.String()) if (err != nil) != tt.wantErr { t.Errorf("GetDevice() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetDevice() got = %v, want %v", got, tt.want) + if foundDevice != nil { + if !reflect.DeepEqual(foundDevice.GoStruct, tt.want) { + t.Errorf("GetDevice() got = %v, want %v", foundDevice.GoStruct, tt.want) + } } + + }) + } +} + +func Test_pndImplementation_GetDeviceByName(t *testing.T) { + p := newPnd() + sbi := NewSBI(spb.Type_OPENCONFIG) + d, err := NewDevice("my-device", newGnmiTransportOptions(), sbi) + if err != nil { + t.Error(err) + return + } + if err = p.addDevice(d); err != nil { + t.Error(err) + return + } + type args struct { + name string + } + tests := []struct { + name string + args args + want ygot.GoStruct + wantErr bool + }{ + { + name: "default", + args: args{name: d.Name}, + want: sbi.Schema().Root, + wantErr: false, + }, + { + name: "device not found", + args: args{name: "test-device"}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + foundDevice, err := p.GetDevice(tt.args.name) + if (err != nil) != tt.wantErr { + t.Errorf("GetDeviceByName() error = %v, wantErr %v", err, tt.wantErr) + return + } + if foundDevice != nil { + if !reflect.DeepEqual(foundDevice.GoStruct, tt.want) { + t.Errorf("GetDeviceByName() got = %v, want %v", foundDevice.GoStruct, tt.want) + } + } + }) } } diff --git a/nucleus/store.go b/nucleus/store.go index 291ed361c39491e49c499a2cefab1e556df88578..639762d43210259758d94970e538a391cd3a84b5 100644 --- a/nucleus/store.go +++ b/nucleus/store.go @@ -1,6 +1,7 @@ package nucleus import ( + "fmt" "reflect" "sync" @@ -43,7 +44,7 @@ func NewSbiStore() *SbiStore { // NewDeviceStore returns a DeviceStore func NewDeviceStore() *DeviceStore { - return &DeviceStore{store{}} + return &DeviceStore{store: store{}, deviceNameToUUIDLookup: make(map[string]uuid.UUID)} } // NewChangeStore returns a ChangeStore @@ -170,13 +171,33 @@ func (s PndStore) Get(id uuid.UUID) (PrincipalNetworkDomain, error) { // DeviceStore is used to store Devices type DeviceStore struct { + deviceNameToUUIDLookup map[string]uuid.UUID store } // Get takes a Device's UUID and returns the Device. If the requested // Device does not exist an error is returned. -func (s DeviceStore) Get(id uuid.UUID) (*Device, error) { - item, err := s.store.Get(id) +func (s DeviceStore) Get(id uuid.UUID, parseErrors ...error) (*Device, error) { + var foundID uuid.UUID + + foundID = id + + for _, parseErrs := range parseErrors { + if parseErrs != nil { + switch e := parseErrs.(type) { + case *errors.ErrInvalidUUID: + myID, ok := s.deviceNameToUUIDLookup[e.DeviceName] + if !ok { + log.Debug(fmt.Sprintf("no device named %s found", foundID)) + return nil, &errors.ErrNotFound{} + } + + foundID = myID + } + } + } + + item, err := s.store.Get(foundID) if err != nil { return nil, err } @@ -189,10 +210,72 @@ func (s DeviceStore) Get(id uuid.UUID) (*Device, error) { } log.WithFields(log.Fields{ "uuid": id, + "name": device.Name, }).Debug("device was accessed") + return device, nil } +// FromString is a helper to check if a provided string as a valid UUID or a name. +func FromString(id string) (uuid.UUID, error) { + idAsUUID, err := uuid.Parse(id) + + // id is no UUID therefore it could be a device name. + // The name will be returned within the error. + if err != nil { + log.WithFields(log.Fields{ + "identifier": id, + }).Debug(err) + return uuid.Nil, &errors.ErrInvalidUUID{DeviceName: id} + } + + return idAsUUID, nil +} + +// Add adds a device to the device store. +// It also adds the name of the device to the lookup table. +func (s DeviceStore) Add(item Storable, name string) error { + if s.Exists(item.ID()) { + return &errors.ErrAlreadyExists{Item: item} + } + + s.deviceNameToUUIDLookup[name] = item.ID() + + storeLock.Lock() + s.store[item.ID()] = item + storeLock.Unlock() + + log.WithFields(log.Fields{ + "type": reflect.TypeOf(item), + "uuid": item.ID(), + }).Debug("storable was added") + + return nil +} + +// Delete deletes a device from the device store. +func (s DeviceStore) Delete(id uuid.UUID) error { + if !s.Exists(id) { + return &errors.ErrNotFound{ID: id} + } + + storeLock.Lock() + delete(s.store, id) + storeLock.Unlock() + + for key, value := range s.deviceNameToUUIDLookup { + if value == id { + delete(s.deviceNameToUUIDLookup, key) + } + } + + log.WithFields(log.Fields{ + "uuid": id, + }).Debug("storable was deleted") + + return nil +} + // ChangeStore is used to store Changes type ChangeStore struct { store diff --git a/nucleus/store_test.go b/nucleus/store_test.go index f2db1ed61741fb75f4ab4360bc192610573f3697..18a13fd4cc1b08552fe030efb7e02a894fb73028 100644 --- a/nucleus/store_test.go +++ b/nucleus/store_test.go @@ -423,9 +423,11 @@ func Test_deviceStore_get(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := DeviceStore{ - store: tt.fields.store, + store: tt.fields.store, + deviceNameToUUIDLookup: make(map[string]uuid.UUID), } - got, err := s.Get(tt.args.id) + + got, err := s.Get(FromString(tt.args.id.String())) if (err != nil) != tt.wantErr { t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) return