zelda/backend/apiserver/proxy/kubeapi/kubeapi.go

85 lines
2.1 KiB
Go
Raw Normal View History

2024-11-19 16:57:27 +08:00
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
}