7698970f22
* Secrets: changes to allow a 3rd party keeper / secret references * fix test * make gofmt * lint * fix tests * assign aws secrets manager to @grafana/grafana-operator-experience-squad * rename Keeper.Reference to Keeper.RetrieveReference * rename ModelSecretsManager to ModelAWSSecretsManager * validator: ensure that only one of keeper.Spec.Aws.AccessKey or keeper.Spec.Aws.AssumeRole are set * move secrets manager dep / go mod tidy * move secrets manager dep * keeper validator: move 3rd party secret stores validation to their own functions * add github.com/aws/aws-sdk-go-v2/service/secretsmanager pkg/extensions/enterprise_imports * make update-workspace * undo go.mod changes in /apps * make update-workspace * fix test * add github.com/aws/aws-sdk-go-v2/service/secretsmanager to enterprise_imports * make update-workspace * gcworker: handle refs * make update-workspace * create toggle: FeatureStageExperimental * allow features.IsEnabled for now * format
243 lines
7.5 KiB
Go
243 lines
7.5 KiB
Go
package service_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
|
|
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
|
|
"github.com/grafana/grafana/pkg/registry/apis/secret/testutils"
|
|
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
|
|
"github.com/stretchr/testify/require"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/utils/ptr"
|
|
)
|
|
|
|
func TestCrud(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("creating a secure value creates new versions", func(t *testing.T) {
|
|
t.Parallel()
|
|
sut := testutils.Setup(t)
|
|
|
|
sv1, err := sut.CreateSv(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
// Create the same secure value twice
|
|
input := sv1.DeepCopy()
|
|
input.Spec.Description = "d2"
|
|
input.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue("v2"))
|
|
|
|
sv2, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(input))
|
|
require.NoError(t, err)
|
|
require.True(t, sv2.Status.Version > sv1.Status.Version)
|
|
|
|
// Read the secure value
|
|
sv, err := sut.SecureValueService.Read(t.Context(), xkube.Namespace(sv2.Namespace), sv2.Name)
|
|
require.NoError(t, err)
|
|
|
|
// It should be the latest version
|
|
require.Equal(t, sv2.Namespace, sv.Namespace)
|
|
require.Equal(t, sv2.Name, sv.Name)
|
|
require.Equal(t, "d2", sv.Spec.Description)
|
|
require.Equal(t, sv2.Status.Version, sv.Status.Version)
|
|
})
|
|
|
|
t.Run("updating a secure value creates new versions", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sut := testutils.Setup(t)
|
|
|
|
// Create a secure value
|
|
sv1, err := sut.CreateSv(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
ns := sv1.Namespace
|
|
name := sv1.Name
|
|
|
|
// Update the secure value
|
|
input := sv1.DeepCopy()
|
|
input.Spec.Description = "d2"
|
|
input.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue("v3"))
|
|
sv2, err := sut.UpdateSv(t.Context(), input)
|
|
require.NoError(t, err)
|
|
|
|
// Read the secure value
|
|
sv3, err := sut.SecureValueService.Read(t.Context(), xkube.Namespace(ns), name)
|
|
require.NoError(t, err)
|
|
|
|
// Nothing has changed except for the updated field.
|
|
require.Equal(t, ns, sv2.Namespace)
|
|
require.Equal(t, name, sv2.Name)
|
|
require.True(t, sv2.Status.Version > sv1.Status.Version)
|
|
require.Equal(t, "d2", sv2.Spec.Description)
|
|
|
|
require.Equal(t, ns, sv3.Namespace)
|
|
require.Equal(t, name, sv3.Name)
|
|
require.Equal(t, sv2.Status.Version, sv3.Status.Version)
|
|
require.Equal(t, "d2", sv3.Spec.Description)
|
|
})
|
|
|
|
t.Run("deleting secure values", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sut := testutils.Setup(t)
|
|
|
|
sv1, err := sut.CreateSv(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
sv2, err := sut.DeleteSv(t.Context(), sv1.Namespace, sv1.Name)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, sv1.Namespace, sv2.Namespace)
|
|
require.Equal(t, sv1.Name, sv2.Name)
|
|
|
|
_, err = sut.SecureValueMetadataStorage.Read(t.Context(), xkube.Namespace(sv1.Namespace), sv1.Name, contracts.ReadOpts{})
|
|
require.ErrorIs(t, err, contracts.ErrSecureValueNotFound)
|
|
})
|
|
|
|
t.Run("secret can be referenced only when the active keeper is a 3rd party keeper", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sut := testutils.Setup(t)
|
|
|
|
ref := "path-to-secret"
|
|
sv := &secretv1beta1.SecureValue{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "sv1",
|
|
Namespace: "ns1",
|
|
},
|
|
Spec: secretv1beta1.SecureValueSpec{
|
|
Description: "desc1",
|
|
Ref: &ref,
|
|
Decrypters: []string{"decrypter1"},
|
|
},
|
|
Status: secretv1beta1.SecureValueStatus{},
|
|
}
|
|
|
|
// Creating a secure value using ref with the system keeper
|
|
createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(sv))
|
|
require.NotNil(t, err)
|
|
require.Nil(t, createdSv)
|
|
require.Contains(t, err.Error(), "tried to create secure value using reference with system keeper, references can only be used with 3rd party keepers")
|
|
|
|
// Create a 3rd party keeper
|
|
keeper := &secretv1beta1.Keeper{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "k1",
|
|
Namespace: "ns1",
|
|
},
|
|
Spec: secretv1beta1.KeeperSpec{
|
|
Description: "desc",
|
|
Aws: &secretv1beta1.KeeperAWSConfig{
|
|
Region: "us-east-1",
|
|
AssumeRole: &secretv1beta1.KeeperAWSAssumeRole{
|
|
AssumeRoleArn: "arn",
|
|
ExternalID: "id",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
// Create a 3rd party keeper
|
|
_, err = sut.KeeperMetadataStorage.Create(t.Context(), keeper, "actor-uid")
|
|
require.NoError(t, err)
|
|
|
|
// Set the new keeper as active
|
|
require.NoError(t, sut.KeeperMetadataStorage.SetAsActive(t.Context(), xkube.Namespace(keeper.Namespace), keeper.Name))
|
|
|
|
// Create a secure value using a ref
|
|
createdSv, err = sut.CreateSv(t.Context(), testutils.CreateSvWithSv(sv))
|
|
require.NoError(t, err)
|
|
require.Equal(t, keeper.Name, createdSv.Status.Keeper)
|
|
})
|
|
|
|
t.Run("creating secure value with reference", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sut := testutils.Setup(t)
|
|
|
|
// Create a keeper because references cannot be used with the system keeper
|
|
keeper, err := sut.KeeperMetadataStorage.Create(t.Context(), &secretv1beta1.Keeper{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: "ns",
|
|
Name: "k1",
|
|
},
|
|
Spec: secretv1beta1.KeeperSpec{
|
|
Aws: &secretv1beta1.KeeperAWSConfig{},
|
|
},
|
|
}, "actor-uid")
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, sut.KeeperMetadataStorage.SetAsActive(t.Context(), xkube.Namespace(keeper.Namespace), keeper.Name))
|
|
|
|
sv, err := sut.CreateSv(t.Context())
|
|
require.NoError(t, err)
|
|
require.NotNil(t, sv)
|
|
})
|
|
}
|
|
|
|
func Test_SetAsActive(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("setting the system keeper as the active keeper", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sut := testutils.Setup(t)
|
|
|
|
namespace := "ns"
|
|
|
|
// Create a new keeper
|
|
keeper, err := sut.KeeperMetadataStorage.Create(t.Context(), &secretv1beta1.Keeper{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: "ns",
|
|
Name: "k1",
|
|
},
|
|
Spec: secretv1beta1.KeeperSpec{
|
|
Description: "description",
|
|
Aws: &secretv1beta1.KeeperAWSConfig{},
|
|
},
|
|
}, "actor-uid")
|
|
require.NoError(t, err)
|
|
|
|
// Set the new keeper as active
|
|
require.NoError(t, sut.KeeperMetadataStorage.SetAsActive(t.Context(), xkube.Namespace(keeper.Namespace), keeper.Name))
|
|
keeperName, _, err := sut.KeeperMetadataStorage.GetActiveKeeperConfig(t.Context(), namespace)
|
|
require.NoError(t, err)
|
|
require.Equal(t, keeper.Name, keeperName)
|
|
|
|
// Set the system keeper as active
|
|
require.NoError(t, sut.KeeperMetadataStorage.SetAsActive(t.Context(), xkube.Namespace(namespace), contracts.SystemKeeperName))
|
|
keeperName, _, err = sut.KeeperMetadataStorage.GetActiveKeeperConfig(t.Context(), namespace)
|
|
require.NoError(t, err)
|
|
require.Equal(t, contracts.SystemKeeperName, keeperName)
|
|
})
|
|
|
|
t.Run("each namespace can have one active keeper", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sut := testutils.Setup(t)
|
|
|
|
k1, err := sut.CreateKeeper(t.Context(), func(ckc *testutils.CreateKeeperConfig) {
|
|
ckc.Keeper.Namespace = "ns1"
|
|
ckc.Keeper.Name = "k1"
|
|
})
|
|
require.NoError(t, err)
|
|
k2, err := sut.CreateKeeper(t.Context(), func(ckc *testutils.CreateKeeperConfig) {
|
|
ckc.Keeper.Namespace = "ns2"
|
|
ckc.Keeper.Name = "k2"
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, sut.KeeperMetadataStorage.SetAsActive(t.Context(), xkube.Namespace(k1.Namespace), k1.Name))
|
|
require.NoError(t, sut.KeeperMetadataStorage.SetAsActive(t.Context(), xkube.Namespace(k2.Namespace), k2.Name))
|
|
|
|
keeperName, _, err := sut.KeeperMetadataStorage.GetActiveKeeperConfig(t.Context(), k1.Namespace)
|
|
require.NoError(t, err)
|
|
require.Equal(t, k1.Name, keeperName)
|
|
|
|
keeperName, _, err = sut.KeeperMetadataStorage.GetActiveKeeperConfig(t.Context(), k2.Namespace)
|
|
require.NoError(t, err)
|
|
require.Equal(t, k2.Name, keeperName)
|
|
})
|
|
}
|