diff --git a/cmd/contour/bootstrap.go b/cmd/contour/bootstrap.go
index e91817a21b8..82e03e48517 100644
--- a/cmd/contour/bootstrap.go
+++ b/cmd/contour/bootstrap.go
@@ -34,6 +34,6 @@ func registerBootstrap(app *kingpin.Application) (*kingpin.CmdClause, *envoy.Boo
bootstrap.Flag("envoy-cert-file", "Client certificate filename for Envoy secure xDS gRPC communication.").Envar("ENVOY_CERT_FILE").StringVar(&config.GrpcClientCert)
bootstrap.Flag("envoy-key-file", "Client key filename for Envoy secure xDS gRPC communication.").Envar("ENVOY_KEY_FILE").StringVar(&config.GrpcClientKey)
bootstrap.Flag("namespace", "The namespace the Envoy container will run in.").Envar("CONTOUR_NAMESPACE").Default("projectcontour").StringVar(&config.Namespace)
- bootstrap.Flag("xds-resource-version", "The versions of the xDS resources to request from Contour.").Default("v2").StringVar((*string)(&config.XDSResourceVersion))
+ bootstrap.Flag("xds-resource-version", "The versions of the xDS resources to request from Contour.").Default("v3").StringVar((*string)(&config.XDSResourceVersion))
return bootstrap, &config
}
diff --git a/cmd/contour/contour.go b/cmd/contour/contour.go
index 878574726ae..634b1d5c514 100644
--- a/cmd/contour/contour.go
+++ b/cmd/contour/contour.go
@@ -18,10 +18,8 @@ import (
resource "github.com/envoyproxy/go-control-plane/pkg/resource/v2"
"github.com/projectcontour/contour/internal/build"
- envoy_v2 "github.com/projectcontour/contour/internal/envoy/v2"
envoy_v3 "github.com/projectcontour/contour/internal/envoy/v3"
"github.com/projectcontour/contour/internal/k8s"
- "github.com/projectcontour/contour/pkg/config"
"github.com/sirupsen/logrus"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
@@ -75,15 +73,8 @@ func main() {
if err != nil {
log.WithError(err).Fatal("failed to parse bootstrap args")
}
- switch bootstrapCtx.XDSResourceVersion {
- case config.XDSv3:
- if err := envoy_v3.WriteBootstrap(bootstrapCtx); err != nil {
- log.WithError(err).Fatal("failed to write bootstrap configuration")
- }
- default:
- if err := envoy_v2.WriteBootstrap(bootstrapCtx); err != nil {
- log.WithError(err).Fatal("failed to write bootstrap configuration")
- }
+ if err := envoy_v3.WriteBootstrap(bootstrapCtx); err != nil {
+ log.WithError(err).Fatal("failed to write bootstrap configuration")
}
case certgenApp.FullCommand():
doCertgen(certgenConfig, log)
diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go
index 6e73df6fe74..2fffa4acc15 100644
--- a/cmd/contour/serve.go
+++ b/cmd/contour/serve.go
@@ -26,7 +26,6 @@ import (
"time"
envoy_auth_v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2/auth"
- envoy_server_v2 "github.com/envoyproxy/go-control-plane/pkg/server/v2"
envoy_server_v3 "github.com/envoyproxy/go-control-plane/pkg/server/v3"
contour_api_v1 "github.com/projectcontour/contour/apis/projectcontour/v1"
"github.com/projectcontour/contour/internal/annotation"
@@ -40,7 +39,6 @@ import (
"github.com/projectcontour/contour/internal/timeout"
"github.com/projectcontour/contour/internal/workgroup"
"github.com/projectcontour/contour/internal/xds"
- contour_xds_v2 "github.com/projectcontour/contour/internal/xds/v2"
contour_xds_v3 "github.com/projectcontour/contour/internal/xds/v3"
"github.com/projectcontour/contour/internal/xdscache"
xdscache_v2 "github.com/projectcontour/contour/internal/xdscache/v2"
@@ -563,20 +561,8 @@ func doServe(log logrus.FieldLogger, ctx *serveContext) error {
v3cache := contour_xds_v3.NewSnapshotCache(false, log)
snapshotHandler.AddSnapshotter(v3cache)
contour_xds_v3.RegisterServer(envoy_server_v3.NewServer(context.Background(), v3cache, nil), grpcServer)
-
- // Check an internal feature flag to disable xDS v2 endpoints. This is strictly for testing.
- if config.GetenvOr("CONTOUR_INTERNAL_DISABLE_XDSV2", "N") == "N" {
- v2cache := contour_xds_v2.NewSnapshotCache(false, log)
- snapshotHandler.AddSnapshotter(v2cache)
- contour_xds_v2.RegisterServer(envoy_server_v2.NewServer(context.Background(), v2cache, nil), grpcServer)
- }
case config.ContourServerType:
contour_xds_v3.RegisterServer(contour_xds_v3.NewContourServer(log, xdscache.ResourcesOf(resources)...), grpcServer)
-
- // Check an internal feature flag to disable xDS v2 endpoints. This is strictly for testing.
- if config.GetenvOr("CONTOUR_INTERNAL_DISABLE_XDSV2", "N") == "N" {
- contour_xds_v2.RegisterServer(contour_xds_v2.NewContourServer(log, xdscache.ResourcesOf(resources)...), grpcServer)
- }
default:
// This can't happen due to config validation.
log.Fatalf("invalid xDS server type %q", ctx.Config.Server.XDSServerType)
diff --git a/internal/envoy/bootstrap.go b/internal/envoy/bootstrap.go
index cdae66057a5..2c15448674d 100644
--- a/internal/envoy/bootstrap.go
+++ b/internal/envoy/bootstrap.go
@@ -53,12 +53,12 @@ type BootstrapConfig struct {
// Defaults to 127.0.0.1.
XDSAddress string
- // XDSGRPCPort is the management server port that provides the v2 gRPC API.
+ // XDSGRPCPort is the management server port that provides the v3 gRPC API.
// Defaults to 8001.
XDSGRPCPort int
// XDSResourceVersion defines the XDS Server Version to use.
- // Defaults to "v2"
+ // Defaults to "v3"
XDSResourceVersion config.ResourceVersion
// Namespace is the namespace where Contour is running
diff --git a/internal/envoy/v2/bootstrap.go b/internal/envoy/v2/bootstrap.go
deleted file mode 100644
index 6084da1b495..00000000000
--- a/internal/envoy/v2/bootstrap.go
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright Project Contour Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package envoy contains APIs for translating between Contour
-// objects and Envoy configuration APIs and types.
-
-package v2
-
-import (
- "fmt"
- "os"
- "path"
- "strconv"
- "strings"
- "time"
-
- api "github.com/envoyproxy/go-control-plane/envoy/api/v2"
- envoy_api_v2_auth "github.com/envoyproxy/go-control-plane/envoy/api/v2/auth"
- clusterv2 "github.com/envoyproxy/go-control-plane/envoy/api/v2/cluster"
- envoy_api_v2_core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
- envoy_api_bootstrap "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v2"
- matcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher"
- "github.com/golang/protobuf/proto"
- "github.com/golang/protobuf/ptypes/any"
- "github.com/projectcontour/contour/internal/envoy"
- "github.com/projectcontour/contour/internal/protobuf"
-)
-
-// WriteBootstrap writes bootstrap configuration to files.
-func WriteBootstrap(c *envoy.BootstrapConfig) error {
- // Create Envoy bootstrap config and associated resource files.
- steps, err := bootstrap(c)
- if err != nil {
- return err
- }
-
- if c.ResourcesDir != "" {
- if err := os.MkdirAll(path.Join(c.ResourcesDir, "sds"), 0750); err != nil {
- return err
- }
- }
-
- // Write all configuration files out to filesystem.
- for _, step := range steps {
- if err := envoy.WriteConfig(step(c)); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-type bootstrapf func(*envoy.BootstrapConfig) (string, proto.Message)
-
-// bootstrap creates a new v2 bootstrap configuration and associated resource files.
-func bootstrap(c *envoy.BootstrapConfig) ([]bootstrapf, error) {
- steps := []bootstrapf{}
-
- if c.GrpcClientCert == "" && c.GrpcClientKey == "" && c.GrpcCABundle == "" {
- steps = append(steps,
- func(*envoy.BootstrapConfig) (string, proto.Message) {
- return c.Path, bootstrapConfig(c)
- })
-
- return steps, nil
- }
-
- for _, f := range []string{c.GrpcClientCert, c.GrpcClientKey, c.GrpcCABundle} {
- // If any of of the TLS options is not empty, they all must be not empty.
- if f == "" {
- return nil, fmt.Errorf(
- "you must supply all TLS parameters - %q, %q, %q, or none of them",
- "--envoy-cafile", "--envoy-cert-file", "--envoy-key-file")
- }
-
- if !c.SkipFilePathCheck {
- // If the TLS secrets aren't set up properly,
- // some files may not be present. In this case,
- // envoy will reject the bootstrap configuration,
- // but there is no way to detect and fix that. If
- // we check and fail here, that is visible in the
- // Pod lifecycle and therefore fixable.
- fi, err := os.Stat(f)
- if err != nil {
- return nil, err
- }
- if fi.Size() == 0 {
- return nil, fmt.Errorf("%q is empty", f)
- }
- }
- }
-
- if c.ResourcesDir == "" {
- // For backwards compatibility, the old behavior
- // is to use direct certificate and key file paths in
- // bootstrap config. Envoy does not support rotation
- // of xDS certificate files in this case.
-
- steps = append(steps,
- func(*envoy.BootstrapConfig) (string, proto.Message) {
- b := bootstrapConfig(c)
- b.StaticResources.Clusters[0].TransportSocket = UpstreamTLSTransportSocket(
- upstreamFileTLSContext(c))
- return c.Path, b
- })
-
- return steps, nil
- }
-
- // xDS certificate rotation is supported by Envoy by using SDS path based resource files.
- // These files are JSON representation of the SDS protobuf messages that normally get sent over the xDS connection,
- // but for xDS connection itself, bootstrapping is done by storing the SDS resources in a local filesystem.
- // Envoy will monitor and reload the resource files and the certificate and key files referred from the SDS resources.
- //
- // Two files are written to ResourcesDir:
- // - SDS resource for xDS client certificate and key for authenticating Envoy towards Contour.
- // - SDS resource for trusted CA certificate for validating Contour server certificate.
- sdsTLSCertificatePath := path.Join(c.ResourcesDir, envoy.SDSResourcesSubdirectory, envoy.SDSTLSCertificateFile)
- sdsValidationContextPath := path.Join(c.ResourcesDir, envoy.SDSResourcesSubdirectory, envoy.SDSValidationContextFile)
-
- steps = append(steps,
- func(*envoy.BootstrapConfig) (string, proto.Message) {
- return sdsTLSCertificatePath, tlsCertificateSdsSecretConfig(c)
- },
- func(*envoy.BootstrapConfig) (string, proto.Message) {
- return sdsValidationContextPath, validationContextSdsSecretConfig(c)
- },
- func(*envoy.BootstrapConfig) (string, proto.Message) {
- b := bootstrapConfig(c)
- b.StaticResources.Clusters[0].TransportSocket = UpstreamTLSTransportSocket(
- upstreamSdsTLSContext(sdsTLSCertificatePath, sdsValidationContextPath))
- return c.Path, b
- },
- )
-
- return steps, nil
-}
-
-func bootstrapConfig(c *envoy.BootstrapConfig) *envoy_api_bootstrap.Bootstrap {
- return &envoy_api_bootstrap.Bootstrap{
- DynamicResources: &envoy_api_bootstrap.Bootstrap_DynamicResources{
- LdsConfig: ConfigSource("contour"),
- CdsConfig: ConfigSource("contour"),
- },
- StaticResources: &envoy_api_bootstrap.Bootstrap_StaticResources{
- Clusters: []*api.Cluster{{
- Name: "contour",
- AltStatName: strings.Join([]string{c.Namespace, "contour", strconv.Itoa(c.GetXdsGRPCPort())}, "_"),
- ConnectTimeout: protobuf.Duration(5 * time.Second),
- ClusterDiscoveryType: ClusterDiscoveryType(api.Cluster_STRICT_DNS),
- LbPolicy: api.Cluster_ROUND_ROBIN,
- LoadAssignment: &api.ClusterLoadAssignment{
- ClusterName: "contour",
- Endpoints: Endpoints(
- SocketAddress(c.GetXdsAddress(), c.GetXdsGRPCPort()),
- ),
- },
- UpstreamConnectionOptions: &api.UpstreamConnectionOptions{
- TcpKeepalive: &envoy_api_v2_core.TcpKeepalive{
- KeepaliveProbes: protobuf.UInt32(3),
- KeepaliveTime: protobuf.UInt32(30),
- KeepaliveInterval: protobuf.UInt32(5),
- },
- },
- Http2ProtocolOptions: new(envoy_api_v2_core.Http2ProtocolOptions), // enables http2
- CircuitBreakers: &clusterv2.CircuitBreakers{
- Thresholds: []*clusterv2.CircuitBreakers_Thresholds{{
- Priority: envoy_api_v2_core.RoutingPriority_HIGH,
- MaxConnections: protobuf.UInt32(100000),
- MaxPendingRequests: protobuf.UInt32(100000),
- MaxRequests: protobuf.UInt32(60000000),
- MaxRetries: protobuf.UInt32(50),
- }, {
- Priority: envoy_api_v2_core.RoutingPriority_DEFAULT,
- MaxConnections: protobuf.UInt32(100000),
- MaxPendingRequests: protobuf.UInt32(100000),
- MaxRequests: protobuf.UInt32(60000000),
- MaxRetries: protobuf.UInt32(50),
- }},
- },
- }, {
- Name: "service-stats",
- AltStatName: strings.Join([]string{c.Namespace, "service-stats", strconv.Itoa(c.GetAdminPort())}, "_"),
- ConnectTimeout: protobuf.Duration(250 * time.Millisecond),
- ClusterDiscoveryType: ClusterDiscoveryType(api.Cluster_LOGICAL_DNS),
- LbPolicy: api.Cluster_ROUND_ROBIN,
- LoadAssignment: &api.ClusterLoadAssignment{
- ClusterName: "service-stats",
- Endpoints: Endpoints(
- SocketAddress(c.GetAdminAddress(), c.GetAdminPort()),
- ),
- },
- }},
- },
- Admin: &envoy_api_bootstrap.Admin{
- AccessLogPath: c.GetAdminAccessLogPath(),
- Address: SocketAddress(c.GetAdminAddress(), c.GetAdminPort()),
- },
- }
-}
-
-func upstreamFileTLSContext(c *envoy.BootstrapConfig) *envoy_api_v2_auth.UpstreamTlsContext {
- context := &envoy_api_v2_auth.UpstreamTlsContext{
- CommonTlsContext: &envoy_api_v2_auth.CommonTlsContext{
- TlsCertificates: []*envoy_api_v2_auth.TlsCertificate{{
- CertificateChain: &envoy_api_v2_core.DataSource{
- Specifier: &envoy_api_v2_core.DataSource_Filename{
- Filename: c.GrpcClientCert,
- },
- },
- PrivateKey: &envoy_api_v2_core.DataSource{
- Specifier: &envoy_api_v2_core.DataSource_Filename{
- Filename: c.GrpcClientKey,
- },
- },
- }},
- ValidationContextType: &envoy_api_v2_auth.CommonTlsContext_ValidationContext{
- ValidationContext: &envoy_api_v2_auth.CertificateValidationContext{
- TrustedCa: &envoy_api_v2_core.DataSource{
- Specifier: &envoy_api_v2_core.DataSource_Filename{
- Filename: c.GrpcCABundle,
- },
- },
- // TODO(youngnick): Does there need to be a flag wired down to here?
- MatchSubjectAltNames: []*matcher.StringMatcher{{
- MatchPattern: &matcher.StringMatcher_Exact{
- Exact: "contour",
- }},
- },
- },
- },
- },
- }
- return context
-}
-
-func upstreamSdsTLSContext(certificateSdsFile, validationSdsFile string) *envoy_api_v2_auth.UpstreamTlsContext {
- context := &envoy_api_v2_auth.UpstreamTlsContext{
- CommonTlsContext: &envoy_api_v2_auth.CommonTlsContext{
- TlsCertificateSdsSecretConfigs: []*envoy_api_v2_auth.SdsSecretConfig{{
- SdsConfig: &envoy_api_v2_core.ConfigSource{
- ConfigSourceSpecifier: &envoy_api_v2_core.ConfigSource_Path{
- Path: certificateSdsFile,
- },
- },
- }},
- ValidationContextType: &envoy_api_v2_auth.CommonTlsContext_ValidationContextSdsSecretConfig{
- ValidationContextSdsSecretConfig: &envoy_api_v2_auth.SdsSecretConfig{
- SdsConfig: &envoy_api_v2_core.ConfigSource{
- ConfigSourceSpecifier: &envoy_api_v2_core.ConfigSource_Path{
- Path: validationSdsFile,
- },
- },
- },
- },
- },
- }
- return context
-}
-
-// tlsCertificateSdsSecretConfig creates DiscoveryResponse with file based SDS resource
-// including paths to TLS certificates and key
-func tlsCertificateSdsSecretConfig(c *envoy.BootstrapConfig) *api.DiscoveryResponse {
- secret := &envoy_api_v2_auth.Secret{
- Type: &envoy_api_v2_auth.Secret_TlsCertificate{
- TlsCertificate: &envoy_api_v2_auth.TlsCertificate{
- CertificateChain: &envoy_api_v2_core.DataSource{
- Specifier: &envoy_api_v2_core.DataSource_Filename{
- Filename: c.GrpcClientCert,
- },
- },
- PrivateKey: &envoy_api_v2_core.DataSource{
- Specifier: &envoy_api_v2_core.DataSource_Filename{
- Filename: c.GrpcClientKey,
- },
- },
- },
- },
- }
-
- return &api.DiscoveryResponse{
- Resources: []*any.Any{protobuf.MustMarshalAny(secret)},
- }
-}
-
-// validationContextSdsSecretConfig creates DiscoveryResponse with file based SDS resource
-// including path to CA certificate bundle
-func validationContextSdsSecretConfig(c *envoy.BootstrapConfig) *api.DiscoveryResponse {
- secret := &envoy_api_v2_auth.Secret{
- Type: &envoy_api_v2_auth.Secret_ValidationContext{
- ValidationContext: &envoy_api_v2_auth.CertificateValidationContext{
- TrustedCa: &envoy_api_v2_core.DataSource{
- Specifier: &envoy_api_v2_core.DataSource_Filename{
- Filename: c.GrpcCABundle,
- },
- },
- MatchSubjectAltNames: []*matcher.StringMatcher{{
- MatchPattern: &matcher.StringMatcher_Exact{
- Exact: "contour",
- }},
- },
- },
- },
- }
-
- return &api.DiscoveryResponse{
- Resources: []*any.Any{protobuf.MustMarshalAny(secret)},
- }
-}
diff --git a/internal/envoy/v2/bootstrap_test.go b/internal/envoy/v2/bootstrap_test.go
deleted file mode 100644
index 1084f0b0eed..00000000000
--- a/internal/envoy/v2/bootstrap_test.go
+++ /dev/null
@@ -1,1047 +0,0 @@
-// Copyright Project Contour Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2
-
-import (
- "path"
- "testing"
-
- api "github.com/envoyproxy/go-control-plane/envoy/api/v2"
- envoy_api_bootstrap "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v2"
- "github.com/golang/protobuf/jsonpb"
- "github.com/golang/protobuf/proto"
- "github.com/projectcontour/contour/internal/envoy"
- "github.com/projectcontour/contour/internal/protobuf"
- "github.com/stretchr/testify/assert"
-)
-
-func TestBootstrap(t *testing.T) {
- tests := map[string]struct {
- config envoy.BootstrapConfig
- wantedBootstrapConfig string
- wantedTLSCertificateConfig string
- wantedValidationContextConfig string
- wantedError bool
- }{
- "default configuration": {
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- Namespace: "testing-ns"},
- wantedBootstrapConfig: `{
- "static_resources": {
- "clusters": [
- {
- "name": "contour",
- "alt_stat_name": "testing-ns_contour_8001",
- "type": "STRICT_DNS",
- "connect_timeout": "5s",
- "load_assignment": {
- "cluster_name": "contour",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 8001
- }
- }
- }
- }
- ]
- }
- ]
- },
- "circuit_breakers": {
- "thresholds": [
- {
- "priority": "HIGH",
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- },
- {
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- }
- ]
- },
- "http2_protocol_options": {},
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- }
- },
- {
- "name": "service-stats",
- "alt_stat_name": "testing-ns_service-stats_9001",
- "type": "LOGICAL_DNS",
- "connect_timeout": "0.250s",
- "load_assignment": {
- "cluster_name": "service-stats",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
- }
- ]
- }
- ]
- }
- }
- ]
- },
- "dynamic_resources": {
- "lds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- },
- "cds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- }
- },
- "admin": {
- "access_log_path": "/dev/null",
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
-}`,
- },
- "--admin-address=8.8.8.8 --admin-port=9200": {
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- AdminAddress: "8.8.8.8",
- AdminPort: 9200,
- Namespace: "testing-ns",
- },
- wantedBootstrapConfig: `{
- "static_resources": {
- "clusters": [
- {
- "name": "contour",
- "alt_stat_name": "testing-ns_contour_8001",
- "type": "STRICT_DNS",
- "connect_timeout": "5s",
- "load_assignment": {
- "cluster_name": "contour",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 8001
- }
- }
- }
- }
- ]
- }
- ]
- },
- "circuit_breakers": {
- "thresholds": [
- {
- "priority": "HIGH",
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- },
- {
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- }
- ]
- },
- "http2_protocol_options": {},
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- }
- },
- {
- "name": "service-stats",
- "alt_stat_name": "testing-ns_service-stats_9200",
- "type": "LOGICAL_DNS",
- "connect_timeout": "0.250s",
- "load_assignment": {
- "cluster_name": "service-stats",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "8.8.8.8",
- "port_value": 9200
- }
- }
- }
- }
- ]
- }
- ]
- }
- }
- ]
- },
- "dynamic_resources": {
- "lds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- },
- "cds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- }
- },
- "admin": {
- "access_log_path": "/dev/null",
- "address": {
- "socket_address": {
- "address": "8.8.8.8",
- "port_value": 9200
- }
- }
- }
-}`,
- },
- "AdminAccessLogPath": { // TODO(dfc) doesn't appear to be exposed via contour bootstrap
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- AdminAccessLogPath: "/var/log/admin.log",
- Namespace: "testing-ns",
- },
- wantedBootstrapConfig: `{
- "static_resources": {
- "clusters": [
- {
- "name": "contour",
- "alt_stat_name": "testing-ns_contour_8001",
- "type": "STRICT_DNS",
- "connect_timeout": "5s",
- "load_assignment": {
- "cluster_name": "contour",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 8001
- }
- }
- }
- }
- ]
- }
- ]
- },
- "circuit_breakers": {
- "thresholds": [
- {
- "priority": "HIGH",
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- },
- {
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- }
- ]
- },
- "http2_protocol_options": {},
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- }
- },
- {
- "name": "service-stats",
- "alt_stat_name": "testing-ns_service-stats_9001",
- "type": "LOGICAL_DNS",
- "connect_timeout": "0.250s",
- "load_assignment": {
- "cluster_name": "service-stats",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
- }
- ]
- }
- ]
- }
- }
- ]
- },
- "dynamic_resources": {
- "lds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- },
- "cds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- }
- },
- "admin": {
- "access_log_path": "/var/log/admin.log",
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
-}`,
- },
- "--xds-address=8.8.8.8 --xds-port=9200": {
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- XDSAddress: "8.8.8.8",
- XDSGRPCPort: 9200,
- Namespace: "testing-ns",
- },
- wantedBootstrapConfig: `{
- "static_resources": {
- "clusters": [
- {
- "name": "contour",
- "alt_stat_name": "testing-ns_contour_9200",
- "type": "STRICT_DNS",
- "connect_timeout": "5s",
- "load_assignment": {
- "cluster_name": "contour",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "8.8.8.8",
- "port_value": 9200
- }
- }
- }
- }
- ]
- }
- ]
- },
- "circuit_breakers": {
- "thresholds": [
- {
- "priority": "HIGH",
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- },
- {
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- }
- ]
- },
- "http2_protocol_options": {},
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- }
- },
- {
- "name": "service-stats",
- "alt_stat_name": "testing-ns_service-stats_9001",
- "type": "LOGICAL_DNS",
- "connect_timeout": "0.250s",
- "load_assignment": {
- "cluster_name": "service-stats",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
- }
- ]
- }
- ]
- }
- }
- ]
- },
- "dynamic_resources": {
- "lds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- },
- "cds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- }
- },
- "admin": {
- "access_log_path": "/dev/null",
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
-}`,
- },
- "--stats-address=8.8.8.8 --stats-port=9200": {
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- Namespace: "testing-ns",
- },
- wantedBootstrapConfig: `{
- "static_resources": {
- "clusters": [
- {
- "name": "contour",
- "alt_stat_name": "testing-ns_contour_8001",
- "type": "STRICT_DNS",
- "connect_timeout": "5s",
- "load_assignment": {
- "cluster_name": "contour",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 8001
- }
- }
- }
- }
- ]
- }
- ]
- },
- "circuit_breakers": {
- "thresholds": [
- {
- "priority": "HIGH",
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- },
- {
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- }
- ]
- },
- "http2_protocol_options": {},
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- }
- },
- {
- "name": "service-stats",
- "alt_stat_name": "testing-ns_service-stats_9001",
- "type": "LOGICAL_DNS",
- "connect_timeout": "0.250s",
- "load_assignment": {
- "cluster_name": "service-stats",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
- }
- ]
- }
- ]
- }
- }
- ]
- },
- "dynamic_resources": {
- "lds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- },
- "cds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- }
- },
- "admin": {
- "access_log_path": "/dev/null",
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
-}`,
- },
- "--envoy-cafile=CA.cert --envoy-client-cert=client.cert --envoy-client-key=client.key": {
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- Namespace: "testing-ns",
- GrpcCABundle: "CA.cert",
- GrpcClientCert: "client.cert",
- GrpcClientKey: "client.key",
- SkipFilePathCheck: true,
- },
- wantedBootstrapConfig: `{
- "static_resources": {
- "clusters": [
- {
- "name": "contour",
- "alt_stat_name": "testing-ns_contour_8001",
- "type": "STRICT_DNS",
- "connect_timeout": "5s",
- "load_assignment": {
- "cluster_name": "contour",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 8001
- }
- }
- }
- }
- ]
- }
- ]
- },
- "circuit_breakers": {
- "thresholds": [
- {
- "priority": "HIGH",
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- },
- {
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- }
- ]
- },
- "http2_protocol_options": {},
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- },
- "transport_socket": {
- "name": "envoy.transport_sockets.tls",
- "typed_config": {
- "@type":"type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext",
- "common_tls_context": {
- "tls_certificates": [
- {
- "certificate_chain": {
- "filename": "client.cert"
- },
- "private_key": {
- "filename": "client.key"
- }
- }
- ],
- "validation_context": {
- "trusted_ca": {
- "filename": "CA.cert"
- },
- "match_subject_alt_names": [
- {
- "exact": "contour"
- }
- ]
- }
- }
- }
- }
- },
- {
- "name": "service-stats",
- "alt_stat_name": "testing-ns_service-stats_9001",
- "type": "LOGICAL_DNS",
- "connect_timeout": "0.250s",
- "load_assignment": {
- "cluster_name": "service-stats",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
- }
- ]
- }
- ]
- }
- }
- ]
- },
- "dynamic_resources": {
- "lds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- },
- "cds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- }
- },
- "admin": {
- "access_log_path": "/dev/null",
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
-}`,
- },
- "--resources-dir tmp --envoy-cafile=CA.cert --envoy-client-cert=client.cert --envoy-client-key=client.key": {
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- Namespace: "testing-ns",
- ResourcesDir: "resources",
- GrpcCABundle: "CA.cert",
- GrpcClientCert: "client.cert",
- GrpcClientKey: "client.key",
- SkipFilePathCheck: true,
- },
- wantedBootstrapConfig: `{
- "static_resources": {
- "clusters": [
- {
- "name": "contour",
- "alt_stat_name": "testing-ns_contour_8001",
- "type": "STRICT_DNS",
- "connect_timeout": "5s",
- "load_assignment": {
- "cluster_name": "contour",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 8001
- }
- }
- }
- }
- ]
- }
- ]
- },
- "circuit_breakers": {
- "thresholds": [
- {
- "priority": "HIGH",
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- },
- {
- "max_connections": 100000,
- "max_pending_requests": 100000,
- "max_requests": 60000000,
- "max_retries": 50
- }
- ]
- },
- "http2_protocol_options": {},
- "transport_socket": {
- "name": "envoy.transport_sockets.tls",
- "typed_config": {
- "@type": "type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext",
- "common_tls_context": {
- "tls_certificate_sds_secret_configs": [
- {
- "sds_config": {
- "path": "resources/sds/xds-tls-certificate.json"
- }
- }
- ],
- "validation_context_sds_secret_config": {
- "sds_config": {
- "path": "resources/sds/xds-validation-context.json"
- }
- }
- }
- }
- },
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- }
- },
- {
- "name": "service-stats",
- "alt_stat_name": "testing-ns_service-stats_9001",
- "type": "LOGICAL_DNS",
- "connect_timeout": "0.250s",
- "load_assignment": {
- "cluster_name": "service-stats",
- "endpoints": [
- {
- "lb_endpoints": [
- {
- "endpoint": {
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
- }
- ]
- }
- ]
- }
- }
- ]
- },
- "dynamic_resources": {
- "lds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- },
- "cds_config": {
- "api_config_source": {
- "api_type": "GRPC",
- "grpc_services": [
- {
- "envoy_grpc": {
- "cluster_name": "contour"
- }
- }
- ]
- }
- }
- },
- "admin": {
- "access_log_path": "/dev/null",
- "address": {
- "socket_address": {
- "address": "127.0.0.1",
- "port_value": 9001
- }
- }
- }
- }`,
- wantedTLSCertificateConfig: `{
- "resources": [
- {
- "@type": "type.googleapis.com/envoy.api.v2.auth.Secret",
- "tls_certificate": {
- "certificate_chain": {
- "filename": "client.cert"
- },
- "private_key": {
- "filename": "client.key"
- }
- }
- }
- ]
- }`,
- wantedValidationContextConfig: `{
- "resources": [
- {
- "@type": "type.googleapis.com/envoy.api.v2.auth.Secret",
- "validation_context": {
- "trusted_ca": {
- "filename": "CA.cert"
- },
- "match_subject_alt_names": [
- {
- "exact": "contour"
- }
- ]
- }
- }
- ]
- }`,
- },
- "return error when not providing all certificate related parameters": {
- config: envoy.BootstrapConfig{
- Path: "envoy.json",
- Namespace: "testing-ns",
- ResourcesDir: "resources",
- GrpcClientCert: "client.cert",
- GrpcClientKey: "client.key",
- },
- wantedError: true,
- }}
-
- for name, tc := range tests {
- t.Run(name, func(t *testing.T) {
- steps, gotError := bootstrap(&tc.config)
- assert.Equal(t, gotError != nil, tc.wantedError)
-
- gotConfigs := map[string]proto.Message{}
- for _, step := range steps {
- path, config := step(&tc.config)
- gotConfigs[path] = config
- }
-
- sdsTLSCertificatePath := path.Join(tc.config.ResourcesDir, envoy.SDSResourcesSubdirectory, envoy.SDSTLSCertificateFile)
- sdsValidationContextPath := path.Join(tc.config.ResourcesDir, envoy.SDSResourcesSubdirectory, envoy.SDSValidationContextFile)
-
- if tc.wantedBootstrapConfig != "" {
- want := new(envoy_api_bootstrap.Bootstrap)
- unmarshal(t, tc.wantedBootstrapConfig, want)
- protobuf.ExpectEqual(t, want, gotConfigs[tc.config.Path])
- delete(gotConfigs, tc.config.Path)
- }
-
- if tc.wantedTLSCertificateConfig != "" {
- want := new(api.DiscoveryResponse)
- unmarshal(t, tc.wantedTLSCertificateConfig, want)
- protobuf.ExpectEqual(t, want, gotConfigs[sdsTLSCertificatePath])
- delete(gotConfigs, sdsTLSCertificatePath)
- }
-
- if tc.wantedValidationContextConfig != "" {
- want := new(api.DiscoveryResponse)
- unmarshal(t, tc.wantedValidationContextConfig, want)
- protobuf.ExpectEqual(t, want, gotConfigs[sdsValidationContextPath])
- delete(gotConfigs, sdsValidationContextPath)
- }
-
- if len(gotConfigs) > 0 {
- t.Fatalf("got more configs than wanted: %s", gotConfigs)
- }
- })
- }
-}
-
-func unmarshal(t *testing.T, data string, pb proto.Message) {
- err := jsonpb.UnmarshalString(data, pb)
- checkErr(t, err)
-}
-
-func checkErr(t *testing.T, err error) {
- t.Helper()
- if err != nil {
- t.Fatal(err)
- }
-}
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
index 161f56f6607..b638db00e09 100644
--- a/pkg/config/parameters.go
+++ b/pkg/config/parameters.go
@@ -45,13 +45,12 @@ func (s ServerType) Validate() error {
// ResourceVersion is a version of an xDS server.
type ResourceVersion string
-const XDSv2 ResourceVersion = "v2"
const XDSv3 ResourceVersion = "v3"
// Validate the xDS server versions.
func (s ResourceVersion) Validate() error {
switch s {
- case XDSv2, XDSv3:
+ case XDSv3:
return nil
default:
return fmt.Errorf("invalid xDS version %q", s)
diff --git a/site/docs/main/configuration.md b/site/docs/main/configuration.md
index 109433781fe..62bd0e76690 100644
--- a/site/docs/main/configuration.md
+++ b/site/docs/main/configuration.md
@@ -210,7 +210,7 @@ connects to Contour:
| --envoy-cert-file | "" | Client certificate filename for Envoy secure xDS gRPC communication. |
| --envoy-key-file | "" | Client key filename for Envoy secure xDS gRPC communication. |
| --namespace | projectcontour | Namespace the Envoy container will run, also configured via ENV variable "CONTOUR_NAMESPACE". Namespace is used as part of the metric names on static resources defined in the bootstrap configuration file. |
-| --xds-resource-version | v2 | Specify the xDS API resource version to use. Options are `v2` or `v3`. |
+| --xds-resource-version | v3 | Currently, the only valid xDS API resource version is `v3`. |
{: class="table thead-dark table-bordered"}