mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 08:42:18 +08:00
127 lines
3.1 KiB
Go
127 lines
3.1 KiB
Go
package runner
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/grafana/grafana-app-sdk/app"
|
|
"github.com/grafana/grafana-app-sdk/resource"
|
|
"github.com/grafana/grafana/pkg/services/apiserver/builder"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/client-go/rest"
|
|
)
|
|
|
|
type RunnerConfig struct {
|
|
RestConfigGetter func(context.Context) (*rest.Config, error)
|
|
APIRegistrar builder.APIRegistrar
|
|
}
|
|
|
|
func NewAPIGroupRunner(cfg RunnerConfig, providers ...app.Provider) (*APIGroupRunner, error) {
|
|
groups := []appBuilderGroup{}
|
|
for _, provider := range providers {
|
|
created, err := newAppBuilderGroup(cfg, provider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
groups = append(groups, created)
|
|
}
|
|
return &APIGroupRunner{
|
|
config: cfg,
|
|
groups: groups,
|
|
initialized: make(chan struct{}),
|
|
}, nil
|
|
}
|
|
|
|
type APIGroupRunner struct {
|
|
config RunnerConfig
|
|
groups []appBuilderGroup
|
|
initialized chan struct{}
|
|
}
|
|
|
|
func (r *APIGroupRunner) Run(ctx context.Context) error {
|
|
<-r.initialized
|
|
runner := app.NewMultiRunner()
|
|
for _, g := range r.groups {
|
|
runner.AddRunnable(g.app.Runner())
|
|
}
|
|
return runner.Run(ctx)
|
|
}
|
|
|
|
func (r *APIGroupRunner) Init(ctx context.Context) error {
|
|
defer close(r.initialized)
|
|
restConfig, err := r.config.RestConfigGetter(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for i := range r.groups {
|
|
appConfig := app.Config{
|
|
KubeConfig: *restConfig,
|
|
ManifestData: *r.groups[i].provider.Manifest().ManifestData,
|
|
SpecificConfig: r.groups[i].customConfig,
|
|
}
|
|
app, err := r.groups[i].provider.NewApp(appConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
r.groups[i].setApp(app)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *APIGroupRunner) GetBuilders() []AppBuilder {
|
|
builders := []AppBuilder{}
|
|
for _, g := range r.groups {
|
|
builders = append(builders, g.builders...)
|
|
}
|
|
return builders
|
|
}
|
|
|
|
type appBuilderGroup struct {
|
|
builders []AppBuilder
|
|
provider app.Provider
|
|
app app.App
|
|
customConfig any
|
|
}
|
|
|
|
func newAppBuilderGroup(cfg RunnerConfig, provider app.Provider) (appBuilderGroup, error) {
|
|
manifest := provider.Manifest()
|
|
if manifest.Location.Type != app.ManifestLocationEmbedded {
|
|
return appBuilderGroup{}, fmt.Errorf("app: %s has unsupported manifest location type: %s", manifest.ManifestData.AppName, manifest.Location.Type)
|
|
}
|
|
|
|
group := appBuilderGroup{
|
|
provider: provider,
|
|
builders: []AppBuilder{},
|
|
}
|
|
|
|
appBuilderConfig, ok := provider.SpecificConfig().(*AppBuilderConfig)
|
|
if !ok {
|
|
return group, fmt.Errorf("provider's SpecificConfig is not of type *AppBuilderConfig, got %T", provider.SpecificConfig())
|
|
}
|
|
|
|
for gv, kinds := range appBuilderConfig.ManagedKinds {
|
|
confCopy := *appBuilderConfig
|
|
confCopy.ManagedKinds = map[schema.GroupVersion][]resource.Kind{
|
|
gv: kinds,
|
|
}
|
|
confCopy.groupVersion = gv
|
|
if confCopy.CustomConfig != nil {
|
|
group.customConfig = confCopy.CustomConfig
|
|
}
|
|
b, err := NewAppBuilder(confCopy)
|
|
if err != nil {
|
|
return group, err
|
|
}
|
|
group.builders = append(group.builders, b)
|
|
cfg.APIRegistrar.RegisterAPI(b)
|
|
}
|
|
return group, nil
|
|
}
|
|
|
|
func (g *appBuilderGroup) setApp(app app.App) {
|
|
g.app = app
|
|
for _, b := range g.builders {
|
|
b.SetApp(app)
|
|
}
|
|
}
|