mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-04 03:42:49 +02:00
grpc: send client traffic through envoy (#2469)
* wip * wip * handle wildcards in override name * remove wait for ready, add comment about sync, force initial sync complete in test * address comments
This commit is contained in:
parent
87c3c675d2
commit
bbec2cae9f
26 changed files with 391 additions and 480 deletions
|
@ -5,7 +5,6 @@ package pomerium
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
@ -66,7 +65,7 @@ func Run(ctx context.Context, configFile string) error {
|
|||
defer traceMgr.Close()
|
||||
|
||||
// setup the control plane
|
||||
controlPlane, err := controlplane.NewServer(src.GetConfig().Options.Services, metricsMgr)
|
||||
controlPlane, err := controlplane.NewServer(src.GetConfig(), metricsMgr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating control plane: %w", err)
|
||||
}
|
||||
|
@ -83,14 +82,14 @@ func Run(ctx context.Context, configFile string) error {
|
|||
return fmt.Errorf("applying config: %w", err)
|
||||
}
|
||||
|
||||
_, grpcPort, _ := net.SplitHostPort(controlPlane.GRPCListener.Addr().String())
|
||||
_, httpPort, _ := net.SplitHostPort(controlPlane.HTTPListener.Addr().String())
|
||||
|
||||
log.Info(ctx).Str("port", grpcPort).Msg("gRPC server started")
|
||||
log.Info(ctx).Str("port", httpPort).Msg("HTTP server started")
|
||||
log.Info(ctx).
|
||||
Str("grpc-port", src.GetConfig().GRPCPort).
|
||||
Str("http-port", src.GetConfig().HTTPPort).
|
||||
Str("outbound-port", src.GetConfig().OutboundPort).
|
||||
Msg("server started")
|
||||
|
||||
// create envoy server
|
||||
envoyServer, err := envoy.NewServer(ctx, src, grpcPort, httpPort, controlPlane.Builder)
|
||||
envoyServer, err := envoy.NewServer(ctx, src, controlPlane.Builder)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating envoy server: %w", err)
|
||||
}
|
||||
|
@ -143,13 +142,6 @@ func Run(ctx context.Context, configFile string) error {
|
|||
eg.Go(func() error {
|
||||
return authorizeServer.Run(ctx)
|
||||
})
|
||||
// in non-all-in-one mode we will wait for the initial sync to complete before starting
|
||||
// the control plane
|
||||
if dataBrokerServer == nil {
|
||||
if err := authorizeServer.WaitForInitialSync(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
eg.Go(func() error {
|
||||
return controlPlane.Run(ctx)
|
||||
|
|
|
@ -81,29 +81,18 @@ func (srv *Server) storeEnvoyConfigurationEvent(ctx context.Context, evt *events
|
|||
}
|
||||
|
||||
func (srv *Server) getDataBrokerClient(ctx context.Context) (databrokerpb.DataBrokerServiceClient, error) {
|
||||
options := srv.currentConfig.Load().Options
|
||||
cfg := srv.currentConfig.Load()
|
||||
|
||||
sharedKey, err := options.GetSharedKey()
|
||||
sharedKey, err := cfg.Options.GetSharedKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
urls, err := options.GetDataBrokerURLs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cc, err := grpc.GetGRPCClientConn(ctx, "databroker", &grpc.Options{
|
||||
Addrs: urls,
|
||||
OverrideCertificateName: options.OverrideCertificateName,
|
||||
CA: options.CA,
|
||||
CAFile: options.CAFile,
|
||||
RequestTimeout: options.GRPCClientTimeout,
|
||||
ClientDNSRoundRobin: options.GRPCClientDNSRoundRobin,
|
||||
WithInsecure: options.GetGRPCInsecure(),
|
||||
InstallationID: options.InstallationID,
|
||||
ServiceName: options.Services,
|
||||
SignedJWTKey: sharedKey,
|
||||
cc, err := grpc.GetOutboundGRPCClientConn(context.Background(), &grpc.OutboundOptions{
|
||||
OutboundPort: cfg.OutboundPort,
|
||||
InstallationID: cfg.Options.InstallationID,
|
||||
ServiceName: cfg.Options.Services,
|
||||
SignedJWTKey: sharedKey,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("controlplane: error creating databroker connection: %w", err)
|
||||
|
|
|
@ -69,6 +69,7 @@ func TestEvents(t *testing.T) {
|
|||
li, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
defer li.Close()
|
||||
_, outboundPort, _ := net.SplitHostPort(li.Addr().String())
|
||||
|
||||
var putRequest *databrokerpb.PutRequest
|
||||
var setOptionsRequest *databrokerpb.SetOptionsRequest
|
||||
|
@ -100,6 +101,7 @@ func TestEvents(t *testing.T) {
|
|||
srv := &Server{}
|
||||
srv.currentConfig.Store(versionedConfig{
|
||||
Config: &config.Config{
|
||||
OutboundPort: outboundPort,
|
||||
Options: &config.Options{
|
||||
SharedKey: cryptutil.NewBase64Key(),
|
||||
DataBrokerURLString: "http://" + li.Addr().String(),
|
||||
|
|
|
@ -68,20 +68,20 @@ type Server struct {
|
|||
}
|
||||
|
||||
// NewServer creates a new Server. Listener ports are chosen by the OS.
|
||||
func NewServer(name string, metricsMgr *config.MetricsManager) (*Server, error) {
|
||||
func NewServer(cfg *config.Config, metricsMgr *config.MetricsManager) (*Server, error) {
|
||||
srv := &Server{
|
||||
metricsMgr: metricsMgr,
|
||||
reproxy: reproxy.New(),
|
||||
envoyConfigurationEvents: make(chan *events.EnvoyConfigurationEvent, 10),
|
||||
}
|
||||
srv.currentConfig.Store(versionedConfig{
|
||||
Config: &config.Config{Options: &config.Options{}},
|
||||
Config: cfg,
|
||||
})
|
||||
|
||||
var err error
|
||||
|
||||
// setup gRPC
|
||||
srv.GRPCListener, err = net.Listen("tcp4", "127.0.0.1:0")
|
||||
srv.GRPCListener, err = net.Listen("tcp4", net.JoinHostPort("127.0.0.1", cfg.GRPCPort))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ func NewServer(name string, metricsMgr *config.MetricsManager) (*Server, error)
|
|||
),
|
||||
)
|
||||
srv.GRPCServer = grpc.NewServer(
|
||||
grpc.StatsHandler(telemetry.NewGRPCServerStatsHandler(name)),
|
||||
grpc.StatsHandler(telemetry.NewGRPCServerStatsHandler(cfg.Options.Services)),
|
||||
grpc.ChainUnaryInterceptor(requestid.UnaryServerInterceptor(), ui),
|
||||
grpc.ChainStreamInterceptor(requestid.StreamServerInterceptor(), si),
|
||||
)
|
||||
|
@ -102,7 +102,7 @@ func NewServer(name string, metricsMgr *config.MetricsManager) (*Server, error)
|
|||
grpc_health_v1.RegisterHealthServer(srv.GRPCServer, pom_grpc.NewHealthCheckServer())
|
||||
|
||||
// setup HTTP
|
||||
srv.HTTPListener, err = net.Listen("tcp4", "127.0.0.1:0")
|
||||
srv.HTTPListener, err = net.Listen("tcp4", net.JoinHostPort("127.0.0.1", cfg.HTTPPort))
|
||||
if err != nil {
|
||||
_ = srv.GRPCListener.Close()
|
||||
return nil, err
|
||||
|
@ -121,7 +121,7 @@ func NewServer(name string, metricsMgr *config.MetricsManager) (*Server, error)
|
|||
)
|
||||
|
||||
ctx := log.WithContext(context.Background(), func(c zerolog.Context) zerolog.Context {
|
||||
return c.Str("server_name", name)
|
||||
return c.Str("server_name", cfg.Options.Services)
|
||||
})
|
||||
|
||||
res, err := srv.buildDiscoveryResources(ctx)
|
||||
|
|
|
@ -157,23 +157,12 @@ func (src *ConfigSource) rebuild(ctx context.Context, firstTime firstTime) {
|
|||
}
|
||||
|
||||
func (src *ConfigSource) runUpdater(cfg *config.Config) {
|
||||
urls, err := cfg.Options.GetDataBrokerURLs()
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Send()
|
||||
return
|
||||
}
|
||||
|
||||
sharedKey, _ := cfg.Options.GetSharedKey()
|
||||
connectionOptions := &grpc.Options{
|
||||
Addrs: urls,
|
||||
OverrideCertificateName: cfg.Options.OverrideCertificateName,
|
||||
CA: cfg.Options.CA,
|
||||
CAFile: cfg.Options.CAFile,
|
||||
RequestTimeout: cfg.Options.GRPCClientTimeout,
|
||||
ClientDNSRoundRobin: cfg.Options.GRPCClientDNSRoundRobin,
|
||||
WithInsecure: cfg.Options.GetGRPCInsecure(),
|
||||
ServiceName: cfg.Options.Services,
|
||||
SignedJWTKey: sharedKey,
|
||||
connectionOptions := &grpc.OutboundOptions{
|
||||
OutboundPort: cfg.OutboundPort,
|
||||
InstallationID: cfg.Options.InstallationID,
|
||||
ServiceName: cfg.Options.Services,
|
||||
SignedJWTKey: sharedKey,
|
||||
}
|
||||
h, err := hashutil.Hash(connectionOptions)
|
||||
if err != nil {
|
||||
|
@ -193,7 +182,7 @@ func (src *ConfigSource) runUpdater(cfg *config.Config) {
|
|||
ctx := context.Background()
|
||||
ctx, src.cancel = context.WithCancel(ctx)
|
||||
|
||||
cc, err := grpc.NewGRPCClientConn(ctx, connectionOptions)
|
||||
cc, err := grpc.GetOutboundGRPCClientConn(ctx, connectionOptions)
|
||||
if err != nil {
|
||||
log.Error(ctx).Err(err).Msg("databroker: failed to create gRPC connection to data broker")
|
||||
return
|
||||
|
|
|
@ -25,6 +25,7 @@ func TestConfigSource(t *testing.T) {
|
|||
return
|
||||
}
|
||||
defer func() { _ = li.Close() }()
|
||||
_, outboundPort, _ := net.SplitHostPort(li.Addr().String())
|
||||
|
||||
dataBrokerServer := New()
|
||||
srv := grpc.NewServer()
|
||||
|
@ -45,7 +46,8 @@ func TestConfigSource(t *testing.T) {
|
|||
})
|
||||
|
||||
baseSource := config.NewStaticSource(&config.Config{
|
||||
Options: base,
|
||||
OutboundPort: outboundPort,
|
||||
Options: base,
|
||||
})
|
||||
src := NewConfigSource(ctx, baseSource, func(_ context.Context, cfg *config.Config) {
|
||||
cfgs <- cfg
|
||||
|
@ -86,6 +88,7 @@ func TestConfigSource(t *testing.T) {
|
|||
}
|
||||
|
||||
baseSource.SetConfig(ctx, &config.Config{
|
||||
Options: base,
|
||||
OutboundPort: outboundPort,
|
||||
Options: base,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ type Server struct {
|
|||
}
|
||||
|
||||
// NewServer creates a new server with traffic routed by envoy.
|
||||
func NewServer(ctx context.Context, src config.Source, grpcPort, httpPort string, builder *envoyconfig.Builder) (*Server, error) {
|
||||
func NewServer(ctx context.Context, src config.Source, builder *envoyconfig.Builder) (*Server, error) {
|
||||
wd := filepath.Join(os.TempDir(), workingDirectoryName)
|
||||
err := os.MkdirAll(wd, embeddedEnvoyPermissions)
|
||||
if err != nil {
|
||||
|
@ -97,8 +97,8 @@ func NewServer(ctx context.Context, src config.Source, grpcPort, httpPort string
|
|||
srv := &Server{
|
||||
wd: wd,
|
||||
builder: builder,
|
||||
grpcPort: grpcPort,
|
||||
httpPort: httpPort,
|
||||
grpcPort: src.GetConfig().GRPCPort,
|
||||
httpPort: src.GetConfig().HTTPPort,
|
||||
envoyPath: envoyPath,
|
||||
|
||||
monitorProcessCancel: func() {},
|
||||
|
|
22
internal/netutil/netutil.go
Normal file
22
internal/netutil/netutil.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Package netutil contains various functions that help with networking.
|
||||
package netutil
|
||||
|
||||
import "net"
|
||||
|
||||
// AllocatePorts allocates random ports suitable for listening.
|
||||
func AllocatePorts(count int) ([]string, error) {
|
||||
var ports []string
|
||||
for i := 0; i < count; i++ {
|
||||
li, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, port, _ := net.SplitHostPort(li.Addr().String())
|
||||
err = li.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ports = append(ports, port)
|
||||
}
|
||||
return ports, nil
|
||||
}
|
|
@ -39,23 +39,11 @@ func (r *Reporter) OnConfigChange(ctx context.Context, cfg *config.Config) {
|
|||
return
|
||||
}
|
||||
|
||||
urls, err := cfg.Options.GetDataBrokerURLs()
|
||||
if err != nil {
|
||||
log.Error(ctx).Err(err).Msg("invalid databroker urls")
|
||||
return
|
||||
}
|
||||
|
||||
registryConn, err := grpc.GetGRPCClientConn(ctx, "databroker", &grpc.Options{
|
||||
Addrs: urls,
|
||||
OverrideCertificateName: cfg.Options.OverrideCertificateName,
|
||||
CA: cfg.Options.CA,
|
||||
CAFile: cfg.Options.CAFile,
|
||||
RequestTimeout: cfg.Options.GRPCClientTimeout,
|
||||
ClientDNSRoundRobin: cfg.Options.GRPCClientDNSRoundRobin,
|
||||
WithInsecure: cfg.Options.GetGRPCInsecure(),
|
||||
InstallationID: cfg.Options.InstallationID,
|
||||
ServiceName: cfg.Options.Services,
|
||||
SignedJWTKey: sharedKey,
|
||||
registryConn, err := grpc.GetOutboundGRPCClientConn(ctx, &grpc.OutboundOptions{
|
||||
OutboundPort: cfg.OutboundPort,
|
||||
InstallationID: cfg.Options.InstallationID,
|
||||
ServiceName: cfg.Options.Services,
|
||||
SignedJWTKey: sharedKey,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error(ctx).Err(err).Msg("connecting to registry")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue