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