start adding some validation to the store

This commit is contained in:
Dafydd
2025-12-02 15:11:46 +00:00
parent 98d454401c
commit 8214dbc758
2 changed files with 74 additions and 1 deletions
@@ -0,0 +1,72 @@
package collections
import (
"context"
"fmt"
collections "github.com/grafana/grafana/apps/collections/pkg/apis/collections/v1alpha1"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
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"
"k8s.io/apiserver/pkg/registry/rest"
)
var _ grafanarest.Storage = (*datasourceStorage)(nil)
type datasourceStorage struct {
grafanarest.Storage
}
func (s *datasourceStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
// TODO run our own validation here
dsStack, ok := obj.(*collections.DataSourceStack)
if !ok {
return nil, fmt.Errorf("expected a datasource stack object")
}
list := field.ErrorList{}
// Check that the modes are valid
// get the keys from the template
template := dsStack.Spec.Template
templateKeys := make([]string, 0, len(template))
for key := range template {
templateKeys = append(templateKeys, key)
}
// for each mode, check that the keys are in the template
modes := dsStack.Spec.Modes
// if a key is not in the template, return an error
for _, mode := range modes {
for key := range mode.Definition {
if indexOf(templateKeys, key) == -1 {
list = append(list, field.Invalid(field.NewPath("spec", "modes", mode.Name, "definition", key), key, fmt.Sprintf("key %s is not in the template", key)))
}
}
}
if len(list) > 0 {
return nil, apierrors.NewInvalid(collections.DatasourceStacksResourceInfo.GroupVersionKind().GroupKind(), dsStack.Name, list)
}
// TODO find any keys missing from the definition, or is that OK?
// TODO Check that each data source reference is valid
return s.Storage.Create(ctx, obj, createValidation, options)
}
func indexOf(slice []string, item string) int {
for i, v := range slice {
if v == item {
return i
}
}
return -1
}
+2 -1
View File
@@ -116,10 +116,11 @@ func (b *APIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupI
// no need for dual writer for a kind that does not exist in the legacy database
resourceInfo := collections.DatasourceStacksResourceInfo
datasourcesStorage, err := grafanaregistry.NewRegistryStore(opts.Scheme, resourceInfo, opts.OptsGetter)
datasources := &datasourceStorage{Storage: datasourcesStorage}
if err != nil {
return err
}
storage[resourceInfo.StoragePath()] = datasourcesStorage
storage[resourceInfo.StoragePath()] = datasources
apiGroupInfo.VersionedResourcesStorageMap[collections.APIVersion] = storage
return nil