package kubeapi import ( "crypto/tls" "crypto/x509" // "encoding/base64" // "fmt" "net" "net/http" "net/http/httputil" "time" "github.com/gin-gonic/gin" "github.com/ycyxuehan/zelda/apiserver/proxy/api" ) type kubeAPI struct { domain string path string certs []string } func NewKubeAPI(domain, path string) api.Proxy { return &kubeAPI{ path: path, domain: domain, } } func (k *kubeAPI) Proxy() gin.HandlerFunc { return func(c *gin.Context) { cert := "" director := func(req *http.Request) { req.URL.Scheme = api.HTTPS req.URL.Host = k.domain req.Header.Set("Content-Type", c.GetHeader("Content-Type")) req.Header.Set("Content-Length", c.GetHeader("Content-Length")) // if c.Request.Method == http.MethodPost || c.Request.Method == http.MethodPatch || c.Request.Method == http.MethodPut { req.Header.Set("Content-Type", "application/json") // } req.Host = k.domain //watch模式需要提升协议为websocket watch := c.Query("watch") follow := c.Query("follow") if watch == "true" || follow == "true" { // fmt.Println("watch mode,允许升级为websocket") req.Header.Set("Upgrade", "websocket") } //从header获取cert cert = req.Header.Get("cert") req.Header.Del("cert") //删除cert } proxy := &httputil.ReverseProxy{Director: director} certs := x509.NewCertPool() transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, DualStack: true, }).DialContext, ForceAttemptHTTP2: true, MaxIdleConns: 100, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, TLSClientConfig: &tls.Config{}, //InsecureSkipVerify: true } //如果有证书,加入 if ok := certs.AppendCertsFromPEM([]byte(cert)); ok { transport.TLSClientConfig.RootCAs = certs } proxy.Transport = transport proxy.ServeHTTP(c.Writer, c.Request) } } func (k *kubeAPI) WithCerts(certs ...string) { k.certs = append(k.certs, certs...) } func (k *kubeAPI) Path() string { return k.path }