diff --git a/pkg/registry/apis/provisioning/finalizers.go b/pkg/registry/apis/provisioning/controller/finalizers.go similarity index 88% rename from pkg/registry/apis/provisioning/finalizers.go rename to pkg/registry/apis/provisioning/controller/finalizers.go index dff3fa1d16a..134abff9fcd 100644 --- a/pkg/registry/apis/provisioning/finalizers.go +++ b/pkg/registry/apis/provisioning/controller/finalizers.go @@ -1,4 +1,4 @@ -package provisioning +package controller import ( "sort" @@ -19,14 +19,14 @@ import ( "github.com/grafana/grafana/pkg/registry/apis/provisioning/resources" ) -// Remove everything this repo created -const finalizer_REMOVE_ORPHAN_RESOURCE = "remove-orphan-resources" +// RemoveOrphanResourcesFinalizer removes everything this repo created +const RemoveOrphanResourcesFinalizer = "remove-orphan-resources" -// Remove the metadata for anything this repo created -const finalizer_RELEASE_ORPHAN_RESOURCE = "release-orphan-resources" +// ReleaseOrphanResourcesFinalizer removes the metadata for anything this repo created +const ReleaseOrphanResourcesFinalizer = "release-orphan-resources" -// Calls the "OnDelete" function for resource -const finalizer_CLEANUP_FINALIZER = "cleanup" +// CleanFinalizer calls the "OnDelete" function for resource +const CleanFinalizer = "cleanup" type finalizer struct { lister resources.ResourceLister @@ -41,7 +41,7 @@ func (f *finalizer) process(ctx context.Context, for _, finalizer := range finalizers { switch finalizer { - case finalizer_CLEANUP_FINALIZER: + case CleanFinalizer: // NOTE: the controller loop will never get run unless a finalizer is set hooks, ok := repo.(repository.RepositoryHooks) if ok { @@ -50,7 +50,7 @@ func (f *finalizer) process(ctx context.Context, } } - case finalizer_RELEASE_ORPHAN_RESOURCE: + case ReleaseOrphanResourcesFinalizer: err := f.processExistingItems(ctx, repo.Config(), func(client dynamic.ResourceInterface, item *provisioning.ResourceListItem) error { _, err := client.Patch(ctx, item.Name, types.JSONPatchType, []byte(`[ @@ -64,7 +64,7 @@ func (f *finalizer) process(ctx context.Context, return err } - case finalizer_REMOVE_ORPHAN_RESOURCE: + case RemoveOrphanResourcesFinalizer: err := f.processExistingItems(ctx, repo.Config(), func(client dynamic.ResourceInterface, item *provisioning.ResourceListItem) error { return client.Delete(ctx, item.Name, v1.DeleteOptions{}) diff --git a/pkg/registry/apis/provisioning/repository_controller.go b/pkg/registry/apis/provisioning/controller/repository.go similarity index 94% rename from pkg/registry/apis/provisioning/repository_controller.go rename to pkg/registry/apis/provisioning/controller/repository.go index a9ae4ec4298..908629ccd11 100644 --- a/pkg/registry/apis/provisioning/repository_controller.go +++ b/pkg/registry/apis/provisioning/controller/repository.go @@ -1,4 +1,4 @@ -package provisioning +package controller import ( "context" @@ -26,11 +26,21 @@ import ( "github.com/grafana/grafana/pkg/registry/apis/provisioning/resources" ) +type RepoGetter interface { + // Given a repository configuration, return it as a repository instance + // This will only error for un-recoverable system errors + // the repository instance may or may not be valid/healthy + AsRepository(ctx context.Context, cfg *provisioning.Repository) (repository.Repository, error) +} + +type RepositoryTester interface { + TestRepository(ctx context.Context, repo repository.Repository) (*provisioning.TestResults, error) +} + const loggerName = "provisioning-repository-controller" const ( - maxAttempts = 3 - ResyncInterval = 10 * time.Second + maxAttempts = 3 ) type queueItem struct { @@ -53,8 +63,7 @@ type RepositoryController struct { // Converts config to instance repoGetter RepoGetter - tester *repository.Tester - + tester RepositoryTester // To allow injection for testing. processFn func(item *queueItem) error enqueueRepository func(obj any) @@ -70,7 +79,7 @@ func NewRepositoryController( repoGetter RepoGetter, resourceLister resources.ResourceLister, parsers *resources.ParserFactory, - tester *repository.Tester, + tester RepositoryTester, jobs jobs.JobQueue, ) (*RepositoryController, error) { rc := &RepositoryController{ @@ -296,9 +305,7 @@ func (rc *RepositoryController) process(item *queueItem) error { statusPatch["health"] = health } - var ( - sync *provisioning.SyncJobOptions - ) + var sync *provisioning.SyncJobOptions switch { case obj.Status.ObservedGeneration < 1: diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index 3e2b88e71f7..1b00490554f 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -29,6 +29,7 @@ import ( clientset "github.com/grafana/grafana/pkg/generated/clientset/versioned" informers "github.com/grafana/grafana/pkg/generated/informers/externalversions" listers "github.com/grafana/grafana/pkg/generated/listers/provisioning/v0alpha1" + "github.com/grafana/grafana/pkg/registry/apis/provisioning/controller" "github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs" "github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs/export" "github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs/pullrequest" @@ -320,8 +321,8 @@ func (b *APIBuilder) Mutate(ctx context.Context, a admission.Attributes, o admis // This is called on every update, so be careful to only add the finalizer for create if len(r.Finalizers) == 0 && a.GetOperation() == admission.Create { r.Finalizers = []string{ - finalizer_REMOVE_ORPHAN_RESOURCE, - finalizer_CLEANUP_FINALIZER, + controller.RemoveOrphanResourcesFinalizer, + controller.CleanFinalizer, } } @@ -413,11 +414,9 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH if err != nil { return err } - sharedInformerFactory := informers.NewSharedInformerFactory( - c, - ResyncInterval, // Health and reconciliation interval check interval - ) + // Informer with resync interval used for health check and reconciliation + sharedInformerFactory := informers.NewSharedInformerFactory(c, 10*time.Second) repoInformer := sharedInformerFactory.Provisioning().V0alpha1().Repositories() go repoInformer.Informer().Run(postStartHookCtx.Context.Done()) @@ -442,7 +441,7 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH } b.jobs.Register(pullRequestWorker) - repoController, err := NewRepositoryController( + repoController, err := controller.NewRepositoryController( c.ProvisioningV0alpha1(), repoInformer, b, // repoGetter