Secrets: Update inline delete when owned to take multiple names (#109227)

* Secrets: Update proto inline secure values to take variadic names on delete

* Secrets: Update inline delete when owned to take multiple names

* trigger CI
This commit is contained in:
Matheus Macabu
2025-08-06 11:45:03 +02:00
committed by GitHub
parent d8360c4e12
commit c9daccfd28
7 changed files with 106 additions and 61 deletions
+1 -1
View File
@@ -15,5 +15,5 @@ type InlineSecureValueSupport interface {
CreateInline(ctx context.Context, owner common.ObjectReference, value common.RawSecureValue) (string, error)
// DeleteWhenOwnedByResource removes secrets if and only if they are owned by a referenced object
DeleteWhenOwnedByResource(ctx context.Context, owner common.ObjectReference, name string) error
DeleteWhenOwnedByResource(ctx context.Context, owner common.ObjectReference, names ...string) error
}
@@ -156,7 +156,7 @@ func (g *GRPCInlineClient) CreateInline(ctx context.Context, owner v0alpha1.Obje
return resp.GetName(), nil
}
func (g *GRPCInlineClient) DeleteWhenOwnedByResource(ctx context.Context, owner v0alpha1.ObjectReference, name string) error {
func (g *GRPCInlineClient) DeleteWhenOwnedByResource(ctx context.Context, owner v0alpha1.ObjectReference, names ...string) error {
client, err := g.getClient(owner.Namespace)
if err != nil {
return err
@@ -170,7 +170,7 @@ func (g *GRPCInlineClient) DeleteWhenOwnedByResource(ctx context.Context, owner
Namespace: owner.Namespace,
Name: owner.Name,
},
Name: name,
Names: names,
}
_, err = client.DeleteWhenOwnedByResource(ctx, req)
@@ -26,6 +26,8 @@ type LocalInlineSecureValueService struct {
accessChecker authlib.AccessChecker
}
var _ contracts.InlineSecureValueSupport = &LocalInlineSecureValueService{}
func NewLocalInlineSecureValueService(
tracer trace.Tracer,
secureValueService contracts.SecureValueService,
@@ -219,14 +221,14 @@ func (s *LocalInlineSecureValueService) CreateInline(ctx context.Context, owner
return createdSv.GetName(), nil
}
func (s *LocalInlineSecureValueService) DeleteWhenOwnedByResource(ctx context.Context, owner common.ObjectReference, name string) error {
func (s *LocalInlineSecureValueService) DeleteWhenOwnedByResource(ctx context.Context, owner common.ObjectReference, names ...string) error {
ctx, span := s.tracer.Start(ctx, "InlineSecureValueService.DeleteWhenOwnedByResource", trace.WithAttributes(
attribute.String("owner.namespace", owner.Namespace),
attribute.String("owner.apiGroup", owner.APIGroup),
attribute.String("owner.apiVersion", owner.APIVersion),
attribute.String("owner.kind", owner.Kind),
attribute.String("owner.name", owner.Name),
attribute.String("secureValue.name", name),
attribute.StringSlice("secureValueNames", names),
))
defer span.End()
@@ -243,17 +245,18 @@ func (s *LocalInlineSecureValueService) DeleteWhenOwnedByResource(ctx context.Co
return fmt.Errorf("owner reference must have a valid API group, API version, kind and name")
}
owned, err := s.isSecureValueOwnedByResource(ctx, owner, name)
if err != nil {
return fmt.Errorf("error checking if secure value %s is owned by %v: %w", name, owner, err)
}
for _, name := range names {
owned, err := s.isSecureValueOwnedByResource(ctx, owner, name)
if err != nil {
return fmt.Errorf("error checking if secure value %s is owned by %v: %w", name, owner, err)
}
if owned {
if _, err := s.secureValueService.Delete(ctx, xkube.Namespace(owner.Namespace), name); err != nil {
return fmt.Errorf("error deleting secure value %s for owner %v: %w", name, owner, err)
if owned {
if _, err := s.secureValueService.Delete(ctx, xkube.Namespace(owner.Namespace), name); err != nil {
return fmt.Errorf("error deleting secure value %s for owner %v: %w", name, owner, err)
}
}
}
// if it is not owned, this is a no-op
return nil
}
@@ -507,4 +507,31 @@ func TestIntegration_InlineSecureValue_DeleteWhenOwnedByResource(t *testing.T) {
require.NotNil(t, sv)
require.Equal(t, sv1, sv.GetName())
})
t.Run("when a secure value is owned and exists but another one doesnt, it deletes the first one but returns an error", func(t *testing.T) {
t.Parallel()
tu := testutils.Setup(t)
sv1 := "test-secure-value-1"
createdSv1, err := tu.CreateSv(t.Context(), func(cfg *testutils.CreateSvConfig) {
cfg.Sv.Name = sv1
cfg.Sv.Namespace = defaultNs
cfg.Sv.OwnerReferences = []metav1.OwnerReference{owner.ToOwnerReference()}
})
require.NoError(t, err)
require.NotNil(t, createdSv1)
svc := inline.NewLocalInlineSecureValueService(tracer, tu.SecureValueService, nil)
ctx := testutils.CreateServiceAuthContext(t.Context(), "", defaultNs, nil)
err = svc.DeleteWhenOwnedByResource(ctx, owner, sv1, "does-not-exist")
require.ErrorIs(t, err, contracts.ErrSecureValueNotFound)
// got deleted
sv, err := tu.SecureValueService.Read(ctx, xkube.Namespace(owner.Namespace), sv1)
require.ErrorIs(t, err, contracts.ErrSecureValueNotFound)
require.Nil(t, sv)
})
}
+25 -11
View File
@@ -143,17 +143,24 @@ func (_c *MockInlineSecureValueSupport_CreateInline_Call) RunAndReturn(run func(
return _c
}
// DeleteWhenOwnedByResource provides a mock function with given fields: ctx, owner, name
func (_m *MockInlineSecureValueSupport) DeleteWhenOwnedByResource(ctx context.Context, owner v0alpha1.ObjectReference, name string) error {
ret := _m.Called(ctx, owner, name)
// DeleteWhenOwnedByResource provides a mock function with given fields: ctx, owner, names
func (_m *MockInlineSecureValueSupport) DeleteWhenOwnedByResource(ctx context.Context, owner v0alpha1.ObjectReference, names ...string) error {
_va := make([]interface{}, len(names))
for _i := range names {
_va[_i] = names[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, owner)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for DeleteWhenOwnedByResource")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, v0alpha1.ObjectReference, string) error); ok {
r0 = rf(ctx, owner, name)
if rf, ok := ret.Get(0).(func(context.Context, v0alpha1.ObjectReference, ...string) error); ok {
r0 = rf(ctx, owner, names...)
} else {
r0 = ret.Error(0)
}
@@ -169,14 +176,21 @@ type MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call struct {
// DeleteWhenOwnedByResource is a helper method to define mock.On call
// - ctx context.Context
// - owner v0alpha1.ObjectReference
// - name string
func (_e *MockInlineSecureValueSupport_Expecter) DeleteWhenOwnedByResource(ctx interface{}, owner interface{}, name interface{}) *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call {
return &MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call{Call: _e.mock.On("DeleteWhenOwnedByResource", ctx, owner, name)}
// - names ...string
func (_e *MockInlineSecureValueSupport_Expecter) DeleteWhenOwnedByResource(ctx interface{}, owner interface{}, names ...interface{}) *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call {
return &MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call{Call: _e.mock.On("DeleteWhenOwnedByResource",
append([]interface{}{ctx, owner}, names...)...)}
}
func (_c *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call) Run(run func(ctx context.Context, owner v0alpha1.ObjectReference, name string)) *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call {
func (_c *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call) Run(run func(ctx context.Context, owner v0alpha1.ObjectReference, names ...string)) *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(v0alpha1.ObjectReference), args[2].(string))
variadicArgs := make([]string, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(string)
}
}
run(args[0].(context.Context), args[1].(v0alpha1.ObjectReference), variadicArgs...)
})
return _c
}
@@ -186,7 +200,7 @@ func (_c *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call) Return(_a
return _c
}
func (_c *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call) RunAndReturn(run func(context.Context, v0alpha1.ObjectReference, string) error) *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call {
func (_c *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call) RunAndReturn(run func(context.Context, v0alpha1.ObjectReference, ...string) error) *MockInlineSecureValueSupport_DeleteWhenOwnedByResource_Call {
_c.Call.Return(run)
return _c
}