omni/internal/backend/k8sproxy/proxy.go
Artem Chernyshev ed946b30a6
feat: display OMNI_ENDPOINT in the service account creation UI
Fixes: https://github.com/siderolabs/omni/issues/858

Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
2025-01-29 15:27:36 +03:00

69 lines
1.7 KiB
Go

// Copyright (c) 2025 Sidero Labs, Inc.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
package k8sproxy
import (
"net/http"
"net/http/httputil"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
"go.uber.org/zap"
"github.com/siderolabs/omni/internal/backend/logging"
"github.com/siderolabs/omni/internal/pkg/ctxstore"
)
// proxyHandler implements the HTTP reverse proxy.
type proxyHandler struct {
multiplexer *multiplexer
proxy *httputil.ReverseProxy
}
func newProxyHandler(m *multiplexer, logger *zap.Logger) *proxyHandler {
p := &proxyHandler{
multiplexer: m,
}
logger = logger.With(logging.Component("k8s_proxy"))
p.proxy = &httputil.ReverseProxy{
Director: p.director,
Transport: m,
ErrorLog: zap.NewStdLog(logger),
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
ctxzap.Error(r.Context(), "proxy handling error", zap.Error(err))
http.Error(w, "proxy error", http.StatusBadGateway)
},
}
return p
}
// director sets the target URL for the reverse proxy.
func (p *proxyHandler) director(req *http.Request) {
clusterNameVal, ok := ctxstore.Value[clusterContextKey](req.Context())
if !ok {
ctxzap.Error(req.Context(), "cluster name not found in request context")
return
}
connector, err := p.multiplexer.getClusterConnector(req.Context(), clusterNameVal.ClusterName)
if err != nil {
ctxzap.Error(req.Context(), "failed to get cluster connector", zap.Error(err))
return
}
req.URL.Scheme = "https"
req.URL.Host = connector.apiHost
}
func (p *proxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
p.proxy.ServeHTTP(w, r)
}