From 5e949fc95526a86155f8d94465a22dd111670565 Mon Sep 17 00:00:00 2001 From: Matheus Macabu Date: Fri, 21 Nov 2025 16:31:17 +0100 Subject: [PATCH] Secrets: Fix secure value creation timestamp changing when updating it (#114290) --- go.mod | 2 +- .../garbagecollectionworker/worker_test.go | 26 +++++---- ...lue_get_latest_version_and_created_at.sql} | 4 +- pkg/storage/secret/metadata/query.go | 10 ++-- pkg/storage/secret/metadata/query_test.go | 4 +- .../secret/metadata/secure_value_model.go | 7 +-- .../secret/metadata/secure_value_store.go | 56 +++++++++++++------ .../metadata/secure_value_store_test.go | 4 +- .../secret/metadata/secure_value_test.go | 51 +++++++++-------- ...ed_at-get latest secure value version.sql} | 4 +- ...ed_at-get latest secure value version.sql} | 4 +- ...ed_at-get latest secure value version.sql} | 4 +- 12 files changed, 104 insertions(+), 72 deletions(-) rename pkg/storage/secret/metadata/data/{secure_value_get_latest_version.sql => secure_value_get_latest_version_and_created_at.sql} (72%) rename pkg/storage/secret/metadata/testdata/{mysql--secure_value_get_latest_version-get latest secure value version.sql => mysql--secure_value_get_latest_version_and_created_at-get latest secure value version.sql} (76%) rename pkg/storage/secret/metadata/testdata/{postgres--secure_value_get_latest_version-get latest secure value version.sql => postgres--secure_value_get_latest_version_and_created_at-get latest secure value version.sql} (76%) rename pkg/storage/secret/metadata/testdata/{sqlite--secure_value_get_latest_version-get latest secure value version.sql => sqlite--secure_value_get_latest_version_and_created_at-get latest secure value version.sql} (76%) diff --git a/go.mod b/go.mod index eb9780e649f..daab4218c91 100644 --- a/go.mod +++ b/go.mod @@ -139,7 +139,6 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // @grafana/alerting-backend github.com/microsoft/go-mssqldb v1.9.2 // @grafana/partner-datasources github.com/migueleliasweb/go-github-mock v1.1.0 // @grafana/grafana-git-ui-sync-team - github.com/mitchellh/copystructure v1.2.0 // @grafana/grafana-operator-experience-squad github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c //@grafana/identity-access-team github.com/mocktools/go-smtp-mock/v2 v2.5.1 // @grafana/grafana-backend-group github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // @grafana/alerting-backend @@ -515,6 +514,7 @@ require ( github.com/miekg/dns v1.1.63 // indirect github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect diff --git a/pkg/registry/apis/secret/garbagecollectionworker/worker_test.go b/pkg/registry/apis/secret/garbagecollectionworker/worker_test.go index 0b5a7614205..9b27aceefc1 100644 --- a/pkg/registry/apis/secret/garbagecollectionworker/worker_test.go +++ b/pkg/registry/apis/secret/garbagecollectionworker/worker_test.go @@ -1,7 +1,6 @@ package garbagecollectionworker_test import ( - "fmt" "slices" "testing" "time" @@ -11,7 +10,6 @@ import ( "github.com/grafana/grafana/pkg/registry/apis/secret/testutils" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/storage/secret/encryption" - "github.com/mitchellh/copystructure" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -133,7 +131,7 @@ func TestProperty(t *testing.T) { t.Repeat(map[string]func(*rapid.T){ "create": func(t *rapid.T) { sv := anySecureValueGen.Draw(t, "sv") - svCopy := deepCopy(sv) + svCopy := sv.DeepCopy() createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(sv)) svCopy.UID = createdSv.UID @@ -194,13 +192,15 @@ func newModel() *model { } func (m *model) create(now time.Time, sv *secretv1beta1.SecureValue) error { + created := now for _, item := range m.items { if item.active && item.Namespace == sv.Namespace && item.Name == sv.Name { item.active = false + created = item.created break } } - m.items = append(m.items, &modelSecureValue{SecureValue: sv, active: true, created: now}) + m.items = append(m.items, &modelSecureValue{SecureValue: sv, active: true, created: created}) return nil } @@ -219,6 +219,16 @@ func (m *model) cleanupInactiveSecureValues(now time.Time, minAge time.Duration, // Using a slice to allow duplicates toDelete := make([]*modelSecureValue, 0) + // The implementation query sorts by created time ascending + slices.SortFunc(m.items, func(a, b *modelSecureValue) int { + if a.created.Before(b.created) { + return -1 + } else if a.created.After(b.created) { + return 1 + } + return 0 + }) + for _, sv := range m.items { if len(toDelete) >= int(maxBatchSize) { break @@ -238,11 +248,3 @@ func (m *model) cleanupInactiveSecureValues(now time.Time, minAge time.Duration, return toDelete, nil } - -func deepCopy[T any](sv T) T { - copied, err := copystructure.Copy(sv) - if err != nil { - panic(fmt.Sprintf("failed to copy secure value: %v", err)) - } - return copied.(T) -} diff --git a/pkg/storage/secret/metadata/data/secure_value_get_latest_version.sql b/pkg/storage/secret/metadata/data/secure_value_get_latest_version_and_created_at.sql similarity index 72% rename from pkg/storage/secret/metadata/data/secure_value_get_latest_version.sql rename to pkg/storage/secret/metadata/data/secure_value_get_latest_version_and_created_at.sql index 90319d469eb..1c804c2d031 100644 --- a/pkg/storage/secret/metadata/data/secure_value_get_latest_version.sql +++ b/pkg/storage/secret/metadata/data/secure_value_get_latest_version_and_created_at.sql @@ -1,5 +1,7 @@ SELECT - {{ .Ident "version" }} + {{ .Ident "created" }}, + {{ .Ident "version" }}, + {{ .Ident "active" }} FROM {{ .Ident "secret_secure_value" }} WHERE diff --git a/pkg/storage/secret/metadata/query.go b/pkg/storage/secret/metadata/query.go index 8e35099a250..e8f84855e7f 100644 --- a/pkg/storage/secret/metadata/query.go +++ b/pkg/storage/secret/metadata/query.go @@ -34,9 +34,9 @@ var ( sqlSecureValueLeaseInactive = mustTemplate("secure_value_lease_inactive.sql") sqlSecureValueListByLeaseToken = mustTemplate("secure_value_list_by_lease_token.sql") - sqlGetLatestSecureValueVersion = mustTemplate("secure_value_get_latest_version.sql") - sqlSecureValueSetVersionToActive = mustTemplate("secure_value_set_version_to_active.sql") - sqlSecureValueSetVersionToInactive = mustTemplate("secure_value_set_version_to_inactive.sql") + sqlGetLatestSecureValueVersionAndCreatedAt = mustTemplate("secure_value_get_latest_version_and_created_at.sql") + sqlSecureValueSetVersionToActive = mustTemplate("secure_value_set_version_to_active.sql") + sqlSecureValueSetVersionToInactive = mustTemplate("secure_value_set_version_to_inactive.sql") ) func mustTemplate(filename string) *template.Template { @@ -171,13 +171,13 @@ func (r readSecureValue) Validate() error { return nil // TODO } -type getLatestSecureValueVersion struct { +type getLatestSecureValueVersionAndCreatedAt struct { sqltemplate.SQLTemplate Namespace string Name string } -func (r getLatestSecureValueVersion) Validate() error { +func (r getLatestSecureValueVersionAndCreatedAt) Validate() error { return nil } diff --git a/pkg/storage/secret/metadata/query_test.go b/pkg/storage/secret/metadata/query_test.go index 75cd970d382..108b9a6a1cd 100644 --- a/pkg/storage/secret/metadata/query_test.go +++ b/pkg/storage/secret/metadata/query_test.go @@ -141,10 +141,10 @@ func TestSecureValueQueries(t *testing.T) { mocks.CheckQuerySnapshots(t, mocks.TemplateTestSetup{ RootDir: "testdata", Templates: map[*template.Template][]mocks.TemplateTestCase{ - sqlGetLatestSecureValueVersion: { + sqlGetLatestSecureValueVersionAndCreatedAt: { { Name: "get latest secure value version", - Data: &getLatestSecureValueVersion{ + Data: &getLatestSecureValueVersionAndCreatedAt{ SQLTemplate: mocks.NewTestingSQLTemplate(), Name: "name", Namespace: "ns", diff --git a/pkg/storage/secret/metadata/secure_value_model.go b/pkg/storage/secret/metadata/secure_value_model.go index f514fa5f2d9..81ed2eb2849 100644 --- a/pkg/storage/secret/metadata/secure_value_model.go +++ b/pkg/storage/secret/metadata/secure_value_model.go @@ -122,17 +122,16 @@ func (sv *secureValueDB) toKubernetes() (*secretv1beta1.SecureValue, error) { } // toCreateRow maps a Kubernetes resource into a DB row for new resources being created/inserted. -func toCreateRow(now time.Time, keeper string, sv *secretv1beta1.SecureValue, actorUID string) (*secureValueDB, error) { +func toCreateRow(createdAt, updatedAt int64, keeper string, sv *secretv1beta1.SecureValue, actorUID string) (*secureValueDB, error) { row, err := toRow(keeper, sv, "") if err != nil { return nil, fmt.Errorf("failed to convert SecureValue to secureValueDB: %w", err) } - timestamp := now.UTC().Unix() row.GUID = uuid.New().String() - row.Created = timestamp + row.Created = createdAt row.CreatedBy = actorUID - row.Updated = timestamp + row.Updated = updatedAt row.UpdatedBy = actorUID return row, nil diff --git a/pkg/storage/secret/metadata/secure_value_store.go b/pkg/storage/secret/metadata/secure_value_store.go index 4463de00c9a..d3a137ea611 100644 --- a/pkg/storage/secret/metadata/secure_value_store.go +++ b/pkg/storage/secret/metadata/secure_value_store.go @@ -85,14 +85,14 @@ func (s *secureValueMetadataStorage) Create(ctx context.Context, keeper string, var row *secureValueDB err := s.db.Transaction(ctx, func(ctx context.Context) error { - latestVersion, err := s.getLatestVersion(ctx, xkube.Namespace(sv.Namespace), sv.Name) + latest, err := s.getLatestVersionAndCreatedAt(ctx, xkube.Namespace(sv.Namespace), sv.Name) if err != nil { return fmt.Errorf("fetching latest secure value version: %w", err) } version := int64(1) - if latestVersion != nil { - version = *latestVersion + 1 + if latest.version > 0 { + version = latest.version + 1 } // Some other concurrent request may have created the version we're trying to create, @@ -102,7 +102,15 @@ func (s *secureValueMetadataStorage) Create(ctx context.Context, keeper string, for { sv.Status.Version = version - row, err = toCreateRow(s.clock.Now(), keeper, sv, actorUID) + now := s.clock.Now().UTC().Unix() + + createdAt := now + if latest.createdAt > 0 { + createdAt = latest.createdAt + } + updatedAt := now + + row, err = toCreateRow(createdAt, updatedAt, keeper, sv, actorUID) if err != nil { return fmt.Errorf("to create row: %w", err) } @@ -153,44 +161,60 @@ func (s *secureValueMetadataStorage) Create(ctx context.Context, keeper string, return createdSecureValue, nil } -func (s *secureValueMetadataStorage) getLatestVersion(ctx context.Context, namespace xkube.Namespace, name string) (*int64, error) { - ctx, span := s.tracer.Start(ctx, "SecureValueMetadataStorage.getLatestVersion", trace.WithAttributes( +type versionAndCreatedAt struct { + createdAt int64 + version int64 +} + +func (s *secureValueMetadataStorage) getLatestVersionAndCreatedAt(ctx context.Context, namespace xkube.Namespace, name string) (versionAndCreatedAt, error) { + ctx, span := s.tracer.Start(ctx, "SecureValueMetadataStorage.getLatestVersionAndCreatedAt", trace.WithAttributes( attribute.String("name", name), attribute.String("namespace", namespace.String()), )) defer span.End() - req := getLatestSecureValueVersion{ + req := getLatestSecureValueVersionAndCreatedAt{ SQLTemplate: sqltemplate.New(s.dialect), Namespace: namespace.String(), Name: name, } - q, err := sqltemplate.Execute(sqlGetLatestSecureValueVersion, req) + q, err := sqltemplate.Execute(sqlGetLatestSecureValueVersionAndCreatedAt, req) if err != nil { - return nil, fmt.Errorf("execute template %q: %w", sqlGetLatestSecureValueVersion.Name(), err) + return versionAndCreatedAt{}, fmt.Errorf("execute template %q: %w", sqlGetLatestSecureValueVersionAndCreatedAt.Name(), err) } rows, err := s.db.QueryContext(ctx, q, req.GetArgs()...) if err != nil { - return nil, fmt.Errorf("fetching latest version for secure value: namespace=%+v name=%+v %w", namespace, name, err) + return versionAndCreatedAt{}, fmt.Errorf("fetching latest version for secure value: namespace=%+v name=%+v %w", namespace, name, err) } defer func() { _ = rows.Close() }() if err := rows.Err(); err != nil { - return nil, fmt.Errorf("error executing query: %w", err) + return versionAndCreatedAt{}, fmt.Errorf("error executing query: %w", err) } if !rows.Next() { - return nil, nil + return versionAndCreatedAt{}, nil } - var version int64 - if err := rows.Scan(&version); err != nil { - return nil, fmt.Errorf("scanning version from returned rows: %w", err) + var ( + createdAt int64 + version int64 + active bool + ) + if err := rows.Scan(&createdAt, &version, &active); err != nil { + return versionAndCreatedAt{}, fmt.Errorf("scanning version from returned rows: %w", err) } - return &version, nil + if !active { + createdAt = 0 + } + + return versionAndCreatedAt{ + createdAt: createdAt, + version: version, + }, nil } func (s *secureValueMetadataStorage) readActiveVersion(ctx context.Context, namespace xkube.Namespace, name string, opts contracts.ReadOpts) (secureValueDB, error) { diff --git a/pkg/storage/secret/metadata/secure_value_store_test.go b/pkg/storage/secret/metadata/secure_value_store_test.go index f1aeeaf9028..f7551e9e484 100644 --- a/pkg/storage/secret/metadata/secure_value_store_test.go +++ b/pkg/storage/secret/metadata/secure_value_store_test.go @@ -199,8 +199,8 @@ func TestPropertySecureValueMetadataStorage(t *testing.T) { t.Repeat(map[string]func(*rapid.T){ "create": func(t *rapid.T) { sv := anySecureValueGen.Draw(t, "sv") - modelCreatedSv, modelErr := model.create(sut.Clock.Now(), deepCopy(sv)) - createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(deepCopy(sv))) + modelCreatedSv, modelErr := model.create(sut.Clock.Now(), sv.DeepCopy()) + createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(sv.DeepCopy())) if err != nil || modelErr != nil { require.ErrorIs(t, err, modelErr) return diff --git a/pkg/storage/secret/metadata/secure_value_test.go b/pkg/storage/secret/metadata/secure_value_test.go index 8d7f318a9b5..0eba9bbf9ce 100644 --- a/pkg/storage/secret/metadata/secure_value_test.go +++ b/pkg/storage/secret/metadata/secure_value_test.go @@ -6,7 +6,6 @@ import ( "testing" "time" - "github.com/mitchellh/copystructure" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" @@ -81,8 +80,15 @@ func (m *model) readActiveVersion(namespace, name string) *modelSecureValue { func (m *model) create(now time.Time, sv *secretv1beta1.SecureValue) (*secretv1beta1.SecureValue, error) { keeper := m.getActiveKeeper(sv.Namespace) - sv = deepCopy(sv) - modelSv := &modelSecureValue{SecureValue: sv, active: false, created: now} + sv = sv.DeepCopy() + + // Preserve the original creation time if this secure value already exists + created := now + if sv := m.readActiveVersion(sv.Namespace, sv.Name); sv != nil { + created = sv.created + } + + modelSv := &modelSecureValue{SecureValue: sv, active: false, created: created} modelSv.Status.Version = m.getNewVersionNumber(modelSv.Namespace, modelSv.Name) modelSv.Status.ExternalID = fmt.Sprintf("%d", modelSv.Status.Version) modelSv.Status.Keeper = keeper.name @@ -126,7 +132,7 @@ func (m *model) createKeeper(keeper *secretv1beta1.Keeper) (*secretv1beta1.Keepe m.keepers = append(m.keepers, &modelKeeper{namespace: keeper.Namespace, name: keeper.Name}) - return deepCopy(keeper), nil + return keeper.DeepCopy(), nil } func (m *model) setKeeperAsActive(namespace, keeperName string) error { @@ -196,7 +202,7 @@ func (m *model) decrypt(decrypter, namespace, name string) (map[string]decrypt.D v.active { if slices.ContainsFunc(v.Spec.Decrypters, func(d string) bool { return d == decrypter }) { return map[string]decrypt.DecryptResult{ - name: decrypt.NewDecryptResultValue(deepCopy(v).Spec.Value), + name: decrypt.NewDecryptResultValue(v.DeepCopy().Spec.Value), }, nil } @@ -328,14 +334,14 @@ func TestModel(t *testing.T) { now := time.Now() // Create a secure value - sv1, err := m.create(now, deepCopy(sv)) + sv1, err := m.create(now, sv.DeepCopy()) require.NoError(t, err) require.Equal(t, sv.Namespace, sv1.Namespace) require.Equal(t, sv.Name, sv1.Name) require.EqualValues(t, 1, sv1.Status.Version) // Create a new version of a secure value - sv2, err := m.create(now, deepCopy(sv)) + sv2, err := m.create(now, sv.DeepCopy()) require.NoError(t, err) require.Equal(t, sv.Namespace, sv2.Namespace) require.Equal(t, sv.Name, sv2.Name) @@ -349,25 +355,25 @@ func TestModel(t *testing.T) { now := time.Now() - sv1, err := m.create(now, deepCopy(sv)) + sv1, err := m.create(now, sv.DeepCopy()) require.NoError(t, err) // Create a new version of a secure value by updating it - sv2, _, err := m.update(now, deepCopy(sv1)) + sv2, _, err := m.update(now, sv1.DeepCopy()) require.NoError(t, err) require.Equal(t, sv.Namespace, sv2.Namespace) require.Equal(t, sv.Name, sv2.Name) require.EqualValues(t, 2, sv2.Status.Version) // Try updating a secure value that doesn't exist without specifying a value for it - sv3 := deepCopy(sv2) + sv3 := sv2.DeepCopy() sv3.Name = "i_dont_exist" sv3.Spec.Value = nil _, _, err = m.update(now, sv3) require.ErrorIs(t, err, contracts.ErrSecureValueNotFound) // Updating a value that doesn't exist creates a new version - sv4 := deepCopy(sv3) + sv4 := sv3.DeepCopy() sv4.Name = "i_dont_exist" sv4.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue("sv4")) _, _, err = m.update(now, sv4) @@ -380,7 +386,7 @@ func TestModel(t *testing.T) { m := newModel() now := time.Now() - sv1, err := m.create(now, deepCopy(sv)) + sv1, err := m.create(now, sv.DeepCopy()) require.NoError(t, err) // Deleting a secure value @@ -407,7 +413,7 @@ func TestModel(t *testing.T) { require.Equal(t, 0, len(list.Items)) // Create a secure value - sv1, err := m.create(now, deepCopy(sv)) + sv1, err := m.create(now, sv.DeepCopy()) require.NoError(t, err) // 1 secure value exists and it should be returned @@ -434,7 +440,7 @@ func TestModel(t *testing.T) { // Create a secure value secret := "v1" - sv1, err := m.create(now, deepCopy(sv)) + sv1, err := m.create(now, sv.DeepCopy()) require.NoError(t, err) // Decrypt the just created secure value @@ -459,8 +465,9 @@ func TestStateMachine(t *testing.T) { "create": func(t *rapid.T) { sv := anySecureValueGen.Draw(t, "sv") - modelCreatedSv, modelErr := model.create(sut.Clock.Now(), deepCopy(sv)) - createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(deepCopy(sv))) + modelCreatedSv, modelErr := model.create(sut.Clock.Now(), sv.DeepCopy()) + + createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(sv.DeepCopy())) if err != nil || modelErr != nil { require.ErrorIs(t, err, modelErr) return @@ -471,8 +478,8 @@ func TestStateMachine(t *testing.T) { }, "update": func(t *rapid.T) { sv := updateSecureValueGen.Draw(t, "sv") - modelCreatedSv, _, modelErr := model.update(sut.Clock.Now(), deepCopy(sv)) - createdSv, err := sut.UpdateSv(t.Context(), deepCopy(sv)) + modelCreatedSv, _, modelErr := model.update(sut.Clock.Now(), sv.DeepCopy()) + createdSv, err := sut.UpdateSv(t.Context(), sv.DeepCopy()) if err != nil || modelErr != nil { require.ErrorIs(t, err, modelErr) return @@ -656,11 +663,3 @@ func TestSecureValueServiceExampleBased(t *testing.T) { require.Equal(t, newSv1.Spec.Description, updatedSv.Spec.Description) }) } - -func deepCopy[T any](sv T) T { - copied, err := copystructure.Copy(sv) - if err != nil { - panic(fmt.Sprintf("failed to copy secure value: %v", err)) - } - return copied.(T) -} diff --git a/pkg/storage/secret/metadata/testdata/mysql--secure_value_get_latest_version-get latest secure value version.sql b/pkg/storage/secret/metadata/testdata/mysql--secure_value_get_latest_version_and_created_at-get latest secure value version.sql similarity index 76% rename from pkg/storage/secret/metadata/testdata/mysql--secure_value_get_latest_version-get latest secure value version.sql rename to pkg/storage/secret/metadata/testdata/mysql--secure_value_get_latest_version_and_created_at-get latest secure value version.sql index 8118fc81489..661c6474221 100755 --- a/pkg/storage/secret/metadata/testdata/mysql--secure_value_get_latest_version-get latest secure value version.sql +++ b/pkg/storage/secret/metadata/testdata/mysql--secure_value_get_latest_version_and_created_at-get latest secure value version.sql @@ -1,5 +1,7 @@ SELECT - `version` + `created`, + `version`, + `active` FROM `secret_secure_value` WHERE diff --git a/pkg/storage/secret/metadata/testdata/postgres--secure_value_get_latest_version-get latest secure value version.sql b/pkg/storage/secret/metadata/testdata/postgres--secure_value_get_latest_version_and_created_at-get latest secure value version.sql similarity index 76% rename from pkg/storage/secret/metadata/testdata/postgres--secure_value_get_latest_version-get latest secure value version.sql rename to pkg/storage/secret/metadata/testdata/postgres--secure_value_get_latest_version_and_created_at-get latest secure value version.sql index 1549114582d..e1c3834ecbb 100755 --- a/pkg/storage/secret/metadata/testdata/postgres--secure_value_get_latest_version-get latest secure value version.sql +++ b/pkg/storage/secret/metadata/testdata/postgres--secure_value_get_latest_version_and_created_at-get latest secure value version.sql @@ -1,5 +1,7 @@ SELECT - "version" + "created", + "version", + "active" FROM "secret_secure_value" WHERE diff --git a/pkg/storage/secret/metadata/testdata/sqlite--secure_value_get_latest_version-get latest secure value version.sql b/pkg/storage/secret/metadata/testdata/sqlite--secure_value_get_latest_version_and_created_at-get latest secure value version.sql similarity index 76% rename from pkg/storage/secret/metadata/testdata/sqlite--secure_value_get_latest_version-get latest secure value version.sql rename to pkg/storage/secret/metadata/testdata/sqlite--secure_value_get_latest_version_and_created_at-get latest secure value version.sql index 1549114582d..e1c3834ecbb 100755 --- a/pkg/storage/secret/metadata/testdata/sqlite--secure_value_get_latest_version-get latest secure value version.sql +++ b/pkg/storage/secret/metadata/testdata/sqlite--secure_value_get_latest_version_and_created_at-get latest secure value version.sql @@ -1,5 +1,7 @@ SELECT - "version" + "created", + "version", + "active" FROM "secret_secure_value" WHERE