PluginExtensions: Added support for sharing functions (#98888)

* feat: add generic plugin extension functions

* updated betterer.

* Fixed type issues after sync with main.

* Remved extensions from datasource and panel.

* Added validation for extension function registry.

* Added tests and validation logic for function extensions registry.

* removed prop already existing on base.

* fixed lint error.

---------

Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
This commit is contained in:
Dominik Süß
2025-02-13 10:18:55 +01:00
committed by GitHub
co-authored by Marcus Andersson
parent fbf96916aa
commit 8a8e47fcea
40 changed files with 1182 additions and 69 deletions
+29 -14
View File
@@ -57,6 +57,7 @@ func TestFinder_Find(t *testing.T) {
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -96,8 +97,10 @@ func TestFinder_Find(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -127,8 +130,10 @@ func TestFinder_Find(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -200,8 +205,10 @@ func TestFinder_Find(t *testing.T) {
{Name: "Nginx Datasource", Type: "datasource", Role: "Viewer", Action: "plugins.app:access"},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -238,8 +245,10 @@ func TestFinder_Find(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -269,8 +278,10 @@ func TestFinder_Find(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -300,8 +311,10 @@ func TestFinder_Find(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -340,8 +353,10 @@ func TestFinder_Find(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
+17 -8
View File
@@ -106,6 +106,7 @@ func TestLoader_Load(t *testing.T) {
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -201,8 +202,10 @@ func TestLoader_Load(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -249,8 +252,10 @@ func TestLoader_Load(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -304,8 +309,10 @@ func TestLoader_Load(t *testing.T) {
},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
@@ -398,8 +405,10 @@ func TestLoader_Load(t *testing.T) {
{Name: "Root Page (react)", Type: "page", Role: org.RoleViewer, Action: plugins.ActionAppAccess, Path: "/a/my-simple-app", DefaultNav: true, AddToNav: true, Slug: "root-page-react"},
},
Extensions: plugins.Extensions{
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedLinks: []plugins.AddedLink{},
AddedComponents: []plugins.AddedComponent{},
AddedFunctions: []plugins.AddedFunction{},
ExposedComponents: []plugins.ExposedComponent{},
ExtensionPoints: []plugins.ExtensionPoint{},
},
+8
View File
@@ -63,6 +63,7 @@ type ExtensionsV2 struct {
AddedComponents []AddedComponent `json:"addedComponents"`
ExposedComponents []ExposedComponent `json:"exposedComponents"`
ExtensionPoints []ExtensionPoint `json:"extensionPoints"`
AddedFunctions []AddedFunction `json:"addedFunctions"`
}
type Extensions ExtensionsV2
@@ -76,6 +77,7 @@ func (e *Extensions) UnmarshalJSON(data []byte) error {
e.AddedLinks = extensionsV2.AddedLinks
e.ExposedComponents = extensionsV2.ExposedComponents
e.ExtensionPoints = extensionsV2.ExtensionPoints
e.AddedFunctions = extensionsV2.AddedFunctions
return nil
}
@@ -123,6 +125,11 @@ type AddedComponent struct {
Description string `json:"description"`
}
type AddedFunction struct {
Targets []string `json:"targets"`
Title string `json:"title"`
}
type ExposedComponent struct {
Id string `json:"id"`
Title string `json:"title"`
@@ -267,6 +274,7 @@ type PluginMetaDTO struct {
Angular AngularMeta `json:"angular"`
MultiValueFilterOperators bool `json:"multiValueFilterOperators"`
LoadingStrategy LoadingStrategy `json:"loadingStrategy"`
Extensions Extensions `json:"extensions"`
}
type DataSourceDTO struct {
+4
View File
@@ -167,6 +167,10 @@ func ReadPluginJSON(reader io.Reader) (JSONData, error) {
plugin.Extensions.AddedComponents = []AddedComponent{}
}
if plugin.Extensions.AddedFunctions == nil {
plugin.Extensions.AddedFunctions = []AddedFunction{}
}
if plugin.Extensions.ExposedComponents == nil {
plugin.Extensions.ExposedComponents = []ExposedComponent{}
}
+26 -8
View File
@@ -56,6 +56,7 @@ func Test_ReadPluginJSON(t *testing.T) {
Extensions: Extensions{
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedFunctions: []AddedFunction{},
ExposedComponents: []ExposedComponent{},
ExtensionPoints: []ExtensionPoint{},
},
@@ -108,8 +109,10 @@ func Test_ReadPluginJSON(t *testing.T) {
Name: "Pie Chart (old)",
Extensions: Extensions{
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedFunctions: []AddedFunction{},
ExposedComponents: []ExposedComponent{},
ExtensionPoints: []ExtensionPoint{},
},
@@ -143,8 +146,10 @@ func Test_ReadPluginJSON(t *testing.T) {
Type: TypeDataSource,
Extensions: Extensions{
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedFunctions: []AddedFunction{},
ExposedComponents: []ExposedComponent{},
ExtensionPoints: []ExtensionPoint{},
},
@@ -188,6 +193,9 @@ func Test_ReadPluginJSON(t *testing.T) {
"id": "myorg-extensions-app/component-1/v1"
}
],
"addedFunctions": [
{"targets": ["foo/bar"], "title":"some hook"}
],
"extensionPoints": [
{
"title": "Extension point 1",
@@ -209,6 +217,7 @@ func Test_ReadPluginJSON(t *testing.T) {
{Title: "Added link 1", Description: "Added link 1 description", Targets: []string{"grafana/dashboard/panel/menu"}},
},
AddedComponents: []AddedComponent{
{Title: "Added component 1", Description: "Added component 1 description", Targets: []string{"grafana/user/profile/tab"}},
},
ExposedComponents: []ExposedComponent{
@@ -217,6 +226,9 @@ func Test_ReadPluginJSON(t *testing.T) {
ExtensionPoints: []ExtensionPoint{
{Id: "myorg-extensions-app/extensions-point-1/v1", Title: "Extension point 1", Description: "Extension points 1 description"},
},
AddedFunctions: []AddedFunction{
{Targets: []string{"foo/bar"}, Title: "some hook"},
},
},
Dependencies: Dependencies{
@@ -271,6 +283,7 @@ func Test_ReadPluginJSON(t *testing.T) {
AddedComponents: []AddedComponent{
{Title: "Added component 1", Description: "Added component 1 description", Targets: []string{"grafana/user/profile/tab"}},
},
AddedFunctions: []AddedFunction{},
ExposedComponents: []ExposedComponent{},
ExtensionPoints: []ExtensionPoint{},
},
@@ -301,8 +314,10 @@ func Test_ReadPluginJSON(t *testing.T) {
Type: TypeApp,
Extensions: Extensions{
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedFunctions: []AddedFunction{},
ExposedComponents: []ExposedComponent{},
ExtensionPoints: []ExtensionPoint{},
},
@@ -332,8 +347,10 @@ func Test_ReadPluginJSON(t *testing.T) {
Type: TypeApp,
Extensions: Extensions{
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedFunctions: []AddedFunction{},
ExposedComponents: []ExposedComponent{},
ExtensionPoints: []ExtensionPoint{},
},
@@ -371,6 +388,7 @@ func Test_ReadPluginJSON(t *testing.T) {
Extensions: Extensions{
AddedLinks: []AddedLink{},
AddedComponents: []AddedComponent{},
AddedFunctions: []AddedFunction{},
ExposedComponents: []ExposedComponent{},
ExtensionPoints: []ExtensionPoint{},
},