github.com/oam-dev/cluster-gateway@v1.9.0/pkg/apis/cluster/v1alpha1/transport.go (about) 1 package v1alpha1 2 3 import ( 4 "context" 5 "net" 6 "net/http" 7 "net/url" 8 "strconv" 9 "time" 10 11 "github.com/pkg/errors" 12 "google.golang.org/grpc" 13 grpccredentials "google.golang.org/grpc/credentials" 14 "google.golang.org/grpc/keepalive" 15 k8snet "k8s.io/apimachinery/pkg/util/net" 16 restclient "k8s.io/client-go/rest" 17 konnectivity "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client" 18 "sigs.k8s.io/apiserver-network-proxy/pkg/util" 19 20 "github.com/oam-dev/cluster-gateway/pkg/config" 21 ) 22 23 var DialerGetter = func(ctx context.Context) (k8snet.DialFunc, error) { 24 tlsCfg, err := util.GetClientTLSConfig( 25 config.ClusterProxyCAFile, 26 config.ClusterProxyCertFile, 27 config.ClusterProxyKeyFile, 28 config.ClusterProxyHost, 29 nil) 30 if err != nil { 31 return nil, err 32 } 33 dialerTunnel, err := konnectivity.CreateSingleUseGrpcTunnel( 34 ctx, 35 net.JoinHostPort(config.ClusterProxyHost, strconv.Itoa(config.ClusterProxyPort)), 36 grpc.WithTransportCredentials(grpccredentials.NewTLS(tlsCfg)), 37 grpc.WithKeepaliveParams(keepalive.ClientParameters{ 38 Time: time.Second * 5, 39 }), 40 ) 41 if err != nil { 42 return nil, err 43 } 44 return dialerTunnel.DialContext, nil 45 } 46 47 func NewConfigFromCluster(ctx context.Context, c *ClusterGateway) (*restclient.Config, error) { 48 cfg := &restclient.Config{ 49 Timeout: time.Second * 40, 50 } 51 // setting up endpoint 52 switch c.Spec.Access.Endpoint.Type { 53 case ClusterEndpointTypeConst: 54 cfg.Host = c.Spec.Access.Endpoint.Const.Address 55 cfg.CAData = c.Spec.Access.Endpoint.Const.CABundle 56 if c.Spec.Access.Endpoint.Const.Insecure != nil && *c.Spec.Access.Endpoint.Const.Insecure { 57 cfg.TLSClientConfig = restclient.TLSClientConfig{Insecure: true} 58 } 59 u, err := url.Parse(c.Spec.Access.Endpoint.Const.Address) 60 if err != nil { 61 return nil, err 62 } 63 64 const missingPort = "missing port in address" 65 host, _, err := net.SplitHostPort(u.Host) 66 if err != nil { 67 addrErr, ok := err.(*net.AddrError) 68 if !ok { 69 return nil, err 70 } 71 if addrErr.Err != missingPort { 72 return nil, err 73 } 74 host = u.Host 75 } 76 cfg.ServerName = host // apiserver may listen on SNI cert 77 78 if c.Spec.Access.Endpoint.Const.ProxyURL != nil { 79 _url, _err := url.Parse(*c.Spec.Access.Endpoint.Const.ProxyURL) 80 if _err != nil { 81 return nil, _err 82 } 83 cfg.Proxy = http.ProxyURL(_url) 84 } 85 case ClusterEndpointTypeClusterProxy: 86 cfg.Host = c.Name // the same as the cluster name 87 cfg.Insecure = true 88 cfg.CAData = nil 89 dail, err := DialerGetter(ctx) 90 if err != nil { 91 return nil, err 92 } 93 cfg.Dial = dail 94 } 95 // setting up credentials 96 switch c.Spec.Access.Credential.Type { 97 case CredentialTypeDynamic: 98 if token := c.Spec.Access.Credential.ServiceAccountToken; token != "" { 99 cfg.BearerToken = token 100 } 101 102 if c.Spec.Access.Credential.X509 != nil && len(c.Spec.Access.Credential.X509.Certificate) > 0 && len(c.Spec.Access.Credential.X509.PrivateKey) > 0 { 103 cfg.CertData = c.Spec.Access.Credential.X509.Certificate 104 cfg.KeyData = c.Spec.Access.Credential.X509.PrivateKey 105 } 106 107 case CredentialTypeServiceAccountToken: 108 cfg.BearerToken = c.Spec.Access.Credential.ServiceAccountToken 109 110 case CredentialTypeX509Certificate: 111 cfg.CertData = c.Spec.Access.Credential.X509.Certificate 112 cfg.KeyData = c.Spec.Access.Credential.X509.PrivateKey 113 } 114 return cfg, nil 115 } 116 117 func GetEndpointURL(c *ClusterGateway) (*url.URL, error) { 118 switch c.Spec.Access.Endpoint.Type { 119 case ClusterEndpointTypeConst: 120 urlAddr, err := url.Parse(c.Spec.Access.Endpoint.Const.Address) 121 if err != nil { 122 return nil, errors.Wrapf(err, "failed parsing url from cluster %s invalid value %s", 123 c.Name, c.Spec.Access.Endpoint.Const.Address) 124 } 125 return urlAddr, nil 126 case ClusterEndpointTypeClusterProxy: 127 return &url.URL{ 128 Scheme: "https", 129 Host: c.Name, 130 }, nil 131 default: 132 return nil, errors.New("unsupported cluster gateway endpoint type") 133 } 134 }