Dashboards: Only expose LibraryPanels and search on v0 (not v1+v2) (#103335)
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"path"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -197,7 +196,7 @@ func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver
|
||||
// v0alpha1
|
||||
if err := b.storageForVersion(apiGroupInfo, opts, largeObjects,
|
||||
v0alpha1.DashboardResourceInfo,
|
||||
v0alpha1.LibraryPanelResourceInfo,
|
||||
&v0alpha1.LibraryPanelResourceInfo,
|
||||
func(obj runtime.Object, access *internal.DashboardAccess) (v runtime.Object, err error) {
|
||||
dto := &v0alpha1.DashboardWithAccessInfo{}
|
||||
dash, ok := obj.(*v0alpha1.Dashboard)
|
||||
@@ -215,7 +214,7 @@ func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver
|
||||
// v1alpha1
|
||||
if err := b.storageForVersion(apiGroupInfo, opts, largeObjects,
|
||||
v1alpha1.DashboardResourceInfo,
|
||||
v1alpha1.LibraryPanelResourceInfo,
|
||||
nil, // do not register library panel
|
||||
func(obj runtime.Object, access *internal.DashboardAccess) (v runtime.Object, err error) {
|
||||
dto := &v1alpha1.DashboardWithAccessInfo{}
|
||||
dash, ok := obj.(*v1alpha1.Dashboard)
|
||||
@@ -233,7 +232,7 @@ func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver
|
||||
// v2alpha1
|
||||
if err := b.storageForVersion(apiGroupInfo, opts, largeObjects,
|
||||
v2alpha1.DashboardResourceInfo,
|
||||
v2alpha1.LibraryPanelResourceInfo,
|
||||
nil, // do not register library panel
|
||||
func(obj runtime.Object, access *internal.DashboardAccess) (v runtime.Object, err error) {
|
||||
dto := &v2alpha1.DashboardWithAccessInfo{}
|
||||
dash, ok := obj.(*v2alpha1.Dashboard)
|
||||
@@ -256,7 +255,7 @@ func (b *DashboardsAPIBuilder) storageForVersion(
|
||||
opts builder.APIGroupOptions,
|
||||
largeObjects apistore.LargeObjectSupport,
|
||||
dashboards utils.ResourceInfo,
|
||||
libraryPanels utils.ResourceInfo,
|
||||
libraryPanels *utils.ResourceInfo,
|
||||
newDTOFunc dtoBuilder,
|
||||
) error {
|
||||
// Register the versioned storage
|
||||
@@ -294,9 +293,11 @@ func (b *DashboardsAPIBuilder) storageForVersion(
|
||||
}
|
||||
|
||||
// Expose read only library panels
|
||||
storage[libraryPanels.StoragePath()] = &LibraryPanelStore{
|
||||
Access: b.legacy.Access,
|
||||
ResourceInfo: libraryPanels,
|
||||
if libraryPanels != nil {
|
||||
storage[libraryPanels.StoragePath()] = &LibraryPanelStore{
|
||||
Access: b.legacy.Access,
|
||||
ResourceInfo: *libraryPanels,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -312,27 +313,15 @@ func (b *DashboardsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefiniti
|
||||
}
|
||||
|
||||
func (b *DashboardsAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) {
|
||||
// The plugin description
|
||||
oas.Info.Description = "Grafana dashboards as resources"
|
||||
|
||||
for _, gv := range b.GetGroupVersions() {
|
||||
version := gv.Version
|
||||
// Hide cluster-scoped resources
|
||||
root := path.Join("/apis/", v0alpha1.GROUP, version)
|
||||
delete(oas.Paths.Paths, path.Join(root, "dashboards"))
|
||||
delete(oas.Paths.Paths, path.Join(root, "watch", "dashboards"))
|
||||
|
||||
if version == v0alpha1.VERSION {
|
||||
sub := oas.Paths.Paths[path.Join(root, "search", "{name}")]
|
||||
oas.Paths.Paths[path.Join(root, "search")] = sub
|
||||
delete(oas.Paths.Paths, path.Join(root, "search", "{name}"))
|
||||
}
|
||||
}
|
||||
|
||||
return oas, nil
|
||||
}
|
||||
|
||||
func (b *DashboardsAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
func (b *DashboardsAPIBuilder) GetAPIRoutes(gv schema.GroupVersion) *builder.APIRoutes {
|
||||
if gv.Version != v0alpha1.VERSION {
|
||||
return nil // Only show the custom routes for v0
|
||||
}
|
||||
|
||||
defs := b.GetOpenAPIDefinitions()(func(path string) spec.Ref { return spec.Ref{} })
|
||||
return b.search.GetAPIRoutes(defs)
|
||||
}
|
||||
|
||||
@@ -34,8 +34,11 @@ import (
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
var _ builder.APIGroupBuilder = (*SnapshotsAPIBuilder)(nil)
|
||||
var _ builder.OpenAPIPostProcessor = (*SnapshotsAPIBuilder)(nil)
|
||||
var (
|
||||
_ builder.APIGroupBuilder = (*SnapshotsAPIBuilder)(nil)
|
||||
_ builder.OpenAPIPostProcessor = (*SnapshotsAPIBuilder)(nil)
|
||||
_ builder.APIGroupRouteProvider = (*SnapshotsAPIBuilder)(nil)
|
||||
)
|
||||
|
||||
var resourceInfo = dashboardsnapshot.DashboardSnapshotResourceInfo
|
||||
|
||||
@@ -146,7 +149,7 @@ func (b *SnapshotsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitio
|
||||
}
|
||||
|
||||
// Register additional routes with the server
|
||||
func (b *SnapshotsAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
func (b *SnapshotsAPIBuilder) GetAPIRoutes(gv schema.GroupVersion) *builder.APIRoutes {
|
||||
prefix := dashboardsnapshot.DashboardSnapshotResourceInfo.GroupResource().Resource
|
||||
defs := dashboardsnapshot.GetOpenAPIDefinitions(func(path string) spec.Ref { return spec.Ref{} })
|
||||
createCmd := defs["github.com/grafana/grafana/apps/dashboard/pkg/apissnapshot/v0alpha1.DashboardCreateCommand"].Schema
|
||||
@@ -347,8 +350,5 @@ func (b *SnapshotsAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.Ope
|
||||
sub.Get.Description = "Read the full dashboard body"
|
||||
}
|
||||
|
||||
// Hide the invalid endpoint to list all snapshots for all orgs
|
||||
delete(oas.Paths.Paths, "/apis/dashboardsnapshot.grafana.app/v0alpha1/dashboardsnapshots")
|
||||
|
||||
return oas, nil
|
||||
}
|
||||
|
||||
@@ -260,9 +260,6 @@ func (b *DataSourceAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.Op
|
||||
// The root api URL
|
||||
root := "/apis/" + b.connectionResourceInfo.GroupVersion().String() + "/"
|
||||
|
||||
// Hide the ability to list all connections across tenants
|
||||
delete(oas.Paths.Paths, root+b.connectionResourceInfo.GroupResource().Resource)
|
||||
|
||||
// Add queries to the request properties
|
||||
// Add queries to the request properties
|
||||
err := queryschema.AddQueriesToOpenAPI(queryschema.OASQueryOptions{
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
)
|
||||
|
||||
var _ builder.APIGroupBuilder = (*FeatureFlagAPIBuilder)(nil)
|
||||
var _ builder.APIGroupRouteProvider = (*FeatureFlagAPIBuilder)(nil)
|
||||
|
||||
var gv = v0alpha1.SchemeGroupVersion
|
||||
|
||||
@@ -100,7 +101,7 @@ func (b *FeatureFlagAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
||||
}
|
||||
|
||||
// Register additional routes with the server
|
||||
func (b *FeatureFlagAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
func (b *FeatureFlagAPIBuilder) GetAPIRoutes(gv schema.GroupVersion) *builder.APIRoutes {
|
||||
defs := v0alpha1.GetOpenAPIDefinitions(func(path string) spec.Ref { return spec.Ref{} })
|
||||
stateSchema := defs["github.com/grafana/grafana/pkg/apis/featuretoggle/v0alpha1.ResolvedToggleState"].Schema
|
||||
|
||||
|
||||
@@ -197,15 +197,7 @@ func (b *FolderAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions
|
||||
}
|
||||
|
||||
func (b *FolderAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) {
|
||||
// The plugin description
|
||||
oas.Info.Description = "Grafana folders"
|
||||
|
||||
// The root api URL
|
||||
root := "/apis/" + b.GetGroupVersion().String() + "/"
|
||||
|
||||
// Hide the ability to list or watch across all tenants
|
||||
delete(oas.Paths.Paths, root+v0alpha1.FolderResourceInfo.GroupResource().Resource)
|
||||
|
||||
return oas, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
)
|
||||
|
||||
var _ builder.APIGroupBuilder = (*IdentityAccessManagementAPIBuilder)(nil)
|
||||
var _ builder.APIGroupRouteProvider = (*IdentityAccessManagementAPIBuilder)(nil)
|
||||
|
||||
// This is used just so wire has something unique to return
|
||||
type IdentityAccessManagementAPIBuilder struct {
|
||||
@@ -182,7 +183,7 @@ func (b *IdentityAccessManagementAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenA
|
||||
return oas, nil
|
||||
}
|
||||
|
||||
func (b *IdentityAccessManagementAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
func (b *IdentityAccessManagementAPIBuilder) GetAPIRoutes(gv schema.GroupVersion) *builder.APIRoutes {
|
||||
defs := b.GetOpenAPIDefinitions()(func(path string) spec.Ref { return spec.Ref{} })
|
||||
return b.display.GetAPIRoutes(defs)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
|
||||
@@ -19,7 +20,7 @@ import (
|
||||
|
||||
// TODO: Move the specific logic to the connector so that we don't have logic all over the place.
|
||||
// GetAPIRoutes implements the direct HTTP handlers that bypass k8s
|
||||
func (b *APIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
func (b *APIBuilder) GetAPIRoutes(gv schema.GroupVersion) *builder.APIRoutes {
|
||||
return &builder.APIRoutes{
|
||||
Namespace: []builder.APIRouteHandler{
|
||||
{
|
||||
|
||||
@@ -29,10 +29,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
_ builder.APIGroupBuilder = (*SecretAPIBuilder)(nil)
|
||||
_ builder.APIGroupMutation = (*SecretAPIBuilder)(nil)
|
||||
_ builder.APIGroupValidation = (*SecretAPIBuilder)(nil)
|
||||
_ builder.APIGroupRouteProvider = (*SecretAPIBuilder)(nil)
|
||||
_ builder.APIGroupBuilder = (*SecretAPIBuilder)(nil)
|
||||
_ builder.APIGroupMutation = (*SecretAPIBuilder)(nil)
|
||||
_ builder.APIGroupValidation = (*SecretAPIBuilder)(nil)
|
||||
)
|
||||
|
||||
type SecretAPIBuilder struct {
|
||||
@@ -156,11 +155,6 @@ func (b *SecretAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
||||
return authsvc.NewResourceAuthorizer(b.accessClient)
|
||||
}
|
||||
|
||||
// Register additional routes with the server.
|
||||
func (b *SecretAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate is called in `Create`, `Update` and `Delete` REST funcs, if the body calls the argument `rest.ValidateObjectFunc`.
|
||||
func (b *SecretAPIBuilder) Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
obj := a.GetObject()
|
||||
|
||||
@@ -64,7 +64,7 @@ type APIGroupValidation interface {
|
||||
|
||||
type APIGroupRouteProvider interface {
|
||||
// Support direct HTTP routes from an APIGroup
|
||||
GetAPIRoutes() *APIRoutes
|
||||
GetAPIRoutes(gv schema.GroupVersion) *APIRoutes
|
||||
}
|
||||
|
||||
type APIGroupPostStartHookProvider interface {
|
||||
|
||||
@@ -125,7 +125,7 @@ func getOpenAPIPostProcessor(version string, builders []APIGroupBuilder) func(*s
|
||||
// Optionally include raw http handlers
|
||||
provider, ok := b.(APIGroupRouteProvider)
|
||||
if ok && provider != nil {
|
||||
routes := provider.GetAPIRoutes()
|
||||
routes := provider.GetAPIRoutes(gv)
|
||||
if routes != nil {
|
||||
for _, route := range routes.Root {
|
||||
copy.Paths.Paths[prefix+route.Path] = &spec3.Path{
|
||||
|
||||
@@ -23,12 +23,12 @@ func GetCustomRoutesHandler(delegateHandler http.Handler, restConfig *restclient
|
||||
continue
|
||||
}
|
||||
|
||||
routes := provider.GetAPIRoutes()
|
||||
if routes == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, gv := range GetGroupVersions(builder) {
|
||||
routes := provider.GetAPIRoutes(gv)
|
||||
if routes == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
prefix := "/apis/" + gv.String()
|
||||
|
||||
// Root handlers
|
||||
|
||||
@@ -1311,8 +1311,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apis/dashboard.grafana.app/v0alpha1/search": null
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -62,6 +62,12 @@ func TestIntegrationOpenAPIs(t *testing.T) {
|
||||
var groups = []schema.GroupVersion{{
|
||||
Group: "dashboard.grafana.app",
|
||||
Version: "v0alpha1",
|
||||
}, {
|
||||
Group: "dashboard.grafana.app",
|
||||
Version: "v1alpha1",
|
||||
}, {
|
||||
Group: "dashboard.grafana.app",
|
||||
Version: "v2alpha1",
|
||||
}, {
|
||||
Group: "folder.grafana.app",
|
||||
Version: "v0alpha1",
|
||||
|
||||
Reference in New Issue
Block a user