561 lines
17 KiB
Go
561 lines
17 KiB
Go
package inline_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"go.opentelemetry.io/otel/trace/noop"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
|
|
"github.com/grafana/grafana/pkg/registry/apis/secret/inline"
|
|
"github.com/grafana/grafana/pkg/registry/apis/secret/testutils"
|
|
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
|
|
)
|
|
|
|
func TestIntegration_InlineSecureValue_CanReference(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tracer := noop.NewTracerProvider().Tracer("test")
|
|
|
|
defaultNs := "org-1234"
|
|
owner := common.ObjectReference{
|
|
APIGroup: "prometheus.datasource.grafana.app",
|
|
APIVersion: "v1alpha1",
|
|
Kind: "DataSourceConfig",
|
|
Name: "test-datasource",
|
|
Namespace: defaultNs,
|
|
}
|
|
|
|
t.Run("happy path with owned and shared secure values", 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)
|
|
|
|
sv2 := "test-secure-value-2"
|
|
createdSv2, err := tu.CreateSv(t.Context(), func(cfg *testutils.CreateSvConfig) {
|
|
cfg.Sv.Name = sv2
|
|
cfg.Sv.Namespace = defaultNs
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, createdSv2)
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{
|
|
"securevalues:read": {"securevalues:uid:" + sv2},
|
|
})
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, tu.SecureValueService, tu.AccessClient)
|
|
|
|
err = svc.CanReference(ctx, owner, sv1, sv2)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("when the auth info is missing it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
err := svc.CanReference(t.Context(), common.ObjectReference{})
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner namespace does not match auth info namespace it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
reqNs := "org-2345"
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), reqNs, map[string][]string{})
|
|
|
|
err := svc.CanReference(ctx, owner)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner namespace is empty it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{})
|
|
|
|
err := svc.CanReference(ctx, common.ObjectReference{})
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner reference has empty fields it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
owner := common.ObjectReference{
|
|
Namespace: defaultNs,
|
|
}
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{})
|
|
|
|
err := svc.CanReference(ctx, owner)
|
|
require.Error(t, err)
|
|
|
|
owner.APIGroup = "prometheus.datasource.grafana.app"
|
|
require.Error(t, svc.CanReference(ctx, owner))
|
|
owner.APIGroup = ""
|
|
|
|
owner.APIVersion = "v1alpha1"
|
|
require.Error(t, svc.CanReference(ctx, owner))
|
|
owner.APIVersion = ""
|
|
|
|
owner.Kind = "DataSourceConfig"
|
|
require.Error(t, svc.CanReference(ctx, owner))
|
|
owner.Kind = ""
|
|
|
|
owner.Name = "test-datasource"
|
|
require.Error(t, svc.CanReference(ctx, owner))
|
|
owner.Name = ""
|
|
})
|
|
|
|
t.Run("when no secure values are provided it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{})
|
|
|
|
err := svc.CanReference(ctx, owner)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the secure value does not exist, it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tu := testutils.Setup(t)
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, tu.SecureValueService, nil)
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{})
|
|
|
|
err := svc.CanReference(ctx, owner, "non-existent-sv")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the secure value is owned by a different resource, it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tu := testutils.Setup(t)
|
|
|
|
differentOwner := common.ObjectReference{
|
|
APIGroup: "prometheus.datasource.grafana.app",
|
|
APIVersion: "v1alpha1",
|
|
Kind: "DataSourceConfig",
|
|
Name: "different-datasource",
|
|
Namespace: defaultNs,
|
|
}
|
|
|
|
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{differentOwner.ToOwnerReference()}
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, createdSv1)
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{})
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, tu.SecureValueService, nil)
|
|
|
|
err = svc.CanReference(ctx, owner, sv1)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the request identity is not a user nor a service account, it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tu := testutils.Setup(t)
|
|
|
|
sv1 := "test-secure-value-1"
|
|
_, err := tu.CreateSv(t.Context(), func(cfg *testutils.CreateSvConfig) {
|
|
cfg.Sv.Name = sv1
|
|
cfg.Sv.Namespace = defaultNs
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
ctx := identity.WithServiceIdentityContext(t.Context(), 1234)
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, tu.SecureValueService, nil)
|
|
|
|
err = svc.CanReference(ctx, owner, sv1)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the identity does not have permissions to read the secure value, it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tu := testutils.Setup(t)
|
|
|
|
sv1 := "test-secure-value-1"
|
|
_, err := tu.CreateSv(t.Context(), func(cfg *testutils.CreateSvConfig) {
|
|
cfg.Sv.Name = sv1
|
|
cfg.Sv.Namespace = defaultNs
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, tu.SecureValueService, tu.AccessClient)
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{
|
|
"securevalues:read": {"securevalues:uid:another-sv"}, // can read, but another resource!
|
|
})
|
|
|
|
err = svc.CanReference(ctx, owner, sv1)
|
|
require.Error(t, err)
|
|
|
|
ctx = testutils.CreateUserAuthContext(t.Context(), defaultNs, nil)
|
|
|
|
err = svc.CanReference(ctx, owner, sv1)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestIntegration_InlineSecureValue_CreateInline(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tracer := noop.NewTracerProvider().Tracer("test")
|
|
|
|
defaultNs := "org-1234"
|
|
owner := common.ObjectReference{
|
|
APIGroup: "prometheus.datasource.grafana.app",
|
|
APIVersion: "v1alpha1",
|
|
Kind: "DataSourceConfig",
|
|
Name: "test-datasource",
|
|
Namespace: defaultNs,
|
|
}
|
|
|
|
t.Run("happy path creates an inline secure value", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tu := testutils.Setup(t)
|
|
|
|
rawSecret := "test-value"
|
|
secret := common.NewSecretValue(rawSecret)
|
|
|
|
serviceIdentity := "service-identity"
|
|
|
|
createAuthCtx := testutils.CreateOBOAuthContext(t.Context(), serviceIdentity, owner.Namespace, nil, nil)
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, tu.SecureValueService, nil)
|
|
|
|
createdName, err := svc.CreateInline(createAuthCtx, owner, secret)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, createdName)
|
|
|
|
decryptedValues, err := tu.DecryptService.Decrypt(t.Context(), serviceIdentity, owner.Namespace, createdName)
|
|
require.NoError(t, err)
|
|
|
|
decryptedResult, ok := decryptedValues[createdName]
|
|
require.True(t, ok)
|
|
require.Equal(t, decryptedResult.Value().DangerouslyExposeAndConsumeValue(), rawSecret)
|
|
|
|
// can also decrypt with the owner.APIGroup as a decrypter
|
|
decryptedValues, err = tu.DecryptService.Decrypt(t.Context(), owner.APIGroup, owner.Namespace, createdName)
|
|
require.NoError(t, err)
|
|
|
|
decryptedResult, ok = decryptedValues[createdName]
|
|
require.True(t, ok)
|
|
require.Equal(t, decryptedResult.Value().DangerouslyExposeAndConsumeValue(), rawSecret)
|
|
|
|
// Ignores empty values and duplicates
|
|
decryptedValues, err = tu.DecryptService.Decrypt(t.Context(), owner.APIGroup, owner.Namespace,
|
|
"", createdName, "", createdName, "") // Empty and duplicate requested names
|
|
require.NoError(t, err)
|
|
require.Len(t, decryptedValues, 1)
|
|
_, ok = decryptedValues[createdName]
|
|
require.True(t, ok)
|
|
|
|
// empty request
|
|
decryptedValues, err = tu.DecryptService.Decrypt(t.Context(), owner.APIGroup, owner.Namespace, "")
|
|
require.NoError(t, err)
|
|
require.Len(t, decryptedValues, 0) // << empty
|
|
})
|
|
|
|
t.Run("when the auth info is missing it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
_, err := svc.CreateInline(t.Context(), common.ObjectReference{}, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the request identity is not a user nor a service account, it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
createAuthCtx := testutils.CreateServiceAuthContext(t.Context(), "service-identity", defaultNs, nil)
|
|
|
|
_, err := svc.CreateInline(createAuthCtx, common.ObjectReference{}, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner namespace does not match auth info namespace it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
reqNs := "org-2345"
|
|
createAuthCtx := testutils.CreateOBOAuthContext(t.Context(), "service-identity", reqNs, nil, nil)
|
|
|
|
_, err := svc.CreateInline(createAuthCtx, owner, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner namespace is empty it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
createAuthCtx := testutils.CreateOBOAuthContext(t.Context(), "service-identity", defaultNs, nil, nil)
|
|
|
|
_, err := svc.CreateInline(createAuthCtx, common.ObjectReference{}, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner reference has empty fields it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
owner := common.ObjectReference{
|
|
Namespace: defaultNs,
|
|
}
|
|
|
|
createAuthCtx := testutils.CreateOBOAuthContext(t.Context(), "service-identity", defaultNs, nil, nil)
|
|
|
|
_, err := svc.CreateInline(createAuthCtx, owner, "")
|
|
require.Error(t, err)
|
|
|
|
owner.APIGroup = "prometheus.datasource.grafana.app"
|
|
_, err = svc.CreateInline(createAuthCtx, owner, "")
|
|
require.Error(t, err)
|
|
|
|
owner.APIVersion = "v1alpha1"
|
|
_, err = svc.CreateInline(createAuthCtx, owner, "")
|
|
require.Error(t, err)
|
|
|
|
owner.Kind = "DataSourceConfig"
|
|
_, err = svc.CreateInline(createAuthCtx, owner, "")
|
|
require.Error(t, err)
|
|
owner.Kind = ""
|
|
|
|
owner.Name = "test-datasource"
|
|
_, err = svc.CreateInline(createAuthCtx, owner, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when an empty secret is provided it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
createAuthCtx := testutils.CreateOBOAuthContext(t.Context(), "service-identity", defaultNs, nil, nil)
|
|
|
|
_, err := svc.CreateInline(createAuthCtx, owner, "")
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestIntegration_InlineSecureValue_DeleteWhenOwnedByResource(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tracer := noop.NewTracerProvider().Tracer("test")
|
|
|
|
defaultNs := "org-1234"
|
|
owner := common.ObjectReference{
|
|
APIGroup: "prometheus.datasource.grafana.app",
|
|
APIVersion: "v1alpha1",
|
|
Kind: "DataSourceConfig",
|
|
Name: "test-datasource",
|
|
Namespace: defaultNs,
|
|
}
|
|
|
|
t.Run("happy path deletes an owned secure value", 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)
|
|
require.NoError(t, err)
|
|
|
|
// make sure it got deleted
|
|
sv, err := tu.SecureValueService.Read(ctx, xkube.Namespace(owner.Namespace), sv1)
|
|
require.ErrorIs(t, err, contracts.ErrSecureValueNotFound)
|
|
require.Nil(t, sv)
|
|
})
|
|
|
|
t.Run("when the auth info is missing it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
err := svc.DeleteWhenOwnedByResource(t.Context(), common.ObjectReference{}, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner namespace does not match auth info namespace it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
reqNs := "org-2345"
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), reqNs, map[string][]string{})
|
|
|
|
err := svc.DeleteWhenOwnedByResource(ctx, owner, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner namespace is empty it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
ctx := testutils.CreateUserAuthContext(t.Context(), defaultNs, map[string][]string{})
|
|
|
|
err := svc.DeleteWhenOwnedByResource(ctx, common.ObjectReference{}, "")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("when the owner reference has empty fields it returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
svc := inline.NewLocalInlineSecureValueService(tracer, nil, nil)
|
|
|
|
owner := common.ObjectReference{
|
|
Namespace: defaultNs,
|
|
}
|
|
|
|
createAuthCtx := testutils.CreateOBOAuthContext(t.Context(), "service-identity", defaultNs, nil, nil)
|
|
|
|
require.Error(t, svc.DeleteWhenOwnedByResource(createAuthCtx, owner, ""))
|
|
|
|
owner.APIGroup = "prometheus.datasource.grafana.app"
|
|
require.Error(t, svc.DeleteWhenOwnedByResource(createAuthCtx, owner, ""))
|
|
|
|
owner.APIVersion = "v1alpha1"
|
|
require.Error(t, svc.DeleteWhenOwnedByResource(createAuthCtx, owner, ""))
|
|
|
|
owner.Kind = "DataSourceConfig"
|
|
require.Error(t, svc.DeleteWhenOwnedByResource(createAuthCtx, owner, ""))
|
|
owner.Kind = ""
|
|
|
|
owner.Name = "test-datasource"
|
|
require.Error(t, svc.DeleteWhenOwnedByResource(createAuthCtx, owner, ""))
|
|
})
|
|
|
|
t.Run("when the secure value exists but the owner does not match, it 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{
|
|
{
|
|
APIVersion: "another.example.com/v0alpha1",
|
|
Kind: "another-kind",
|
|
Name: "another-name",
|
|
},
|
|
}
|
|
})
|
|
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)
|
|
require.Error(t, err)
|
|
|
|
// make sure it still exists
|
|
sv, err := tu.SecureValueService.Read(ctx, xkube.Namespace(owner.Namespace), sv1)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, sv)
|
|
require.Equal(t, sv1, sv.GetName())
|
|
})
|
|
|
|
t.Run("when the secure value exists but it is shared (no owner), it does not return an error (noop)", 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
|
|
})
|
|
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)
|
|
require.NoError(t, err)
|
|
|
|
// make sure it still exists
|
|
sv, err := tu.SecureValueService.Read(ctx, xkube.Namespace(owner.Namespace), sv1)
|
|
require.NoError(t, err)
|
|
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)
|
|
})
|
|
}
|