mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 09:34:27 +08:00

* Dashboards API: v2alpha2 missing pieces * Fix issue with dashboard client scope for alpha versions As we now have 2 different alpha versions for v2 we need to store the clients separately. * Improve debuggability of provisioning export test - Add a helper function to print the tree structure. - Be explicit about the expected file names expected in each case. * Update pkg/registry/apis/dashboard/mutate.go * Update pkg/services/authz/zanzana/server/server.go Co-authored-by: Igor Suleymanov <radiohead@users.noreply.github.com> * Review * go lint --------- Co-authored-by: Roberto Jimenez Sanchez <roberto.jimenez@grafana.com> Co-authored-by: Stephanie Hingtgen <stephanie.hingtgen@grafana.com> Co-authored-by: Igor Suleymanov <radiohead@users.noreply.github.com>
78 lines
2.9 KiB
Go
78 lines
2.9 KiB
Go
package dashboard
|
|
|
|
import (
|
|
"context"
|
|
_ "embed"
|
|
"fmt"
|
|
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
|
|
|
v0 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
|
v1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
|
v2alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
|
|
v2alpha2 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha2"
|
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
)
|
|
|
|
// ValidateDashboardSpec validates the dashboard spec and throws a detailed error if there are validation errors.
|
|
func (b *DashboardsAPIBuilder) ValidateDashboardSpec(ctx context.Context, obj runtime.Object, fieldValidationMode string) (field.ErrorList, error) {
|
|
accessor, err := utils.MetaAccessor(obj)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting meta accessor: %w", err)
|
|
}
|
|
|
|
errorOnSchemaMismatches := false
|
|
mode := fieldValidationMode
|
|
if mode != metav1.FieldValidationIgnore {
|
|
switch obj.(type) {
|
|
case *v0.Dashboard:
|
|
errorOnSchemaMismatches = false // Never error for v0
|
|
case *v1.Dashboard:
|
|
errorOnSchemaMismatches = !b.features.IsEnabled(ctx, featuremgmt.FlagDashboardDisableSchemaValidationV1)
|
|
case *v2alpha1.Dashboard:
|
|
case *v2alpha2.Dashboard:
|
|
errorOnSchemaMismatches = !b.features.IsEnabled(ctx, featuremgmt.FlagDashboardDisableSchemaValidationV2)
|
|
default:
|
|
return nil, fmt.Errorf("invalid dashboard type: %T", obj)
|
|
}
|
|
}
|
|
if mode == metav1.FieldValidationWarn {
|
|
return nil, apierrors.NewBadRequest("Not supported: FieldValidationMode: Warn")
|
|
}
|
|
|
|
alwaysLogSchemaValidationErrors := b.features.IsEnabled(ctx, featuremgmt.FlagDashboardSchemaValidationLogging)
|
|
|
|
var errors field.ErrorList
|
|
var schemaVersionError field.ErrorList
|
|
if errorOnSchemaMismatches || alwaysLogSchemaValidationErrors {
|
|
switch v := obj.(type) {
|
|
case *v0.Dashboard:
|
|
errors, schemaVersionError = v0.ValidateDashboardSpec(v, alwaysLogSchemaValidationErrors)
|
|
case *v1.Dashboard:
|
|
errors, schemaVersionError = v1.ValidateDashboardSpec(v, alwaysLogSchemaValidationErrors)
|
|
case *v2alpha1.Dashboard:
|
|
errors = v2alpha1.ValidateDashboardSpec(v)
|
|
case *v2alpha2.Dashboard:
|
|
errors = v2alpha2.ValidateDashboardSpec(v)
|
|
}
|
|
}
|
|
|
|
if alwaysLogSchemaValidationErrors && len(errors) > 0 {
|
|
b.log.Info("Schema validation errors during dashboard validation", "group_version", obj.GetObjectKind().GroupVersionKind().GroupVersion().String(), "name", accessor.GetName(), "errors", errors.ToAggregate().Error(), "schema_version_mismatch", schemaVersionError != nil)
|
|
}
|
|
|
|
if errorOnSchemaMismatches {
|
|
if schemaVersionError != nil {
|
|
return schemaVersionError, nil
|
|
}
|
|
if len(errors) > 0 {
|
|
return errors, nil
|
|
}
|
|
}
|
|
return nil, nil
|
|
}
|