diff --git a/lib/backend/dynamo/dynamodbbk.go b/lib/backend/dynamo/dynamodbbk.go index 3aef1d04b7c2d..44772550310a9 100644 --- a/lib/backend/dynamo/dynamodbbk.go +++ b/lib/backend/dynamo/dynamodbbk.go @@ -837,7 +837,7 @@ const ( // prependPrefix adds leading 'teleport/' to the key for backwards compatibility // with previous implementation of DynamoDB backend func prependPrefix(key backend.Key) string { - return keyPrefix + string(key) + return keyPrefix + key.String() } // trimPrefix removes leading 'teleport' from the key diff --git a/lib/backend/dynamo/dynamodbbk_test.go b/lib/backend/dynamo/dynamodbbk_test.go index 0688990279d77..ce0420e00f1fc 100644 --- a/lib/backend/dynamo/dynamodbbk_test.go +++ b/lib/backend/dynamo/dynamodbbk_test.go @@ -29,6 +29,7 @@ import ( "github.com/gravitational/trace" "github.com/jonboulle/clockwork" log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/lib/backend" @@ -214,3 +215,21 @@ func TestCreateTable(t *testing.T) { }) } } + +func TestKeyPrefix(t *testing.T) { + t.Run("leading separator in key", func(t *testing.T) { + prefixed := prependPrefix(backend.NewKey("test", "llama")) + assert.Equal(t, "teleport/test/llama", prefixed) + + key := trimPrefix(prefixed) + assert.Equal(t, "/test/llama", key.String()) + }) + + t.Run("no leading separator in key", func(t *testing.T) { + prefixed := prependPrefix(backend.Key(".locks/test/llama")) + assert.Equal(t, "teleport.locks/test/llama", prefixed) + + key := trimPrefix(prefixed) + assert.Equal(t, ".locks/test/llama", key.String()) + }) +} diff --git a/lib/backend/etcdbk/etcd.go b/lib/backend/etcdbk/etcd.go index 68e0e7267f668..02cd015e7c1fc 100644 --- a/lib/backend/etcdbk/etcd.go +++ b/lib/backend/etcdbk/etcd.go @@ -1016,10 +1016,10 @@ func fromType(eventType mvccpb.Event_EventType) types.OpType { } } -func (b *EtcdBackend) trimPrefix(in backend.Key) backend.Key { - return in.TrimPrefix(backend.Key(b.cfg.Key)) +func (b *EtcdBackend) trimPrefix(in []byte) backend.Key { + return backend.Key(in).TrimPrefix(backend.Key(b.cfg.Key)) } func (b *EtcdBackend) prependPrefix(in backend.Key) string { - return b.cfg.Key + string(in) + return b.cfg.Key + in.String() } diff --git a/lib/backend/etcdbk/etcd_test.go b/lib/backend/etcdbk/etcd_test.go index df1f76f1326ef..bd48c7184be3d 100644 --- a/lib/backend/etcdbk/etcd_test.go +++ b/lib/backend/etcdbk/etcd_test.go @@ -26,6 +26,7 @@ import ( "github.com/gravitational/trace" "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/lib/backend" @@ -255,3 +256,29 @@ func etcdTestEndpoint() string { } return "https://127.0.0.1:2379" } + +func TestKeyPrefix(t *testing.T) { + prefixes := []string{"teleport", "/teleport", "/teleport/"} + + for _, prefix := range prefixes { + t.Run("prefix="+prefix, func(t *testing.T) { + bk := EtcdBackend{cfg: &Config{Key: prefix}} + + t.Run("leading separator in key", func(t *testing.T) { + prefixed := bk.prependPrefix(backend.NewKey("test", "llama")) + assert.Equal(t, prefix+"/test/llama", prefixed) + + key := bk.trimPrefix([]byte(prefixed)) + assert.Equal(t, "/test/llama", key.String()) + }) + + t.Run("no leading separator in key", func(t *testing.T) { + prefixed := bk.prependPrefix(backend.Key(".locks/test/llama")) + assert.Equal(t, prefix+".locks/test/llama", prefixed) + + key := bk.trimPrefix([]byte(prefixed)) + assert.Equal(t, ".locks/test/llama", key.String()) + }) + }) + } +} diff --git a/lib/backend/helpers.go b/lib/backend/lock.go similarity index 100% rename from lib/backend/helpers.go rename to lib/backend/lock.go diff --git a/lib/backend/helpers_test.go b/lib/backend/lock_test.go similarity index 88% rename from lib/backend/helpers_test.go rename to lib/backend/lock_test.go index 496c476d674ca..822ede66236f0 100644 --- a/lib/backend/helpers_test.go +++ b/lib/backend/lock_test.go @@ -21,9 +21,24 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +func TestLockKey(t *testing.T) { + t.Run("empty parts", func(t *testing.T) { + key := lockKey() + assert.Equal(t, ".locks", key.String()) + assert.Equal(t, [][]byte{[]byte(".locks")}, key.Components()) + }) + + t.Run("with parts", func(t *testing.T) { + key := lockKey("test", "llama") + assert.Equal(t, ".locks/test/llama", key.String()) + assert.Equal(t, [][]byte{[]byte(".locks"), []byte("test"), []byte("llama")}, key.Components()) + }) +} + func TestLockConfiguration_CheckAndSetDefaults(t *testing.T) { type mockBackend struct { Backend