diff --git a/pkg/api/common_test.go b/pkg/api/common_test.go index 2929fb9ec20..442c25684e8 100644 --- a/pkg/api/common_test.go +++ b/pkg/api/common_test.go @@ -57,6 +57,7 @@ import ( "github.com/grafana/grafana/pkg/services/searchusers" "github.com/grafana/grafana/pkg/services/searchusers/filters" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/tag/tagimpl" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/team/teamimpl" @@ -356,7 +357,7 @@ func setupHTTPServerWithCfgDb( } else { var err error ac = acimpl.ProvideAccessControl(cfg) - userSvc, err = userimpl.ProvideService(db, nil, cfg, teamimpl.ProvideService(db, cfg), localcache.ProvideService(), quotatest.New(false, nil)) + userSvc, err = userimpl.ProvideService(db, nil, cfg, teamimpl.ProvideService(db, cfg), localcache.ProvideService(), quotatest.New(false, nil), supportbundlestest.NewFakeBundleService()) require.NoError(t, err) acService, err = acimpl.ProvideService(cfg, db, routeRegister, localcache.ProvideService(), ac, featuremgmt.WithFeatures()) require.NoError(t, err) diff --git a/pkg/api/org_users_test.go b/pkg/api/org_users_test.go index e4ae7c5b0e7..5c19c3c9784 100644 --- a/pkg/api/org_users_test.go +++ b/pkg/api/org_users_test.go @@ -26,6 +26,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgtest" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team/teamtest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" @@ -41,7 +42,7 @@ func setUpGetOrgUsersDB(t *testing.T, sqlStore *sqlstore.SQLStore) { quotaService := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgService, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) _, err = usrSvc.Create(context.Background(), &user.CreateUserCommand{Email: "testUser@grafana.com", Login: testUserLogin}) diff --git a/pkg/api/team_members_test.go b/pkg/api/team_members_test.go index 5d7643c3f56..7a6f44d4cf9 100644 --- a/pkg/api/team_members_test.go +++ b/pkg/api/team_members_test.go @@ -22,6 +22,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/team/teamtest" @@ -54,7 +55,7 @@ func setUpGetTeamMembersHandler(t *testing.T, sqlStore *sqlstore.SQLStore) { quotaService := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgService, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < 3; i++ { diff --git a/pkg/api/user_test.go b/pkg/api/user_test.go index 3fbd072553d..40c03d0315b 100644 --- a/pkg/api/user_test.go +++ b/pkg/api/user_test.go @@ -31,6 +31,7 @@ import ( "github.com/grafana/grafana/pkg/services/searchusers/filters" "github.com/grafana/grafana/pkg/services/secrets/database" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/services/user/usertest" @@ -67,7 +68,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) { hs.authInfoService = srv orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotatest.New(false, nil)) require.NoError(t, err) - userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sc.cfg, nil, nil, quotatest.New(false, nil)) + userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sc.cfg, nil, nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService()) require.NoError(t, err) hs.userService = userSvc @@ -135,7 +136,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) { } orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotatest.New(false, nil)) require.NoError(t, err) - userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sc.cfg, nil, nil, quotatest.New(false, nil)) + userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sc.cfg, nil, nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService()) require.NoError(t, err) _, err = userSvc.Create(context.Background(), &createUserCmd) require.Nil(t, err) diff --git a/pkg/cmd/grafana-cli/commands/conflict_user_command.go b/pkg/cmd/grafana-cli/commands/conflict_user_command.go index f30be391856..3fafb94997d 100644 --- a/pkg/cmd/grafana-cli/commands/conflict_user_command.go +++ b/pkg/cmd/grafana-cli/commands/conflict_user_command.go @@ -27,6 +27,7 @@ import ( "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/migrations" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" @@ -61,7 +62,7 @@ func initializeConflictResolver(cmd *utils.ContextCommandLine, f Formatter, ctx return nil, fmt.Errorf("%v: %w", "failed to get users with conflicting logins", err) } quotaService := quotaimpl.ProvideService(s, cfg) - userService, err := userimpl.ProvideService(s, nil, cfg, nil, nil, quotaService) + userService, err := userimpl.ProvideService(s, nil, cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) if err != nil { return nil, fmt.Errorf("%v: %w", "failed to get user service", err) } diff --git a/pkg/cmd/grafana-cli/commands/conflict_user_command_test.go b/pkg/cmd/grafana-cli/commands/conflict_user_command_test.go index 87b63e7c49d..05e5b343f6e 100644 --- a/pkg/cmd/grafana-cli/commands/conflict_user_command_test.go +++ b/pkg/cmd/grafana-cli/commands/conflict_user_command_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" @@ -855,7 +856,7 @@ func setupTestUserService(t *testing.T, sqlStore *sqlstore.SQLStore) user.Servic t.Helper() orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, "atest.FakeQuotaService{}) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, "atest.FakeQuotaService{}) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, "atest.FakeQuotaService{}, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) return usrSvc diff --git a/pkg/cmd/grafana-cli/runner/wire.go b/pkg/cmd/grafana-cli/runner/wire.go index 3314bacc7c8..86b52a5223a 100644 --- a/pkg/cmd/grafana-cli/runner/wire.go +++ b/pkg/cmd/grafana-cli/runner/wire.go @@ -109,6 +109,8 @@ import ( "github.com/grafana/grafana/pkg/services/store" entitystoredummy "github.com/grafana/grafana/pkg/services/store/entity/dummy" "github.com/grafana/grafana/pkg/services/store/sanitizer" + "github.com/grafana/grafana/pkg/services/supportbundles" + "github.com/grafana/grafana/pkg/services/supportbundles/bundleregistry" "github.com/grafana/grafana/pkg/services/tag" "github.com/grafana/grafana/pkg/services/tag/tagimpl" "github.com/grafana/grafana/pkg/services/team/teamimpl" @@ -158,6 +160,8 @@ var wireSet = wire.NewSet( wire.Bind(new(secrets.Store), new(*secretsDatabase.SecretsStoreImpl)), secretsManager.ProvideSecretsService, wire.Bind(new(secrets.Service), new(*secretsManager.SecretsService)), + bundleregistry.ProvideService, + wire.Bind(new(supportbundles.Service), new(*bundleregistry.Service)), hooks.ProvideService, legacydataservice.ProvideService, wire.Bind(new(legacydata.RequestHandler), new(*legacydataservice.Service)), diff --git a/pkg/infra/usagestats/service/service.go b/pkg/infra/usagestats/service/service.go index 6ab6551c867..9c024b253cb 100644 --- a/pkg/infra/usagestats/service/service.go +++ b/pkg/infra/usagestats/service/service.go @@ -2,6 +2,7 @@ package service import ( "context" + "encoding/json" "time" "github.com/grafana/grafana/pkg/api/routing" @@ -11,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/plugins" ac "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/supportbundles" "github.com/grafana/grafana/pkg/setting" ) @@ -34,7 +36,9 @@ func ProvideService(cfg *setting.Cfg, routeRegister routing.RouteRegister, tracer tracing.Tracer, accesscontrol ac.AccessControl, - accesscontrolService ac.Service) (*UsageStats, error) { + accesscontrolService ac.Service, + bundleRegistry supportbundles.Service, +) (*UsageStats, error) { s := &UsageStats{ Cfg: cfg, RouteRegister: routeRegister, @@ -52,6 +56,7 @@ func ProvideService(cfg *setting.Cfg, } s.registerAPIEndpoints() + bundleRegistry.RegisterSupportItemCollector(s.supportBundleCollector()) return s, nil } @@ -118,3 +123,28 @@ func (uss *UsageStats) ShouldBeReported(ctx context.Context, dsType string) bool return ds.Signature.IsValid() || ds.Signature.IsInternal() } + +func (uss *UsageStats) supportBundleCollector() supportbundles.Collector { + return supportbundles.Collector{ + UID: "usage-stats", + DisplayName: "Usage statistics", + Description: "Usage statistics of the Grafana instance", + IncludedByDefault: false, + Default: true, + Fn: func(ctx context.Context) (*supportbundles.SupportItem, error) { + report, err := uss.GetUsageReport(context.Background()) + if err != nil { + return nil, err + } + + data, err := json.Marshal(report) + if err != nil { + return nil, err + } + return &supportbundles.SupportItem{ + Filename: "usage-stats.json", + FileBytes: data, + }, nil + }, + } +} diff --git a/pkg/infra/usagestats/service/usage_stats_test.go b/pkg/infra/usagestats/service/usage_stats_test.go index 31ad226729f..1c5778031cd 100644 --- a/pkg/infra/usagestats/service/usage_stats_test.go +++ b/pkg/infra/usagestats/service/usage_stats_test.go @@ -23,6 +23,7 @@ import ( "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/setting" ) @@ -223,6 +224,7 @@ func createService(t *testing.T, cfg setting.Cfg, sqlStore db.DB, withDB bool) * tracing.InitializeTracerForTest(), actest.FakeAccessControl{ExpectedDisabled: true}, actest.FakeService{}, + supportbundlestest.NewFakeBundleService(), ) return service diff --git a/pkg/server/wire.go b/pkg/server/wire.go index f1e387d57f7..6e3cfdd25bd 100644 --- a/pkg/server/wire.go +++ b/pkg/server/wire.go @@ -128,6 +128,7 @@ import ( "github.com/grafana/grafana/pkg/services/store/resolver" "github.com/grafana/grafana/pkg/services/store/sanitizer" "github.com/grafana/grafana/pkg/services/supportbundles" + "github.com/grafana/grafana/pkg/services/supportbundles/bundleregistry" "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlesimpl" "github.com/grafana/grafana/pkg/services/tag" "github.com/grafana/grafana/pkg/services/tag/tagimpl" @@ -185,6 +186,8 @@ var wireBasicSet = wire.NewSet( hooks.ProvideService, kvstore.ProvideService, localcache.ProvideService, + bundleregistry.ProvideService, + wire.Bind(new(supportbundles.Service), new(*bundleregistry.Service)), dashboardthumbsimpl.ProvideService, updatechecker.ProvideGrafanaService, updatechecker.ProvidePluginsService, @@ -362,7 +365,6 @@ var wireBasicSet = wire.NewSet( wire.Bind(new(authn.Service), new(*authnimpl.Service)), k8saccess.ProvideK8SAccess, supportbundlesimpl.ProvideService, - wire.Bind(new(supportbundles.Service), new(*supportbundlesimpl.Service)), ) var wireSet = wire.NewSet( diff --git a/pkg/services/accesscontrol/database/database_test.go b/pkg/services/accesscontrol/database/database_test.go index fa40140caa4..3c54802cfc1 100644 --- a/pkg/services/accesscontrol/database/database_test.go +++ b/pkg/services/accesscontrol/database/database_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/user" @@ -296,7 +297,7 @@ func setupTestEnv(t testing.TB) (*AccessControlStore, rs.Store, user.Service, te teamService := teamimpl.ProvideService(sql, cfg) orgService, err := orgimpl.ProvideService(sql, cfg, quotatest.New(false, nil)) require.NoError(t, err) - userService, err := userimpl.ProvideService(sql, orgService, cfg, teamService, localcache.ProvideService(), quotatest.New(false, nil)) + userService, err := userimpl.ProvideService(sql, orgService, cfg, teamService, localcache.ProvideService(), quotatest.New(false, nil), supportbundlestest.NewFakeBundleService()) require.NoError(t, err) return acstore, permissionStore, userService, teamService, orgService } diff --git a/pkg/services/accesscontrol/resourcepermissions/api_test.go b/pkg/services/accesscontrol/resourcepermissions/api_test.go index 06a918738af..da13f042aa6 100644 --- a/pkg/services/accesscontrol/resourcepermissions/api_test.go +++ b/pkg/services/accesscontrol/resourcepermissions/api_test.go @@ -21,6 +21,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" @@ -410,7 +411,7 @@ func TestApi_setUserPermission(t *testing.T) { // seed user orgSvc, err := orgimpl.ProvideService(sql, sql.Cfg, quotatest.New(false, nil)) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}) + usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) _, err = usrSvc.Create(context.Background(), &user.CreateUserCommand{Login: "test", OrgID: 1}) require.NoError(t, err) @@ -517,7 +518,7 @@ func seedPermissions(t *testing.T, resourceID string, sql *sqlstore.SQLStore, se // seed user 1 with "View" permission on dashboard 1 orgSvc, err := orgimpl.ProvideService(sql, sql.Cfg, quotatest.New(false, nil)) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}) + usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) u, err := usrSvc.Create(context.Background(), &user.CreateUserCommand{Login: "test", OrgID: 1}) require.NoError(t, err) diff --git a/pkg/services/accesscontrol/resourcepermissions/service_test.go b/pkg/services/accesscontrol/resourcepermissions/service_test.go index dd1a038368a..e3fc8e870e1 100644 --- a/pkg/services/accesscontrol/resourcepermissions/service_test.go +++ b/pkg/services/accesscontrol/resourcepermissions/service_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/user" @@ -50,7 +51,7 @@ func TestService_SetUserPermission(t *testing.T) { // seed user orgSvc, err := orgimpl.ProvideService(sql, sql.Cfg, quotatest.New(false, nil)) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}) + usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) user, err := usrSvc.Create(context.Background(), &user.CreateUserCommand{Login: "test", OrgID: 1}) require.NoError(t, err) @@ -211,7 +212,7 @@ func TestService_SetPermissions(t *testing.T) { // seed user orgSvc, err := orgimpl.ProvideService(sql, sql.Cfg, quotatest.New(false, nil)) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}) + usrSvc, err := userimpl.ProvideService(sql, orgSvc, sql.Cfg, nil, nil, "atest.FakeQuotaService{}, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) _, err = usrSvc.Create(context.Background(), &user.CreateUserCommand{Login: "user", OrgID: 1}) require.NoError(t, err) @@ -235,7 +236,7 @@ func setupTestEnvironment(t *testing.T, permissions []accesscontrol.Permission, sql := db.InitTestDB(t) cfg := setting.NewCfg() teamSvc := teamimpl.ProvideService(sql, cfg) - userSvc, err := userimpl.ProvideService(sql, nil, cfg, teamimpl.ProvideService(sql, cfg), nil, quotatest.New(false, nil)) + userSvc, err := userimpl.ProvideService(sql, nil, cfg, teamimpl.ProvideService(sql, cfg), nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService()) require.NoError(t, err) license := licensingtest.NewFakeLicensing() license.On("FeatureEnabled", "accesscontrol.enforcement").Return(true).Maybe() diff --git a/pkg/services/accesscontrol/resourcepermissions/store_bench_test.go b/pkg/services/accesscontrol/resourcepermissions/store_bench_test.go index 36a45c8d5e5..56ce744653f 100644 --- a/pkg/services/accesscontrol/resourcepermissions/store_bench_test.go +++ b/pkg/services/accesscontrol/resourcepermissions/store_bench_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" @@ -143,7 +144,7 @@ func generateTeamsAndUsers(b *testing.B, db *sqlstore.SQLStore, users int) ([]in qs := quotatest.New(false, nil) orgSvc, err := orgimpl.ProvideService(db, db.Cfg, qs) require.NoError(b, err) - usrSvc, err := userimpl.ProvideService(db, orgSvc, db.Cfg, nil, nil, qs) + usrSvc, err := userimpl.ProvideService(db, orgSvc, db.Cfg, nil, nil, qs, supportbundlestest.NewFakeBundleService()) require.NoError(b, err) userIds := make([]int64, 0) teamIds := make([]int64, 0) diff --git a/pkg/services/accesscontrol/resourcepermissions/store_test.go b/pkg/services/accesscontrol/resourcepermissions/store_test.go index b568e57a46b..1a89f5f29a0 100644 --- a/pkg/services/accesscontrol/resourcepermissions/store_test.go +++ b/pkg/services/accesscontrol/resourcepermissions/store_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" ) @@ -490,7 +491,7 @@ func TestIntegrationStore_GetResourcePermissions(t *testing.T) { func seedResourcePermissions(t *testing.T, store *store, sql *sqlstore.SQLStore, orgService org.Service, actions []string, resource, resourceID, resourceAttribute string, numUsers int) { t.Helper() var orgModel *org.Org - usrSvc, err := userimpl.ProvideService(sql, orgService, sql.Cfg, nil, nil, quotatest.New(false, nil)) + usrSvc, err := userimpl.ProvideService(sql, orgService, sql.Cfg, nil, nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < numUsers; i++ { diff --git a/pkg/services/dashboards/database/acl_test.go b/pkg/services/dashboards/database/acl_test.go index 6efeb8d3921..153b4112926 100644 --- a/pkg/services/dashboards/database/acl_test.go +++ b/pkg/services/dashboards/database/acl_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/tag/tagimpl" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/user" @@ -278,7 +279,7 @@ func createUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role str qs := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgService, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, qs) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, qs) + usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, qs, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) currentUserCmd := user.CreateUserCommand{Login: name, Email: name + "@test.com", Name: "a " + name, IsAdmin: isAdmin} diff --git a/pkg/services/guardian/accesscontrol_guardian_test.go b/pkg/services/guardian/accesscontrol_guardian_test.go index 0eb5b7eebfc..7face49461f 100644 --- a/pkg/services/guardian/accesscontrol_guardian_test.go +++ b/pkg/services/guardian/accesscontrol_guardian_test.go @@ -20,6 +20,7 @@ import ( "github.com/grafana/grafana/pkg/services/folder/foldertest" "github.com/grafana/grafana/pkg/services/licensing/licensingtest" "github.com/grafana/grafana/pkg/services/quota/quotatest" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/tag/tagimpl" "github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/user" @@ -607,7 +608,7 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []acce license := licensingtest.NewFakeLicensing() license.On("FeatureEnabled", "accesscontrol.enforcement").Return(true).Maybe() teamSvc := teamimpl.ProvideService(store, store.Cfg) - userSvc, err := userimpl.ProvideService(store, nil, store.Cfg, nil, nil, quotatest.New(false, nil)) + userSvc, err := userimpl.ProvideService(store, nil, store.Cfg, nil, nil, quotatest.New(false, nil), supportbundlestest.NewFakeBundleService()) require.NoError(t, err) folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions( diff --git a/pkg/services/libraryelements/libraryelements_test.go b/pkg/services/libraryelements/libraryelements_test.go index ea6f04fc768..310ebee5451 100644 --- a/pkg/services/libraryelements/libraryelements_test.go +++ b/pkg/services/libraryelements/libraryelements_test.go @@ -35,6 +35,7 @@ import ( "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/tag/tagimpl" "github.com/grafana/grafana/pkg/services/team/teamtest" "github.com/grafana/grafana/pkg/services/user" @@ -462,7 +463,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo } orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) _, err = usrSvc.Create(context.Background(), &cmd) require.NoError(t, err) diff --git a/pkg/services/librarypanels/librarypanels_test.go b/pkg/services/librarypanels/librarypanels_test.go index df659c9c30e..450a116a33e 100644 --- a/pkg/services/librarypanels/librarypanels_test.go +++ b/pkg/services/librarypanels/librarypanels_test.go @@ -34,6 +34,7 @@ import ( "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/tag/tagimpl" "github.com/grafana/grafana/pkg/services/team/teamtest" "github.com/grafana/grafana/pkg/services/user" @@ -870,7 +871,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo ctx := appcontext.WithUser(context.Background(), usr) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) _, err = usrSvc.Create(context.Background(), &cmd) require.NoError(t, err) diff --git a/pkg/services/login/authinfoservice/user_auth_test.go b/pkg/services/login/authinfoservice/user_auth_test.go index d61e8191482..01a2112d0d4 100644 --- a/pkg/services/login/authinfoservice/user_auth_test.go +++ b/pkg/services/login/authinfoservice/user_auth_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/login/authinfoservice/database" "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" ) @@ -34,7 +35,7 @@ func TestUserAuth(t *testing.T) { qs := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, qs) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < 5; i++ { @@ -215,7 +216,7 @@ func TestUserAuth(t *testing.T) { qs := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, qs) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < 5; i++ { @@ -288,7 +289,7 @@ func TestUserAuth(t *testing.T) { qs := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, qs) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < 5; i++ { @@ -427,7 +428,7 @@ func TestUserAuth(t *testing.T) { qs := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, qs) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < 5; i++ { cmd := user.CreateUserCommand{ @@ -450,7 +451,7 @@ func TestUserAuth(t *testing.T) { qs := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, qs) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, qs, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < 5; i++ { diff --git a/pkg/services/org/orgimpl/store_test.go b/pkg/services/org/orgimpl/store_test.go index 98582a28466..37edce6d778 100644 --- a/pkg/services/org/orgimpl/store_test.go +++ b/pkg/services/org/orgimpl/store_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" @@ -820,7 +821,7 @@ func createOrgAndUserSvc(t *testing.T, store db.DB, cfg *setting.Cfg) (org.Servi quotaService := quotaimpl.ProvideService(store, cfg) orgService, err := ProvideService(store, cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(store, orgService, cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(store, orgService, cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) return orgService, usrSvc diff --git a/pkg/services/queryhistory/queryhistory_test.go b/pkg/services/queryhistory/queryhistory_test.go index e598c45b67f..d112d6cdcb4 100644 --- a/pkg/services/queryhistory/queryhistory_test.go +++ b/pkg/services/queryhistory/queryhistory_test.go @@ -19,6 +19,7 @@ import ( "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" @@ -58,7 +59,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo quotaService := quotatest.New(false, nil) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) usr := user.SignedInUser{ diff --git a/pkg/services/quota/quotaimpl/quota_test.go b/pkg/services/quota/quotaimpl/quota_test.go index d98632e72de..20570ca46f6 100644 --- a/pkg/services/quota/quotaimpl/quota_test.go +++ b/pkg/services/quota/quotaimpl/quota_test.go @@ -38,6 +38,7 @@ import ( secretsmng "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/services/sqlstore" storesrv "github.com/grafana/grafana/pkg/services/store" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/tag/tagimpl" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" @@ -90,7 +91,7 @@ func TestIntegrationQuotaCommandsAndQueries(t *testing.T) { quotaService := ProvideService(sqlStore, sqlStore.Cfg) orgService, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - userService, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService) + userService, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) setupEnv(t, sqlStore, b, quotaService) diff --git a/pkg/services/serviceaccounts/database/store_test.go b/pkg/services/serviceaccounts/database/store_test.go index 0b9bf72cdc9..f281bd746e9 100644 --- a/pkg/services/serviceaccounts/database/store_test.go +++ b/pkg/services/serviceaccounts/database/store_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts/tests" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" @@ -119,7 +120,7 @@ func setupTestDatabase(t *testing.T) (*sqlstore.SQLStore, *ServiceAccountsStoreI kvStore := kvstore.ProvideService(db) orgService, err := orgimpl.ProvideService(db, setting.NewCfg(), quotaService) require.NoError(t, err) - userSvc, err := userimpl.ProvideService(db, orgService, db.Cfg, nil, nil, quotaService) + userSvc, err := userimpl.ProvideService(db, orgService, db.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) return db, ProvideServiceAccountsStore(db.Cfg, db, apiKeyService, kvStore, userSvc, orgService) } diff --git a/pkg/services/serviceaccounts/tests/common.go b/pkg/services/serviceaccounts/tests/common.go index 61dfac50ec3..1e12c690543 100644 --- a/pkg/services/serviceaccounts/tests/common.go +++ b/pkg/services/serviceaccounts/tests/common.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" ) @@ -46,7 +47,7 @@ func SetupUserServiceAccount(t *testing.T, sqlStore *sqlstore.SQLStore, testUser quotaService := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgService, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) u1, err := usrSvc.CreateUserForTests(context.Background(), &user.CreateUserCommand{ diff --git a/pkg/services/stats/statsimpl/stats_test.go b/pkg/services/stats/statsimpl/stats_test.go index b116ecc107e..97ad6bd0648 100644 --- a/pkg/services/stats/statsimpl/stats_test.go +++ b/pkg/services/stats/statsimpl/stats_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/services/quota/quotatest" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/stats" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" ) @@ -73,7 +74,7 @@ func populateDB(t *testing.T, sqlStore *sqlstore.SQLStore) { t.Helper() orgService, _ := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotatest.New(false, nil)) - userSvc, _ := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, "atest.FakeQuotaService{}) + userSvc, _ := userimpl.ProvideService(sqlStore, orgService, sqlStore.Cfg, nil, nil, "atest.FakeQuotaService{}, supportbundlestest.NewFakeBundleService()) users := make([]user.User, 3) for i := range users { diff --git a/pkg/services/supportbundles/bundleregistry/service.go b/pkg/services/supportbundles/bundleregistry/service.go new file mode 100644 index 00000000000..6d3df76930e --- /dev/null +++ b/pkg/services/supportbundles/bundleregistry/service.go @@ -0,0 +1,32 @@ +package bundleregistry + +import ( + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/services/supportbundles" +) + +// Service is the service that registers support bundle collectors. +type Service struct { + collectors map[string]supportbundles.Collector + log log.Logger +} + +// NewService creates a new support bundle collector register service. +func ProvideService() *Service { + return &Service{ + collectors: make(map[string]supportbundles.Collector), + log: log.New("support-bundle-collector-registry"), + } +} + +func (s *Service) RegisterSupportItemCollector(collector supportbundles.Collector) { + if _, ok := s.collectors[collector.UID]; ok { + s.log.Warn("Support bundle collector with the same UID already registered", "uid", collector.UID) + } + + s.collectors[collector.UID] = collector +} + +func (s *Service) Collectors() map[string]supportbundles.Collector { + return s.collectors +} diff --git a/pkg/services/supportbundles/supportbundlesimpl/service_test.go b/pkg/services/supportbundles/bundleregistry/service_test.go similarity index 67% rename from pkg/services/supportbundles/supportbundlesimpl/service_test.go rename to pkg/services/supportbundles/bundleregistry/service_test.go index 39241804020..08228762b67 100644 --- a/pkg/services/supportbundles/supportbundlesimpl/service_test.go +++ b/pkg/services/supportbundles/bundleregistry/service_test.go @@ -1,4 +1,4 @@ -package supportbundlesimpl +package bundleregistry import ( "context" @@ -6,22 +6,11 @@ import ( "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/supportbundles" - "github.com/grafana/grafana/pkg/setting" ) func TestService_RegisterSupportItemCollector(t *testing.T) { - s := &Service{ - cfg: &setting.Cfg{}, - store: nil, - pluginStore: nil, - pluginSettings: nil, - accessControl: nil, - features: nil, - log: log.NewNopLogger(), - collectors: map[string]supportbundles.Collector{}, - } + s := ProvideService() collector := supportbundles.Collector{ UID: "test", DisplayName: "test", @@ -36,10 +25,12 @@ func TestService_RegisterSupportItemCollector(t *testing.T) { t.Run("should register collector", func(t *testing.T) { s.RegisterSupportItemCollector(collector) require.Len(t, s.collectors, 1) + require.Len(t, s.Collectors(), 1) }) t.Run("should not register collector with same UID", func(t *testing.T) { s.RegisterSupportItemCollector(collector) require.Len(t, s.collectors, 1) + require.Len(t, s.Collectors(), 1) }) } diff --git a/pkg/services/supportbundles/supportbundlesimpl/api.go b/pkg/services/supportbundles/supportbundlesimpl/api.go index 74551db8419..75de93fe9ec 100644 --- a/pkg/services/supportbundles/supportbundlesimpl/api.go +++ b/pkg/services/supportbundles/supportbundlesimpl/api.go @@ -113,9 +113,9 @@ func (s *Service) handleRemove(ctx *contextmodel.ReqContext) response.Response { } func (s *Service) handleGetCollectors(ctx *contextmodel.ReqContext) response.Response { - collectors := make([]supportbundles.Collector, 0, len(s.collectors)) + collectors := make([]supportbundles.Collector, 0, len(s.bundleRegistry.Collectors())) - for _, c := range s.collectors { + for _, c := range s.bundleRegistry.Collectors() { collectors = append(collectors, c) } diff --git a/pkg/services/supportbundles/supportbundlesimpl/collectors.go b/pkg/services/supportbundles/supportbundlesimpl/collectors.go index fa39c0e0352..f7fc2136932 100644 --- a/pkg/services/supportbundles/supportbundlesimpl/collectors.go +++ b/pkg/services/supportbundles/supportbundlesimpl/collectors.go @@ -7,7 +7,6 @@ import ( "runtime" "time" - "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/pluginsettings" "github.com/grafana/grafana/pkg/services/supportbundles" @@ -104,31 +103,6 @@ func settingsCollector(settings setting.Provider) supportbundles.Collector { } } -func usageStatesCollector(stats usagestats.Service) supportbundles.Collector { - return supportbundles.Collector{ - UID: "usage-stats", - DisplayName: "Usage statistics", - Description: "Usage statistics of the Grafana instance", - IncludedByDefault: false, - Default: true, - Fn: func(ctx context.Context) (*supportbundles.SupportItem, error) { - report, err := stats.GetUsageReport(context.Background()) - if err != nil { - return nil, err - } - - data, err := json.Marshal(report) - if err != nil { - return nil, err - } - return &supportbundles.SupportItem{ - Filename: "usage-stats.json", - FileBytes: data, - }, nil - }, - } -} - func pluginInfoCollector(pluginStore plugins.Store, pluginSettings pluginsettings.Service) supportbundles.Collector { return supportbundles.Collector{ UID: "plugins", diff --git a/pkg/services/supportbundles/supportbundlesimpl/service.go b/pkg/services/supportbundles/supportbundlesimpl/service.go index 50fa8fe7d58..7f3b4b44bf1 100644 --- a/pkg/services/supportbundles/supportbundlesimpl/service.go +++ b/pkg/services/supportbundles/supportbundlesimpl/service.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/pluginsettings" "github.com/grafana/grafana/pkg/services/supportbundles" + "github.com/grafana/grafana/pkg/services/supportbundles/bundleregistry" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -32,22 +33,21 @@ type Service struct { pluginSettings pluginsettings.Service accessControl ac.AccessControl features *featuremgmt.FeatureManager + bundleRegistry *bundleregistry.Service log log.Logger enabled bool serverAdminOnly bool - - collectors map[string]supportbundles.Collector } func ProvideService(cfg *setting.Cfg, + bundleRegistry *bundleregistry.Service, sql db.DB, kvStore kvstore.KVStore, accessControl ac.AccessControl, accesscontrolService ac.Service, routeRegister routing.RouteRegister, - userService user.Service, settings setting.Provider, pluginStore plugins.Store, pluginSettings pluginsettings.Service, @@ -62,10 +62,10 @@ func ProvideService(cfg *setting.Cfg, pluginSettings: pluginSettings, accessControl: accessControl, features: features, + bundleRegistry: bundleRegistry, log: log.New("supportbundle.service"), enabled: section.Key("enabled").MustBool(true), serverAdminOnly: section.Key("server_admin_only").MustBool(true), - collectors: make(map[string]supportbundles.Collector), } if !features.IsEnabled(featuremgmt.FlagSupportBundles) || !s.enabled { @@ -81,24 +81,14 @@ func ProvideService(cfg *setting.Cfg, s.registerAPIEndpoints(httpServer, routeRegister) // TODO: move to relevant services - s.RegisterSupportItemCollector(basicCollector(cfg)) - s.RegisterSupportItemCollector(settingsCollector(settings)) - s.RegisterSupportItemCollector(usageStatesCollector(usageStats)) - s.RegisterSupportItemCollector(userCollector(userService)) - s.RegisterSupportItemCollector(dbCollector(sql)) - s.RegisterSupportItemCollector(pluginInfoCollector(pluginStore, pluginSettings)) + s.bundleRegistry.RegisterSupportItemCollector(basicCollector(cfg)) + s.bundleRegistry.RegisterSupportItemCollector(settingsCollector(settings)) + s.bundleRegistry.RegisterSupportItemCollector(dbCollector(sql)) + s.bundleRegistry.RegisterSupportItemCollector(pluginInfoCollector(pluginStore, pluginSettings)) return s, nil } -func (s *Service) RegisterSupportItemCollector(collector supportbundles.Collector) { - if _, ok := s.collectors[collector.UID]; ok { - s.log.Warn("Support bundle collector with the same UID already registered", "uid", collector.UID) - } - - s.collectors[collector.UID] = collector -} - func (s *Service) Run(ctx context.Context) error { if !s.features.IsEnabled(featuremgmt.FlagSupportBundles) { return nil diff --git a/pkg/services/supportbundles/supportbundlesimpl/service_bundle.go b/pkg/services/supportbundles/supportbundlesimpl/service_bundle.go index 6a798a0c051..4d560bd23a8 100644 --- a/pkg/services/supportbundles/supportbundlesimpl/service_bundle.go +++ b/pkg/services/supportbundles/supportbundlesimpl/service_bundle.go @@ -70,7 +70,7 @@ func (s *Service) bundle(ctx context.Context, collectors []string, uid string) ( files := map[string][]byte{} - for _, collector := range s.collectors { + for _, collector := range s.bundleRegistry.Collectors() { if !lookup[collector.UID] && !collector.IncludedByDefault { continue } diff --git a/pkg/services/supportbundles/supportbundlesimpl/user_collector.go b/pkg/services/supportbundles/supportbundlesimpl/user_collector.go deleted file mode 100644 index 84309b0ba35..00000000000 --- a/pkg/services/supportbundles/supportbundlesimpl/user_collector.go +++ /dev/null @@ -1,47 +0,0 @@ -package supportbundlesimpl - -import ( - "context" - "encoding/json" - - "github.com/grafana/grafana/pkg/services/supportbundles" - "github.com/grafana/grafana/pkg/services/user" -) - -func userCollector(users user.Service) supportbundles.Collector { - collectorFn := func(ctx context.Context) (*supportbundles.SupportItem, error) { - query := &user.SearchUsersQuery{ - SignedInUser: &user.SignedInUser{}, - OrgID: 0, - Query: "", - Page: 0, - Limit: 0, - AuthModule: "", - Filters: []user.Filter{}, - IsDisabled: new(bool), - } - res, err := users.Search(ctx, query) - if err != nil { - return nil, err - } - - userBytes, err := json.Marshal(res.Users) - if err != nil { - return nil, err - } - - return &supportbundles.SupportItem{ - Filename: "users.json", - FileBytes: userBytes, - }, nil - } - - return supportbundles.Collector{ - UID: "users", - DisplayName: "User information", - Description: "List users belonging to the Grafana instance", - IncludedByDefault: false, - Default: false, - Fn: collectorFn, - } -} diff --git a/pkg/services/supportbundles/supportbundlestest/fake.go b/pkg/services/supportbundles/supportbundlestest/fake.go new file mode 100644 index 00000000000..8634834f4b4 --- /dev/null +++ b/pkg/services/supportbundles/supportbundlestest/fake.go @@ -0,0 +1,12 @@ +package supportbundlestest + +import "github.com/grafana/grafana/pkg/services/supportbundles" + +type FakeBundleService struct { +} + +func NewFakeBundleService() *FakeBundleService { + return &FakeBundleService{} +} + +func (s *FakeBundleService) RegisterSupportItemCollector(collector supportbundles.Collector) {} diff --git a/pkg/services/team/teamimpl/store_test.go b/pkg/services/team/teamimpl/store_test.go index 73cdb964e69..e5dea577616 100644 --- a/pkg/services/team/teamimpl/store_test.go +++ b/pkg/services/team/teamimpl/store_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" @@ -42,7 +43,8 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) { quotaService := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, teamSvc, nil, quotaService) + userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, teamSvc, nil, quotaService, + supportbundlestest.NewFakeBundleService()) require.NoError(t, err) t.Run("Given saved users and two teams", func(t *testing.T) { @@ -385,7 +387,7 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) { quotaService := quotaimpl.ProvideService(sqlStore, sqlStore.Cfg) orgSvc, err := orgimpl.ProvideService(sqlStore, sqlStore.Cfg, quotaService) require.NoError(t, err) - userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, teamSvc, nil, quotaService) + userSvc, err := userimpl.ProvideService(sqlStore, orgSvc, sqlStore.Cfg, teamSvc, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) setup() userCmd = user.CreateUserCommand{ @@ -514,7 +516,7 @@ func TestIntegrationSQLStore_GetTeamMembers_ACFilter(t *testing.T) { quotaService := quotaimpl.ProvideService(store, store.Cfg) orgSvc, err := orgimpl.ProvideService(store, store.Cfg, quotaService) require.NoError(t, err) - userSvc, err := userimpl.ProvideService(store, orgSvc, store.Cfg, teamSvc, nil, quotaService) + userSvc, err := userimpl.ProvideService(store, orgSvc, store.Cfg, teamSvc, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) for i := 0; i < 4; i++ { diff --git a/pkg/services/user/userimpl/store_test.go b/pkg/services/user/userimpl/store_test.go index ec86278bde9..bcf07e56d47 100644 --- a/pkg/services/user/userimpl/store_test.go +++ b/pkg/services/user/userimpl/store_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" ) @@ -30,7 +31,7 @@ func TestIntegrationUserDataAccess(t *testing.T) { orgService, err := orgimpl.ProvideService(ss, ss.Cfg, quotaService) require.NoError(t, err) userStore := ProvideStore(ss, setting.NewCfg()) - usrSvc, err := ProvideService(ss, orgService, ss.Cfg, nil, nil, quotaService) + usrSvc, err := ProvideService(ss, orgService, ss.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) usr := &user.SignedInUser{ OrgID: 1, @@ -497,7 +498,7 @@ func TestIntegrationUserDataAccess(t *testing.T) { ss := db.InitTestDB(t) orgService, err := orgimpl.ProvideService(ss, ss.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := ProvideService(ss, orgService, ss.Cfg, nil, nil, quotaService) + usrSvc, err := ProvideService(ss, orgService, ss.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) createFiveTestUsers(t, usrSvc, func(i int) *user.CreateUserCommand { @@ -942,7 +943,7 @@ func createOrgAndUserSvc(t *testing.T, store db.DB, cfg *setting.Cfg) (org.Servi quotaService := quotaimpl.ProvideService(store, cfg) orgService, err := orgimpl.ProvideService(store, cfg, quotaService) require.NoError(t, err) - usrSvc, err := ProvideService(store, orgService, cfg, nil, nil, quotaService) + usrSvc, err := ProvideService(store, orgService, cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) return orgService, usrSvc diff --git a/pkg/services/user/userimpl/user.go b/pkg/services/user/userimpl/user.go index c84a7cfe66f..61964209d2e 100644 --- a/pkg/services/user/userimpl/user.go +++ b/pkg/services/user/userimpl/user.go @@ -2,6 +2,7 @@ package userimpl import ( "context" + "encoding/json" "errors" "fmt" "strings" @@ -13,6 +14,7 @@ import ( ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/quota" + "github.com/grafana/grafana/pkg/services/supportbundles" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" @@ -34,6 +36,7 @@ func ProvideService( teamService team.Service, cacheService *localcache.CacheService, quotaService quota.Service, + bundleRegistry supportbundles.Service, ) (user.Service, error) { store := ProvideStore(db, cfg) s := &Service{ @@ -56,6 +59,8 @@ func ProvideService( }); err != nil { return s, err } + + bundleRegistry.RegisterSupportItemCollector(s.supportBundleCollector()) return s, nil } @@ -547,3 +552,45 @@ func (s *Service) CreateServiceAccount(ctx context.Context, cmd *user.CreateUser } return usr, nil } + +func (s *Service) supportBundleCollector() supportbundles.Collector { + collectorFn := func(ctx context.Context) (*supportbundles.SupportItem, error) { + query := &user.SearchUsersQuery{ + SignedInUser: &user.SignedInUser{ + Login: "sa-supportbundle", + OrgRole: "Admin", + IsGrafanaAdmin: true, + IsServiceAccount: true}, + OrgID: 0, + Query: "", + Page: 0, + Limit: 0, + AuthModule: "", + Filters: []user.Filter{}, + IsDisabled: new(bool), + } + res, err := s.Search(ctx, query) + if err != nil { + return nil, err + } + + userBytes, err := json.Marshal(res.Users) + if err != nil { + return nil, err + } + + return &supportbundles.SupportItem{ + Filename: "users.json", + FileBytes: userBytes, + }, nil + } + + return supportbundles.Collector{ + UID: "users", + DisplayName: "User information", + Description: "List users belonging to the Grafana instance", + IncludedByDefault: false, + Default: false, + Fn: collectorFn, + } +} diff --git a/pkg/tests/api/alerting/api_alertmanager_test.go b/pkg/tests/api/alerting/api_alertmanager_test.go index 65ca48ec988..5dcaf53249f 100644 --- a/pkg/tests/api/alerting/api_alertmanager_test.go +++ b/pkg/tests/api/alerting/api_alertmanager_test.go @@ -12,11 +12,12 @@ import ( "testing" "time" - "github.com/grafana/grafana/pkg/expr" "github.com/prometheus/common/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/expr" + apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ngstore "github.com/grafana/grafana/pkg/services/ngalert/store" @@ -24,6 +25,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" @@ -2564,7 +2566,7 @@ func createUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserComma quotaService := quotaimpl.ProvideService(store, store.Cfg) orgService, err := orgimpl.ProvideService(store, store.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) u, err := usrSvc.CreateUserForTests(context.Background(), &cmd) diff --git a/pkg/tests/api/correlations/common_test.go b/pkg/tests/api/correlations/common_test.go index aabdb761929..998de1bcd5b 100644 --- a/pkg/tests/api/correlations/common_test.go +++ b/pkg/tests/api/correlations/common_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/tests/testinfra" @@ -141,7 +142,7 @@ func (c TestContext) createUser(cmd user.CreateUserCommand) { quotaService := quotaimpl.ProvideService(store, store.Cfg) orgService, err := orgimpl.ProvideService(store, store.Cfg, quotaService) require.NoError(c.t, err) - usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(c.t, err) _, err = usrSvc.CreateUserForTests(context.Background(), &cmd) diff --git a/pkg/tests/api/dashboards/api_dashboards_test.go b/pkg/tests/api/dashboards/api_dashboards_test.go index 2d7c96fb405..af49bf79c41 100644 --- a/pkg/tests/api/dashboards/api_dashboards_test.go +++ b/pkg/tests/api/dashboards/api_dashboards_test.go @@ -24,6 +24,7 @@ import ( "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/search/model" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/tests/testinfra" @@ -110,7 +111,7 @@ func createUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserComma quotaService := quotaimpl.ProvideService(store, store.Cfg) orgService, err := orgimpl.ProvideService(store, store.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) u, err := usrSvc.CreateUserForTests(context.Background(), &cmd) diff --git a/pkg/tests/api/plugins/api_plugins_test.go b/pkg/tests/api/plugins/api_plugins_test.go index 81f8c831332..af924c70b6b 100644 --- a/pkg/tests/api/plugins/api_plugins_test.go +++ b/pkg/tests/api/plugins/api_plugins_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/tests/testinfra" @@ -125,7 +126,7 @@ func createUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserComma quotaService := quotaimpl.ProvideService(store, store.Cfg) orgService, err := orgimpl.ProvideService(store, store.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) _, err = usrSvc.CreateUserForTests(context.Background(), &cmd) diff --git a/pkg/tests/testinfra/testinfra.go b/pkg/tests/testinfra/testinfra.go index 97d156e54f8..9f4bc60aab9 100644 --- a/pkg/tests/testinfra/testinfra.go +++ b/pkg/tests/testinfra/testinfra.go @@ -25,6 +25,7 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgimpl" "github.com/grafana/grafana/pkg/services/quota/quotaimpl" "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" @@ -385,7 +386,7 @@ func CreateUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserComma quotaService := quotaimpl.ProvideService(store, store.Cfg) orgService, err := orgimpl.ProvideService(store, store.Cfg, quotaService) require.NoError(t, err) - usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService) + usrSvc, err := userimpl.ProvideService(store, orgService, store.Cfg, nil, nil, quotaService, supportbundlestest.NewFakeBundleService()) require.NoError(t, err) u, err := usrSvc.CreateUserForTests(context.Background(), &cmd)