Provisioning: use kind consistently for provisioning stats (#111977)

This commit is contained in:
Ryan McKinley
2025-10-04 09:02:02 -05:00
committed by GitHub
parent 99312a7582
commit 2486dba881
18 changed files with 169 additions and 165 deletions
@@ -221,9 +221,9 @@ func (in JobStatus) ToSyncStatus(jobId string) SyncStatus {
}
type JobResourceSummary struct {
Group string `json:"group,omitempty"`
Resource string `json:"resource,omitempty"`
Total int64 `json:"total,omitempty"` // the count (if known)
Group string `json:"group,omitempty"`
Kind string `json:"kind,omitempty"`
Total int64 `json:"total,omitempty"` // the count (if known)
Create int64 `json:"create,omitempty"`
Update int64 `json:"update,omitempty"`
@@ -846,7 +846,7 @@ func schema_pkg_apis_provisioning_v0alpha1_JobResourceSummary(ref common.Referen
Format: "",
},
},
"resource": {
"kind": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
@@ -7,16 +7,16 @@ package v0alpha1
// JobResourceSummaryApplyConfiguration represents a declarative configuration of the JobResourceSummary type for use
// with apply.
type JobResourceSummaryApplyConfiguration struct {
Group *string `json:"group,omitempty"`
Resource *string `json:"resource,omitempty"`
Total *int64 `json:"total,omitempty"`
Create *int64 `json:"create,omitempty"`
Update *int64 `json:"update,omitempty"`
Delete *int64 `json:"delete,omitempty"`
Write *int64 `json:"write,omitempty"`
Error *int64 `json:"error,omitempty"`
Noop *int64 `json:"noop,omitempty"`
Errors []string `json:"errors,omitempty"`
Group *string `json:"group,omitempty"`
Kind *string `json:"kind,omitempty"`
Total *int64 `json:"total,omitempty"`
Create *int64 `json:"create,omitempty"`
Update *int64 `json:"update,omitempty"`
Delete *int64 `json:"delete,omitempty"`
Write *int64 `json:"write,omitempty"`
Error *int64 `json:"error,omitempty"`
Noop *int64 `json:"noop,omitempty"`
Errors []string `json:"errors,omitempty"`
}
// JobResourceSummaryApplyConfiguration constructs a declarative configuration of the JobResourceSummary type for use with
@@ -33,11 +33,11 @@ func (b *JobResourceSummaryApplyConfiguration) WithGroup(value string) *JobResou
return b
}
// WithResource sets the Resource field in the declarative configuration to the given value
// WithKind sets the Kind field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Resource field is set to the value of the last call.
func (b *JobResourceSummaryApplyConfiguration) WithResource(value string) *JobResourceSummaryApplyConfiguration {
b.Resource = &value
// If called multiple times, the Kind field is set to the value of the last call.
func (b *JobResourceSummaryApplyConfiguration) WithKind(value string) *JobResourceSummaryApplyConfiguration {
b.Kind = &value
return b
}
@@ -45,11 +45,11 @@ func ExportFolders(ctx context.Context, repoName string, options provisioning.Ex
progress.SetMessage(ctx, "write folders to repository")
err := repositoryResources.EnsureFolderTreeExists(ctx, options.Branch, options.Path, tree, func(folder resources.Folder, created bool, err error) error {
result := jobs.JobResourceResult{
Action: repository.FileActionCreated,
Name: folder.ID,
Resource: resources.FolderResource.Resource,
Group: resources.FolderResource.Group,
Path: folder.Path,
Action: repository.FileActionCreated,
Name: folder.ID,
Group: resources.FolderResource.Group,
Kind: resources.FolderKind.Kind,
Path: folder.Path,
}
if err != nil {
@@ -98,10 +98,10 @@ func exportResource(ctx context.Context,
return resources.ForEach(ctx, client, func(item *unstructured.Unstructured) (err error) {
gvk := item.GroupVersionKind()
result := jobs.JobResourceResult{
Name: item.GetName(),
Resource: resource,
Group: gvk.Group,
Action: repository.FileActionCreated,
Name: item.GetName(),
Group: gvk.Group,
Kind: gvk.Kind,
Action: repository.FileActionCreated,
}
// Check if resource is already managed by a repository
@@ -8,7 +8,6 @@ import (
"testing"
"time"
"github.com/grafana/grafana/apps/provisioning/pkg/loki"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -17,6 +16,7 @@ import (
"k8s.io/apimachinery/pkg/types"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/apps/provisioning/pkg/loki"
)
func TestLokiJobHistory_WriteJob(t *testing.T) {
@@ -86,16 +86,16 @@ func TestLokiJobHistory_WriteJob(t *testing.T) {
Errors: []string{"warning: deprecated field used"},
Progress: 100.0,
Summary: []*provisioning.JobResourceSummary{{
Group: "dashboard.grafana.app",
Resource: "dashboards",
Total: 10,
Create: 3,
Update: 5,
Delete: 1,
Write: 8,
Error: 1,
Noop: 0,
Errors: []string{"failed to process dashboard-x"},
Group: "dashboard.grafana.app",
Kind: "Dashboard",
Total: 10,
Create: 3,
Update: 5,
Delete: 1,
Write: 8,
Error: 1,
Noop: 0,
Errors: []string{"failed to process dashboard-x"},
}},
},
}
@@ -178,7 +178,7 @@ func TestLokiJobHistory_WriteJob(t *testing.T) {
require.Len(t, deserializedJob.Status.Summary, 1)
summary := deserializedJob.Status.Summary[0]
assert.Equal(t, "dashboard.grafana.app", summary.Group)
assert.Equal(t, "dashboards", summary.Resource)
assert.Equal(t, "Dashboard", summary.Kind)
assert.Equal(t, int64(10), summary.Total)
assert.Equal(t, int64(3), summary.Create)
assert.Equal(t, int64(5), summary.Update)
@@ -4,12 +4,13 @@ import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
//go:generate mockery --name NamespaceCleaner --structname MockNamespaceCleaner --inpackage --filename mock_namespace_cleaner.go --with-expecter
@@ -40,10 +41,10 @@ func (c *namespaceCleaner) Clean(ctx context.Context, namespace string, progress
if err = resources.ForEach(ctx, client, func(item *unstructured.Unstructured) error {
result := jobs.JobResourceResult{
Name: item.GetName(),
Resource: item.GetKind(),
Group: item.GroupVersionKind().Group,
Action: repository.FileActionDeleted,
Name: item.GetName(),
Kind: item.GetKind(),
Group: item.GroupVersionKind().Group,
Action: repository.FileActionDeleted,
}
// Skip provisioned resources - only delete unprovisioned (unmanaged) resources
@@ -63,7 +64,7 @@ func (c *namespaceCleaner) Clean(ctx context.Context, namespace string, progress
}
if err := client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}); err != nil {
result.Error = fmt.Errorf("deleting resource %s/%s %s: %w", result.Group, result.Resource, result.Name, err)
result.Error = fmt.Errorf("deleting resource %s/%s %s: %w", result.Group, result.Kind, result.Name, err)
progress.Record(ctx, result)
return fmt.Errorf("delete resource: %w", err)
}
@@ -204,11 +204,11 @@ func (r *legacyResourceResourceMigrator) Write(ctx context.Context, key *resourc
}
result := jobs.JobResourceResult{
Name: parsed.Meta.GetName(),
Resource: r.kind.Resource,
Group: r.kind.Group,
Action: repository.FileActionCreated,
Path: fileName,
Name: parsed.Meta.GetName(),
Group: r.kind.Group,
Kind: parsed.GVK.Kind,
Action: repository.FileActionCreated,
Path: fileName,
}
if err != nil {
@@ -667,7 +667,7 @@ func TestLegacyResourceResourceMigrator_Write(t *testing.T) {
return result.Action == repository.FileActionCreated &&
result.Name == "test" &&
result.Error == nil &&
result.Resource == "tests" &&
result.Kind == "" && // empty kind
result.Group == "test.grafana.app" &&
result.Path == "test/path"
})).Return()
+10 -10
View File
@@ -35,12 +35,12 @@ func maybeNotifyProgress(threshold time.Duration, fn ProgressFn) ProgressFn {
// FIXME: ProgressRecorder should be initialized in the queue
type JobResourceResult struct {
Name string
Resource string
Group string
Path string
Action repository.FileAction
Error error
Name string
Group string
Kind string
Path string
Action repository.FileAction
Error error
}
type jobProgressRecorder struct {
@@ -73,7 +73,7 @@ func (r *jobProgressRecorder) Record(ctx context.Context, result JobResourceResu
r.mu.Lock()
r.resultCount++
logger := logging.FromContext(ctx).With("path", result.Path, "resource", result.Resource, "group", result.Group, "action", result.Action, "name", result.Name)
logger := logging.FromContext(ctx).With("path", result.Path, "group", result.Group, "kind", result.Kind, "action", result.Action, "name", result.Name)
if result.Error != nil {
logger.Error("job resource operation failed", "err", result.Error)
if len(r.errors) < 20 {
@@ -173,12 +173,12 @@ func (r *jobProgressRecorder) summary() []*provisioning.JobResourceSummary {
func (r *jobProgressRecorder) updateSummary(result JobResourceResult) {
// Note: This method is called from Record() which already holds the lock
key := result.Resource + ":" + result.Group
key := result.Group + ":" + result.Kind
summary, exists := r.summaries[key]
if !exists {
summary = &provisioning.JobResourceSummary{
Resource: result.Resource,
Group: result.Group,
Group: result.Group,
Kind: result.Kind,
}
r.summaries[key] = summary
}
@@ -4,15 +4,16 @@ import (
"context"
"fmt"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/apps/provisioning/pkg/safepath"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func FullSync(
@@ -92,9 +93,7 @@ func applyChanges(ctx context.Context, changes []ResourceFileChange, clients res
deleteSpan.End()
continue
}
result.Name = change.Existing.Name
result.Resource = change.Existing.Resource
result.Group = change.Existing.Group
versionlessGVR := schema.GroupVersionResource{
@@ -103,15 +102,17 @@ func applyChanges(ctx context.Context, changes []ResourceFileChange, clients res
}
// TODO: should we use the clients or the resource manager instead?
client, _, err := clients.ForResource(deleteCtx, versionlessGVR)
client, gvk, err := clients.ForResource(deleteCtx, versionlessGVR)
if err != nil {
result.Kind = versionlessGVR.Resource // could not find a kind
result.Error = fmt.Errorf("get client for deleted object: %w", err)
progress.Record(deleteCtx, result)
continue
}
result.Kind = gvk.Kind
if err := client.Delete(deleteCtx, change.Existing.Name, metav1.DeleteOptions{}); err != nil {
result.Error = fmt.Errorf("deleting resource %s/%s %s: %w", change.Existing.Group, change.Existing.Resource, change.Existing.Name, err)
result.Error = fmt.Errorf("deleting resource %s/%s %s: %w", change.Existing.Group, gvk.Kind, change.Existing.Name, err)
}
progress.Record(deleteCtx, result)
deleteSpan.End()
@@ -122,10 +123,10 @@ func applyChanges(ctx context.Context, changes []ResourceFileChange, clients res
if safepath.IsDir(change.Path) {
ensureFolderCtx, ensureFolderSpan := tracer.Start(ctx, "provisioning.sync.full.apply_changes.ensure_folder_exists")
result := jobs.JobResourceResult{
Path: change.Path,
Action: change.Action,
Resource: resources.FolderResource.Resource,
Group: resources.FolderResource.Group,
Path: change.Path,
Action: change.Action,
Group: resources.FolderKind.Group,
Kind: resources.FolderKind.Kind,
}
folder, err := repositoryResources.EnsureFolderPathExist(ensureFolderCtx, change.Path)
@@ -147,11 +148,11 @@ func applyChanges(ctx context.Context, changes []ResourceFileChange, clients res
writeCtx, writeSpan := tracer.Start(ctx, "provisioning.sync.full.apply_changes.write_resource_from_file")
name, gvk, err := repositoryResources.WriteResourceFromFile(writeCtx, change.Path, "")
result := jobs.JobResourceResult{
Path: change.Path,
Action: change.Action,
Name: name,
Resource: gvk.Kind,
Group: gvk.Group,
Path: change.Path,
Action: change.Action,
Name: name,
Group: gvk.Group,
Kind: gvk.Kind,
}
if err != nil {
@@ -6,11 +6,6 @@ import (
"fmt"
"testing"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -18,6 +13,12 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
dynamicfake "k8s.io/client-go/dynamic/fake"
k8testing "k8s.io/client-go/testing"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
)
func TestFullSync_ContextCancelled(t *testing.T) {
@@ -209,11 +210,11 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
Return("test-dashboard", schema.GroupVersionKind{Kind: "Dashboard", Group: "dashboards"}, nil)
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionCreated,
Path: "dashboards/one.json",
Name: "test-dashboard",
Resource: "Dashboard",
Group: "dashboards",
Action: repository.FileActionCreated,
Path: "dashboards/one.json",
Name: "test-dashboard",
Kind: "Dashboard",
Group: "dashboards",
}).Return()
},
expectedError: "too many errors",
@@ -234,11 +235,11 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
Return("test-dashboard", schema.GroupVersionKind{Kind: "Dashboard", Group: "dashboards"}, nil)
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionCreated,
Path: "dashboards/test.json",
Name: "test-dashboard",
Resource: "Dashboard",
Group: "dashboards",
Action: repository.FileActionCreated,
Path: "dashboards/test.json",
Name: "test-dashboard",
Kind: "Dashboard",
Group: "dashboards",
}).Return()
},
},
@@ -261,7 +262,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
return result.Action == repository.FileActionCreated &&
result.Path == "dashboards/test.json" &&
result.Name == "test-dashboard" &&
result.Resource == "Dashboard" &&
result.Kind == "Dashboard" &&
result.Group == "dashboards" &&
result.Error != nil &&
result.Error.Error() == "writing resource from file dashboards/test.json: write error"
@@ -284,11 +285,11 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
Return("test-dashboard", schema.GroupVersionKind{Kind: "Dashboard", Group: "dashboards"}, nil)
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionUpdated,
Path: "dashboards/test.json",
Name: "test-dashboard",
Resource: "Dashboard",
Group: "dashboards",
Action: repository.FileActionUpdated,
Path: "dashboards/test.json",
Name: "test-dashboard",
Kind: "Dashboard",
Group: "dashboards",
}).Return()
},
},
@@ -311,7 +312,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
return result.Action == repository.FileActionUpdated &&
result.Path == "dashboards/test.json" &&
result.Name == "test-dashboard" &&
result.Resource == "Dashboard" &&
result.Kind == "Dashboard" &&
result.Group == "dashboards" &&
result.Error != nil &&
result.Error.Error() == "writing resource from file dashboards/test.json: write error"
@@ -335,9 +336,8 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
Action: repository.FileActionCreated,
Path: "one/two/three/",
Name: "some-folder",
// FIXME: this is probably inconsistent across the codebase
Resource: "folders",
Group: "folder.grafana.app",
Kind: "Folder",
Group: "folder.grafana.app",
}).Return()
},
},
@@ -362,7 +362,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
return result.Action == repository.FileActionCreated &&
result.Path == "one/two/three/" &&
result.Name == "" &&
result.Resource == "folders" &&
result.Kind == "Folder" &&
result.Group == "folder.grafana.app" &&
result.Error != nil &&
result.Error.Error() == "ensuring folder exists at path one/two/three/: folder creation error"
@@ -378,7 +378,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
Path: "dashboards/test.json",
Existing: &provisioning.ResourceListItem{
Name: "test-dashboard",
Resource: "Dashboard",
Resource: "dashboards",
Group: "dashboards",
},
},
@@ -411,7 +411,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
clients.On("ForResource", mock.Anything, schema.GroupVersionResource{
Group: "dashboards",
Resource: "Dashboard",
Resource: "dashboards",
}).Return(fakeDynamicClient.Resource(resources.DashboardResource), schema.GroupVersionKind{
Kind: "Dashboard",
Group: "dashboards",
@@ -419,12 +419,12 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
}, nil)
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionDeleted,
Path: "dashboards/test.json",
Name: "test-dashboard",
Resource: "Dashboard",
Group: "dashboards",
Error: nil,
Action: repository.FileActionDeleted,
Path: "dashboards/test.json",
Name: "test-dashboard",
Kind: "Dashboard",
Group: "dashboards",
Error: nil,
}).Return()
},
},
@@ -437,7 +437,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
Path: "dashboards/test.json",
Existing: &provisioning.ResourceListItem{
Name: "test-dashboard",
Resource: "Dashboard",
Resource: "dashboards",
Group: "dashboards",
},
},
@@ -470,7 +470,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
clients.On("ForResource", mock.Anything, schema.GroupVersionResource{
Group: "dashboards",
Resource: "Dashboard",
Resource: "dashboards",
}).Return(fakeDynamicClient.Resource(resources.DashboardResource), schema.GroupVersionKind{
Kind: "Dashboard",
Group: "dashboards",
@@ -481,7 +481,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
return result.Action == repository.FileActionDeleted &&
result.Path == "dashboards/test.json" &&
result.Name == "test-dashboard" &&
result.Resource == "Dashboard" &&
result.Kind == "Dashboard" &&
result.Group == "dashboards" &&
result.Error != nil &&
result.Error.Error() == "deleting resource dashboards/Dashboard test-dashboard: delete failed"
@@ -538,7 +538,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
Existing: &provisioning.ResourceListItem{
Name: "test-dashboard",
Group: "dashboards",
Resource: "Dashboard",
Resource: "dashboards",
},
},
},
@@ -547,16 +547,16 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
clients.On("ForResource", mock.Anything, schema.GroupVersionResource{
Group: "dashboards",
Resource: "Dashboard",
Resource: "dashboards",
}).Return(nil, schema.GroupVersionKind{}, errors.New("didn't work"))
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Name: "test-dashboard",
Group: "dashboards",
Resource: "Dashboard",
Action: repository.FileActionDeleted,
Path: "dashboards/test.json",
Error: fmt.Errorf("get client for deleted object: %w", errors.New("didn't work")),
Name: "test-dashboard",
Group: "dashboards",
Kind: "dashboards", // could not find a real kind
Action: repository.FileActionDeleted,
Path: "dashboards/test.json",
Error: fmt.Errorf("get client for deleted object: %w", errors.New("didn't work")),
}).Return()
},
},
@@ -610,12 +610,12 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
}, nil)
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionDeleted,
Path: "to-be-deleted/",
Name: "test-folder",
Resource: "Folder",
Group: "folders",
Error: nil,
Action: repository.FileActionDeleted,
Path: "to-be-deleted/",
Name: "test-folder",
Kind: "Folder",
Group: "folders",
Error: nil,
}).Return()
},
},
@@ -672,7 +672,7 @@ func TestFullSync_ApplyChanges(t *testing.T) { //nolint:gocyclo
return result.Action == repository.FileActionDeleted &&
result.Path == "to-be-deleted/" &&
result.Name == "test-folder" &&
result.Resource == "Folder" &&
result.Kind == "Folder" &&
result.Group == "folders" &&
result.Error != nil &&
result.Error.Error() == "deleting resource folders/Folder test-folder: delete failed"
@@ -63,11 +63,11 @@ func IncrementalSync(ctx context.Context, repo repository.Versioned, previousRef
}
progress.Record(ensureFolderCtx, jobs.JobResourceResult{
Path: safeSegment,
Action: repository.FileActionCreated,
Resource: resources.FolderResource.Resource,
Group: resources.FolderResource.Group,
Name: folder,
Path: safeSegment,
Action: repository.FileActionCreated,
Group: resources.FolderResource.Group,
Kind: resources.FolderKind.Kind,
Name: folder,
})
ensureFolderSpan.End()
continue
@@ -95,7 +95,7 @@ func IncrementalSync(ctx context.Context, repo repository.Versioned, previousRef
result.Error = fmt.Errorf("writing resource from file %s: %w", change.Path, err)
}
result.Name = name
result.Resource = gvk.Kind
result.Kind = gvk.Kind
result.Group = gvk.Group
writeSpan.End()
case repository.FileActionDeleted:
@@ -106,7 +106,7 @@ func IncrementalSync(ctx context.Context, repo repository.Versioned, previousRef
result.Error = fmt.Errorf("removing resource from file %s: %w", change.Path, err)
}
result.Name = name
result.Resource = gvk.Kind
result.Kind = gvk.Kind
result.Group = gvk.Group
removeSpan.End()
case repository.FileActionRenamed:
@@ -117,7 +117,7 @@ func IncrementalSync(ctx context.Context, repo repository.Versioned, previousRef
result.Error = fmt.Errorf("renaming resource file from %s to %s: %w", change.PreviousPath, change.Path, err)
}
result.Name = name
result.Resource = gvk.Kind
result.Kind = gvk.Kind
result.Group = gvk.Group
renameSpan.End()
case repository.FileActionIgnored:
@@ -5,13 +5,14 @@ import (
"fmt"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func TestIncrementalSync_ContextCancelled(t *testing.T) {
@@ -131,11 +132,11 @@ func TestIncrementalSync(t *testing.T) {
// Mock progress recording
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionCreated,
Path: "unsupported/path/",
Resource: resources.FolderResource.Resource,
Group: resources.FolderResource.Group,
Name: "test-folder",
Action: repository.FileActionCreated,
Path: "unsupported/path/",
Kind: resources.FolderKind.Kind,
Group: resources.FolderResource.Group,
Name: "test-folder",
}).Return()
progress.On("TooManyErrors").Return(nil)
@@ -190,11 +191,11 @@ func TestIncrementalSync(t *testing.T) {
// Mock progress recording
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionDeleted,
Path: "dashboards/old.json",
Name: "old-dashboard",
Resource: "Dashboard",
Group: "dashboards",
Action: repository.FileActionDeleted,
Path: "dashboards/old.json",
Name: "old-dashboard",
Kind: "Dashboard",
Group: "dashboards",
}).Return()
progress.On("TooManyErrors").Return(nil)
@@ -226,11 +227,11 @@ func TestIncrementalSync(t *testing.T) {
// Mock progress recording
progress.On("Record", mock.Anything, jobs.JobResourceResult{
Action: repository.FileActionRenamed,
Path: "dashboards/new.json",
Name: "renamed-dashboard",
Resource: "Dashboard",
Group: "dashboards",
Action: repository.FileActionRenamed,
Path: "dashboards/new.json",
Name: "renamed-dashboard",
Kind: "Dashboard",
Group: "dashboards",
}).Return()
progress.On("TooManyErrors").Return(nil)
@@ -310,7 +311,7 @@ func TestIncrementalSync(t *testing.T) {
return result.Action == repository.FileActionCreated &&
result.Path == "dashboards/test.json" &&
result.Name == "test-dashboard" &&
result.Resource == "Dashboard" &&
result.Kind == "Dashboard" &&
result.Group == "dashboards" &&
result.Error != nil &&
result.Error.Error() == "writing resource from file dashboards/test.json: write failed"
@@ -346,7 +347,7 @@ func TestIncrementalSync(t *testing.T) {
return result.Action == repository.FileActionDeleted &&
result.Path == "dashboards/old.json" &&
result.Name == "old-dashboard" &&
result.Resource == "Dashboard" &&
result.Kind == "Dashboard" &&
result.Group == "dashboards" &&
result.Error != nil &&
result.Error.Error() == "removing resource from file dashboards/old.json: delete failed"
@@ -22,6 +22,7 @@ import (
var (
UserResource = iam.UserResourceInfo.GroupVersionResource()
FolderResource = folders.FolderResourceInfo.GroupVersionResource()
FolderKind = folders.FolderResourceInfo.GroupVersionKind()
DashboardResource = dashboardV1.DashboardResourceInfo.GroupVersionResource()
DashboardResourceV2alpha1 = dashboardV2alpha1.DashboardResourceInfo.GroupVersionResource()
DashboardResourceV2beta1 = dashboardV2beta1.DashboardResourceInfo.GroupVersionResource()
@@ -3706,14 +3706,14 @@
"group": {
"type": "string"
},
"kind": {
"type": "string"
},
"noop": {
"description": "No action required (useful for sync)",
"type": "integer",
"format": "int64"
},
"resource": {
"type": "string"
},
"total": {
"type": "integer",
"format": "int64"
@@ -1010,9 +1010,9 @@ export type JobResourceSummary = {
/** Report errors for this resource type This may not be an exhaustive list and recommend looking at the logs for more info */
errors?: string[];
group?: string;
kind?: string;
/** No action required (useful for sync) */
noop?: number;
resource?: string;
total?: number;
update?: number;
write?: number;
@@ -11,7 +11,7 @@ const getSummaryColumns = () => [
{
id: 'resource',
header: 'Resource',
cell: ({ row: { original: item } }: SummaryCell) => item.resource,
cell: ({ row: { original: item } }: SummaryCell) => item.kind,
},
{
id: 'created',
@@ -58,7 +58,7 @@ export function JobSummary({ summary }: Props) {
<InteractiveTable
data={summary}
columns={getSummaryColumns()}
getRowId={(item) => item.resource || ''}
getRowId={(item) => item.kind || ''}
pageSize={10}
/>
</Stack>