ResourceServer: Add resource server protobuf and wrapper (#90007)

This commit is contained in:
Ryan McKinley
2024-07-09 15:08:13 -07:00
committed by GitHub
parent 05ce16cf7b
commit 079f0715aa
40 changed files with 5852 additions and 62 deletions
+11 -8
View File
@@ -4,20 +4,23 @@ import (
"fmt"
"net"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/spf13/pflag"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/options"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
)
type StorageType string
const (
StorageTypeFile StorageType = "file"
StorageTypeEtcd StorageType = "etcd"
StorageTypeLegacy StorageType = "legacy"
StorageTypeUnified StorageType = "unified"
StorageTypeUnifiedGrpc StorageType = "unified-grpc"
StorageTypeFile StorageType = "file"
StorageTypeEtcd StorageType = "etcd"
StorageTypeLegacy StorageType = "legacy"
StorageTypeUnified StorageType = "unified"
StorageTypeUnifiedGrpc StorageType = "unified-grpc"
StorageTypeUnifiedNext StorageType = "unified-next"
StorageTypeUnifiedNextGrpc StorageType = "unified-next-grpc"
)
type StorageOptions struct {
@@ -43,10 +46,10 @@ func (o *StorageOptions) AddFlags(fs *pflag.FlagSet) {
func (o *StorageOptions) Validate() []error {
errs := []error{}
switch o.StorageType {
case StorageTypeFile, StorageTypeEtcd, StorageTypeLegacy, StorageTypeUnified, StorageTypeUnifiedGrpc:
case StorageTypeFile, StorageTypeEtcd, StorageTypeLegacy, StorageTypeUnified, StorageTypeUnifiedGrpc, StorageTypeUnifiedNext, StorageTypeUnifiedNextGrpc:
// no-op
default:
errs = append(errs, fmt.Errorf("--grafana-apiserver-storage-type must be one of %s, %s, %s, %s, %s", StorageTypeFile, StorageTypeEtcd, StorageTypeLegacy, StorageTypeUnified, StorageTypeUnifiedGrpc))
errs = append(errs, fmt.Errorf("--grafana-apiserver-storage-type must be one of %s, %s, %s, %s, %s, %s, %s", StorageTypeFile, StorageTypeEtcd, StorageTypeLegacy, StorageTypeUnified, StorageTypeUnifiedGrpc, StorageTypeUnifiedNext, StorageTypeUnifiedNextGrpc))
}
if _, _, err := net.SplitHostPort(o.Address); err != nil {
+77 -22
View File
@@ -4,10 +4,13 @@ import (
"context"
"fmt"
"net/http"
"os"
"path"
"path/filepath"
"github.com/grafana/dskit/services"
"github.com/prometheus/client_golang/prometheus"
"gocloud.dev/blob/fileblob"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -44,6 +47,9 @@ import (
"github.com/grafana/grafana/pkg/services/store/entity/db/dbimpl"
"github.com/grafana/grafana/pkg/services/store/entity/sqlstash"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/storage/unified/apistore"
"github.com/grafana/grafana/pkg/storage/unified/entitybridge"
"github.com/grafana/grafana/pkg/storage/unified/resource"
)
var (
@@ -199,6 +205,7 @@ func (s *service) RegisterAPI(b builder.APIGroupBuilder) {
s.builders = append(s.builders, b)
}
// nolint:gocyclo
func (s *service) start(ctx context.Context) error {
defer close(s.startedCh)
@@ -258,39 +265,87 @@ func (s *service) start(ctx context.Context) error {
return err
}
case grafanaapiserveroptions.StorageTypeUnified:
case grafanaapiserveroptions.StorageTypeUnifiedNext:
// CDK (for now)
dir := filepath.Join(s.cfg.DataPath, "unistore", "resource")
if err := os.MkdirAll(dir, 0o750); err != nil {
return err
}
bucket, err := fileblob.OpenBucket(dir, &fileblob.Options{
CreateDir: true,
Metadata: fileblob.MetadataDontWrite, // skip
})
if err != nil {
return err
}
backend, err := resource.NewCDKBackend(context.Background(), resource.CDKBackendOptions{
Tracer: s.tracing,
Bucket: bucket,
})
if err != nil {
return err
}
server, err := resource.NewResourceServer(resource.ResourceServerOptions{Backend: backend})
if err != nil {
return err
}
serverConfig.Config.RESTOptionsGetter = apistore.NewRESTOptionsGetterForServer(server,
o.RecommendedOptions.Etcd.StorageConfig.Codec)
case grafanaapiserveroptions.StorageTypeUnifiedNextGrpc:
if !s.features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorage) {
return fmt.Errorf("unified storage requires the unifiedStorage feature flag")
}
eDB, err := dbimpl.ProvideEntityDB(s.db, s.cfg, s.features, s.tracing)
if err != nil {
return err
}
storeServer, err := sqlstash.ProvideSQLEntityServer(eDB, s.tracing)
if err != nil {
return err
}
store := entity.NewEntityStoreClientLocal(storeServer)
serverConfig.Config.RESTOptionsGetter = entitystorage.NewRESTOptionsGetter(s.cfg, store, o.RecommendedOptions.Etcd.StorageConfig.Codec)
case grafanaapiserveroptions.StorageTypeUnifiedGrpc:
// Create a connection to the gRPC server
conn, err := grpc.NewClient(o.StorageOptions.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return err
}
// TODO: determine when to close the connection, we cannot defer it here
// defer conn.Close()
// Create a client instance
store := entity.NewEntityStoreClientGRPC(conn)
client := resource.NewResourceStoreClientGRPC(conn)
serverConfig.Config.RESTOptionsGetter = apistore.NewRESTOptionsGetter(client, o.RecommendedOptions.Etcd.StorageConfig.Codec)
serverConfig.Config.RESTOptionsGetter = entitystorage.NewRESTOptionsGetter(s.cfg, store, o.RecommendedOptions.Etcd.StorageConfig.Codec)
case grafanaapiserveroptions.StorageTypeUnified, grafanaapiserveroptions.StorageTypeUnifiedGrpc:
var client entity.EntityStoreClient
var entityServer sqlstash.SqlEntityServer
if o.StorageOptions.StorageType == grafanaapiserveroptions.StorageTypeUnifiedGrpc {
conn, err := grpc.NewClient(o.StorageOptions.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return err
}
client = entity.NewEntityStoreClientGRPC(conn)
} else {
if !s.features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorage) {
return fmt.Errorf("unified storage requires the unifiedStorage feature flag")
}
eDB, err := dbimpl.ProvideEntityDB(s.db, s.cfg, s.features, s.tracing)
if err != nil {
return err
}
entityServer, err = sqlstash.ProvideSQLEntityServer(eDB, s.tracing)
if err != nil {
return err
}
client = entity.NewEntityStoreClientLocal(entityServer)
}
if false {
// Use the entity bridge
server, err := entitybridge.EntityAsResourceServer(client, entityServer, s.tracing)
if err != nil {
return err
}
serverConfig.Config.RESTOptionsGetter = apistore.NewRESTOptionsGetterForServer(server,
o.RecommendedOptions.Etcd.StorageConfig.Codec)
} else {
serverConfig.Config.RESTOptionsGetter = entitystorage.NewRESTOptionsGetter(s.cfg,
client, o.RecommendedOptions.Etcd.StorageConfig.Codec)
}
case grafanaapiserveroptions.StorageTypeLegacy:
fallthrough