Plugins App: PluginMeta -> Meta (#115034)

This commit is contained in:
Todd Treece
2025-12-09 16:01:22 -05:00
committed by GitHub
parent d9fc183e39
commit 0088e55b8f
32 changed files with 888 additions and 895 deletions
+1 -2
View File
@@ -56,8 +56,7 @@ import (
_ "github.com/grafana/e2e"
_ "github.com/grafana/gofpdf"
_ "github.com/grafana/gomemcache/memcache"
_ "github.com/grafana/tempo/pkg/traceql"
_ "github.com/grafana/grafana/apps/alerting/alertenrichment/pkg/apis/alertenrichment/v1beta1"
_ "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1"
_ "github.com/grafana/tempo/pkg/traceql"
)
+7 -7
View File
@@ -13,15 +13,15 @@ const (
ActionPluginsPluginsDelete = "plugins.plugins:delete" // DELETE.
// PluginMetas
ActionPluginsPluginsMetaCreate = "plugins.pluginsmeta:create" // CREATE.
ActionPluginsPluginsMetaWrite = "plugins.pluginsmeta:write" // UPDATE.
ActionPluginsPluginsMetaRead = "plugins.pluginsmeta:read" // GET + LIST.
ActionPluginsPluginsMetaDelete = "plugins.pluginsmeta:delete" // DELETE.
ActionPluginsPluginsMetaCreate = "plugins.metas:create" // CREATE.
ActionPluginsPluginsMetaWrite = "plugins.metas:write" // UPDATE.
ActionPluginsPluginsMetaRead = "plugins.metas:read" // GET + LIST.
ActionPluginsPluginsMetaDelete = "plugins.metas:delete" // DELETE.
)
var (
ScopeProviderPluginsPlugins = accesscontrol.NewScopeProvider("plugins.plugins")
ScopeProviderPluginsPluginsMeta = accesscontrol.NewScopeProvider("plugins.pluginsmeta")
ScopeProviderPluginsPluginsMeta = accesscontrol.NewScopeProvider("plugins.metas")
ScopeAllPluginsPlugins = ScopeProviderPluginsPlugins.GetResourceAllScope()
ScopeAllPluginsPluginsMeta = ScopeProviderPluginsPluginsMeta.GetResourceAllScope()
@@ -76,7 +76,7 @@ func registerAccessControlRoles(service accesscontrol.Service) error {
// PluginMetas
pluginsMetaReader := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Name: "fixed:plugins.pluginsmeta:reader",
Name: "fixed:plugins.metas:reader",
DisplayName: "Plugin Metas Reader",
Description: "Read and list plugin metadata.",
Group: "Plugins",
@@ -92,7 +92,7 @@ func registerAccessControlRoles(service accesscontrol.Service) error {
pluginsMetaWriter := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Name: "fixed:plugins.pluginsmeta:writer",
Name: "fixed:plugins.metas:writer",
DisplayName: "Plugin Metas Writer",
Description: "Create, update and delete plugin metadata.",
Group: "Plugins",
@@ -85,7 +85,7 @@ func newPermissionRegistry() *permissionRegistry {
"orgs": "orgs:id:",
"plugins": "plugins:id:",
"plugins.plugins": "plugins.plugins:uid:",
"plugins.pluginsmeta": "plugins.pluginsmeta:uid:",
"plugins.metas": "plugins.metas:uid:",
"provisioners": "provisioners:",
"reports": "reports:id:",
"permissions": "permissions:type:",
+2 -2
View File
@@ -298,8 +298,8 @@ func NewMapperRegistry() MapperRegistry {
},
},
"plugins.grafana.app": {
"plugins": newResourceTranslation("plugins.plugins", "uid", false, nil),
"pluginsmeta": newResourceTranslation("plugins.pluginsmeta", "uid", false, nil),
"plugins": newResourceTranslation("plugins.plugins", "uid", false, nil),
"metas": newResourceTranslation("plugins.metas", "uid", false, nil),
},
})
+4 -4
View File
@@ -15,19 +15,19 @@ const pluginsDiscoveryJSON = `[
"freshness": "Current",
"resources": [
{
"resource": "pluginmetas",
"resource": "metas",
"responseKind": {
"group": "",
"kind": "PluginMeta",
"kind": "Meta",
"version": ""
},
"scope": "Namespaced",
"singularResource": "pluginmeta",
"singularResource": "meta",
"subresources": [
{
"responseKind": {
"group": "",
"kind": "PluginMeta",
"kind": "Meta",
"version": ""
},
"subresource": "status",
+4 -4
View File
@@ -21,19 +21,19 @@ func TestIntegrationPluginsIntegrationDiscovery(t *testing.T) {
"freshness": "Current",
"resources": [
{
"resource": "pluginmetas",
"resource": "metas",
"responseKind": {
"group": "",
"kind": "PluginMeta",
"kind": "Meta",
"version": ""
},
"scope": "Namespaced",
"singularResource": "pluginmeta",
"singularResource": "meta",
"subresources": [
{
"responseKind": {
"group": "",
"kind": "PluginMeta",
"kind": "Meta",
"version": ""
},
"subresource": "status",
@@ -15,6 +15,72 @@ import (
func TestIntegrationPluginMeta(t *testing.T) {
testutil.SkipIntegrationTestInShortMode(t)
t.Run("list plugin metas", func(t *testing.T) {
helper := setupHelper(t)
ctx := context.Background()
client := helper.GetResourceClient(apis.ResourceClientArgs{
User: helper.Org1.Admin,
GVR: gvrPlugins,
})
plugin1Name := "test-plugin-metas-1"
plugin1 := helper.LoadYAMLOrJSON(fmt.Sprintf(`{
"apiVersion": "plugins.grafana.app/v0alpha1",
"kind": "Plugin",
"metadata": {"name": "%s"},
"spec": {"id": "grafana-piechart-panel", "version": "1.0.0"}
}`, plugin1Name))
_, err := client.Resource.Create(ctx, plugin1, metav1.CreateOptions{})
require.NoError(t, err)
plugin2Name := "test-plugin-metas-2"
plugin2 := helper.LoadYAMLOrJSON(fmt.Sprintf(`{
"apiVersion": "plugins.grafana.app/v0alpha1",
"kind": "Plugin",
"metadata": {"name": "%s"},
"spec": {"id": "grafana-clock-panel", "version": "1.0.0"}
}`, plugin2Name))
_, err = client.Resource.Create(ctx, plugin2, metav1.CreateOptions{})
require.NoError(t, err)
namespace := helper.Namespacer(helper.Org1.Admin.Identity.GetOrgID())
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/metas", namespace)
response := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Method: "GET",
Path: path,
}, &pluginsv0alpha1.MetaList{})
require.NotNil(t, response.Result)
require.NotNil(t, response.Result.Items)
require.GreaterOrEqual(t, len(response.Result.Items), 2)
foundIDs := make(map[string]bool)
for _, item := range response.Result.Items {
require.NotNil(t, item.Spec.PluginJSON)
foundIDs[item.Spec.PluginJSON.Id] = true
require.NotEmpty(t, item.Spec.PluginJSON.Id)
require.NotEmpty(t, item.Spec.PluginJSON.Type)
require.NotEmpty(t, item.Spec.PluginJSON.Name)
}
require.True(t, foundIDs["grafana-piechart-panel"])
require.True(t, foundIDs["grafana-clock-panel"])
})
t.Run("list plugin metas with no plugins", func(t *testing.T) {
helper := setupHelper(t)
namespace := helper.Namespacer(helper.Org1.Admin.Identity.GetOrgID())
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/metas", namespace)
response := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Method: "GET",
Path: path,
}, &pluginsv0alpha1.MetaList{})
require.NotNil(t, response.Result)
require.NotNil(t, response.Result.Items)
require.GreaterOrEqual(t, len(response.Result.Items), 0)
})
t.Run("get plugin meta", func(t *testing.T) {
helper := setupHelper(t)
@@ -35,12 +101,12 @@ func TestIntegrationPluginMeta(t *testing.T) {
require.NoError(t, err)
namespace := helper.Org1.Admin.Identity.GetNamespace()
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/pluginmetas/%s", namespace, pluginName)
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/metas/%s", namespace, pluginName)
response := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Method: "GET",
Path: path,
}, &pluginsv0alpha1.PluginMeta{})
}, &pluginsv0alpha1.Meta{})
require.NotNil(t, response.Result)
require.NotNil(t, response.Result.Spec.PluginJSON)
@@ -52,12 +118,12 @@ func TestIntegrationPluginMeta(t *testing.T) {
t.Run("get plugin meta for non-existent plugin", func(t *testing.T) {
helper := setupHelper(t)
namespace := helper.Org1.Admin.Identity.GetNamespace()
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/pluginmetas/non-existent-plugin", namespace)
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/metas/non-existent-plugin", namespace)
response := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Method: "GET",
Path: path,
}, &pluginsv0alpha1.PluginMeta{})
}, &pluginsv0alpha1.Meta{})
require.NotNil(t, response.Status)
require.Equal(t, int32(404), response.Status.Code)
@@ -82,12 +148,12 @@ func TestIntegrationPluginMeta(t *testing.T) {
require.NoError(t, err)
namespace := helper.Org1.Admin.Identity.GetNamespace()
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/pluginmetas/%s", namespace, pluginName)
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/metas/%s", namespace, pluginName)
response := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Method: "GET",
Path: path,
}, &pluginsv0alpha1.PluginMeta{})
}, &pluginsv0alpha1.Meta{})
require.NotNil(t, response.Status)
require.Equal(t, int32(404), response.Status.Code)
@@ -1,85 +0,0 @@
package plugins
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1"
"github.com/grafana/grafana/pkg/tests/apis"
"github.com/grafana/grafana/pkg/util/testutil"
)
func TestIntegrationPluginMetas(t *testing.T) {
testutil.SkipIntegrationTestInShortMode(t)
t.Run("list plugin metas", func(t *testing.T) {
helper := setupHelper(t)
ctx := context.Background()
client := helper.GetResourceClient(apis.ResourceClientArgs{
User: helper.Org1.Admin,
GVR: gvrPlugins,
})
plugin1Name := "test-plugin-metas-1"
plugin1 := helper.LoadYAMLOrJSON(fmt.Sprintf(`{
"apiVersion": "plugins.grafana.app/v0alpha1",
"kind": "Plugin",
"metadata": {"name": "%s"},
"spec": {"id": "grafana-piechart-panel", "version": "1.0.0"}
}`, plugin1Name))
_, err := client.Resource.Create(ctx, plugin1, metav1.CreateOptions{})
require.NoError(t, err)
plugin2Name := "test-plugin-metas-2"
plugin2 := helper.LoadYAMLOrJSON(fmt.Sprintf(`{
"apiVersion": "plugins.grafana.app/v0alpha1",
"kind": "Plugin",
"metadata": {"name": "%s"},
"spec": {"id": "grafana-clock-panel", "version": "1.0.0"}
}`, plugin2Name))
_, err = client.Resource.Create(ctx, plugin2, metav1.CreateOptions{})
require.NoError(t, err)
namespace := helper.Namespacer(helper.Org1.Admin.Identity.GetOrgID())
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/pluginmetas", namespace)
response := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Method: "GET",
Path: path,
}, &pluginsv0alpha1.PluginMetaList{})
require.NotNil(t, response.Result)
require.NotNil(t, response.Result.Items)
require.GreaterOrEqual(t, len(response.Result.Items), 2)
foundIDs := make(map[string]bool)
for _, item := range response.Result.Items {
require.NotNil(t, item.Spec.PluginJSON)
foundIDs[item.Spec.PluginJSON.Id] = true
require.NotEmpty(t, item.Spec.PluginJSON.Id)
require.NotEmpty(t, item.Spec.PluginJSON.Type)
require.NotEmpty(t, item.Spec.PluginJSON.Name)
}
require.True(t, foundIDs["grafana-piechart-panel"])
require.True(t, foundIDs["grafana-clock-panel"])
})
t.Run("list plugin metas with no plugins", func(t *testing.T) {
helper := setupHelper(t)
namespace := helper.Namespacer(helper.Org1.Admin.Identity.GetOrgID())
path := fmt.Sprintf("/apis/plugins.grafana.app/v0alpha1/namespaces/%s/pluginmetas", namespace)
response := apis.DoRequest(helper, apis.RequestParams{
User: helper.Org1.Admin,
Method: "GET",
Path: path,
}, &pluginsv0alpha1.PluginMetaList{})
require.NotNil(t, response.Result)
require.NotNil(t, response.Result.Items)
require.GreaterOrEqual(t, len(response.Result.Items), 0)
})
}