diff --git a/pkg/tests/apis/scopes/scope_nodes_example_test.go b/pkg/tests/apis/scopes/scope_nodes_example_test.go new file mode 100644 index 00000000000..71846d207df --- /dev/null +++ b/pkg/tests/apis/scopes/scope_nodes_example_test.go @@ -0,0 +1,84 @@ +package scopes + +import ( + "context" + "encoding/json" + "os" + "testing" + + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/tests/apis" + "github.com/grafana/grafana/pkg/tests/testinfra" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestIntegrationScopeNodesExample(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test in short mode.") + } + + ctx := context.Background() + helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{ + AppModeProduction: false, // required for experimental APIs + EnableFeatureToggles: []string{ + featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs, // Required to start the example service + }, + }) + + scopeClient := helper.GetResourceClient(apis.ResourceClientArgs{ + User: helper.Org1.Admin, + Namespace: "default", // actually org1 + GVR: schema.GroupVersionResource{ + Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopes", + }, + }) + + scopeNodesClient := helper.GetResourceClient(apis.ResourceClientArgs{ + User: helper.Org1.Admin, + Namespace: "default", // actually org1 + GVR: schema.GroupVersionResource{ + Group: "scope.grafana.app", Version: "v0alpha1", Resource: "scopenodes", + }, + }) + + createOptions := metav1.CreateOptions{FieldValidation: "Strict"} + + t.Run("Create scopes", func(t *testing.T) { + ul := jsonListToUnstructuredList(t, "testdata/scopeNodesExample/scopes.json") + + for _, item := range ul.Items { + _, err := scopeClient.Resource.Create(ctx, &item, createOptions) + require.NoError(t, err) + } + + found, err := scopeClient.Resource.List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + require.Len(t, found.Items, 5) + }) + + t.Run("Create scopeNodes", func(t *testing.T) { + ul := jsonListToUnstructuredList(t, "testdata/scopeNodesExample/scopeNodes.json") + + for _, item := range ul.Items { + _, err := scopeNodesClient.Resource.Create(ctx, &item, createOptions) + require.NoError(t, err) + } + + found, err := scopeNodesClient.Resource.List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + require.Len(t, found.Items, 12) + }) +} + +func jsonListToUnstructuredList(t *testing.T, fname string) (ul unstructured.UnstructuredList) { + // nolint:gosec + f, err := os.ReadFile(fname) + require.NoError(t, err) + + err = json.Unmarshal(f, &ul) + require.NoError(t, err) + return +} diff --git a/pkg/tests/apis/scopes/scopes_test.go b/pkg/tests/apis/scopes/scopes_test.go index c0401686f0c..9116e716fbc 100644 --- a/pkg/tests/apis/scopes/scopes_test.go +++ b/pkg/tests/apis/scopes/scopes_test.go @@ -1,4 +1,4 @@ -package playlist +package scopes import ( "context" diff --git a/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopeNodes.json b/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopeNodes.json new file mode 100644 index 00000000000..0cec2dc0417 --- /dev/null +++ b/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopeNodes.json @@ -0,0 +1,179 @@ +{ + "kind": "List", + "items": [ + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "applications" + }, + "spec": { + "description": "Application Scopes", + "title": "Applications", + "nodeType": "container" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "applications.clusters" + }, + "spec": { + "description": "Application/Clusters Scopes", + "title": "Clusters", + "nodeType": "container", + "parentName": "applications", + "linkID": "indexHelperCluster", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "clusters" + }, + "spec": { + "description": "Cluster Scopes", + "title": "Clusters", + "nodeType": "container", + "linkID": "indexHelperCluster", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "clusters.application" + }, + "spec": { + "description": "Clusters/Application Scopes", + "title": "Applications", + "nodeType": "container", + "parentName": "clusters" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "applications-slothPictureFactory" + }, + "spec": { + "description": "slothPictureFactory", + "title": "slothPictureFactory", + "nodeType": "leaf", + "parentName": "applications", + "linkID": "slothPictureFactory", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "applications-slothVoteTracker" + }, + "spec": { + "description": "slothVoteTracker", + "title": "slothVoteTracker", + "nodeType": "leaf", + "parentName": "applications", + "linkID": "slothVoteTracker", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "applications.clusters-slothClusterNorth" + }, + "spec": { + "description": "slothClusterNorth", + "title": "slothClusterNorth", + "nodeType": "leaf", + "parentName": "applications.clusters", + "linkID": "slothClusterNorth", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "applications.clusters-slothClusterSouth" + }, + "spec": { + "description": "slothClusterSouth", + "title": "slothClusterSouth", + "nodeType": "leaf", + "parentName": "applications.clusters", + "linkID": "slothClusterSouth", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "clusters-slothClusterNorth" + }, + "spec": { + "description": "slothClusterNorth", + "title": "slothClusterNorth", + "nodeType": "leaf", + "parentName": "clusters", + "linkID": "slothClusterNorth", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "clusters-slothClusterSouth" + }, + "spec": { + "description": "slothClusterSouth", + "title": "slothClusterSouth", + "nodeType": "leaf", + "parentName": "clusters", + "linkID": "slothClusterSouth", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "clusters.applications-slothPictureFactory" + }, + "spec": { + "description": "slothPictureFactory", + "title": "slothPictureFactory", + "nodeType": "leaf", + "parentName": "clusters.applications", + "linkID": "slothPictureFactory", + "linkType": "scope" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "ScopeNode", + "metadata": { + "name": "clusters.applications-slothVoteTracker" + }, + "spec": { + "description": "slothVoteTracker", + "title": "slothVoteTracker", + "nodeType": "leaf", + "parentName": "clusters.applications", + "linkID": "slothVoteTracker", + "linkType": "scope" + } + } + ] +} \ No newline at end of file diff --git a/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopes.json b/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopes.json new file mode 100644 index 00000000000..0dea887bcd3 --- /dev/null +++ b/pkg/tests/apis/scopes/testdata/scopeNodesExample/scopes.json @@ -0,0 +1,105 @@ +{ + "kind": "List", + "items": [ + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "Scope", + "metadata": { + "name": "slothClusterNorth" + }, + "spec": { + "category": "clusters", + "description": "slothClusterNorth", + "filters": [ + { + "key": "cluster", + "operator": "equals", + "value": "slothClusterNorth" + } + ], + "title": "slothClusterNorth", + "type": "cluster" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "Scope", + "metadata": { + "name": "slothClusterSouth" + }, + "spec": { + "category": "clusters", + "description": "slothClusterSouth", + "filters": [ + { + "key": "cluster", + "operator": "equals", + "value": "slothClusterSouth" + } + ], + "title": "slothClusterSouth", + "type": "cluster" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "Scope", + "metadata": { + "name": "slothPictureFactory" + }, + "spec": { + "category": "apps", + "description": "slothPictureFactory", + "filters": [ + { + "key": "app", + "operator": "equals", + "value": "slothPictureFactory" + } + ], + "title": "slothPictureFactory", + "type": "app" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "Scope", + "metadata": { + "name": "slothVoteTracker" + }, + "spec": { + "category": "apps", + "description": "slothVoteTracker", + "filters": [ + { + "key": "app", + "operator": "equals", + "value": "slothVoteTracker" + } + ], + "title": "slothVoteTracker", + "type": "app" + } + }, + { + "apiVersion": "scope.grafana.app/v0alpha1", + "kind": "Scope", + "metadata": { + "name": "indexHelperCluster" + }, + "spec": { + "category": "indexHelpers", + "description": "redundant label filter but makes queries faster", + "filters": [ + { + "key": "indexHelper", + "operator": "equals", + "value": "cluster" + } + ], + "title": "Cluster Index Helper", + "type": "indexHelper" + } + } + ] +} \ No newline at end of file