mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Playlist: Implement the entire API with k8s client (#77596)
This commit is contained in:
@@ -26,7 +26,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/server"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
||||
@@ -43,24 +42,16 @@ type K8sTestHelper struct {
|
||||
env server.TestEnv
|
||||
namespacer request.NamespaceMapper
|
||||
|
||||
Org1 OrgUsers
|
||||
Org2 OrgUsers
|
||||
Org1 OrgUsers // default
|
||||
OrgB OrgUsers // some other id
|
||||
|
||||
// // Registered groups
|
||||
groups []metav1.APIGroup
|
||||
}
|
||||
|
||||
func NewK8sTestHelper(t *testing.T) *K8sTestHelper {
|
||||
func NewK8sTestHelper(t *testing.T, opts testinfra.GrafanaOpts) *K8sTestHelper {
|
||||
t.Helper()
|
||||
dir, path := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true, // do not start extra port 6443
|
||||
DisableAnonymous: true,
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagGrafanaAPIServer,
|
||||
featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs,
|
||||
},
|
||||
})
|
||||
|
||||
dir, path := testinfra.CreateGrafDir(t, opts)
|
||||
_, env := testinfra.StartGrafanaEnv(t, dir, path)
|
||||
c := &K8sTestHelper{
|
||||
env: *env,
|
||||
@@ -68,8 +59,8 @@ func NewK8sTestHelper(t *testing.T) *K8sTestHelper {
|
||||
namespacer: request.GetNamespaceMapper(nil),
|
||||
}
|
||||
|
||||
c.Org1 = c.createTestUsers(int64(1))
|
||||
c.Org2 = c.createTestUsers(int64(2))
|
||||
c.Org1 = c.createTestUsers("Org1")
|
||||
c.OrgB = c.createTestUsers("OrgB")
|
||||
|
||||
// Read the API groups
|
||||
rsp := DoRequest(c, RequestParams{
|
||||
@@ -81,6 +72,12 @@ func NewK8sTestHelper(t *testing.T) *K8sTestHelper {
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *K8sTestHelper) Shutdown() {
|
||||
fmt.Printf("calling shutdown on: %s\n", c.env.Server.HTTPServer.Listener.Addr())
|
||||
err := c.env.Server.Shutdown(context.Background(), "done")
|
||||
require.NoError(c.t, err)
|
||||
}
|
||||
|
||||
type ResourceClientArgs struct {
|
||||
User User
|
||||
Namespace string
|
||||
@@ -327,20 +324,27 @@ func (c *K8sTestHelper) LoadYAMLOrJSON(body string) *unstructured.Unstructured {
|
||||
return &unstructured.Unstructured{Object: unstructuredMap}
|
||||
}
|
||||
|
||||
func (c K8sTestHelper) createTestUsers(orgId int64) OrgUsers {
|
||||
func (c K8sTestHelper) createTestUsers(orgName string) OrgUsers {
|
||||
c.t.Helper()
|
||||
|
||||
store := c.env.SQLStore
|
||||
store.Cfg.AutoAssignOrg = true
|
||||
store.Cfg.AutoAssignOrgId = int(orgId)
|
||||
defer func() {
|
||||
store.Cfg.AutoAssignOrg = false
|
||||
store.Cfg.AutoAssignOrgId = 1 // the default
|
||||
}()
|
||||
|
||||
quotaService := quotaimpl.ProvideService(store, store.Cfg)
|
||||
|
||||
orgService, err := orgimpl.ProvideService(store, store.Cfg, quotaService)
|
||||
require.NoError(c.t, err)
|
||||
|
||||
gotID, err := orgService.GetOrCreate(context.Background(), fmt.Sprintf("Org%d", orgId))
|
||||
require.NoError(c.t, err)
|
||||
require.Equal(c.t, orgId, gotID)
|
||||
orgId := int64(1)
|
||||
if orgName != "Org1" {
|
||||
orgId, err = orgService.GetOrCreate(context.Background(), orgName)
|
||||
require.NoError(c.t, err)
|
||||
}
|
||||
store.Cfg.AutoAssignOrg = true
|
||||
store.Cfg.AutoAssignOrgId = int(orgId)
|
||||
|
||||
teamSvc := teamimpl.ProvideService(store, store.Cfg)
|
||||
cache := localcache.ProvideService()
|
||||
@@ -354,7 +358,7 @@ func (c K8sTestHelper) createTestUsers(orgId int64) OrgUsers {
|
||||
u, err := userSvc.Create(context.Background(), &user.CreateUserCommand{
|
||||
DefaultOrgRole: string(role),
|
||||
Password: key,
|
||||
Login: fmt.Sprintf("%s%d", key, orgId),
|
||||
Login: fmt.Sprintf("%s-%d", key, orgId),
|
||||
OrgID: orgId,
|
||||
})
|
||||
require.NoError(c.t, err)
|
||||
|
||||
@@ -14,21 +14,50 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
"github.com/grafana/grafana/pkg/tests/apis"
|
||||
"github.com/grafana/grafana/pkg/tests/testinfra"
|
||||
)
|
||||
|
||||
func TestPlaylist(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
helper := apis.NewK8sTestHelper(t)
|
||||
|
||||
t.Run("default setup", func(t *testing.T) {
|
||||
doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true, // do not start extra port 6443
|
||||
DisableAnonymous: true,
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagGrafanaAPIServer,
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("with k8s api flag", func(t *testing.T) {
|
||||
doPlaylistTests(t, apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{
|
||||
AppModeProduction: true, // do not start extra port 6443
|
||||
DisableAnonymous: true,
|
||||
EnableFeatureToggles: []string{
|
||||
featuremgmt.FlagGrafanaAPIServer,
|
||||
featuremgmt.FlagKubernetesPlaylistsAPI, // <<< The change we are testing!
|
||||
},
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
func doPlaylistTests(t *testing.T, helper *apis.K8sTestHelper) {
|
||||
gvr := schema.GroupVersionResource{
|
||||
Group: "playlist.grafana.app",
|
||||
Version: "v0alpha1",
|
||||
Resource: "playlists",
|
||||
}
|
||||
|
||||
defer func() {
|
||||
helper.Shutdown()
|
||||
}()
|
||||
|
||||
t.Run("Check direct List permissions from different org users", func(t *testing.T) {
|
||||
// Check view permissions
|
||||
rsp := helper.List(helper.Org1.Viewer, "default", gvr)
|
||||
@@ -38,13 +67,13 @@ func TestPlaylist(t *testing.T) {
|
||||
require.Nil(t, rsp.Status)
|
||||
|
||||
// Check view permissions
|
||||
rsp = helper.List(helper.Org2.Viewer, "default", gvr)
|
||||
require.Equal(t, 403, rsp.Response.StatusCode) // Org2 can not see default namespace
|
||||
rsp = helper.List(helper.OrgB.Viewer, "default", gvr)
|
||||
require.Equal(t, 403, rsp.Response.StatusCode) // OrgB can not see default namespace
|
||||
require.Nil(t, rsp.Result)
|
||||
require.Equal(t, metav1.StatusReasonForbidden, rsp.Status.Reason)
|
||||
|
||||
// Check view permissions
|
||||
rsp = helper.List(helper.Org2.Viewer, "org-22", gvr)
|
||||
rsp = helper.List(helper.OrgB.Viewer, "org-22", gvr)
|
||||
require.Equal(t, 403, rsp.Response.StatusCode) // Unknown/not a member
|
||||
require.Nil(t, rsp.Result)
|
||||
require.Equal(t, metav1.StatusReasonForbidden, rsp.Status.Reason)
|
||||
@@ -63,7 +92,7 @@ func TestPlaylist(t *testing.T) {
|
||||
|
||||
// Check org2 viewer can not see org1 (default namespace)
|
||||
client = helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org2.Viewer,
|
||||
User: helper.OrgB.Viewer,
|
||||
Namespace: "default", // actually org1
|
||||
GVR: gvr,
|
||||
})
|
||||
@@ -74,7 +103,7 @@ func TestPlaylist(t *testing.T) {
|
||||
|
||||
// Check invalid namespace
|
||||
client = helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org2.Viewer,
|
||||
User: helper.OrgB.Viewer,
|
||||
Namespace: "org-22", // org 22 does not exist
|
||||
GVR: gvr,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user