diff --git a/.changelog/16274.txt b/.changelog/16274.txt
deleted file mode 100644
index 983d33b195998..0000000000000
--- a/.changelog/16274.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-```release-note:improvement
-connect: Bump Envoy 1.22.5 to 1.22.7, 1.23.2 to 1.23.4, 1.24.0 to 1.24.2, add 1.25.1, remove 1.21.5
-```
diff --git a/.changelog/16292.txt b/.changelog/16292.txt
deleted file mode 100644
index 085fe7fd07c27..0000000000000
--- a/.changelog/16292.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-```release-note:feature
-server: added server side RPC requests global read/write rate-limiter.
-```
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7dd57d1bbe994..dae806a625bdb 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -23,10 +23,10 @@ references:
BASH_ENV: .circleci/bash_env.sh
GO_VERSION: 1.19.4
envoy-versions: &supported_envoy_versions
- - &default_envoy_version "1.22.7"
- - "1.23.4"
- - "1.24.2"
- - "1.25.1"
+ - &default_envoy_version "1.21.5"
+ - "1.22.5"
+ - "1.23.2"
+ - "1.24.0"
nomad-versions: &supported_nomad_versions
- &default_nomad_version "1.3.3"
- "1.2.10"
diff --git a/.github/workflows/nightly-test-1.15.x.yaml b/.github/workflows/nightly-test-1.11.x.yaml
similarity index 98%
rename from .github/workflows/nightly-test-1.15.x.yaml
rename to .github/workflows/nightly-test-1.11.x.yaml
index 18fe5466f0091..cd913d4eca492 100644
--- a/.github/workflows/nightly-test-1.15.x.yaml
+++ b/.github/workflows/nightly-test-1.11.x.yaml
@@ -1,4 +1,4 @@
-name: Nightly Test 1.15.x
+name: Nightly Test 1.11.x
on:
schedule:
- cron: '0 4 * * *'
@@ -6,8 +6,8 @@ on:
env:
EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition
- BRANCH: "release/1.15.x"
- BRANCH_NAME: "release/1.15.x" # Used for naming artifacts
+ BRANCH: "release/1.11.x"
+ BRANCH_NAME: "release-1.11.x" # Used for naming artifacts
jobs:
frontend-test-workspace-node:
diff --git a/agent/proxycfg/testing_api_gateway.go b/agent/proxycfg/testing_api_gateway.go
deleted file mode 100644
index 8a9e113f76edc..0000000000000
--- a/agent/proxycfg/testing_api_gateway.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package proxycfg
-
-import (
- "fmt"
- "github.com/hashicorp/consul/agent/connect"
- "github.com/hashicorp/consul/agent/consul/discoverychain"
- "github.com/mitchellh/go-testing-interface"
-
- "github.com/hashicorp/consul/agent/structs"
-)
-
-func TestConfigSnapshotAPIGateway(
- t testing.T,
- variation string,
- nsFn func(ns *structs.NodeService),
- configFn func(entry *structs.APIGatewayConfigEntry, boundEntry *structs.BoundAPIGatewayConfigEntry),
- routes []structs.BoundRoute,
- extraUpdates []UpdateEvent,
- additionalEntries ...structs.ConfigEntry,
-) *ConfigSnapshot {
- roots, placeholderLeaf := TestCerts(t)
-
- entry := &structs.APIGatewayConfigEntry{
- Kind: structs.APIGateway,
- Name: "api-gateway",
- }
- boundEntry := &structs.BoundAPIGatewayConfigEntry{
- Kind: structs.BoundAPIGateway,
- Name: "api-gateway",
- }
-
- if configFn != nil {
- configFn(entry, boundEntry)
- }
-
- baseEvents := []UpdateEvent{
- {
- CorrelationID: rootsWatchID,
- Result: roots,
- },
- {
- CorrelationID: leafWatchID,
- Result: placeholderLeaf,
- },
- {
- CorrelationID: gatewayConfigWatchID,
- Result: &structs.ConfigEntryResponse{
- Entry: entry,
- },
- },
- {
- CorrelationID: gatewayConfigWatchID,
- Result: &structs.ConfigEntryResponse{
- Entry: boundEntry,
- },
- },
- }
-
- for _, route := range routes {
- // Add the watch event for the route.
- watch := UpdateEvent{
- CorrelationID: routeConfigWatchID,
- Result: &structs.ConfigEntryResponse{
- Entry: route,
- },
- }
- baseEvents = append(baseEvents, watch)
-
- // Add the watch event for the discovery chain.
- entries := []structs.ConfigEntry{
- &structs.ProxyConfigEntry{
- Kind: structs.ProxyDefaults,
- Name: structs.ProxyConfigGlobal,
- Config: map[string]interface{}{
- "protocol": route.GetProtocol(),
- },
- },
- &structs.ServiceResolverConfigEntry{
- Kind: structs.ServiceResolver,
- Name: "api-gateway",
- },
- }
-
- // Add a discovery chain watch event for each service.
- for _, serviceName := range route.GetServiceNames() {
- discoChain := UpdateEvent{
- CorrelationID: fmt.Sprintf("discovery-chain:%s", UpstreamIDString("", "", serviceName.Name, &serviceName.EnterpriseMeta, "")),
- Result: &structs.DiscoveryChainResponse{
- Chain: discoverychain.TestCompileConfigEntries(t, serviceName.Name, "default", "default", "dc1", connect.TestClusterID+".consul", nil, entries...),
- },
- }
- baseEvents = append(baseEvents, discoChain)
- }
- }
-
- upstreams := structs.TestUpstreams(t)
-
- baseEvents = testSpliceEvents(baseEvents, setupTestVariationConfigEntriesAndSnapshot(
- t, variation, upstreams, additionalEntries...,
- ))
-
- return testConfigSnapshotFixture(t, &structs.NodeService{
- Kind: structs.ServiceKindAPIGateway,
- Service: "api-gateway",
- Address: "1.2.3.4",
- Meta: nil,
- TaggedAddresses: nil,
- }, nsFn, nil, testSpliceEvents(baseEvents, extraUpdates))
-}
-
-// TestConfigSnapshotAPIGateway_NilConfigEntry is used to test when
-// the update event for the config entry returns nil
-// since this always happens on the first watch if it doesn't exist.
-func TestConfigSnapshotAPIGateway_NilConfigEntry(
- t testing.T,
-) *ConfigSnapshot {
- roots, _ := TestCerts(t)
-
- baseEvents := []UpdateEvent{
- {
- CorrelationID: rootsWatchID,
- Result: roots,
- },
- {
- CorrelationID: gatewayConfigWatchID,
- Result: &structs.ConfigEntryResponse{
- Entry: nil, // The first watch on a config entry will return nil if the config entry doesn't exist.
- },
- },
- {
- CorrelationID: gatewayConfigWatchID,
- Result: &structs.ConfigEntryResponse{
- Entry: nil, // The first watch on a config entry will return nil if the config entry doesn't exist.
- },
- },
- }
-
- return testConfigSnapshotFixture(t, &structs.NodeService{
- Kind: structs.ServiceKindAPIGateway,
- Service: "api-gateway",
- Address: "1.2.3.4",
- Meta: nil,
- TaggedAddresses: nil,
- }, nil, nil, testSpliceEvents(baseEvents, nil))
-}
diff --git a/agent/xds/listeners_test.go b/agent/xds/listeners_test.go
index e4e7c84575146..fffe3dc342dfd 100644
--- a/agent/xds/listeners_test.go
+++ b/agent/xds/listeners_test.go
@@ -527,211 +527,6 @@ func TestListenersFromSnapshot(t *testing.T) {
}, nil)
},
},
- {
- name: "api-gateway",
- create: func(t testinf.T) *proxycfg.ConfigSnapshot {
- return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, nil, nil, nil)
- },
- },
- {
- name: "api-gateway-nil-config-entry",
- create: func(t testinf.T) *proxycfg.ConfigSnapshot {
- return proxycfg.TestConfigSnapshotAPIGateway_NilConfigEntry(t)
- },
- },
- {
- name: "api-gateway-tcp-listener",
- create: func(t testinf.T) *proxycfg.ConfigSnapshot {
- return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) {
- entry.Listeners = []structs.APIGatewayListener{
- {
- Name: "listener",
- Protocol: structs.ListenerProtocolTCP,
- Port: 8080,
- },
- }
- bound.Listeners = []structs.BoundAPIGatewayListener{
- {
- Name: "listener",
- },
- }
- }, nil, nil)
- },
- },
- {
- name: "api-gateway-tcp-listener-with-tcp-route",
- create: func(t testinf.T) *proxycfg.ConfigSnapshot {
- return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) {
- entry.Listeners = []structs.APIGatewayListener{
- {
- Name: "listener",
- Protocol: structs.ListenerProtocolTCP,
- Port: 8080,
- },
- }
- bound.Listeners = []structs.BoundAPIGatewayListener{
- {
- Name: "listener",
- Routes: []structs.ResourceReference{
- {
- Name: "tcp-route",
- Kind: structs.TCPRoute,
- },
- },
- },
- }
-
- }, []structs.BoundRoute{
- &structs.TCPRouteConfigEntry{
- Name: "tcp-route",
- Kind: structs.TCPRoute,
- Parents: []structs.ResourceReference{
- {
- Kind: structs.APIGateway,
- Name: "api-gateway",
- },
- },
- Services: []structs.TCPService{
- {Name: "tcp-service"},
- },
- },
- }, nil)
- },
- },
- {
- name: "api-gateway-http-listener",
- create: func(t testinf.T) *proxycfg.ConfigSnapshot {
- return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) {
- entry.Listeners = []structs.APIGatewayListener{
- {
- Name: "listener",
- Protocol: structs.ListenerProtocolHTTP,
- Port: 8080,
- },
- }
- bound.Listeners = []structs.BoundAPIGatewayListener{
- {
- Name: "listener",
- Routes: []structs.ResourceReference{},
- },
- }
- }, nil, nil)
- },
- },
- {
- name: "api-gateway-http-listener-with-http-route",
- create: func(t testinf.T) *proxycfg.ConfigSnapshot {
- return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) {
- entry.Listeners = []structs.APIGatewayListener{
- {
- Name: "listener",
- Protocol: structs.ListenerProtocolHTTP,
- Port: 8080,
- },
- }
- bound.Listeners = []structs.BoundAPIGatewayListener{
- {
- Name: "listener",
- Routes: []structs.ResourceReference{
- {
- Name: "http-route",
- Kind: structs.HTTPRoute,
- },
- },
- },
- }
- }, []structs.BoundRoute{
- &structs.HTTPRouteConfigEntry{
- Name: "http-route",
- Kind: structs.HTTPRoute,
- Parents: []structs.ResourceReference{
- {
- Kind: structs.APIGateway,
- Name: "api-gateway",
- },
- },
- Rules: []structs.HTTPRouteRule{
- {
- Services: []structs.HTTPService{
- {Name: "http-service"},
- },
- },
- },
- },
- }, nil)
- },
- },
- {
- name: "api-gateway-tcp-listener-with-tcp-and-http-route",
- create: func(t testinf.T) *proxycfg.ConfigSnapshot {
- return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) {
- entry.Listeners = []structs.APIGatewayListener{
- {
- Name: "listener-tcp",
- Protocol: structs.ListenerProtocolTCP,
- Port: 8080,
- },
- {
- Name: "listener-http",
- Protocol: structs.ListenerProtocolHTTP,
- Port: 8081,
- },
- }
- bound.Listeners = []structs.BoundAPIGatewayListener{
- {
- Name: "listener-tcp",
- Routes: []structs.ResourceReference{
- {
- Name: "tcp-route",
- Kind: structs.TCPRoute,
- },
- },
- },
- {
- Name: "listener-http",
- Routes: []structs.ResourceReference{
- {
- Name: "http-route",
- Kind: structs.HTTPRoute,
- },
- },
- },
- }
-
- }, []structs.BoundRoute{
- &structs.TCPRouteConfigEntry{
- Name: "tcp-route",
- Kind: structs.TCPRoute,
- Parents: []structs.ResourceReference{
- {
- Kind: structs.APIGateway,
- Name: "api-gateway",
- },
- },
- Services: []structs.TCPService{
- {Name: "tcp-service"},
- },
- },
- &structs.HTTPRouteConfigEntry{
- Name: "http-route",
- Kind: structs.HTTPRoute,
- Parents: []structs.ResourceReference{
- {
- Kind: structs.APIGateway,
- Name: "api-gateway",
- },
- },
- Rules: []structs.HTTPRouteRule{
- {
- Services: []structs.HTTPService{
- {Name: "http-service"},
- },
- },
- },
- },
- }, nil)
- },
- },
{
name: "ingress-gateway",
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
diff --git a/agent/xds/testdata/listeners/api-gateway-http-listener-with-http-route.latest.golden b/agent/xds/testdata/listeners/api-gateway-http-listener-with-http-route.latest.golden
deleted file mode 100644
index 0bf31dc66240b..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway-http-listener-with-http-route.latest.golden
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "versionInfo": "00000001",
- "resources": [
- {
- "@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "name": "http:1.2.3.4:8080",
- "address": {
- "socketAddress": {
- "address": "1.2.3.4",
- "portValue": 8080
- }
- },
- "filterChains": [
- {
- "filters": [
- {
- "name": "envoy.filters.network.http_connection_manager",
- "typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
- "statPrefix": "ingress_upstream_8080",
- "rds": {
- "configSource": {
- "ads": {},
- "resourceApiVersion": "V3"
- },
- "routeConfigName": "8080"
- },
- "httpFilters": [
- {
- "name": "envoy.filters.http.router",
- "typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
- }
- }
- ],
- "tracing": {
- "randomSampling": {}
- }
- }
- }
- ]
- }
- ],
- "trafficDirection": "OUTBOUND"
- }
- ],
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/agent/xds/testdata/listeners/api-gateway-http-listener.latest.golden b/agent/xds/testdata/listeners/api-gateway-http-listener.latest.golden
deleted file mode 100644
index 53b67bb37300e..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway-http-listener.latest.golden
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "versionInfo": "00000001",
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/agent/xds/testdata/listeners/api-gateway-nil-config-entry.latest.golden b/agent/xds/testdata/listeners/api-gateway-nil-config-entry.latest.golden
deleted file mode 100644
index 53b67bb37300e..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway-nil-config-entry.latest.golden
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "versionInfo": "00000001",
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden
deleted file mode 100644
index 8da750a592962..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "versionInfo": "00000001",
- "resources": [
- {
- "@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "name": "http:1.2.3.4:8081",
- "address": {
- "socketAddress": {
- "address": "1.2.3.4",
- "portValue": 8081
- }
- },
- "filterChains": [
- {
- "filters": [
- {
- "name": "envoy.filters.network.http_connection_manager",
- "typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
- "statPrefix": "ingress_upstream_8081",
- "rds": {
- "configSource": {
- "ads": {},
- "resourceApiVersion": "V3"
- },
- "routeConfigName": "8081"
- },
- "httpFilters": [
- {
- "name": "envoy.filters.http.router",
- "typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
- }
- }
- ],
- "tracing": {
- "randomSampling": {}
- }
- }
- }
- ]
- }
- ],
- "trafficDirection": "OUTBOUND"
- },
- {
- "@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "name": "tcp-service:1.2.3.4:8080",
- "address": {
- "socketAddress": {
- "address": "1.2.3.4",
- "portValue": 8080
- }
- },
- "filterChains": [
- {
- "filters": [
- {
- "name": "envoy.filters.network.tcp_proxy",
- "typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
- "statPrefix": "upstream.tcp-service.default.default.dc1",
- "cluster": "tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
- }
- }
- ]
- }
- ],
- "trafficDirection": "OUTBOUND"
- }
- ],
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-route.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-route.latest.golden
deleted file mode 100644
index 12f6c29726d5e..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-route.latest.golden
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "versionInfo": "00000001",
- "resources": [
- {
- "@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "name": "tcp-service:1.2.3.4:8080",
- "address": {
- "socketAddress": {
- "address": "1.2.3.4",
- "portValue": 8080
- }
- },
- "filterChains": [
- {
- "filters": [
- {
- "name": "envoy.filters.network.tcp_proxy",
- "typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
- "statPrefix": "upstream.tcp-service.default.default.dc1",
- "cluster": "tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
- }
- }
- ]
- }
- ],
- "trafficDirection": "OUTBOUND"
- }
- ],
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listener.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listener.latest.golden
deleted file mode 100644
index 53b67bb37300e..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway-tcp-listener.latest.golden
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "versionInfo": "00000001",
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listeners.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listeners.latest.golden
deleted file mode 100644
index d2d839adf9567..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway-tcp-listeners.latest.golden
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "versionInfo": "00000001",
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/agent/xds/testdata/listeners/api-gateway.latest.golden b/agent/xds/testdata/listeners/api-gateway.latest.golden
deleted file mode 100644
index d2d839adf9567..0000000000000
--- a/agent/xds/testdata/listeners/api-gateway.latest.golden
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "versionInfo": "00000001",
- "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
- "nonce": "00000001"
-}
\ No newline at end of file
diff --git a/envoyextensions/xdscommon/envoy_versioning_test.go b/envoyextensions/xdscommon/envoy_versioning_test.go
index e20a2ca8ceefa..833e3014ebeec 100644
--- a/envoyextensions/xdscommon/envoy_versioning_test.go
+++ b/envoyextensions/xdscommon/envoy_versioning_test.go
@@ -121,7 +121,6 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) {
"1.18.6": {expectErr: "Envoy 1.18.6 " + errTooOld},
"1.19.5": {expectErr: "Envoy 1.19.5 " + errTooOld},
"1.20.7": {expectErr: "Envoy 1.20.7 " + errTooOld},
- "1.21.5": {expectErr: "Envoy 1.21.5 " + errTooOld},
}
// Insert a bunch of valid versions.
@@ -136,10 +135,10 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) {
}
*/
for _, v := range []string{
+ "1.21.0", "1.21.1", "1.21.2", "1.21.3", "1.21.4", "1.21.5",
"1.22.0", "1.22.1", "1.22.2", "1.22.3", "1.22.4", "1.22.5",
- "1.23.0", "1.23.1", "1.23.2", "1.23.3", "1.23.4",
- "1.24.0", "1.24.1", "1.24.2",
- "1.25.0", "1.25.1",
+ "1.23.0", "1.23.1", "1.23.2",
+ "1.24.0",
} {
cases[v] = testcase{expect: SupportedProxyFeatures{}}
}
diff --git a/envoyextensions/xdscommon/proxysupport.go b/envoyextensions/xdscommon/proxysupport.go
index bedc0608bfd39..963e0dba0c2aa 100644
--- a/envoyextensions/xdscommon/proxysupport.go
+++ b/envoyextensions/xdscommon/proxysupport.go
@@ -9,10 +9,10 @@ import "strings"
//
// see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions
var EnvoyVersions = []string{
- "1.25.1",
- "1.24.2",
- "1.23.4",
+ "1.24.0",
+ "1.23.2",
"1.22.5",
+ "1.21.5",
}
// UnsupportedEnvoyVersions lists any unsupported Envoy versions (mainly minor versions) that fall
diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh
index bb9baacbb0f91..2394ab23621ed 100644
--- a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh
+++ b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh
@@ -38,7 +38,6 @@ services = [
]
parents = [
{
- kind = "api-gateway"
name = "api-gateway"
}
]
@@ -48,4 +47,4 @@ register_services primary
gen_envoy_bootstrap api-gateway 20000 primary true
gen_envoy_bootstrap s1 19000
-gen_envoy_bootstrap s2 19001
+gen_envoy_bootstrap s2 19001
\ No newline at end of file
diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh b/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh
index 56a86166d4c04..fd4f474abfdcc 100644
--- a/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh
+++ b/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh
@@ -47,7 +47,6 @@ parents = [
{
name = "api-gateway"
sectionName = "listener-two"
- kind = "api-gateway"
}
]
'
@@ -74,4 +73,4 @@ register_services primary
gen_envoy_bootstrap api-gateway 20000 primary true
gen_envoy_bootstrap s1 19000
-gen_envoy_bootstrap s2 19001
+gen_envoy_bootstrap s2 19001
\ No newline at end of file
diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-simple/verify.bats b/test/integration/connect/envoy/case-api-gateway-tcp-simple/verify.bats
index e96f473be4f4a..51ed646bd6bca 100644
--- a/test/integration/connect/envoy/case-api-gateway-tcp-simple/verify.bats
+++ b/test/integration/connect/envoy/case-api-gateway-tcp-simple/verify.bats
@@ -29,4 +29,4 @@ load helpers
@test "api gateway should get an intentions error connecting to s2 via configured port" {
run retry_default must_fail_tcp_connection localhost:9998
-}
+}
\ No newline at end of file
diff --git a/test/integration/consul-container/libs/assert/envoy.go b/test/integration/consul-container/libs/assert/envoy.go
index 6713c4fb6490d..e62118c4f1d8a 100644
--- a/test/integration/consul-container/libs/assert/envoy.go
+++ b/test/integration/consul-container/libs/assert/envoy.go
@@ -127,7 +127,7 @@ func AssertEnvoyMetricAtLeast(t *testing.T, adminPort int, prefix, metric string
err error
)
failer := func() *retry.Timer {
- return &retry.Timer{Timeout: 60 * time.Second, Wait: 500 * time.Millisecond}
+ return &retry.Timer{Timeout: 30 * time.Second, Wait: 500 * time.Millisecond}
}
retry.RunWith(failer(), t, func(r *retry.R) {
diff --git a/test/integration/consul-container/libs/service/connect.go b/test/integration/consul-container/libs/service/connect.go
index b5a8087d2d67f..ac4907d4e583e 100644
--- a/test/integration/consul-container/libs/service/connect.go
+++ b/test/integration/consul-container/libs/service/connect.go
@@ -109,13 +109,6 @@ func (g ConnectContainer) Start() error {
return g.container.Start(g.ctx)
}
-func (g ConnectContainer) Stop() error {
- if g.container == nil {
- return fmt.Errorf("container has not been initialized")
- }
- return g.container.Stop(context.Background(), nil)
-}
-
func (g ConnectContainer) Terminate() error {
return cluster.TerminateContainer(g.ctx, g.container, true)
}
diff --git a/test/integration/consul-container/libs/service/examples.go b/test/integration/consul-container/libs/service/examples.go
index da075f5aec9c9..9d95f6e9099f7 100644
--- a/test/integration/consul-container/libs/service/examples.go
+++ b/test/integration/consul-container/libs/service/examples.go
@@ -101,13 +101,6 @@ func (g exampleContainer) Start() error {
return g.container.Start(context.Background())
}
-func (g exampleContainer) Stop() error {
- if g.container == nil {
- return fmt.Errorf("container has not been initialized")
- }
- return g.container.Stop(context.Background(), nil)
-}
-
func (c exampleContainer) Terminate() error {
return cluster.TerminateContainer(c.ctx, c.container, true)
}
diff --git a/test/integration/consul-container/libs/service/gateway.go b/test/integration/consul-container/libs/service/gateway.go
index 70897fc7b0992..5fb3a36184b4a 100644
--- a/test/integration/consul-container/libs/service/gateway.go
+++ b/test/integration/consul-container/libs/service/gateway.go
@@ -86,13 +86,6 @@ func (g gatewayContainer) Start() error {
return g.container.Start(context.Background())
}
-func (g gatewayContainer) Stop() error {
- if g.container == nil {
- return fmt.Errorf("container has not been initialized")
- }
- return g.container.Stop(context.Background(), nil)
-}
-
func (c gatewayContainer) Terminate() error {
return cluster.TerminateContainer(c.ctx, c.container, true)
}
diff --git a/test/integration/consul-container/libs/service/service.go b/test/integration/consul-container/libs/service/service.go
index 99da558226904..57a3539a64123 100644
--- a/test/integration/consul-container/libs/service/service.go
+++ b/test/integration/consul-container/libs/service/service.go
@@ -18,7 +18,6 @@ type Service interface {
GetName() string
GetServiceName() string
Start() (err error)
- Stop() (err error)
Terminate() error
Restart() error
GetStatus() (string, error)
diff --git a/test/integration/consul-container/libs/topology/peering_topology.go b/test/integration/consul-container/libs/topology/peering_topology.go
index ba36978c72f43..1c764c45c53cd 100644
--- a/test/integration/consul-container/libs/topology/peering_topology.go
+++ b/test/integration/consul-container/libs/topology/peering_topology.go
@@ -41,7 +41,6 @@ type BuiltCluster struct {
func BasicPeeringTwoClustersSetup(
t *testing.T,
consulVersion string,
- peeringThroughMeshgateway bool,
) (*BuiltCluster, *BuiltCluster) {
// acceptingCluster, acceptingCtx, acceptingClient := NewPeeringCluster(t, "dc1", 3, consulVersion, true)
acceptingCluster, acceptingCtx, acceptingClient := NewPeeringCluster(t, 3, &libcluster.BuildOptions{
@@ -54,38 +53,6 @@ func BasicPeeringTwoClustersSetup(
ConsulVersion: consulVersion,
InjectAutoEncryption: true,
})
-
- // Create the mesh gateway for dataplane traffic and peering control plane traffic (if enabled)
- acceptingClusterGateway, err := libservice.NewGatewayService(context.Background(), "mesh", "mesh", acceptingCluster.Clients()[0])
- require.NoError(t, err)
- dialingClusterGateway, err := libservice.NewGatewayService(context.Background(), "mesh", "mesh", dialingCluster.Clients()[0])
- require.NoError(t, err)
-
- // Enable peering control plane traffic through mesh gateway
- if peeringThroughMeshgateway {
- req := &api.MeshConfigEntry{
- Peering: &api.PeeringMeshConfig{
- PeerThroughMeshGateways: true,
- },
- }
- configCluster := func(cli *api.Client) error {
- libassert.CatalogServiceExists(t, cli, "mesh")
- ok, _, err := cli.ConfigEntries().Set(req, &api.WriteOptions{})
- if !ok {
- return fmt.Errorf("config entry is not set")
- }
-
- if err != nil {
- return fmt.Errorf("error writing config entry: %s", err)
- }
- return nil
- }
- err = configCluster(dialingClient)
- require.NoError(t, err)
- err = configCluster(acceptingClient)
- require.NoError(t, err)
- }
-
require.NoError(t, dialingCluster.PeerWithCluster(acceptingClient, AcceptingPeerName, DialingPeerName))
libassert.PeeringStatus(t, acceptingClient, AcceptingPeerName, api.PeeringStateActive)
@@ -93,6 +60,7 @@ func BasicPeeringTwoClustersSetup(
// Register an static-server service in acceptingCluster and export to dialing cluster
var serverService, serverSidecarService libservice.Service
+ var acceptingClusterGateway libservice.Service
{
clientNode := acceptingCluster.Clients()[0]
@@ -113,10 +81,15 @@ func BasicPeeringTwoClustersSetup(
libassert.CatalogServiceExists(t, acceptingClient, "static-server-sidecar-proxy")
require.NoError(t, serverService.Export("default", AcceptingPeerName, acceptingClient))
+
+ // Create the mesh gateway for dataplane traffic
+ acceptingClusterGateway, err = libservice.NewGatewayService(context.Background(), "mesh", "mesh", clientNode)
+ require.NoError(t, err)
}
// Register an static-client service in dialing cluster and set upstream to static-server service
var clientSidecarService *libservice.ConnectContainer
+ var dialingClusterGateway libservice.Service
{
clientNode := dialingCluster.Clients()[0]
@@ -127,6 +100,9 @@ func BasicPeeringTwoClustersSetup(
libassert.CatalogServiceExists(t, dialingClient, "static-client-sidecar-proxy")
+ // Create the mesh gateway for dataplane traffic
+ dialingClusterGateway, err = libservice.NewGatewayService(context.Background(), "mesh", "mesh", clientNode)
+ require.NoError(t, err)
}
_, adminPort := clientSidecarService.GetAdminAddr()
diff --git a/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go b/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go
index bbac9cc034019..223effa449b26 100644
--- a/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go
+++ b/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go
@@ -50,7 +50,7 @@ import (
func TestPeering_RotateServerAndCAThenFail_(t *testing.T) {
t.Parallel()
- accepting, dialing := libtopology.BasicPeeringTwoClustersSetup(t, utils.TargetVersion, false)
+ accepting, dialing := libtopology.BasicPeeringTwoClustersSetup(t, utils.TargetVersion)
var (
acceptingCluster = accepting.Cluster
dialingCluster = dialing.Cluster
diff --git a/test/integration/consul-container/test/troubleshoot/troubleshoot_test.go b/test/integration/consul-container/test/troubleshoot/troubleshoot_upstream_test.go
similarity index 100%
rename from test/integration/consul-container/test/troubleshoot/troubleshoot_test.go
rename to test/integration/consul-container/test/troubleshoot/troubleshoot_upstream_test.go
diff --git a/test/integration/consul-container/test/upgrade/peering_control_plane_mgw_test.go b/test/integration/consul-container/test/upgrade/peering_control_plane_mgw_test.go
index 5ccba95677391..f4112b6f6b83e 100644
--- a/test/integration/consul-container/test/upgrade/peering_control_plane_mgw_test.go
+++ b/test/integration/consul-container/test/upgrade/peering_control_plane_mgw_test.go
@@ -42,7 +42,7 @@ func TestPeering_Upgrade_ControlPlane_MGW(t *testing.T) {
}
run := func(t *testing.T, tc testcase) {
- accepting, dialing := libtopology.BasicPeeringTwoClustersSetup(t, tc.oldversion, true)
+ accepting, dialing := libtopology.BasicPeeringTwoClustersSetup(t, tc.oldversion)
var (
acceptingCluster = accepting.Cluster
dialingCluster = dialing.Cluster
@@ -54,6 +54,19 @@ func TestPeering_Upgrade_ControlPlane_MGW(t *testing.T) {
acceptingClient, err := acceptingCluster.GetClient(nil, false)
require.NoError(t, err)
+ // Enable peering control plane traffic through mesh gateway
+ req := &api.MeshConfigEntry{
+ Peering: &api.PeeringMeshConfig{
+ PeerThroughMeshGateways: true,
+ },
+ }
+ ok, _, err := dialingClient.ConfigEntries().Set(req, &api.WriteOptions{})
+ require.True(t, ok)
+ require.NoError(t, err)
+ ok, _, err = acceptingClient.ConfigEntries().Set(req, &api.WriteOptions{})
+ require.True(t, ok)
+ require.NoError(t, err)
+
// Verify control plane endpoints and traffic in gateway
_, gatewayAdminPort := dialing.Gateway.GetAdminAddr()
libassert.AssertUpstreamEndpointStatus(t, gatewayAdminPort, "server.dc1.peering", "HEALTHY", 1)
@@ -61,9 +74,6 @@ func TestPeering_Upgrade_ControlPlane_MGW(t *testing.T) {
libassert.AssertEnvoyMetricAtLeast(t, gatewayAdminPort,
"cluster.static-server.default.default.accepting-to-dialer.external",
"upstream_cx_total", 1)
- libassert.AssertEnvoyMetricAtLeast(t, gatewayAdminPort,
- "cluster.server.dc1.peering",
- "upstream_cx_total", 1)
// Upgrade the accepting cluster and assert peering is still ACTIVE
require.NoError(t, acceptingCluster.StandardUpgrade(t, context.Background(), tc.targetVersion))
@@ -80,12 +90,11 @@ func TestPeering_Upgrade_ControlPlane_MGW(t *testing.T) {
// - Register a new static-client service in dialing cluster and
// - set upstream to static-server service in peered cluster
- // Stop the accepting gateway and restart dialing gateway
- // to force peering control plane traffic through dialing mesh gateway
- require.NoError(t, accepting.Gateway.Stop())
+ // Restart the gateway & proxy sidecar
require.NoError(t, dialing.Gateway.Restart())
+ require.NoError(t, dialing.Container.Restart())
- // Restarted dialing gateway should not have any measurement on data plane traffic
+ // Restarted gateway should not have any measurement on data plane traffic
libassert.AssertEnvoyMetricAtMost(t, gatewayAdminPort,
"cluster.static-server.default.default.accepting-to-dialer.external",
"upstream_cx_total", 0)
@@ -93,7 +102,6 @@ func TestPeering_Upgrade_ControlPlane_MGW(t *testing.T) {
libassert.AssertEnvoyMetricAtLeast(t, gatewayAdminPort,
"cluster.server.dc1.peering",
"upstream_cx_total", 1)
- require.NoError(t, accepting.Gateway.Start())
clientSidecarService, err := libservice.CreateAndRegisterStaticClientSidecar(dialingCluster.Servers()[0], libtopology.DialingPeerName, true)
require.NoError(t, err)
diff --git a/test/integration/consul-container/test/upgrade/peering_http_test.go b/test/integration/consul-container/test/upgrade/peering_http_test.go
index fe91f76530988..aec03a3edb41c 100644
--- a/test/integration/consul-container/test/upgrade/peering_http_test.go
+++ b/test/integration/consul-container/test/upgrade/peering_http_test.go
@@ -99,7 +99,7 @@ func TestPeering_UpgradeToTarget_fromLatest(t *testing.T) {
}
run := func(t *testing.T, tc testcase) {
- accepting, dialing := libtopology.BasicPeeringTwoClustersSetup(t, tc.oldversion, false)
+ accepting, dialing := libtopology.BasicPeeringTwoClustersSetup(t, tc.oldversion)
var (
acceptingCluster = accepting.Cluster
dialingCluster = dialing.Cluster
diff --git a/version/VERSION b/version/VERSION
index 1f0d2f335194a..0dec25d15b37f 100644
--- a/version/VERSION
+++ b/version/VERSION
@@ -1 +1 @@
-1.16.0-dev
+1.15.0-dev
\ No newline at end of file
diff --git a/website/content/docs/connect/config-entries/service-splitter.mdx b/website/content/docs/connect/config-entries/service-splitter.mdx
index 34ea9597e2185..4386fba281bcd 100644
--- a/website/content/docs/connect/config-entries/service-splitter.mdx
+++ b/website/content/docs/connect/config-entries/service-splitter.mdx
@@ -1,575 +1,54 @@
----
+---
layout: docs
-page_title: Service Splitter Configuration Entry Reference
-description: >-
- Service splitter configuration entries are L7 traffic management tools for redirecting requests for a service to
- multiple instances. Learn how to write `service-splitter` config entries in HCL or YAML with a specification
- reference, configuration model, a complete example, and example code by use case.
+page_title: Service Splitter - Configuration Entry Reference
+description: >-
+ The service splitter configuration entry kind defines how to divide service mesh traffic between service instances. Use the reference guide to learn about `""service-splitter""` config entry parameters and how it can be used for traffic management behaviors like canary rollouts, blue green deployment, and load balancing across environments.
---
-# Service Splitter Configuration Reference
-
-This reference page describes the structure and contents of service splitter configuration entries. Configure and apply service splitters to redirect a percentage of incoming traffic requests for a service to one or more specific service instances.
-
-## Configuration model
-
-The following list outlines field hierarchy, language-specific data types, and requirements in a service splitter configuration entry. Click on a property name to view additional details, including default values.
-
-
-
-
-
-- [`Kind`](#kind): string | required
-- [`Name`](#name): string | required
-- [`Namespace`](#namespace): string
-- [`Partition`](#partition): string
-- [`Meta`](#meta): map
-- [`Splits`](#splits): map | required
- - [`Weight`](#splits-weight): number | required
- - [`Service`](#splits-service): string | required
- - [`ServiceSubset`](#splits-servicesubset): string
- - [`Namespace`](#splits-namespace): string
- - [`Partition`](#splits-partition): string
- - [`RequestHeaders`](#splits-requestheaders): map
- - [`Add`](#splits-requestheaders): map
- - [`Set`](#splits-requestheaders): map
- - [`Remove`](#splits-requestheaders): map
- - [`ResponseHeaders`](#splits-responseheaders): map
- - [`Add`](#splits-responseheaders): map
- - [`Set`](#splits-responseheaders): map
- - [`Remove`](#splits-responseheaders): map
-
-
-
-
-
-- [`apiVersion`](#apiversion): string | required
-- [`kind`](#kind): string | required
-- [`metadata`](#metadata): object | required
- - [`name`](#metadata-name): string | required
- - [`namespace`](#metadata-namespace): string | optional
-- [`spec`](#spec): object | required
- - [`splits`](#spec-splits): list | required
- - [`weight`](#spec-splits-weight): float32 | required
- - [`service`](#spec-splits-service): string | required
- - [`serviceSubset`](#spec-splits-servicesubset): string
- - [`namespace`](#spec-splits-namespace): string
- - [`partition`](#spec-splits-partition): string
- - [`requestHeaders`](#spec-splits-requestheaders): HTTPHeaderModifiers
- - [`add`](#spec-splits-requestheaders): map
- - [`set`](#spec-splits-requestheaders): map
- - [`remove`](#spec-splits-requestheaders): map
- - [`responseHeaders`](#spec-splits-responseheaders): HTTPHeaderModifiers
- - [`add`](#spec-splits-responseheaders): map
- - [`set`](#spec-splits-responseheaders): map
- - [`remove`](#spec-splits-responseheaders): map
-
-
-
-
-## Complete configuration
-
-When every field is defined, a service splitter configuration entry has the following form:
-
-
-
-
-
-```hcl
-Kind = "service-splitter" ## string | required
-Name = "config-entry-name" ## string | required
-Namespace = "main" ## string
-Partition = "partition" ## string
-Meta = { ## map
- key = "value"
-}
-Splits = [ ## list | required
- { ## map
- Weight = 90 ## number | required
- Service = "service" ## string
- ServiceSubset = "v1" ## string
- Namespace = "target-namespace" ## string
- Partition = "target-partition" ## string
- RequestHeaders = { ## map
- Set = {
- "X-Web-Version" : "from-v1"
- }
- }
- ResponseHeaders = { ## map
- Set = {
- "X-Web-Version" : "to-v1"
- }
- }
- },
- {
- Weight = 10
- Service = "service"
- ServiceSubset = "v2"
- Namespace = "target-namespace"
- Partition = "target-partition"
- RequestHeaders = {
- Set = {
- "X-Web-Version" : "from-v2"
- }
- }
- ResponseHeaders = {
- Set = {
- "X-Web-Version" : "to-v2"
- }
- }
- }
-]
-```
-
-
-
-
-
-```json
-{
- "Kind" : "service-splitter", ## string | required
- "Name" : "config-entry-name", ## string | required
- "Namespace" : "main", ## string
- "Partition" : "partition", ## string
- "Meta" : { ## map
- "_key_" : "_value_"
- },
- "Splits" : [ ## list | required
- { ## map
- "Weight" : 90, ## number | required
- "Service" : "service", ## string
- "ServiceSubset" : "v1", ## string
- "Namespace" : "target-namespace", ## string
- "Partition" : "target-partition", ## string
- "RequestHeaders" : { ## map
- "Set" : {
- "X-Web-Version": "from-v1"
- }
- },
- "ResponseHeaders" : { ## map
- "Set" : {
- "X-Web-Version": "to-v1"
- }
- }
- },
- {
- "Weight" : 10,
- "Service" : "service",
- "ServiceSubset" : "v2",
- "Namespace" : "target-namespace",
- "Partition" : "target-partition",
- "RequestHeaders" : {
- "Set" : {
- "X-Web-Version": "from-v2"
- }
- },
- "ResponseHeaders" : {
- "Set" : {
- "X-Web-Version": "to-v2"
- }
- }
- }
- ]
-}
-```
-
-
-
-
-
-```yaml
-apiVersion: consul.hashicorp.com/v1alpha1 # string | required
-kind: ServiceSplitter # string | required
-metadata: # object | required
- name: config-entry-name # string | required
- namespace: main # string
-spec:
- splits: # list
- - weight: 90 # floating point | required
- service: service # string
- serviceSubset: v1 # string
- namespace: target-namespace # string
- partition: target-partition # string
- requestHeaders:
- set:
- x-web-version: from-v1 # string
- responseHeaders:
- set:
- x-web-version: to-v1 # string
- - weight: 10
- service: service
- serviceSubset: v2
- namespace: target-namespace
- partition: target-partition
- requestHeaders:
- set:
- x-web-version: from-v2
- responseHeaders:
- set:
- x-web-version: to-v2
-```
-
-
-
-
-
-## Specification
-
-This section provides details about the fields you can configure in the service splitter configuration entry.
-
-
-
-
-
-### `Kind`
-
-Specifies the type of configuration entry to implement.
-
-#### Values
-
-- Default: none
-- This field is required.
-- Data type: String value that must be set to `service-splitter`.
-
-### `Name`
-
-Specifies a name for the configuration entry. The name is metadata that you can use to reference the configuration entry when performing Consul operations, such as applying a configuration entry to a specific cluster.
-
-#### Values
-
-- Default: Defaults to the name of the node after writing the entry to the Consul server.
-- This field is required.
-- Data type: String
-
-
-### `Namespace`
-
-Specifies the [namespace](/consul/docs/enterprise/namespaces) to apply the configuration entry.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `Partition`
-
-Specifies the [admin partition](/consul/docs/enterprise/admin-partitions) to apply the configuration entry.
-
-#### Values
-
-- Default: `Default`
-- Data type: String
-
-### `Meta`
-
-Specifies key-value pairs to add to the KV store.
-
-#### Values
-
-- Default: none
-- Data type: Map of one or more key-value pairs
- - keys: String
- - values: String, integer, or float
-
-### `Splits`
-
-Defines how much traffic to send to sets of service instances during a traffic split.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: list of objects that can contain the following fields:
- - `Weight`: The sum of weights for a set of service instances must add up to 100.
- - `Service`: This field is required.
- - `ServiceSubset`
- - `Namespace`
- - `Partition`
- - `RequestHeaders`
- - `ResponseHeaders`
-
-### `Splits[].Weight`
-
-Specifies the percentage of traffic sent to the set of service instances specified in the [`Service`](#service) field. Each weight must be a floating integer between `0` and `100`. The smallest representable value is `.01`. The sum of weights across all splits must add up to `100`.
-
-#### Values
-
-- Default: `null`
-- This field is required.
-- Data type: Floating number from `.01` to `100`.
-
-### `Splits[].Service`
-
-Specifies the name of the service to resolve.
-
-#### Values
-
-- Default: Inherits the value of the [`Name`](#name) field.
-- Data type: String
-
-### `Splits[].ServiceSubset`
-
-Specifies a subset of the service to resolve. A service subset assigns a name to a specific subset of discoverable service instances within a datacenter, such as `version2` or `canary`. All services have an unnamed default subset that returns all healthy instances.
-
-You can define service subsets in a [service resolver configuration entry](/consul/docs/connect/config-entries/service-resolver), which are referenced by their names throughout the other configuration entries. This field overrides the default subset value in the service resolver configuration entry.
-
-#### Values
-
-- Default: If empty, the `split` uses the default subset.
-- Data type: String
-
-### `Splits[].Namespace`
-
-Specifies the [namespace](/consul/docs/enterprise/namespaces) to use in the FQDN when resolving the service.
-
-#### Values
-
-- Default: Inherits the value of [`Namespace`](#Namespace) from the top-level of the configuration entry.
-- Data type: String
-
-### `Splits[].Partition`
-
-Specifies the [admin partition](/consul/docs/enterprise/admin-partitions) to use in the FQDN when resolving the service.
-
-#### Values
-
-- Default: By default, the `service-splitter` uses the [admin partition specified in the top-level configuration entry](#partition).
-- Data type: String
-
-### `Splits[].RequestHeaders`
-
-Specifies a set of HTTP-specific header modification rules applied to requests routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
-
-#### Values
-
-- Default: None
-- Values: Object containing one or more fields that define header modification rules
- - `Add`: Map of one or more key-value pairs
- - `Set`: Map of one or more key-value pairs
- - `Remove`: Map of one or more key-value pairs
-
-The following table describes how to configure values for request headers:
-
-| Rule | Description | Type |
-| --- | --- | --- |
-| `Add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `Set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `Remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
-
-#### Use variable placeholders
-
-For `Add` and `Set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
-
-
-### `Splits[].ResponseHeaders`
-
-Specifies a set of HTTP-specific header modification rules applied to responses routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
-
-#### Values
-
-- Default: None
-- Values: Object containing one or more fields that define header modification rules
- - `Add`: Map of one or more string key-value pairs
- - `Set`: Map of one or more string key-value pairs
- - `Remove`: Map of one or more string key-value pairs
-
-The following table describes how to configure values for response headers:
-
-| Rule | Description | Type |
-| --- | --- | --- |
-| `Add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `Set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `Remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
-
-#### Use variable placeholders
-
-For `Add` and `Set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
-
-
-
-
-
-### `apiVersion`
-
-Kubernetes-only parameter that specifies the version of the Consul API that the configuration entry maps to Kubernetes configurations. The value must be `consul.hashicorp.com/v1alpha1`.
-
-### `kind`
-
-Specifies the type of configuration entry to implement.
-
-#### Values
-
-- Default: none
-- This field is required.
-- Data type: String value that must be set to `serviceSplitter`.
-
-### `metadata.name`
-
-Specifies a name for the configuration entry. The name is metadata that you can use to reference the configuration entry when performing Consul operations, such as applying a configuration entry to a specific cluster.
-
-#### Values
-
-- Default: Inherits name from the host node
-- This field is required.
-- Data type: String
-
-
-### `metadata.namespace`
-
-Specifies the Consul namespace to use for resolving the service. You can map Consul namespaces to Kubernetes Namespaces in different ways. Refer to [Custom Resource Definitions (CRDs) for Consul on Kubernetes](/consul/docs/k8s/crds#consul-enterprise) for additional information.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec`
-
-Kubernetes-only field that contains all of the configurations for service splitter pods.
-
-#### Values
-
-- Default: none
-- This field is required.
-- Data type: Object containing [`spec.splits`](#spec-splits) configuration
-
-### `spec.meta`
-
-Specifies key-value pairs to add to the KV store.
-
-#### Values
-
-- Default: none
-- Data type: Map of one or more key-value pairs
- - keys: String
- - values: String, integer, or float
-
-### `spec.splits`
-
-Defines how much traffic to send to sets of service instances during a traffic split.
+# Service Splitter Configuration Entry
-#### Values
+-> **v1.8.4+:** On Kubernetes, the `ServiceSplitter` custom resource is supported in Consul versions 1.8.4+.
+**v1.6.0+:** On other platforms, this config entry is supported in Consul versions 1.6.0+.
-- Default: None
-- This field is required.
-- Data type: list of objects that can contain the following fields:
- - `weight`: The sum of weights for a set of service instances. The total defined value must add up to 100.
- - `service`: This field is required.
- - `serviceSubset`
- - `namespace`
- - `partition`
- - `requestHeaders`
- - `responseHeaders`
+The `service-splitter` config entry kind (`ServiceSplitter` on Kubernetes) controls how to split incoming Connect
+requests across different subsets of a single service (like during staged
+canary rollouts), or perhaps across different services (like during a v2
+rewrite or other type of codebase migration).
-### `spec.splits[].weight`
+If no splitter config is defined for a service it is assumed 100% of traffic
+flows to a service with the same name and discovery continues on to the
+resolution stage.
-Specifies the percentage of traffic sent to the set of service instances specified in the [`spec.splits.service`](#spec-splits-service) field. Each weight must be a floating integer between `0` and `100`. The smallest representable value is `.01`. The sum of weights across all splits must add up to `100`.
+## Interaction with other Config Entries
-#### Values
+- Service splitter config entries are a component of [L7 Traffic
+ Management](/consul/docs/connect/l7-traffic).
-- Default: `null`
-- This field is required.
-- Data type: Floating integer from `.01` to `100`
+- Service splitter config entries are restricted to only services that define
+ their protocol as http-based via a corresponding
+ [`service-defaults`](/consul/docs/connect/config-entries/service-defaults) config
+ entry or globally via
+ [`proxy-defaults`](/consul/docs/connect/config-entries/proxy-defaults) .
-### `spec.splits[].service`
+- Any split destination that specifies a different `Service` field and omits
+ the `ServiceSubset` field is eligible for further splitting should a splitter
+ be configured for that other service, otherwise resolution proceeds according
+ to any configured
+ [`service-resolver`](/consul/docs/connect/config-entries/service-resolver).
-Specifies the name of the service to resolve.
+## UI
-#### Values
+Once a `service-splitter` is successfully entered, you can view it in the UI. Service routers, service splitters, and service resolvers can all be viewed by clicking on your service then switching to the _routing_ tab.
-- Default: The service matching the configuration entry [`meta.name`](#metadata-name) field.
-- Data type: String
+
-### `spec.splits[].serviceSubset`
-
-Specifies a subset of the service to resolve. This field overrides the `DefaultSubset`.
-
-#### Values
-
-- Default: Inherits the name of the default subset.
-- Data type: String
-
-### `spec.splits[].namespace`
-
-Specifies the [namespace](/consul/docs/enterprise/namespaces) to use when resolving the service.
-
-#### Values
-
-- Default: The namespace specified in the top-level configuration entry.
-- Data type: String
-
-### `spec.splits[].partition`
-
-Specifies which [admin partition](/consul/docs/enterprise/admin-partitions) to use in the FQDN when resolving the service.
-
-#### Values
-
-- Default: `default`
-- Data type: String
-
-### `spec.splits[].requestHeaders`
-
-Specifies a set of HTTP-specific header modification rules applied to requests routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
-
-#### Values
-
-- Default: None
-- Values: Object containing one or more fields that define header modification rules
- - `add`: Map of one or more key-value pairs
- - `set`: Map of one or more key-value pairs
- - `remove`: Map of one or more key-value pairs
-
-The following table describes how to configure values for request headers:
-
-| Rule | Description | Type |
-| --- | --- | --- |
-| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
-
-#### Use variable placeholders
-
-For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
-
-### `spec.splits[].responseHeaders`
-
-Specifies a set of HTTP-specific header modification rules applied to responses routed with the service split. You cannot configure request headers if the listener protocol is set to `tcp`. Refer to [Set HTTP Headers](#set-http-headers) for an example configuration.
-
-#### Values
-
-- Default: None
-- Values: Object containing one or more fields that define header modification rules
- - `add`: Map of one or more string key-value pairs
- - `set`: Map of one or more string key-value pairs
- - `remove`: Map of one or more string key-value pairs
-
-The following table describes how to configure values for response headers:
-
-| Rule | Description | Type |
-| --- | --- | --- |
-| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings |
-| `remove` | Defines an list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings |
-
-#### Use variable placeholders
-
-For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` in your configuration entry allows you to pass a value that is generated when the split occurs.
-
-
-
-
-
-## Examples
-
-The following examples demonstrate common service splitter configuration patterns for specific use cases.
+## Sample Config Entries
### Two subsets of same service
Split traffic between two subsets of the same service:
-
-
-
+
```hcl
Kind = "service-splitter"
@@ -586,9 +65,18 @@ Splits = [
]
```
-
-
-
+```yaml
+apiVersion: consul.hashicorp.com/v1alpha1
+kind: ServiceSplitter
+metadata:
+ name: web
+spec:
+ splits:
+ - weight: 90
+ serviceSubset: v1
+ - weight: 10
+ serviceSubset: v2
+```
```json
{
@@ -607,34 +95,13 @@ Splits = [
}
```
-
-
-
-
-```yaml
-apiVersion: consul.hashicorp.com/v1alpha1
-kind: ServiceSplitter
-metadata:
- name: web
-spec:
- splits:
- - weight: 90
- serviceSubset: v1
- - weight: 10
- serviceSubset: v2
-```
-
-
-
-
+
### Two different services
Split traffic between two services:
-
-
-
+
```hcl
Kind = "service-splitter"
@@ -651,9 +118,18 @@ Splits = [
]
```
-
-
-
+```yaml
+apiVersion: consul.hashicorp.com/v1alpha1
+kind: ServiceSplitter
+metadata:
+ name: web
+spec:
+ splits:
+ - weight: 50
+ # will default to service with same name as config entry ("web")
+ - weight: 50
+ service: web-rewrite
+```
```json
{
@@ -671,35 +147,14 @@ Splits = [
}
```
-
-
-
-
-```yaml
-apiVersion: consul.hashicorp.com/v1alpha1
-kind: ServiceSplitter
-metadata:
- name: web
-spec:
- splits:
- - weight: 50
- # defaults to the service with same name as the configuration entry ("web")
- - weight: 50
- service: web-rewrite
-```
-
-
-
-
+
### Set HTTP Headers
Split traffic between two subsets with extra headers added so clients can tell
which version:
-
-
-
+
```hcl
Kind = "service-splitter"
@@ -726,9 +181,24 @@ Splits = [
]
```
-
-
-
+```yaml
+apiVersion: consul.hashicorp.com/v1alpha1
+kind: ServiceSplitter
+metadata:
+ name: web
+spec:
+ splits:
+ - weight: 90
+ serviceSubset: v1
+ responseHeaders:
+ set:
+ x-web-version: v1
+ - weight: 10
+ serviceSubset: v2
+ responseHeaders:
+ set:
+ x-web-version: v2
+```
```json
{
@@ -757,31 +227,136 @@ Splits = [
}
```
-
+
+## Available Fields
+',
+ yaml: false,
+ },
+ {
+ name: 'Namespace',
+ type: `string: "default"`,
+ enterprise: true,
+ description:
+ 'Specifies the namespace to which the configuration entry will apply.',
+ yaml: false,
+ },
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description:
+ 'Specifies the admin partition to which the configuration entry will apply.',
+ yaml: false,
+ },
+ {
+ name: 'Meta',
+ type: 'map: nil',
+ description:
+ 'Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.',
+ yaml: false,
+ },
+ {
+ name: 'metadata',
+ children: [
+ {
+ name: 'name',
+ description: 'Set to the name of the service being configured.',
+ },
+ {
+ name: 'namespace',
+ description:
+ 'If running Consul Open Source, the namespace is ignored (see [Kubernetes Namespaces in Consul OSS](/consul/docs/k8s/crds#consul-oss)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/consul/docs/k8s/crds#consul-enterprise) for more details.',
+ },
+ ],
+ hcl: false,
+ },
+ {
+ name: 'Splits',
+ type: 'array',
+ description:
+ 'Defines how much traffic to send to which set of service instances during a traffic split. The sum of weights across all splits must add up to 100.',
+ children: [
+ {
+ name: 'weight',
+ type: 'float32: 0',
+ description:
+ 'A value between 0 and 100 reflecting what portion of traffic should be directed to this split. The smallest representable weight is 1/10000 or .01%',
+ },
+ {
+ name: 'Service',
+ type: 'string: ""',
+ description: 'The service to resolve instead of the default.',
+ },
+ {
+ name: 'ServiceSubset',
+ type: 'string: ""',
+ description: {
+ hcl:
+ "A named subset of the given service to resolve instead of one defined as that service's `DefaultSubset`. If empty the default subset is used.",
+ yaml:
+ "A named subset of the given service to resolve instead of one defined as that service's `defaultSubset`. If empty the default subset is used.",
+ },
+ },
+ {
+ name: 'Namespace',
+ enterprise: true,
+ type: 'string: ""',
+ description:
+ 'The namespace to resolve the service from instead of the current namespace. If empty, the current namespace is used.',
+ },
+ {
+ name: 'Partition',
+ enterprise: true,
+ type: 'string: ""',
+ description:
+ 'The admin partition to resolve the service from instead of the current partition. If empty, the current partition is used.',
+ },
+ {
+ name: 'RequestHeaders',
+ type: 'HTTPHeaderModifiers: ',
+ description: `A set of [HTTP-specific header modification rules](/consul/docs/connect/config-entries/service-router#httpheadermodifiers)
+ that will be applied to requests routed to this split.
+ This cannot be used with a \`tcp\` listener.`,
+ },
+ {
+ name: 'ResponseHeaders',
+ type: 'HTTPHeaderModifiers: ',
+ description: `A set of [HTTP-specific header modification rules](/consul/docs/connect/config-entries/service-router#httpheadermodifiers)
+ that will be applied to responses from this split.
+ This cannot be used with a \`tcp\` listener.`,
+ },
+ ],
+ },
+ ]}
+/>
-
+## ACLs
-```yaml
-apiVersion: consul.hashicorp.com/v1alpha1
-kind: ServiceSplitter
-metadata:
- name: web
-spec:
- splits:
- - weight: 90
- serviceSubset: v1
- responseHeaders:
- set:
- x-web-version: v1
- - weight: 10
- serviceSubset: v2
- responseHeaders:
- set:
- x-web-version: v2
-```
+Configuration entries may be protected by [ACLs](/consul/docs/security/acl).
+
+Reading a `service-splitter` config entry requires `service:read` on the resource.
-
+Creating, updating, or deleting a `service-splitter` config entry requires
+`service:write` on the resource and `service:read` on any other service referenced by
+name in these fields:
-
\ No newline at end of file
+- [`Splits[].Service`](#service)
diff --git a/website/content/docs/connect/proxies/envoy.mdx b/website/content/docs/connect/proxies/envoy.mdx
index b47639dc765ea..19e98a1367653 100644
--- a/website/content/docs/connect/proxies/envoy.mdx
+++ b/website/content/docs/connect/proxies/envoy.mdx
@@ -39,7 +39,6 @@ Consul supports **four major Envoy releases** at the beginning of each major Con
| Consul Version | Compatible Envoy Versions |
| ------------------- | -----------------------------------------------------------------------------------|
-| 1.15.x | 1.25.1, 1.24.2, 1.23.4, 1.22.5 |
| 1.14.x | 1.24.0, 1.23.1, 1.22.5, 1.21.5 |
| 1.13.x | 1.23.1, 1.22.5, 1.21.5, 1.20.7 |
| 1.12.x | 1.22.5, 1.21.5, 1.20.7, 1.19.5 |
@@ -53,7 +52,6 @@ Consul Dataplane is a feature introduced in Consul v1.14. Because each version o
| Consul Version | Consul Dataplane Version | Bundled Envoy Version |
| ------------------- | ------------------------ | ---------------------- |
-| 1.15.x | 1.1.x | 1.25.x |
| 1.14.x | 1.0.x | 1.24.x |
## Getting Started