mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			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"
 | 
						|
	v2beta1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1"
 | 
						|
	"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 *v2beta1.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 *v2beta1.Dashboard:
 | 
						|
			errors = v2beta1.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
 | 
						|
}
 |