85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
|
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
|
|||
|
}
|