@@ -10,6 +10,7 @@ import (
1010	"github.com/go-openapi/spec" 
1111	"github.com/platform-mesh/golang-commons/logger" 
1212	"k8s.io/client-go/rest" 
13+ 	ctrl "sigs.k8s.io/controller-runtime" 
1314	"sigs.k8s.io/controller-runtime/pkg/client" 
1415
1516	"github.com/platform-mesh/kubernetes-graphql-gateway/common/auth" 
@@ -64,6 +65,7 @@ func NewTargetCluster(
6465	log  * logger.Logger ,
6566	appCfg  appConfig.Config ,
6667	roundTripperFactory  func (http.RoundTripper , rest.TLSClientConfig ) http.RoundTripper ,
68+ 	enableHTTP2  bool ,
6769) (* TargetCluster , error ) {
6870	fileData , err  :=  readSchemaFile (schemaFilePath )
6971	if  err  !=  nil  {
@@ -77,7 +79,7 @@ func NewTargetCluster(
7779	}
7880
7981	// Connect to cluster - use metadata if available, otherwise fall back to standard config 
80- 	if  err  :=  cluster .connect (appCfg , fileData .ClusterMetadata , roundTripperFactory ); err  !=  nil  {
82+ 	if  err  :=  cluster .connect (appCfg , fileData .ClusterMetadata , roundTripperFactory ,  enableHTTP2 ); err  !=  nil  {
8183		return  nil , fmt .Errorf ("failed to connect to cluster: %w" , err )
8284	}
8385
@@ -110,7 +112,7 @@ func (tc *TargetCluster) loadSchemaFromFile(schemaFilePath string) error {
110112}
111113
112114// connect establishes connection to the target cluster 
113- func  (tc  * TargetCluster ) connect (appCfg  appConfig.Config , metadata  * ClusterMetadata , roundTripperFactory  func (http.RoundTripper , rest.TLSClientConfig ) http.RoundTripper ) error  {
115+ func  (tc  * TargetCluster ) connect (appCfg  appConfig.Config , metadata  * ClusterMetadata , roundTripperFactory  func (http.RoundTripper , rest.TLSClientConfig ) http.RoundTripper ,  enableHTTP2   bool ) error  {
114116	// All clusters now use metadata from schema files to get kubeconfig 
115117	if  metadata  ==  nil  {
116118		return  fmt .Errorf ("cluster %s requires cluster metadata in schema file" , tc .name )
@@ -120,14 +122,37 @@ func (tc *TargetCluster) connect(appCfg appConfig.Config, metadata *ClusterMetad
120122		Str ("cluster" , tc .name ).
121123		Str ("host" , metadata .Host ).
122124		Bool ("isVirtualWorkspace" , strings .HasPrefix (tc .name , tc .appCfg .Url .VirtualWorkspacePrefix )).
125+ 		Bool ("enableHTTP2" , enableHTTP2 ).
123126		Msg ("Using cluster metadata from schema file for connection" )
124127
125128	var  err  error 
126- 	tc .restCfg , err  =  buildConfigFromMetadata (metadata , tc .log )
127- 	if  err  !=  nil  {
128- 		return  fmt .Errorf ("failed to build config from metadata: %w" , err )
129+ 
130+ 	// Use the same configuration approach as the Listener for consistency 
131+ 	// This ensures we have the same authentication and connection setup 
132+ 	tc .log .Debug ().Msg ("Using ctrl.GetConfigOrDie() approach for consistency with Listener" )
133+ 	tc .restCfg  =  ctrl .GetConfigOrDie ()
134+ 
135+ 	// Override the host with our cluster-specific metadata host 
136+ 	tc .restCfg .Host  =  metadata .Host 
137+ 
138+ 	// For KCP connections, use insecure TLS to avoid certificate issues 
139+ 	// This is safe for internal KCP communication within the same cluster 
140+ 	tc .restCfg .TLSClientConfig .Insecure  =  true 
141+ 	tc .restCfg .TLSClientConfig .CAFile  =  "" 
142+ 	tc .restCfg .TLSClientConfig .CAData  =  nil 
143+ 
144+ 	// Force HTTP/1.1 to avoid HTTP/2 stream errors with KCP 
145+ 	if  ! enableHTTP2  {
146+ 		tc .restCfg .TLSClientConfig .NextProtos  =  []string {"http/1.1" }
147+ 		tc .log .Debug ().Msg ("Disabled HTTP/2 for cluster connection" )
129148	}
130149
150+ 	tc .log .Debug ().
151+ 		Str ("host" , metadata .Host ).
152+ 		Bool ("enableHTTP2" , enableHTTP2 ).
153+ 		Strs ("nextProtos" , tc .restCfg .TLSClientConfig .NextProtos ).
154+ 		Msg ("Configured cluster connection using Listener approach" )
155+ 
131156	if  roundTripperFactory  !=  nil  {
132157		tc .restCfg .Wrap (func (rt  http.RoundTripper ) http.RoundTripper  {
133158			return  roundTripperFactory (rt , tc .restCfg .TLSClientConfig )
@@ -145,7 +170,7 @@ func (tc *TargetCluster) connect(appCfg appConfig.Config, metadata *ClusterMetad
145170}
146171
147172// buildConfigFromMetadata creates rest.Config from cluster metadata 
148- func  buildConfigFromMetadata (metadata  * ClusterMetadata , log  * logger.Logger ) (* rest.Config , error ) {
173+ func  buildConfigFromMetadata (metadata  * ClusterMetadata , log  * logger.Logger ,  enableHTTP2   bool ) (* rest.Config , error ) {
149174	var  authType , token , kubeconfig , certData , keyData , caData  string 
150175
151176	if  metadata .Auth  !=  nil  {
@@ -166,10 +191,17 @@ func buildConfigFromMetadata(metadata *ClusterMetadata, log *logger.Logger) (*re
166191		return  nil , err 
167192	}
168193
194+ 	// Apply HTTP/2 configuration to match Listener behavior 
195+ 	if  ! enableHTTP2  {
196+ 		log .Debug ().Msg ("disabling HTTP/2 for cluster connection" )
197+ 		config .TLSClientConfig .NextProtos  =  []string {"http/1.1" }
198+ 	}
199+ 
169200	log .Debug ().
170201		Str ("host" , metadata .Host ).
171202		Str ("authType" , authType ).
172203		Bool ("hasCA" , caData  !=  "" ).
204+ 		Bool ("enableHTTP2" , enableHTTP2 ).
173205		Msg ("configured cluster from metadata" )
174206
175207	return  config , nil 
0 commit comments