Zanzana: bootstrap authz server (#95036)

Bootstrap authz extended server
This commit is contained in:
Karl Persson 2024-10-21 14:58:57 +02:00 committed by GitHub
parent db06a5a5d3
commit b4366ebed2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 209 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,7 @@
version: v2
lint:
use:
- DEFAULT
breaking:
use:
- FILE

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

View File

@ -0,0 +1,7 @@
syntax = "proto3";
option go_package = "github.com/grafana/grafana/pkg/services/authz/proto/v1";
package authz.extention.v1;
service AuthzExtentionService {}

View File

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

View File

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

View File

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

View File

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