Secrets manager: create secure value using the active keeper (#114039)

* Secrets manager: create secure value using the active keeper

* SecureValueService.Update: fetch secure value from db to get the keeper

* fix keeper_store_test.go

* SecureValueService: fix bug in update where the current version keeper wasn't being passed to the createNewVersion method

* make gofmt

* remove outdated test

* update TestModel

* undo enterprise_imports changes

* use xkube.Namespace

* migrator: set secret_secure_value.keeper to 'system' when the column is null

* indent cue

* fix tests

* fix enterprise imports

* properly fix enterprise imports

* make update-workspace

* go mod tidy

---------

Co-authored-by: Matheus Macabu <macabu.matheus@gmail.com>
This commit is contained in:
Bruno
2025-11-21 11:20:16 -03:00
committed by GitHub
co-authored by Matheus Macabu
parent 133677d1d6
commit 0d67442f1a
33 changed files with 647 additions and 196 deletions
@@ -41,6 +41,10 @@ func (v *keeperValidator) Validate(keeper *secretv1beta1.Keeper, oldKeeper *secr
return errs
}
if keeper.Name == contracts.SystemKeeperName {
errs = append(errs, field.Forbidden(field.NewPath("name"), "the keeper name `system` is reserved"))
}
if keeper.Spec.Description == "" {
errs = append(errs, field.Required(field.NewPath("spec", "description"), "a `description` is required"))
}
@@ -35,36 +35,6 @@ func TestValidateKeeper(t *testing.T) {
})
})
t.Run("only one `keeper` must be present", func(t *testing.T) {
keeper := &secretv1beta1.Keeper{
ObjectMeta: objectMeta,
Spec: secretv1beta1.KeeperSpec{
Description: "short description",
Aws: &secretv1beta1.KeeperAWSConfig{},
Azure: &secretv1beta1.KeeperAzureConfig{},
Gcp: &secretv1beta1.KeeperGCPConfig{},
HashiCorpVault: &secretv1beta1.KeeperHashiCorpConfig{},
},
}
errs := validator.Validate(keeper, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
})
t.Run("at least one `keeper` must be present", func(t *testing.T) {
keeper := &secretv1beta1.Keeper{
ObjectMeta: objectMeta,
Spec: secretv1beta1.KeeperSpec{
Description: "description",
},
}
errs := validator.Validate(keeper, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
})
t.Run("aws keeper validation", func(t *testing.T) {
validKeeperAWS := &secretv1beta1.Keeper{
ObjectMeta: objectMeta,
@@ -341,4 +311,27 @@ func TestValidateKeeper(t *testing.T) {
require.Len(t, errs, 1)
require.Equal(t, "metadata.namespace", errs[0].Field)
})
t.Run("keeper name `system` is reserved", func(t *testing.T) {
keeper := &secretv1beta1.Keeper{
ObjectMeta: metav1.ObjectMeta{
Name: "system",
Namespace: "ns1",
},
Spec: secretv1beta1.KeeperSpec{
Description: "description",
HashiCorpVault: &secretv1beta1.KeeperHashiCorpConfig{
Address: "http://address",
Token: secretv1beta1.KeeperCredentialValue{
ValueFromConfig: "config.path.value",
},
},
},
}
errs := validator.Validate(keeper, nil, admission.Create)
require.Len(t, errs, 1)
require.Equal(t, "name", errs[0].Field)
require.Equal(t, "the keeper name `system` is reserved", errs[0].Detail)
})
}
@@ -110,11 +110,6 @@ func validateSecureValueUpdate(sv, oldSv *secretv1beta1.SecureValue) field.Error
}
}
// Keeper cannot be changed.
if sv.Spec.Keeper != oldSv.Spec.Keeper {
errs = append(errs, field.Forbidden(field.NewPath("spec"), "the `keeper` cannot be changed"))
}
return errs
}
@@ -25,9 +25,9 @@ func TestValidateSecureValue(t *testing.T) {
Spec: secretv1beta1.SecureValueSpec{
Description: "description",
Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")),
Keeper: &keeper,
Decrypters: []string{"app1", "app2"},
},
Status: secretv1beta1.SecureValueStatus{Keeper: keeper},
}
t.Run("the `description` must be present", func(t *testing.T) {
@@ -182,28 +182,6 @@ func TestValidateSecureValue(t *testing.T) {
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
})
t.Run("when trying to change the `keeper`, it returns an error", func(t *testing.T) {
keeperA := "a-keeper"
keeperAnother := "another-keeper"
oldSv := &secretv1beta1.SecureValue{
ObjectMeta: objectMeta,
Spec: secretv1beta1.SecureValueSpec{
Keeper: &keeperA,
},
}
sv := &secretv1beta1.SecureValue{
ObjectMeta: objectMeta,
Spec: secretv1beta1.SecureValueSpec{
Keeper: &keeperAnother,
},
}
errs := validator.Validate(sv, oldSv, admission.Update)
require.Len(t, errs, 1)
require.Equal(t, "spec", errs[0].Field)
})
})
t.Run("`decrypters` must have unique items", func(t *testing.T) {