POC/Provisioning: Import: Apply folder nesting properly (#97143)

This commit is contained in:
Mariell Hoversholm authored and GitHub committed 2024-11-28 14:03:26 +01:00
1 parent d8b1834139
commit a600cc6eb7
2 files changed
+23 -28

No files matched your search

+3 -6
View File
@@ -89,7 +89,8 @@ func RegisterAPIService(
ghFactory github.ClientFactory,
) *ProvisioningAPIBuilder {
if !(features.IsEnabledGlobally(featuremgmt.FlagProvisioning) ||
features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs)) {
features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) ||
features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerTestingWithExperimentalAPIs)) {
return nil // skip registration unless opting into experimental apis OR the feature specifically
}
builder := NewProvisioningAPIBuilder(&repository.LocalFolderResolver{
@@ -279,11 +280,6 @@ func (b *ProvisioningAPIBuilder) beginUpdate(ctx context.Context, obj, old runti
}
func (b *ProvisioningAPIBuilder) ensureRepositoryFolderExists(ctx context.Context, cfg *provisioning.Repository) error {
if !b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesFolders) && !b.features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerTestingWithExperimentalAPIs) {
// Nothing to do: we can't use the folders API.
return nil
}
if cfg.Spec.Folder == "" {
// The root folder can't not exist, so we don't have to do anything.
return nil
@@ -293,6 +289,7 @@ func (b *ProvisioningAPIBuilder) ensureRepositoryFolderExists(ctx context.Contex
if err != nil {
return err
}
// FIXME: make sure folders are actually enabled in the apiserver.
folderIface := client.Resource(schema.GroupVersionResource{
Group: "folder.grafana.app",
Version: "v0alpha1",
@@ -5,10 +5,10 @@ import (
"errors"
"fmt"
"log/slog"
"path"
"path/filepath"
"strings"
apiutils "github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -45,18 +45,20 @@ func (f *ReplicatorFactory) New() (repository.FileReplicator, error) {
})
return &replicator{
logger: slog.Default().With("logger", "replicator", "namespace", f.namespace),
parser: parser,
client: dynamicClient,
folders: folders,
logger: slog.Default().With("logger", "replicator", "namespace", f.namespace),
parser: parser,
client: dynamicClient,
folders: folders,
repository: f.repo,
}, nil
}
type replicator struct {
logger *slog.Logger
client *DynamicClient
parser *FileParser
folders dynamic.ResourceInterface
logger *slog.Logger
client *DynamicClient
parser *FileParser
folders dynamic.ResourceInterface
repository repository.Repository
}
// Replicate creates a new resource in the cluster.
@@ -99,13 +101,13 @@ func (r *replicator) Replicate(ctx context.Context, fileInfo *repository.FileInf
func (r *replicator) createFolderPath(ctx context.Context, filePath string) (string, error) {
dir := filepath.Dir(filePath)
if dir == "." || dir == "/" {
return "", nil
parent := r.repository.Config().Spec.Folder
if dir == "." {
return parent, nil
}
logger := r.logger.With("file", filePath)
for _, folder := range strings.Split(dir, "/") {
for _, folder := range strings.Split(dir, string(filepath.Separator)) {
logger := logger.With("folder", folder)
obj, err := r.folders.Get(ctx, folder, metav1.GetOptions{})
// FIXME: Check for IsNotFound properly
@@ -119,6 +121,9 @@ func (r *replicator) createFolderPath(ctx context.Context, filePath string) (str
"metadata": map[string]any{
"name": folder,
"namespace": r.client.GetNamespace(),
"annotations": map[string]any{
apiutils.AnnoKeyFolder: parent,
},
},
"spec": map[string]any{
"title": folder, // TODO: how do we want to get this?
@@ -127,18 +132,11 @@ func (r *replicator) createFolderPath(ctx context.Context, filePath string) (str
},
}, metav1.CreateOptions{})
if err != nil {
return "", fmt.Errorf("failed to create folder %s: %w", folder, err)
return parent, fmt.Errorf("failed to create folder %s: %w", folder, err)
}
parent = folder
logger.InfoContext(ctx, "folder created")
// TODO: folder parents
// TODO: the top-most folder's parent must be the repo folder.
}
parent := path.Base(path.Dir(filePath))
if parent == "." || parent == "/" {
return "", nil
}
return parent, nil