From 9d063069f753cf95d281a8d2840bd7151b6552e7 Mon Sep 17 00:00:00 2001 From: Baraa Basata Date: Wed, 9 Jul 2025 10:19:39 -0400 Subject: [PATCH 1/4] experimental: what if - interceptors --- tf5muxserver/mux_server.go | 13 +++++++++++++ tf5muxserver/mux_server_ListResource.go | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/tf5muxserver/mux_server.go b/tf5muxserver/mux_server.go index ab0393b..cb496c0 100644 --- a/tf5muxserver/mux_server.go +++ b/tf5muxserver/mux_server.go @@ -55,6 +55,19 @@ type muxServer struct { // Underlying servers for requests that should be handled by all servers servers []tfprotov5.ProviderServer + + // interceptors []tfprotov5.Interceptor + listResourceInterceptors []Interceptor[*tfprotov5.ListResourceRequest] +} + +type Event byte + +const ( + Before Event = iota +) + +type Interceptor[T any] interface { + Call(ctx context.Context, e Event, request T) (newContext context.Context, newRequest T) } // ProviderServer is a function compatible with tf6server.Serve. diff --git a/tf5muxserver/mux_server_ListResource.go b/tf5muxserver/mux_server_ListResource.go index 3b6be28..fedd545 100644 --- a/tf5muxserver/mux_server_ListResource.go +++ b/tf5muxserver/mux_server_ListResource.go @@ -17,6 +17,10 @@ func (s *muxServer) ListResource(ctx context.Context, req *tfprotov5.ListResourc ctx = logging.InitContext(ctx) ctx = logging.RpcContext(ctx, rpc) + for _, i := range s.listResourceInterceptors { + ctx, req = i.Call(ctx, Before, req) + } + server, diags, err := s.getListResourceServer(ctx, req.TypeName) if err != nil { From 47cdc7e4bf20939ea65e0f13be3e434693e07ede Mon Sep 17 00:00:00 2001 From: Baraa Basata Date: Wed, 9 Jul 2025 10:46:46 -0400 Subject: [PATCH 2/4] Register interceptors --- tf5muxserver/mux_server.go | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tf5muxserver/mux_server.go b/tf5muxserver/mux_server.go index cb496c0..19d35f2 100644 --- a/tf5muxserver/mux_server.go +++ b/tf5muxserver/mux_server.go @@ -439,3 +439,48 @@ func NewMuxServer(_ context.Context, servers ...func() tfprotov5.ProviderServer) return &result, nil } + +type Option func(*muxServer) + +func OptServers(servers ...func() tfprotov5.ProviderServer) Option { + return func(mux *muxServer) { + for _, server := range servers { + mux.servers = append(mux.servers, server()) + } + } +} + +func OptListResourceInterceptors(interceptors ...Interceptor[*tfprotov5.ListResourceRequest]) Option { + return func(mux *muxServer) { + mux.listResourceInterceptors = append(mux.listResourceInterceptors, interceptors...) + } +} + +// NewMuxServerWithOptions returns a muxed server that will route gRPC requests between +// tfprotov5.ProviderServers specified. The GetProviderSchema method of each +// is called to verify that the overall muxed server is compatible by ensuring: +// +// - All provider schemas exactly match +// - All provider meta schemas exactly match +// - Only one provider implements each managed resource +// - Only one provider implements each data source +// - Only one provider implements each function +// - Only one provider implements each ephemeral resource +// - Only one provider implements each list resource +// - Only one provider implements each resource identity +func NewMuxServerWithOptions(_ context.Context, options ...Option) (*muxServer, error) { + result := muxServer{ + dataSources: make(map[string]tfprotov5.ProviderServer), + ephemeralResources: make(map[string]tfprotov5.ProviderServer), + listResources: make(map[string]tfprotov5.ProviderServer), + functions: make(map[string]tfprotov5.ProviderServer), + resources: make(map[string]tfprotov5.ProviderServer), + resourceCapabilities: make(map[string]*tfprotov5.ServerCapabilities), + } + + for _, option := range options { + option(&result) + } + + return &result, nil +} From 6225fb92f9d2b52d4f2651eac5153efa58de92f5 Mon Sep 17 00:00:00 2001 From: Baraa Basata Date: Wed, 9 Jul 2025 10:55:56 -0400 Subject: [PATCH 3/4] Refactor --- tf5muxserver/mux_server.go | 16 +++++----------- tf5muxserver/mux_server_ListResource.go | 7 +++++-- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/tf5muxserver/mux_server.go b/tf5muxserver/mux_server.go index 19d35f2..edc38b3 100644 --- a/tf5muxserver/mux_server.go +++ b/tf5muxserver/mux_server.go @@ -57,17 +57,11 @@ type muxServer struct { servers []tfprotov5.ProviderServer // interceptors []tfprotov5.Interceptor - listResourceInterceptors []Interceptor[*tfprotov5.ListResourceRequest] + interceptors []Interceptor } -type Event byte - -const ( - Before Event = iota -) - -type Interceptor[T any] interface { - Call(ctx context.Context, e Event, request T) (newContext context.Context, newRequest T) +type Interceptor struct { + BeforeListResource func(context.Context, *tfprotov5.ListResourceRequest) context.Context } // ProviderServer is a function compatible with tf6server.Serve. @@ -450,9 +444,9 @@ func OptServers(servers ...func() tfprotov5.ProviderServer) Option { } } -func OptListResourceInterceptors(interceptors ...Interceptor[*tfprotov5.ListResourceRequest]) Option { +func OptInterceptors(interceptors ...Interceptor) Option { return func(mux *muxServer) { - mux.listResourceInterceptors = append(mux.listResourceInterceptors, interceptors...) + mux.interceptors = append(mux.interceptors, interceptors...) } } diff --git a/tf5muxserver/mux_server_ListResource.go b/tf5muxserver/mux_server_ListResource.go index fedd545..4c59aea 100644 --- a/tf5muxserver/mux_server_ListResource.go +++ b/tf5muxserver/mux_server_ListResource.go @@ -17,8 +17,11 @@ func (s *muxServer) ListResource(ctx context.Context, req *tfprotov5.ListResourc ctx = logging.InitContext(ctx) ctx = logging.RpcContext(ctx, rpc) - for _, i := range s.listResourceInterceptors { - ctx, req = i.Call(ctx, Before, req) + for _, i := range s.interceptors { + if i.BeforeListResource == nil { + continue + } + ctx = i.BeforeListResource(ctx, req) } server, diags, err := s.getListResourceServer(ctx, req.TypeName) From 70f977f9fcb3829d403a8b30f823883d8b56b4f1 Mon Sep 17 00:00:00 2001 From: Baraa Basata Date: Wed, 9 Jul 2025 10:55:56 -0400 Subject: [PATCH 4/4] Refactor --- tf5muxserver/mux_server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tf5muxserver/mux_server.go b/tf5muxserver/mux_server.go index edc38b3..82421f7 100644 --- a/tf5muxserver/mux_server.go +++ b/tf5muxserver/mux_server.go @@ -436,7 +436,7 @@ func NewMuxServer(_ context.Context, servers ...func() tfprotov5.ProviderServer) type Option func(*muxServer) -func OptServers(servers ...func() tfprotov5.ProviderServer) Option { +func Servers(servers ...func() tfprotov5.ProviderServer) Option { return func(mux *muxServer) { for _, server := range servers { mux.servers = append(mux.servers, server()) @@ -444,7 +444,7 @@ func OptServers(servers ...func() tfprotov5.ProviderServer) Option { } } -func OptInterceptors(interceptors ...Interceptor) Option { +func Interceptors(interceptors ...Interceptor) Option { return func(mux *muxServer) { mux.interceptors = append(mux.interceptors, interceptors...) }