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