Provisioning: Configurable Repository Types in monolith and operators (#110822)

* Configurable repository types in monolith and operator

* Default to Github in operators

* Regenerate wire

* Fix and implement unit tests

* Same types for enterprise tests

* Remove unnecessary conversion

* Remove the issue with import cycles
This commit is contained in:
Roberto Jiménez Sánchez
2025-09-09 19:13:22 +02:00
committed by GitHub
parent 3f4c523ef5
commit acbc2cf01a
8 changed files with 361 additions and 45 deletions
+11 -3
View File
@@ -23,6 +23,7 @@ import (
authrt "github.com/grafana/grafana/apps/provisioning/pkg/auth"
client "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/git"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/github"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/local"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
@@ -64,9 +65,10 @@ type provisioningControllerConfig struct {
// tls_key_file =
// tls_ca_file =
// resync_interval =
// repository_types =
// home_path =
// local_permitted_prefixes =
// [provisioning]
// repository_types =
func setupFromConfig(cfg *setting.Cfg) (controllerCfg *provisioningControllerConfig, err error) {
if cfg == nil {
return nil, fmt.Errorf("no configuration available")
@@ -220,7 +222,11 @@ func setupRepoFactory(
provisioningClient *client.Clientset,
) (repository.Factory, error) {
operatorSec := cfg.SectionWithEnvOverrides("operator")
repoTypes := operatorSec.Key("repository_types").Strings("|")
provisioningSec := cfg.SectionWithEnvOverrides("provisioning")
repoTypes := provisioningSec.Key("repository_types").Strings("|")
if len(repoTypes) == 0 {
repoTypes = []string{"github"}
}
// TODO: This depends on the different flavor of Grafana
// https://github.com/grafana/git-ui-sync-project/issues/495
@@ -234,6 +240,8 @@ func setupRepoFactory(
alreadyRegistered[provisioning.RepositoryType(t)] = struct{}{}
switch provisioning.RepositoryType(t) {
case provisioning.GitRepositoryType:
extras = append(extras, git.Extra(decrypter))
case provisioning.GitHubRepositoryType:
var webhook *webhooks.WebhookExtraBuilder
provisioningAppURL := operatorSec.Key("provisioning_server_public_url").String()
@@ -267,7 +275,7 @@ func setupRepoFactory(
}
}
repoFactory, err := repository.ProvideFactory(extras)
repoFactory, err := repository.ProvideFactory(alreadyRegistered, extras)
if err != nil {
return nil, fmt.Errorf("create repository factory: %w", err)
}
@@ -1,7 +1,9 @@
package extras
import (
apisprovisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/git"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/github"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/local"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
@@ -25,13 +27,15 @@ func ProvideProvisioningOSSRepositoryExtras(
ghFactory *github.Factory,
webhooksBuilder *webhooks.WebhookExtraBuilder,
) []repository.Extra {
decrypter := repository.ProvideDecrypter(decryptSvc)
return []repository.Extra{
local.Extra(
cfg.HomePath,
cfg.PermittedProvisioningPaths,
),
git.Extra(decrypter),
github.Extra(
repository.ProvideDecrypter(decryptSvc),
decrypter,
ghFactory,
webhooksBuilder,
),
@@ -41,3 +45,12 @@ func ProvideProvisioningOSSRepositoryExtras(
func ProvideExtraWorkers(pullRequestWorker *pullrequest.PullRequestWorker) []jobs.Worker {
return []jobs.Worker{pullRequestWorker}
}
func ProvideFactoryFromConfig(cfg *setting.Cfg, extras []repository.Extra) (repository.Factory, error) {
enabledTypes := make(map[apisprovisioning.RepositoryType]struct{}, len(cfg.ProvisioningRepositoryTypes))
for _, e := range cfg.ProvisioningRepositoryTypes {
enabledTypes[apisprovisioning.RepositoryType(e)] = struct{}{}
}
return repository.ProvideFactory(enabledTypes, extras)
}
+1 -2
View File
@@ -3,7 +3,6 @@ package apiregistry
import (
"github.com/google/wire"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
dashboardinternal "github.com/grafana/grafana/pkg/registry/apis/dashboard"
"github.com/grafana/grafana/pkg/registry/apis/dashboardsnapshot"
"github.com/grafana/grafana/pkg/registry/apis/datasource"
@@ -32,9 +31,9 @@ var WireSetExts = wire.NewSet(
)
var provisioningExtras = wire.NewSet(
repository.ProvideFactory,
pullrequest.ProvidePullRequestWorker,
webhooks.ProvideWebhooksWithImages,
extras.ProvideFactoryFromConfig,
extras.ProvideProvisioningExtraAPIs,
extras.ProvideExtraWorkers,
)
+2 -3
View File
@@ -10,7 +10,6 @@ import (
"github.com/google/wire"
httpclient2 "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/github"
"github.com/grafana/grafana/pkg/api"
"github.com/grafana/grafana/pkg/api/avatar"
@@ -830,7 +829,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
}
factory := github.ProvideFactory()
v5 := extras.ProvideProvisioningOSSRepositoryExtras(cfg, decryptService, factory, webhookExtraBuilder)
repositoryFactory, err := repository.ProvideFactory(v5)
repositoryFactory, err := extras.ProvideFactoryFromConfig(cfg, v5)
if err != nil {
return nil, err
}
@@ -1419,7 +1418,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
}
factory := github.ProvideFactory()
v5 := extras.ProvideProvisioningOSSRepositoryExtras(cfg, decryptService, factory, webhookExtraBuilder)
repositoryFactory, err := repository.ProvideFactory(v5)
repositoryFactory, err := extras.ProvideFactoryFromConfig(cfg, v5)
if err != nil {
return nil, err
}
+14
View File
@@ -134,6 +134,7 @@ type Cfg struct {
PermittedProvisioningPaths []string
// Provisioning config
ProvisioningDisableControllers bool
ProvisioningRepositoryTypes []string
ProvisioningLokiURL string
ProvisioningLokiUser string
ProvisioningLokiPassword string
@@ -2103,6 +2104,19 @@ func (cfg *Cfg) readProvisioningSettings(iniFile *ini.File) error {
}
}
repositoryTypes := strings.TrimSpace(valueAsString(iniFile.Section("provisioning"), "repository_types", "github|local"))
if repositoryTypes != "|" && repositoryTypes != "" {
cfg.ProvisioningRepositoryTypes = strings.Split(repositoryTypes, "|")
for i, s := range cfg.ProvisioningRepositoryTypes {
s = strings.TrimSpace(s)
if s == "" {
return fmt.Errorf("a provisioning repository type is empty in '%s' (at index %d)", repositoryTypes, i)
}
cfg.ProvisioningRepositoryTypes[i] = s
}
}
cfg.ProvisioningDisableControllers = iniFile.Section("provisioning").Key("disable_controllers").MustBool(false)
// Read job history configuration
+4 -16
View File
@@ -19,7 +19,6 @@ import (
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/extensions"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/tests/apis"
"github.com/grafana/grafana/pkg/util/testutil"
@@ -134,21 +133,10 @@ func TestIntegrationProvisioning_CreatingAndGetting(t *testing.T) {
return
}
// FIXME: this should be an enterprise integration test
if extensions.IsEnterprise {
assert.ElementsMatch(collect, []provisioning.RepositoryType{
provisioning.LocalRepositoryType,
provisioning.GitHubRepositoryType,
provisioning.GitRepositoryType,
provisioning.BitbucketRepositoryType,
provisioning.GitLabRepositoryType,
}, settings.AvailableRepositoryTypes)
} else {
assert.ElementsMatch(collect, []provisioning.RepositoryType{
provisioning.LocalRepositoryType,
provisioning.GitHubRepositoryType,
}, settings.AvailableRepositoryTypes)
}
assert.ElementsMatch(collect, []provisioning.RepositoryType{
provisioning.LocalRepositoryType,
provisioning.GitHubRepositoryType,
}, settings.AvailableRepositoryTypes)
}, time.Second*10, time.Millisecond*100, "Expected settings to match")
})