mirror of https://github.com/grafana/grafana.git
Zanzana: bootstrap authz server (#95036)
Bootstrap authz extended server
This commit is contained in:
parent
db06a5a5d3
commit
b4366ebed2
1
Makefile
1
Makefile
|
@ -416,6 +416,7 @@ protobuf: ## Compile protobuf definitions
|
||||||
buf generate pkg/plugins/backendplugin/pluginextensionv2 --template pkg/plugins/backendplugin/pluginextensionv2/buf.gen.yaml
|
buf generate pkg/plugins/backendplugin/pluginextensionv2 --template pkg/plugins/backendplugin/pluginextensionv2/buf.gen.yaml
|
||||||
buf generate pkg/plugins/backendplugin/secretsmanagerplugin --template pkg/plugins/backendplugin/secretsmanagerplugin/buf.gen.yaml
|
buf generate pkg/plugins/backendplugin/secretsmanagerplugin --template pkg/plugins/backendplugin/secretsmanagerplugin/buf.gen.yaml
|
||||||
buf generate pkg/storage/unified/resource --template pkg/storage/unified/resource/buf.gen.yaml
|
buf generate pkg/storage/unified/resource --template pkg/storage/unified/resource/buf.gen.yaml
|
||||||
|
buf generate pkg/services/authz/zanzana/proto/v1 --template pkg/services/authz/zanzana/proto/v1/buf.gen.yaml
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: ## Clean up intermediate build artifacts.
|
clean: ## Clean up intermediate build artifacts.
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/fullstorydev/grpchan/inprocgrpc"
|
"github.com/fullstorydev/grpchan/inprocgrpc"
|
||||||
|
authzv1 "github.com/grafana/authlib/authz/proto/v1"
|
||||||
"github.com/grafana/dskit/services"
|
"github.com/grafana/dskit/services"
|
||||||
openfgav1 "github.com/openfga/api/proto/openfga/v1"
|
openfgav1 "github.com/openfga/api/proto/openfga/v1"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
@ -17,6 +18,7 @@ import (
|
||||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/authz/zanzana"
|
"github.com/grafana/grafana/pkg/services/authz/zanzana"
|
||||||
"github.com/grafana/grafana/pkg/services/authz/zanzana/client"
|
"github.com/grafana/grafana/pkg/services/authz/zanzana/client"
|
||||||
|
authzextv1 "github.com/grafana/grafana/pkg/services/authz/zanzana/proto/v1"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/grpcserver"
|
"github.com/grafana/grafana/pkg/services/grpcserver"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
@ -49,13 +51,16 @@ func ProvideZanzana(cfg *setting.Cfg, db db.DB, features featuremgmt.FeatureTogg
|
||||||
return nil, fmt.Errorf("failed to start zanzana: %w", err)
|
return nil, fmt.Errorf("failed to start zanzana: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
srv, err := zanzana.NewServer(cfg, store, logger)
|
openfga, err := zanzana.NewOpenFGAServer(cfg, store, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to start zanzana: %w", err)
|
return nil, fmt.Errorf("failed to start zanzana: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srv := zanzana.NewAuthzServer(openfga)
|
||||||
channel := &inprocgrpc.Channel{}
|
channel := &inprocgrpc.Channel{}
|
||||||
openfgav1.RegisterOpenFGAServiceServer(channel, srv)
|
openfgav1.RegisterOpenFGAServiceServer(channel, openfga)
|
||||||
|
authzv1.RegisterAuthzServiceServer(channel, srv)
|
||||||
|
authzextv1.RegisterAuthzExtentionServiceServer(channel, srv)
|
||||||
|
|
||||||
client, err = zanzana.NewClient(context.Background(), channel, cfg)
|
client, err = zanzana.NewClient(context.Background(), channel, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -104,11 +109,13 @@ func (z *Zanzana) start(ctx context.Context) error {
|
||||||
return fmt.Errorf("failed to initilize zanana store: %w", err)
|
return fmt.Errorf("failed to initilize zanana store: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
srv, err := zanzana.NewServer(z.cfg, store, z.logger)
|
openfga, err := zanzana.NewOpenFGAServer(z.cfg, store, z.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to start zanzana: %w", err)
|
return fmt.Errorf("failed to start zanzana: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srv := zanzana.NewAuthzServer(openfga)
|
||||||
|
|
||||||
tracingCfg, err := tracing.ProvideTracingConfig(z.cfg)
|
tracingCfg, err := tracing.ProvideTracingConfig(z.cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -127,7 +134,11 @@ func (z *Zanzana) start(ctx context.Context) error {
|
||||||
return fmt.Errorf("failed to create zanzana grpc server: %w", err)
|
return fmt.Errorf("failed to create zanzana grpc server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
openfgav1.RegisterOpenFGAServiceServer(z.handle.GetServer(), srv)
|
s := z.handle.GetServer()
|
||||||
|
openfgav1.RegisterOpenFGAServiceServer(s, openfga)
|
||||||
|
authzv1.RegisterAuthzServiceServer(s, srv)
|
||||||
|
authzextv1.RegisterAuthzExtentionServiceServer(s, srv)
|
||||||
|
|
||||||
if _, err := grpcserver.ProvideReflectionService(z.cfg, z.handle); err != nil {
|
if _, err := grpcserver.ProvideReflectionService(z.cfg, z.handle); err != nil {
|
||||||
return fmt.Errorf("failed to register reflection for zanzana: %w", err)
|
return fmt.Errorf("failed to register reflection for zanzana: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ func zanzanaServerIntegrationTest(tb testing.TB) *inprocgrpc.Channel {
|
||||||
store, err := zstore.NewEmbeddedStore(cfg, db, logger)
|
store, err := zstore.NewEmbeddedStore(cfg, db, logger)
|
||||||
require.NoError(tb, err)
|
require.NoError(tb, err)
|
||||||
|
|
||||||
srv, err := zserver.New(&cfg.Zanzana, store, logger)
|
srv, err := zserver.NewOpenFGA(&cfg.Zanzana, store, logger)
|
||||||
require.NoError(tb, err)
|
require.NoError(tb, err)
|
||||||
|
|
||||||
channel := &inprocgrpc.Channel{}
|
channel := &inprocgrpc.Channel{}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
version: v1
|
||||||
|
plugins:
|
||||||
|
- plugin: go
|
||||||
|
out: pkg/services/authz/zanzana/proto/v1
|
||||||
|
opt: paths=source_relative
|
||||||
|
- plugin: go-grpc
|
||||||
|
out: pkg/services/authz/zanzana/proto/v1
|
||||||
|
opt:
|
||||||
|
- paths=source_relative
|
||||||
|
- require_unimplemented_servers=false
|
|
@ -0,0 +1,7 @@
|
||||||
|
version: v2
|
||||||
|
lint:
|
||||||
|
use:
|
||||||
|
- DEFAULT
|
||||||
|
breaking:
|
||||||
|
use:
|
||||||
|
- FILE
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.34.2
|
||||||
|
// protoc (unknown)
|
||||||
|
// source: extention.proto
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
var File_extention_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
var file_extention_proto_rawDesc = []byte{
|
||||||
|
0x0a, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x12, 0x12, 0x61, 0x75, 0x74, 0x68, 0x7a, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x69,
|
||||||
|
0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x32, 0x17, 0x0a, 0x15, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x45, 0x78,
|
||||||
|
0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x38,
|
||||||
|
0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61,
|
||||||
|
0x66, 0x61, 0x6e, 0x61, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67,
|
||||||
|
0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x7a, 0x2f,
|
||||||
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_extention_proto_goTypes = []any{}
|
||||||
|
var file_extention_proto_depIdxs = []int32{
|
||||||
|
0, // [0:0] is the sub-list for method output_type
|
||||||
|
0, // [0:0] is the sub-list for method input_type
|
||||||
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
|
0, // [0:0] is the sub-list for extension extendee
|
||||||
|
0, // [0:0] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_extention_proto_init() }
|
||||||
|
func file_extention_proto_init() {
|
||||||
|
if File_extention_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_extention_proto_rawDesc,
|
||||||
|
NumEnums: 0,
|
||||||
|
NumMessages: 0,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 1,
|
||||||
|
},
|
||||||
|
GoTypes: file_extention_proto_goTypes,
|
||||||
|
DependencyIndexes: file_extention_proto_depIdxs,
|
||||||
|
}.Build()
|
||||||
|
File_extention_proto = out.File
|
||||||
|
file_extention_proto_rawDesc = nil
|
||||||
|
file_extention_proto_goTypes = nil
|
||||||
|
file_extention_proto_depIdxs = nil
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option go_package = "github.com/grafana/grafana/pkg/services/authz/proto/v1";
|
||||||
|
|
||||||
|
package authz.extention.v1;
|
||||||
|
|
||||||
|
service AuthzExtentionService {}
|
|
@ -0,0 +1,62 @@
|
||||||
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// - protoc-gen-go-grpc v1.4.0
|
||||||
|
// - protoc (unknown)
|
||||||
|
// source: extention.proto
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
grpc "google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the grpc package it is being compiled against.
|
||||||
|
// Requires gRPC-Go v1.62.0 or later.
|
||||||
|
const _ = grpc.SupportPackageIsVersion8
|
||||||
|
|
||||||
|
// AuthzExtentionServiceClient is the client API for AuthzExtentionService service.
|
||||||
|
//
|
||||||
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||||
|
type AuthzExtentionServiceClient interface {
|
||||||
|
}
|
||||||
|
|
||||||
|
type authzExtentionServiceClient struct {
|
||||||
|
cc grpc.ClientConnInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAuthzExtentionServiceClient(cc grpc.ClientConnInterface) AuthzExtentionServiceClient {
|
||||||
|
return &authzExtentionServiceClient{cc}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthzExtentionServiceServer is the server API for AuthzExtentionService service.
|
||||||
|
// All implementations should embed UnimplementedAuthzExtentionServiceServer
|
||||||
|
// for forward compatibility
|
||||||
|
type AuthzExtentionServiceServer interface {
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnimplementedAuthzExtentionServiceServer should be embedded to have forward compatible implementations.
|
||||||
|
type UnimplementedAuthzExtentionServiceServer struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsafeAuthzExtentionServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||||
|
// Use of this interface is not recommended, as added methods to AuthzExtentionServiceServer will
|
||||||
|
// result in compilation errors.
|
||||||
|
type UnsafeAuthzExtentionServiceServer interface {
|
||||||
|
mustEmbedUnimplementedAuthzExtentionServiceServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterAuthzExtentionServiceServer(s grpc.ServiceRegistrar, srv AuthzExtentionServiceServer) {
|
||||||
|
s.RegisterService(&AuthzExtentionService_ServiceDesc, srv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthzExtentionService_ServiceDesc is the grpc.ServiceDesc for AuthzExtentionService service.
|
||||||
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
|
// and not to be introspected or modified (even as a copy)
|
||||||
|
var AuthzExtentionService_ServiceDesc = grpc.ServiceDesc{
|
||||||
|
ServiceName: "authz.extention.v1.AuthzExtentionService",
|
||||||
|
HandlerType: (*AuthzExtentionServiceServer)(nil),
|
||||||
|
Methods: []grpc.MethodDesc{},
|
||||||
|
Streams: []grpc.StreamDesc{},
|
||||||
|
Metadata: "extention.proto",
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package zanzana
|
package zanzana
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
openfgav1 "github.com/openfga/api/proto/openfga/v1"
|
||||||
"github.com/openfga/openfga/pkg/server"
|
"github.com/openfga/openfga/pkg/server"
|
||||||
"github.com/openfga/openfga/pkg/storage"
|
"github.com/openfga/openfga/pkg/storage"
|
||||||
|
|
||||||
|
@ -11,8 +12,12 @@ import (
|
||||||
zserver "github.com/grafana/grafana/pkg/services/authz/zanzana/server"
|
zserver "github.com/grafana/grafana/pkg/services/authz/zanzana/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewServer(cfg *setting.Cfg, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) {
|
func NewOpenFGAServer(cfg *setting.Cfg, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) {
|
||||||
return zserver.New(&cfg.Zanzana, store, logger)
|
return zserver.NewOpenFGA(&cfg.Zanzana, store, logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAuthzServer(openfga openfgav1.OpenFGAServiceServer) *zserver.Server {
|
||||||
|
return zserver.NewAuthz(openfga)
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartOpenFGAHttpSever(cfg *setting.Cfg, srv grpcserver.Provider, logger log.Logger) error {
|
func StartOpenFGAHttpSever(cfg *setting.Cfg, srv grpcserver.Provider, logger log.Logger) error {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
authzv1 "github.com/grafana/authlib/authz/proto/v1"
|
||||||
|
openfgav1 "github.com/openfga/api/proto/openfga/v1"
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
|
|
||||||
|
authzextv1 "github.com/grafana/grafana/pkg/services/authz/zanzana/proto/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ authzv1.AuthzServiceServer = (*Server)(nil)
|
||||||
|
var _ authzextv1.AuthzExtentionServiceServer = (*Server)(nil)
|
||||||
|
|
||||||
|
var tracer = otel.Tracer("github.com/grafana/grafana/pkg/services/authz/zanzana/server")
|
||||||
|
|
||||||
|
func NewAuthz(openfga openfgav1.OpenFGAServiceServer) *Server {
|
||||||
|
return &Server{openfga: openfga}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
authzv1.UnimplementedAuthzServiceServer
|
||||||
|
authzextv1.UnimplementedAuthzExtentionServiceServer
|
||||||
|
|
||||||
|
openfga openfgav1.OpenFGAServiceServer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Check(ctx context.Context, r *authzv1.CheckRequest) (*authzv1.CheckResponse, error) {
|
||||||
|
tracer.Start(ctx, "authzServer.Check")
|
||||||
|
return &authzv1.CheckResponse{}, nil
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ import (
|
||||||
zlogger "github.com/grafana/grafana/pkg/services/authz/zanzana/logger"
|
zlogger "github.com/grafana/grafana/pkg/services/authz/zanzana/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(cfg *setting.ZanzanaSettings, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) {
|
func NewOpenFGA(cfg *setting.ZanzanaSettings, store storage.OpenFGADatastore, logger log.Logger) (*server.Server, error) {
|
||||||
opts := []server.OpenFGAServiceV1Option{
|
opts := []server.OpenFGAServiceV1Option{
|
||||||
server.WithDatastore(store),
|
server.WithDatastore(store),
|
||||||
server.WithLogger(zlogger.New(logger)),
|
server.WithLogger(zlogger.New(logger)),
|
Loading…
Reference in New Issue