support loading route configuration via rds (#4098)

* support loading route configuration via rds

* fix any shadowing

* fix test

* add fully static option

* support dynamically defined rds

* fix build

* downgrade opa
This commit is contained in:
Caleb Doxsey 2023-04-17 11:20:12 -06:00 committed by GitHub
parent d485ca8306
commit f63945c0ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 300 additions and 672 deletions

View file

@ -1,6 +1,7 @@
package envoyconfig package envoyconfig
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -25,6 +26,47 @@ var (
envoyAdminClusterName = "pomerium-envoy-admin" envoyAdminClusterName = "pomerium-envoy-admin"
) )
// BuildBootstrap builds the bootstrap config.
func (b *Builder) BuildBootstrap(
ctx context.Context,
cfg *config.Config,
fullyStatic bool,
) (bootstrap *envoy_config_bootstrap_v3.Bootstrap, err error) {
bootstrap = new(envoy_config_bootstrap_v3.Bootstrap)
bootstrap.Admin, err = b.BuildBootstrapAdmin(cfg)
if err != nil {
return nil, fmt.Errorf("error building bootstrap admin: %w", err)
}
bootstrap.DynamicResources, err = b.BuildBootstrapDynamicResources(cfg, fullyStatic)
if err != nil {
return nil, fmt.Errorf("error building bootstrap dynamic resources: %w", err)
}
bootstrap.LayeredRuntime, err = b.BuildBootstrapLayeredRuntime()
if err != nil {
return nil, fmt.Errorf("error building bootstrap layered runtime: %w", err)
}
bootstrap.Node = &envoy_config_core_v3.Node{
Id: telemetry.ServiceName(cfg.Options.Services),
Cluster: telemetry.ServiceName(cfg.Options.Services),
}
bootstrap.StaticResources, err = b.BuildBootstrapStaticResources(ctx, cfg, fullyStatic)
if err != nil {
return nil, fmt.Errorf("error building bootstrap static resources: %w", err)
}
bootstrap.StatsConfig, err = b.BuildBootstrapStatsConfig(cfg)
if err != nil {
return nil, err
}
return bootstrap, nil
}
// BuildBootstrapAdmin builds the admin config for the envoy bootstrap. // BuildBootstrapAdmin builds the admin config for the envoy bootstrap.
func (b *Builder) BuildBootstrapAdmin(cfg *config.Config) (admin *envoy_config_bootstrap_v3.Admin, err error) { func (b *Builder) BuildBootstrapAdmin(cfg *config.Config) (admin *envoy_config_bootstrap_v3.Admin, err error) {
admin = &envoy_config_bootstrap_v3.Admin{ admin = &envoy_config_bootstrap_v3.Admin{
@ -53,6 +95,39 @@ func (b *Builder) BuildBootstrapAdmin(cfg *config.Config) (admin *envoy_config_b
return admin, nil return admin, nil
} }
// BuildBootstrapDynamicResources builds the dynamic resources for the envoy bootstrap.
func (b *Builder) BuildBootstrapDynamicResources(
cfg *config.Config,
fullyStatic bool,
) (dynamicResources *envoy_config_bootstrap_v3.Bootstrap_DynamicResources, err error) {
if fullyStatic {
return nil, nil
}
return &envoy_config_bootstrap_v3.Bootstrap_DynamicResources{
AdsConfig: &envoy_config_core_v3.ApiConfigSource{
ApiType: envoy_config_core_v3.ApiConfigSource_ApiType(envoy_config_core_v3.ApiConfigSource_ApiType_value["DELTA_GRPC"]),
TransportApiVersion: envoy_config_core_v3.ApiVersion_V3,
GrpcServices: []*envoy_config_core_v3.GrpcService{
{
TargetSpecifier: &envoy_config_core_v3.GrpcService_EnvoyGrpc_{
EnvoyGrpc: &envoy_config_core_v3.GrpcService_EnvoyGrpc{
ClusterName: "pomerium-control-plane-grpc",
},
},
},
},
},
LdsConfig: &envoy_config_core_v3.ConfigSource{
ResourceApiVersion: envoy_config_core_v3.ApiVersion_V3,
ConfigSourceSpecifier: &envoy_config_core_v3.ConfigSource_Ads{},
},
CdsConfig: &envoy_config_core_v3.ConfigSource{
ResourceApiVersion: envoy_config_core_v3.ApiVersion_V3,
ConfigSourceSpecifier: &envoy_config_core_v3.ConfigSource_Ads{},
},
}, nil
}
// BuildBootstrapLayeredRuntime builds the layered runtime for the envoy bootstrap. // BuildBootstrapLayeredRuntime builds the layered runtime for the envoy bootstrap.
func (b *Builder) BuildBootstrapLayeredRuntime() (*envoy_config_bootstrap_v3.LayeredRuntime, error) { func (b *Builder) BuildBootstrapLayeredRuntime() (*envoy_config_bootstrap_v3.LayeredRuntime, error) {
layer, err := structpb.NewStruct(map[string]interface{}{ layer, err := structpb.NewStruct(map[string]interface{}{
@ -78,7 +153,27 @@ func (b *Builder) BuildBootstrapLayeredRuntime() (*envoy_config_bootstrap_v3.Lay
// BuildBootstrapStaticResources builds the static resources for the envoy bootstrap. It includes the control plane // BuildBootstrapStaticResources builds the static resources for the envoy bootstrap. It includes the control plane
// cluster. // cluster.
func (b *Builder) BuildBootstrapStaticResources() (*envoy_config_bootstrap_v3.Bootstrap_StaticResources, error) { func (b *Builder) BuildBootstrapStaticResources(
ctx context.Context,
cfg *config.Config,
fullyStatic bool,
) (staticResources *envoy_config_bootstrap_v3.Bootstrap_StaticResources, err error) {
staticResources = new(envoy_config_bootstrap_v3.Bootstrap_StaticResources)
if fullyStatic {
staticResources.Clusters, err = b.BuildClusters(ctx, cfg)
if err != nil {
return nil, fmt.Errorf("error building clusters: %w", err)
}
staticResources.Listeners, err = b.BuildListeners(ctx, cfg, fullyStatic)
if err != nil {
return nil, fmt.Errorf("error building listeners: %w", err)
}
return staticResources, nil
}
grpcAddr, err := parseAddress(b.localGRPCAddress) grpcAddr, err := parseAddress(b.localGRPCAddress)
if err != nil { if err != nil {
return nil, fmt.Errorf("envoyconfig: invalid local gRPC address: %w", err) return nil, fmt.Errorf("envoyconfig: invalid local gRPC address: %w", err)
@ -114,13 +209,9 @@ func (b *Builder) BuildBootstrapStaticResources() (*envoy_config_bootstrap_v3.Bo
TypedExtensionProtocolOptions: buildTypedExtensionProtocolOptions(nil, upstreamProtocolHTTP2), TypedExtensionProtocolOptions: buildTypedExtensionProtocolOptions(nil, upstreamProtocolHTTP2),
} }
staticCfg := &envoy_config_bootstrap_v3.Bootstrap_StaticResources{ staticResources.Clusters = append(staticResources.Clusters, controlPlaneCluster)
Clusters: []*envoy_config_cluster_v3.Cluster{
controlPlaneCluster,
},
}
return staticCfg, nil return staticResources, nil
} }
// BuildBootstrapStatsConfig builds a the stats config the envoy bootstrap. // BuildBootstrapStatsConfig builds a the stats config the envoy bootstrap.

View file

@ -1,6 +1,7 @@
package envoyconfig package envoyconfig
import ( import (
"context"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -51,7 +52,7 @@ func TestBuilder_BuildBootstrapLayeredRuntime(t *testing.T) {
func TestBuilder_BuildBootstrapStaticResources(t *testing.T) { func TestBuilder_BuildBootstrapStaticResources(t *testing.T) {
t.Run("valid", func(t *testing.T) { t.Run("valid", func(t *testing.T) {
b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil) b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil)
staticCfg, err := b.BuildBootstrapStaticResources() staticCfg, err := b.BuildBootstrapStaticResources(context.Background(), &config.Config{}, false)
assert.NoError(t, err) assert.NoError(t, err)
testutil.AssertProtoJSONEqual(t, ` testutil.AssertProtoJSONEqual(t, `
{ {
@ -95,7 +96,7 @@ func TestBuilder_BuildBootstrapStaticResources(t *testing.T) {
}) })
t.Run("bad gRPC address", func(t *testing.T) { t.Run("bad gRPC address", func(t *testing.T) {
b := New("xyz:zyx", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil) b := New("xyz:zyx", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil)
_, err := b.BuildBootstrapStaticResources() _, err := b.BuildBootstrapStaticResources(context.Background(), &config.Config{}, false)
assert.Error(t, err) assert.Error(t, err)
}) })
} }

View file

@ -56,11 +56,15 @@ func init() {
} }
// BuildListeners builds envoy listeners from the given config. // BuildListeners builds envoy listeners from the given config.
func (b *Builder) BuildListeners(ctx context.Context, cfg *config.Config) ([]*envoy_config_listener_v3.Listener, error) { func (b *Builder) BuildListeners(
ctx context.Context,
cfg *config.Config,
fullyStatic bool,
) ([]*envoy_config_listener_v3.Listener, error) {
var listeners []*envoy_config_listener_v3.Listener var listeners []*envoy_config_listener_v3.Listener
if config.IsAuthenticate(cfg.Options.Services) || config.IsProxy(cfg.Options.Services) { if config.IsAuthenticate(cfg.Options.Services) || config.IsProxy(cfg.Options.Services) {
li, err := b.buildMainListener(ctx, cfg) li, err := b.buildMainListener(ctx, cfg, fullyStatic)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -128,7 +132,11 @@ func (b *Builder) buildTLSSocket(ctx context.Context, cfg *config.Config, certs
}, nil }, nil
} }
func (b *Builder) buildMainListener(ctx context.Context, cfg *config.Config) (*envoy_config_listener_v3.Listener, error) { func (b *Builder) buildMainListener(
ctx context.Context,
cfg *config.Config,
fullyStatic bool,
) (*envoy_config_listener_v3.Listener, error) {
li := newEnvoyListener("http-ingress") li := newEnvoyListener("http-ingress")
if cfg.Options.UseProxyProtocol { if cfg.Options.UseProxyProtocol {
li.ListenerFilters = append(li.ListenerFilters, ProxyProtocolFilter()) li.ListenerFilters = append(li.ListenerFilters, ProxyProtocolFilter())
@ -137,7 +145,7 @@ func (b *Builder) buildMainListener(ctx context.Context, cfg *config.Config) (*e
if cfg.Options.InsecureServer { if cfg.Options.InsecureServer {
li.Address = buildAddress(cfg.Options.Addr, 80) li.Address = buildAddress(cfg.Options.Addr, 80)
filter, err := b.buildMainHTTPConnectionManagerFilter(cfg.Options) filter, err := b.buildMainHTTPConnectionManagerFilter(ctx, cfg, fullyStatic)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -156,7 +164,7 @@ func (b *Builder) buildMainListener(ctx context.Context, cfg *config.Config) (*e
return nil, err return nil, err
} }
filter, err := b.buildMainHTTPConnectionManagerFilter(cfg.Options, allCertificates...) filter, err := b.buildMainHTTPConnectionManagerFilter(ctx, cfg, fullyStatic)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -254,67 +262,13 @@ func (b *Builder) buildMetricsListener(cfg *config.Config) (*envoy_config_listen
} }
func (b *Builder) buildMainHTTPConnectionManagerFilter( func (b *Builder) buildMainHTTPConnectionManagerFilter(
options *config.Options, ctx context.Context,
certs ...tls.Certificate, cfg *config.Config,
fullyStatic bool,
) (*envoy_config_listener_v3.Filter, error) { ) (*envoy_config_listener_v3.Filter, error) {
authorizeURLs, err := options.GetInternalAuthorizeURLs()
if err != nil {
return nil, err
}
dataBrokerURLs, err := options.GetInternalDataBrokerURLs()
if err != nil {
return nil, err
}
allHosts, err := getAllRouteableHosts(options, options.Addr)
if err != nil {
return nil, err
}
var virtualHosts []*envoy_config_route_v3.VirtualHost
for _, host := range allHosts {
requireStrictTransportSecurity := cryptutil.HasCertificateForServerName(certs, host)
vh, err := b.buildVirtualHost(options, host, host, requireStrictTransportSecurity)
if err != nil {
return nil, err
}
if options.Addr == options.GetGRPCAddr() {
// if this is a gRPC service domain and we're supposed to handle that, add those routes
if (config.IsAuthorize(options.Services) && urlsMatchHost(authorizeURLs, host)) ||
(config.IsDataBroker(options.Services) && urlsMatchHost(dataBrokerURLs, host)) {
rs, err := b.buildGRPCRoutes()
if err != nil {
return nil, err
}
vh.Routes = append(vh.Routes, rs...)
}
}
// if we're the proxy, add all the policy routes
if config.IsProxy(options.Services) {
rs, err := b.buildPolicyRoutes(options, host)
if err != nil {
return nil, err
}
vh.Routes = append(vh.Routes, rs...)
}
if len(vh.Routes) > 0 {
virtualHosts = append(virtualHosts, vh)
}
}
vh, err := b.buildVirtualHost(options, "catch-all", "*", false)
if err != nil {
return nil, err
}
virtualHosts = append(virtualHosts, vh)
var grpcClientTimeout *durationpb.Duration var grpcClientTimeout *durationpb.Duration
if options.GRPCClientTimeout != 0 { if cfg.Options.GRPCClientTimeout != 0 {
grpcClientTimeout = durationpb.New(options.GRPCClientTimeout) grpcClientTimeout = durationpb.New(cfg.Options.GRPCClientTimeout)
} else { } else {
grpcClientTimeout = durationpb.New(30 * time.Second) grpcClientTimeout = durationpb.New(30 * time.Second)
} }
@ -329,45 +283,59 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
filters = append(filters, HTTPRouterFilter()) filters = append(filters, HTTPRouterFilter())
var maxStreamDuration *durationpb.Duration var maxStreamDuration *durationpb.Duration
if options.WriteTimeout > 0 { if cfg.Options.WriteTimeout > 0 {
maxStreamDuration = durationpb.New(options.WriteTimeout) maxStreamDuration = durationpb.New(cfg.Options.WriteTimeout)
} }
rc, err := b.buildRouteConfiguration("main", virtualHosts) tracingProvider, err := buildTracingHTTP(cfg.Options)
if err != nil {
return nil, err
}
tracingProvider, err := buildTracingHTTP(options)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{ mgr := &envoy_http_connection_manager.HttpConnectionManager{
AlwaysSetRequestIdInResponse: true, AlwaysSetRequestIdInResponse: true,
CodecType: cfg.Options.GetCodecType().ToEnvoy(),
CodecType: options.GetCodecType().ToEnvoy(), StatPrefix: "ingress",
StatPrefix: "ingress", HttpFilters: filters,
RouteSpecifier: &envoy_http_connection_manager.HttpConnectionManager_RouteConfig{ AccessLog: buildAccessLogs(cfg.Options),
RouteConfig: rc,
},
HttpFilters: filters,
AccessLog: buildAccessLogs(options),
CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{ CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{
IdleTimeout: durationpb.New(options.IdleTimeout), IdleTimeout: durationpb.New(cfg.Options.IdleTimeout),
MaxStreamDuration: maxStreamDuration, MaxStreamDuration: maxStreamDuration,
}, },
HttpProtocolOptions: http1ProtocolOptions, HttpProtocolOptions: http1ProtocolOptions,
RequestTimeout: durationpb.New(options.ReadTimeout), RequestTimeout: durationpb.New(cfg.Options.ReadTimeout),
Tracing: &envoy_http_connection_manager.HttpConnectionManager_Tracing{ Tracing: &envoy_http_connection_manager.HttpConnectionManager_Tracing{
RandomSampling: &envoy_type_v3.Percent{Value: options.TracingSampleRate * 100}, RandomSampling: &envoy_type_v3.Percent{Value: cfg.Options.TracingSampleRate * 100},
Provider: tracingProvider, Provider: tracingProvider,
}, },
// See https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for // See https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
UseRemoteAddress: &wrappers.BoolValue{Value: true}, UseRemoteAddress: &wrappers.BoolValue{Value: true},
SkipXffAppend: options.SkipXffAppend, SkipXffAppend: cfg.Options.SkipXffAppend,
XffNumTrustedHops: options.XffNumTrustedHops, XffNumTrustedHops: cfg.Options.XffNumTrustedHops,
LocalReplyConfig: b.buildLocalReplyConfig(options, false), LocalReplyConfig: b.buildLocalReplyConfig(cfg.Options, false),
}), nil }
if fullyStatic {
routeConfiguration, err := b.buildMainRouteConfiguration(ctx, cfg)
if err != nil {
return nil, err
}
mgr.RouteSpecifier = &envoy_http_connection_manager.HttpConnectionManager_RouteConfig{
RouteConfig: routeConfiguration,
}
} else {
mgr.RouteSpecifier = &envoy_http_connection_manager.HttpConnectionManager_Rds{
Rds: &envoy_http_connection_manager.Rds{
ConfigSource: &envoy_config_core_v3.ConfigSource{
ResourceApiVersion: envoy_config_core_v3.ApiVersion_V3,
ConfigSourceSpecifier: &envoy_config_core_v3.ConfigSource_Ads{},
},
RouteConfigName: "main",
},
}
}
return HTTPConnectionManagerFilter(mgr), nil
} }
func (b *Builder) buildMetricsHTTPConnectionManagerFilter() (*envoy_config_listener_v3.Filter, error) { func (b *Builder) buildMetricsHTTPConnectionManagerFilter() (*envoy_config_listener_v3.Filter, error) {
@ -546,7 +514,8 @@ func (b *Builder) buildDownstreamTLSContextMulti(
TlsCertificates: envoyCerts, TlsCertificates: envoyCerts,
AlpnProtocols: getALPNProtos(cfg.Options), AlpnProtocols: getALPNProtos(cfg.Options),
ValidationContextType: b.buildDownstreamValidationContext(ctx, cfg), ValidationContextType: b.buildDownstreamValidationContext(ctx, cfg),
}}, nil },
}, nil
} }
func getALPNProtos(opts *config.Options) []string { func getALPNProtos(opts *config.Options) []string {

View file

@ -65,7 +65,7 @@ func Test_buildMainHTTPConnectionManagerFilter(t *testing.T) {
options.SkipXffAppend = true options.SkipXffAppend = true
options.XffNumTrustedHops = 1 options.XffNumTrustedHops = 1
options.AuthenticateURLString = "https://authenticate.example.com" options.AuthenticateURLString = "https://authenticate.example.com"
filter, err := b.buildMainHTTPConnectionManagerFilter(options) filter, err := b.buildMainHTTPConnectionManagerFilter(context.Background(), &config.Config{Options: options}, false)
require.NoError(t, err) require.NoError(t, err)
testutil.AssertProtoJSONEqual(t, testData(t, "main_http_connection_manager_filter.json", nil), filter) testutil.AssertProtoJSONEqual(t, testData(t, "main_http_connection_manager_filter.json", nil), filter)
} }
@ -353,7 +353,7 @@ func Test_requireProxyProtocol(t *testing.T) {
li, err := b.buildMainListener(context.Background(), &config.Config{Options: &config.Options{ li, err := b.buildMainListener(context.Background(), &config.Config{Options: &config.Options{
UseProxyProtocol: true, UseProxyProtocol: true,
InsecureServer: true, InsecureServer: true,
}}) }}, false)
require.NoError(t, err) require.NoError(t, err)
testutil.AssertProtoJSONEqual(t, `[ testutil.AssertProtoJSONEqual(t, `[
{ {
@ -368,7 +368,7 @@ func Test_requireProxyProtocol(t *testing.T) {
li, err := b.buildMainListener(context.Background(), &config.Config{Options: &config.Options{ li, err := b.buildMainListener(context.Background(), &config.Config{Options: &config.Options{
UseProxyProtocol: false, UseProxyProtocol: false,
InsecureServer: true, InsecureServer: true,
}}) }}, false)
require.NoError(t, err) require.NoError(t, err)
assert.Len(t, li.GetListenerFilters(), 0) assert.Len(t, li.GetListenerFilters(), 0)
}) })

View file

@ -0,0 +1,105 @@
package envoyconfig
import (
"context"
"crypto/tls"
envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/pkg/cryptutil"
)
// BuildRouteConfigurations builds the route configurations for the RDS service.
func (b *Builder) BuildRouteConfigurations(
ctx context.Context,
cfg *config.Config,
) ([]*envoy_config_route_v3.RouteConfiguration, error) {
var routeConfigurations []*envoy_config_route_v3.RouteConfiguration
if config.IsAuthenticate(cfg.Options.Services) || config.IsProxy(cfg.Options.Services) {
rc, err := b.buildMainRouteConfiguration(ctx, cfg)
if err != nil {
return nil, err
}
routeConfigurations = append(routeConfigurations, rc)
}
return routeConfigurations, nil
}
func (b *Builder) buildMainRouteConfiguration(
ctx context.Context,
cfg *config.Config,
) (*envoy_config_route_v3.RouteConfiguration, error) {
var certs []tls.Certificate
if !cfg.Options.InsecureServer {
var err error
certs, err = getAllCertificates(cfg)
if err != nil {
return nil, err
}
}
authorizeURLs, err := cfg.Options.GetInternalAuthorizeURLs()
if err != nil {
return nil, err
}
dataBrokerURLs, err := cfg.Options.GetInternalDataBrokerURLs()
if err != nil {
return nil, err
}
allHosts, err := getAllRouteableHosts(cfg.Options, cfg.Options.Addr)
if err != nil {
return nil, err
}
var virtualHosts []*envoy_config_route_v3.VirtualHost
for _, host := range allHosts {
requireStrictTransportSecurity := cryptutil.HasCertificateForServerName(certs, host)
vh, err := b.buildVirtualHost(cfg.Options, host, host, requireStrictTransportSecurity)
if err != nil {
return nil, err
}
if cfg.Options.Addr == cfg.Options.GetGRPCAddr() {
// if this is a gRPC service domain and we're supposed to handle that, add those routes
if (config.IsAuthorize(cfg.Options.Services) && urlsMatchHost(authorizeURLs, host)) ||
(config.IsDataBroker(cfg.Options.Services) && urlsMatchHost(dataBrokerURLs, host)) {
rs, err := b.buildGRPCRoutes()
if err != nil {
return nil, err
}
vh.Routes = append(vh.Routes, rs...)
}
}
// if we're the proxy, add all the policy routes
if config.IsProxy(cfg.Options.Services) {
rs, err := b.buildPolicyRoutes(cfg.Options, host)
if err != nil {
return nil, err
}
vh.Routes = append(vh.Routes, rs...)
}
if len(vh.Routes) > 0 {
virtualHosts = append(virtualHosts, vh)
}
}
vh, err := b.buildVirtualHost(cfg.Options, "catch-all", "*", false)
if err != nil {
return nil, err
}
virtualHosts = append(virtualHosts, vh)
rc, err := b.buildRouteConfiguration("main", virtualHosts)
if err != nil {
return nil, err
}
return rc, nil
}

View file

@ -120,506 +120,12 @@
] ]
}, },
"requestTimeout": "30s", "requestTimeout": "30s",
"routeConfig": { "rds": {
"name": "main", "configSource": {
"validateClusters": false, "ads": {},
"virtualHosts": [ "resourceApiVersion": "V3"
{ },
"domains": ["authenticate.example.com"], "routeConfigName": "main"
"name": "authenticate.example.com",
"responseHeadersToAdd": [
{
"appendAction": "OVERWRITE_IF_EXISTS_OR_ADD",
"header": {
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
}
},
{
"appendAction": "OVERWRITE_IF_EXISTS_OR_ADD",
"header": {
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
}
],
"routes": [
{
"match": {
"path": "/.pomerium/jwt"
},
"name": "pomerium-path-/.pomerium/jwt",
"route": {
"cluster": "pomerium-control-plane-http"
}
},
{
"match": {
"path": "/.pomerium/webauthn"
},
"name": "pomerium-path-/.pomerium/webauthn",
"route": {
"cluster": "pomerium-control-plane-http"
}
},
{
"match": {
"path": "/ping"
},
"name": "pomerium-path-/ping",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/healthz"
},
"name": "pomerium-path-/healthz",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/.pomerium"
},
"name": "pomerium-path-/.pomerium",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"prefix": "/.pomerium/"
},
"name": "pomerium-prefix-/.pomerium/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/.well-known/pomerium"
},
"name": "pomerium-path-/.well-known/pomerium",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"prefix": "/.well-known/pomerium/"
},
"name": "pomerium-prefix-/.well-known/pomerium/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/robots.txt"
},
"name": "pomerium-path-/robots.txt",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/oauth2/callback"
},
"name": "pomerium-path-/oauth2/callback",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/"
},
"name": "pomerium-path-/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
}
]
},
{
"domains": ["authenticate.example.com:443"],
"name": "authenticate.example.com:443",
"responseHeadersToAdd": [
{
"appendAction": "OVERWRITE_IF_EXISTS_OR_ADD",
"header": {
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
}
},
{
"appendAction": "OVERWRITE_IF_EXISTS_OR_ADD",
"header": {
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
}
],
"routes": [
{
"match": {
"path": "/.pomerium/jwt"
},
"name": "pomerium-path-/.pomerium/jwt",
"route": {
"cluster": "pomerium-control-plane-http"
}
},
{
"match": {
"path": "/.pomerium/webauthn"
},
"name": "pomerium-path-/.pomerium/webauthn",
"route": {
"cluster": "pomerium-control-plane-http"
}
},
{
"match": {
"path": "/ping"
},
"name": "pomerium-path-/ping",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/healthz"
},
"name": "pomerium-path-/healthz",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/.pomerium"
},
"name": "pomerium-path-/.pomerium",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"prefix": "/.pomerium/"
},
"name": "pomerium-prefix-/.pomerium/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/.well-known/pomerium"
},
"name": "pomerium-path-/.well-known/pomerium",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"prefix": "/.well-known/pomerium/"
},
"name": "pomerium-prefix-/.well-known/pomerium/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/robots.txt"
},
"name": "pomerium-path-/robots.txt",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/oauth2/callback"
},
"name": "pomerium-path-/oauth2/callback",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/"
},
"name": "pomerium-path-/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
}
]
},
{
"domains": ["*"],
"name": "catch-all",
"responseHeadersToAdd": [
{
"appendAction": "OVERWRITE_IF_EXISTS_OR_ADD",
"header": {
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
}
},
{
"appendAction": "OVERWRITE_IF_EXISTS_OR_ADD",
"header": {
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
}
],
"routes": [
{
"match": {
"path": "/.pomerium/jwt"
},
"name": "pomerium-path-/.pomerium/jwt",
"route": {
"cluster": "pomerium-control-plane-http"
}
},
{
"match": {
"path": "/.pomerium/webauthn"
},
"name": "pomerium-path-/.pomerium/webauthn",
"route": {
"cluster": "pomerium-control-plane-http"
}
},
{
"match": {
"path": "/ping"
},
"name": "pomerium-path-/ping",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/healthz"
},
"name": "pomerium-path-/healthz",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/.pomerium"
},
"name": "pomerium-path-/.pomerium",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"prefix": "/.pomerium/"
},
"name": "pomerium-prefix-/.pomerium/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/.well-known/pomerium"
},
"name": "pomerium-path-/.well-known/pomerium",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"prefix": "/.well-known/pomerium/"
},
"name": "pomerium-prefix-/.well-known/pomerium/",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
},
{
"match": {
"path": "/robots.txt"
},
"name": "pomerium-path-/robots.txt",
"route": {
"cluster": "pomerium-control-plane-http"
},
"typedPerFilterConfig": {
"envoy.filters.http.ext_authz": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute",
"disabled": true
}
}
}
]
}
]
}, },
"skipXffAppend": true, "skipXffAppend": true,
"statPrefix": "ingress", "statPrefix": "ingress",

