Support bundles: Refactor registry into separate service (#62945)

* add bundle registry service to avoid dependency cycles

* move user support bundle collector to user service

* move usage stat bundle implementation to usage stats

* add info for background service

* fix remaining imports

* whitespace
This commit is contained in:
Jo
2023-02-06 17:50:03 +01:00
committed by GitHub
parent 09943407e4
commit f9163351fd
42 changed files with 219 additions and 151 deletions

View File

@@ -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)
}

View File

@@ -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",

View File

@@ -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

View File

@@ -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
}

View File

@@ -1,45 +0,0 @@
package supportbundlesimpl
import (
"context"
"testing"
"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{},
}
collector := supportbundles.Collector{
UID: "test",
DisplayName: "test",
Description: "test",
IncludedByDefault: true,
Default: true,
Fn: func(context.Context) (*supportbundles.SupportItem, error) {
return nil, nil
},
}
t.Run("should register collector", func(t *testing.T) {
s.RegisterSupportItemCollector(collector)
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)
})
}

View File

@@ -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,
}
}