kube-explorer/internal/ui/content/external.go
Yuxing Deng eacc47482e refactor: UI resource logic
- Support embed api-ui resources
- The ui-path arg will be applied if provided. Also applied to api-ui resource files
2024-07-23 16:53:49 +08:00

98 lines
1.8 KiB
Go

package content
import (
"bytes"
"crypto/tls"
"errors"
"io"
"net/http"
"sync"
)
const (
defaultIndex = "https://releases.rancher.com/dashboard/latest/index.html"
)
func NewExternal(getIndex func() string) Handler {
return &externalIndexHandler{
getIndexFunc: getIndex,
}
}
var (
insecureClient = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
_ Handler = &externalIndexHandler{}
)
type externalIndexHandler struct {
sync.RWMutex
getIndexFunc func() string
current string
downloadSuccess *bool
}
func (u *externalIndexHandler) ServeAssets(_ func(http.Handler) http.Handler, next http.Handler) http.Handler {
return next
}
func (u *externalIndexHandler) ServeFaviconDashboard() http.Handler {
return http.NotFoundHandler()
}
func (u *externalIndexHandler) GetIndex() ([]byte, error) {
if u.canDownload() {
var buffer bytes.Buffer
if err := serveIndex(&buffer, u.current); err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
return nil, errors.New("external index is not available")
}
func serveIndex(resp io.Writer, url string) error {
r, err := insecureClient.Get(url)
if err != nil {
return err
}
defer r.Body.Close()
_, err = io.Copy(resp, r.Body)
return err
}
func (u *externalIndexHandler) canDownload() bool {
u.RLock()
rtn := u.downloadSuccess
u.RUnlock()
if rtn != nil {
return *rtn
}
return u.refresh()
}
func (u *externalIndexHandler) refresh() bool {
u.Lock()
defer u.RUnlock()
u.current = u.getIndexFunc()
if u.current == "" {
u.current = defaultIndex
}
t := serveIndex(io.Discard, u.current) == nil
u.downloadSuccess = &t
return t
}
func (u *externalIndexHandler) Refresh() {
_ = u.refresh()
}