omni/internal/backend/k8sproxy/proxy.go
Andrey Smirnov dfcbaae7d0
chore: initial commit
Omni is source-available under BUSL.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
Co-Authored-By: Artem Chernyshev <artem.chernyshev@talos-systems.com>
Co-Authored-By: Utku Ozdemir <utku.ozdemir@siderolabs.com>
Co-Authored-By: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
Co-Authored-By: Philipp Sauter <philipp.sauter@siderolabs.com>
Co-Authored-By: Noel Georgi <git@frezbo.dev>
Co-Authored-By: evgeniybryzh <evgeniybryzh@gmail.com>
Co-Authored-By: Tim Jones <tim.jones@siderolabs.com>
Co-Authored-By: Andrew Rynhard <andrew@rynhard.io>
Co-Authored-By: Spencer Smith <spencer.smith@talos-systems.com>
Co-Authored-By: Christian Rolland <christian.rolland@siderolabs.com>
Co-Authored-By: Gerard de Leeuw <gdeleeuw@leeuwit.nl>
Co-Authored-By: Steve Francis <67986293+steverfrancis@users.noreply.github.com>
Co-Authored-By: Volodymyr Mazurets <volodymyrmazureets@gmail.com>
2024-02-29 17:19:57 +04:00

68 lines
1.6 KiB
Go

// Copyright (c) 2024 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"
)
// 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) {
clusterName, ok := req.Context().Value(clusterContextKey{}).(string)
if !ok {
ctxzap.Error(req.Context(), "cluster name not found in request context")
return
}
connector, err := p.multiplexer.getClusterConnector(req.Context(), 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)
}