2
go.mod
View file

@ -41,7 +41,7 @@ require (
github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/natefinch/atomic v1.0.1 github.com/natefinch/atomic v1.0.1
github.com/open-policy-agent/opa v0.51.0 github.com/open-policy-agent/opa v0.49.2
github.com/openzipkin/zipkin-go v0.4.1 github.com/openzipkin/zipkin-go v0.4.1
github.com/ory/dockertest/v3 v3.9.1 github.com/ory/dockertest/v3 v3.9.1
github.com/peterbourgon/ff/v3 v3.3.0 github.com/peterbourgon/ff/v3 v3.3.0

10
go.sum
View file

@ -281,7 +281,7 @@ github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4
github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y=
github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= github.com/foxcpp/go-mockdns v0.0.0-20210729171921-fb145fc6f897 h1:E52jfcE64UG42SwLmrW0QByONfGynWuzBvm86BoB9z8=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -314,7 +314,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
@ -693,8 +693,8 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI= github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
github.com/open-policy-agent/opa v0.51.0 h1:2hS5xhos8HtkN+mgpqMhNJSFtn/1n/h3wh+AeTPJg6Q= github.com/open-policy-agent/opa v0.49.2 h1:n8ntRq/yDWy+cmYaqSLrHXmrT3tX8WlK28vjFQdC6W8=
github.com/open-policy-agent/opa v0.51.0/go.mod h1:OjmwLfXdeR7skSxrt8Yd3ScXTqPxyJn7GeTRJrcEerU= github.com/open-policy-agent/opa v0.49.2/go.mod h1:7L3lN5qe8xboRmEHxC5lGjo5KsRMdK+CCLiFoOCP7rU=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
@ -1237,7 +1237,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -11,8 +11,9 @@ import (
) )
const ( const (
clusterTypeURL = "type.googleapis.com/envoy.config.cluster.v3.Cluster" clusterTypeURL = "type.googleapis.com/envoy.config.cluster.v3.Cluster"
listenerTypeURL = "type.googleapis.com/envoy.config.listener.v3.Listener" listenerTypeURL = "type.googleapis.com/envoy.config.listener.v3.Listener"
routeConfigurationTypeURL = "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
) )
func (srv *Server) buildDiscoveryResources(ctx context.Context) (map[string][]*envoy_service_discovery_v3.Resource, error) { func (srv *Server) buildDiscoveryResources(ctx context.Context) (map[string][]*envoy_service_discovery_v3.Resource, error) {
@ -24,25 +25,36 @@ func (srv *Server) buildDiscoveryResources(ctx context.Context) (map[string][]*e
return nil, err return nil, err
} }
for _, cluster := range clusters { for _, cluster := range clusters {
any := protoutil.NewAny(cluster)
resources[clusterTypeURL] = append(resources[clusterTypeURL], &envoy_service_discovery_v3.Resource{ resources[clusterTypeURL] = append(resources[clusterTypeURL], &envoy_service_discovery_v3.Resource{
Name: cluster.Name, Name: cluster.Name,
Version: hex.EncodeToString(cryptutil.HashProto(cluster)), Version: hex.EncodeToString(cryptutil.HashProto(cluster)),
Resource: any, Resource: protoutil.NewAny(cluster),
}) })
} }
listeners, err := srv.Builder.BuildListeners(ctx, cfg.Config) listeners, err := srv.Builder.BuildListeners(ctx, cfg.Config, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, listener := range listeners { for _, listener := range listeners {
any := protoutil.NewAny(listener)
resources[listenerTypeURL] = append(resources[listenerTypeURL], &envoy_service_discovery_v3.Resource{ resources[listenerTypeURL] = append(resources[listenerTypeURL], &envoy_service_discovery_v3.Resource{
Name: listener.Name, Name: listener.Name,
Version: hex.EncodeToString(cryptutil.HashProto(listener)), Version: hex.EncodeToString(cryptutil.HashProto(listener)),
Resource: any, Resource: protoutil.NewAny(listener),
}) })
} }
routeConfigurations, err := srv.Builder.BuildRouteConfigurations(ctx, cfg.Config)
if err != nil {
return nil, err
}
for _, routeConfiguration := range routeConfigurations {
resources[routeConfigurationTypeURL] = append(resources[routeConfigurationTypeURL], &envoy_service_discovery_v3.Resource{
Name: routeConfiguration.Name,
Version: hex.EncodeToString(cryptutil.HashProto(routeConfiguration)),
Resource: protoutil.NewAny(routeConfiguration),
})
}
return resources, nil return resources, nil
} }

