Files
grafana/pkg/tests/apis/secret/main_test.go
Dana Axinte 7f2923d4ed SecretsManager: Introduce keeper store (#105557)
* SecretsManager: Introduce secret database wrapper

Co-authored-by: PoorlyDefinedBehaviour <brunotj2015@hotmail.com>
Co-authored-by: Leandro Deveikis <leandro.deveikis@gmail.com>
Co-authored-by: Dana Axinte <53751979+dana-axinte@users.noreply.github.com>
Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>

* SecretsManager: Introduce db migrator with keeper table

Co-authored-by: PoorlyDefinedBehaviour <brunotj2015@hotmail.com>
Co-authored-by: Leandro Deveikis <leandro.deveikis@gmail.com>
Co-authored-by: Dana Axinte <53751979+dana-axinte@users.noreply.github.com>
Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>

* SecretsManager: Introduce keeper store

Co-authored-by: Leandro Deveikis <leandro.deveikis@gmail.com>
Co-authored-by: Dana Axinte <53751979+dana-axinte@users.noreply.github.com>
Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>

* new line

* without query listByNameSecureValue

* remove unused extractSecureValues for now

* SecretsManager: Add keeper integration tests

Co-authored-by: Leandro Deveikis <leandro.deveikis@gmail.com>
Co-authored-by: Dana Axinte <53751979+dana-axinte@users.noreply.github.com>
Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>

---------

Co-authored-by: PoorlyDefinedBehaviour <brunotj2015@hotmail.com>
Co-authored-by: Leandro Deveikis <leandro.deveikis@gmail.com>
Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>
2025-05-22 14:26:47 +01:00

151 lines
4.5 KiB
Go

package secret
import (
"cmp"
"context"
"encoding/json"
"math/rand/v2"
"strconv"
"testing"
"github.com/grafana/grafana/pkg/registry/apis/secret"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/tests/apis"
"github.com/grafana/grafana/pkg/tests/testinfra"
"github.com/grafana/grafana/pkg/tests/testsuite"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
var (
ResourceSecureValues = "secret.securevalues"
ResourceKeepers = "secret.keepers"
ActionsAllKeepers = []string{
secret.ActionSecretKeepersCreate,
secret.ActionSecretKeepersWrite,
secret.ActionSecretKeepersRead,
secret.ActionSecretKeepersDelete,
}
ActionsAllSecureValues = []string{
secret.ActionSecretSecureValuesCreate,
secret.ActionSecretSecureValuesWrite,
secret.ActionSecretSecureValuesRead,
secret.ActionSecretSecureValuesDelete,
}
)
type ResourcePermission struct {
Actions []string
Name string // empty or "*" for all
}
func TestMain(m *testing.M) {
testsuite.Run(m)
}
func TestIntegrationDiscoveryClient(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
AppModeProduction: false, // required for experimental APIs
EnableFeatureToggles: []string{
// Required to start the example service
featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs,
featuremgmt.FlagSecretsManagementAppPlatform,
},
})
t.Run("check discovery client", func(t *testing.T) {
disco := helper.NewDiscoveryClient()
resources, err := disco.ServerResourcesForGroupVersion("secret.grafana.app/v0alpha1")
require.NoError(t, err)
v1Disco, err := json.MarshalIndent(resources, "", " ")
require.NoError(t, err)
var apiResourceList map[string]any
require.NoError(t, json.Unmarshal(v1Disco, &apiResourceList))
groupVersion, ok := apiResourceList["groupVersion"].(string)
require.True(t, ok)
require.Equal(t, "secret.grafana.app/v0alpha1", groupVersion)
apiResources, ok := apiResourceList["resources"].([]any)
require.True(t, ok)
require.Len(t, apiResources, 2) // securevalue + keeper + (subresources...)
})
}
func mustCreateUsersWithOrg(t *testing.T, helper *apis.K8sTestHelper, orgID int64, permissionMap map[string]ResourcePermission) apis.OrgUsers {
t.Helper()
permissions := make([]resourcepermissions.SetResourcePermissionCommand, 0, len(permissionMap))
for resource, permission := range permissionMap {
permissions = append(permissions, resourcepermissions.SetResourcePermissionCommand{
Actions: permission.Actions,
Resource: resource,
ResourceAttribute: "uid",
ResourceID: cmp.Or(permission.Name, "*"),
})
}
orgName := "org-" + strconv.FormatInt(orgID, 10)
userSuffix := strconv.FormatInt(rand.Int64(), 10)
// Add here admin or viewer if necessary.
editor := helper.CreateUser("editor-"+userSuffix, orgName, org.RoleEditor, permissions)
staff := helper.CreateTeam("staff-"+userSuffix, "staff-"+userSuffix+"@"+orgName, editor.Identity.GetOrgID())
// Also call this method for each new user.
helper.AddOrUpdateTeamMember(editor, staff.ID, team.PermissionTypeMember)
return apis.OrgUsers{
Editor: editor,
Staff: staff,
}
}
func mustCreateUsers(t *testing.T, helper *apis.K8sTestHelper, permissionMap map[string]ResourcePermission) apis.OrgUsers {
orgID := rand.Int64() + 2 // if it is 0, becomes 2 and not 1.
return mustCreateUsersWithOrg(t, helper, orgID, permissionMap)
}
func mustGenerateKeeper(t *testing.T, helper *apis.K8sTestHelper, user apis.User, specType map[string]any, testFile string) *unstructured.Unstructured {
t.Helper()
require.NotEmpty(t, testFile, "testFile must not be empty")
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
keeperClient := helper.GetResourceClient(apis.ResourceClientArgs{
User: user,
GVR: gvrKeepers,
})
testKeeper := helper.LoadYAMLOrJSONFile(testFile)
if specType != nil {
testKeeper.Object["spec"] = specType
}
raw, err := keeperClient.Resource.Create(ctx, testKeeper, metav1.CreateOptions{})
require.NoError(t, err)
require.NotNil(t, raw)
t.Cleanup(func() {
require.NoError(t, keeperClient.Resource.Delete(ctx, raw.GetName(), metav1.DeleteOptions{}))
})
return raw
}