View file

@ -19,8 +19,6 @@ import (
"time" "time"
"github.com/cenkalti/backoff/v4" "github.com/cenkalti/backoff/v4"
envoy_config_bootstrap_v3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/natefinch/atomic" "github.com/natefinch/atomic"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -30,7 +28,6 @@ import (
"github.com/pomerium/pomerium/config" "github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/config/envoyconfig" "github.com/pomerium/pomerium/config/envoyconfig"
"github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/telemetry"
"github.com/pomerium/pomerium/pkg/envoy/files" "github.com/pomerium/pomerium/pkg/envoy/files"
) )
@ -185,7 +182,7 @@ func (srv *Server) run(ctx context.Context, cfg *config.Config) error {
} }
func (srv *Server) writeConfig(ctx context.Context, cfg *config.Config) error { func (srv *Server) writeConfig(ctx context.Context, cfg *config.Config) error {
confBytes, err := srv.buildBootstrapConfig(cfg) confBytes, err := srv.buildBootstrapConfig(ctx, cfg)
if err != nil { if err != nil {
return err return err
} }
@ -196,65 +193,12 @@ func (srv *Server) writeConfig(ctx context.Context, cfg *config.Config) error {
return atomic.WriteFile(cfgPath, bytes.NewReader(confBytes)) return atomic.WriteFile(cfgPath, bytes.NewReader(confBytes))
} }
func (srv *Server) buildBootstrapConfig(cfg *config.Config) ([]byte, error) { func (srv *Server) buildBootstrapConfig(ctx context.Context, cfg *config.Config) ([]byte, error) {
nodeCfg := &envoy_config_core_v3.Node{ bootstrapCfg, err := srv.builder.BuildBootstrap(ctx, cfg, false)
Id: telemetry.ServiceName(cfg.Options.Services),
Cluster: telemetry.ServiceName(cfg.Options.Services),
}
adminCfg, err := srv.builder.BuildBootstrapAdmin(cfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
dynamicCfg := &envoy_config_bootstrap_v3.Bootstrap_DynamicResources{
AdsConfig: &envoy_config_core_v3.ApiConfigSource{
ApiType: envoy_config_core_v3.ApiConfigSource_ApiType(envoy_config_core_v3.ApiConfigSource_ApiType_value["DELTA_GRPC"]),
TransportApiVersion: envoy_config_core_v3.ApiVersion_V3,
GrpcServices: []*envoy_config_core_v3.GrpcService{
{
TargetSpecifier: &envoy_config_core_v3.GrpcService_EnvoyGrpc_{
EnvoyGrpc: &envoy_config_core_v3.GrpcService_EnvoyGrpc{
ClusterName: "pomerium-control-plane-grpc",
},
},
},
},
},
LdsConfig: &envoy_config_core_v3.ConfigSource{
ResourceApiVersion: envoy_config_core_v3.ApiVersion_V3,
ConfigSourceSpecifier: &envoy_config_core_v3.ConfigSource_Ads{},
},
CdsConfig: &envoy_config_core_v3.ConfigSource{
ResourceApiVersion: envoy_config_core_v3.ApiVersion_V3,
ConfigSourceSpecifier: &envoy_config_core_v3.ConfigSource_Ads{},
},
}
staticCfg, err := srv.builder.BuildBootstrapStaticResources()
if err != nil {
return nil, err
}
statsCfg, err := srv.builder.BuildBootstrapStatsConfig(cfg)
if err != nil {
return nil, err
}
layeredRuntimeCfg, err := srv.builder.BuildBootstrapLayeredRuntime()
if err != nil {
return nil, err
}
bootstrapCfg := &envoy_config_bootstrap_v3.Bootstrap{
Node: nodeCfg,
Admin: adminCfg,
DynamicResources: dynamicCfg,
StaticResources: staticCfg,
StatsConfig: statsCfg,
LayeredRuntime: layeredRuntimeCfg,
}
jsonBytes, err := protojson.Marshal(bootstrapCfg) jsonBytes, err := protojson.Marshal(bootstrapCfg)
if err != nil { if err != nil {
return nil, err return nil, err