mirror of https://github.com/status-im/consul.git
add partition to SNI when partition is non default (#10917)
This commit is contained in:
parent
3254308fd3
commit
09197c989c
|
@ -2,10 +2,17 @@ package connect
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
internal = "internal"
|
||||||
|
version = "v1"
|
||||||
|
internalVersion = internal + "-" + version
|
||||||
|
)
|
||||||
|
|
||||||
func UpstreamSNI(u *structs.Upstream, subset string, dc string, trustDomain string) string {
|
func UpstreamSNI(u *structs.Upstream, subset string, dc string, trustDomain string) string {
|
||||||
if u.Datacenter != "" {
|
if u.Datacenter != "" {
|
||||||
dc = u.Datacenter
|
dc = u.Datacenter
|
||||||
|
@ -14,23 +21,39 @@ func UpstreamSNI(u *structs.Upstream, subset string, dc string, trustDomain stri
|
||||||
if u.DestinationType == structs.UpstreamDestTypePreparedQuery {
|
if u.DestinationType == structs.UpstreamDestTypePreparedQuery {
|
||||||
return QuerySNI(u.DestinationName, dc, trustDomain)
|
return QuerySNI(u.DestinationName, dc, trustDomain)
|
||||||
}
|
}
|
||||||
return ServiceSNI(u.DestinationName, subset, u.DestinationNamespace, dc, trustDomain)
|
return ServiceSNI(u.DestinationName, subset, u.DestinationNamespace, u.DestinationPartition, dc, trustDomain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DatacenterSNI(dc string, trustDomain string) string {
|
func DatacenterSNI(dc string, trustDomain string) string {
|
||||||
return fmt.Sprintf("%s.internal.%s", dc, trustDomain)
|
return fmt.Sprintf("%s.internal.%s", dc, trustDomain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServiceSNI(service string, subset string, namespace string, datacenter string, trustDomain string) string {
|
func ServiceSNI(service string, subset string, namespace string, partition string, datacenter string, trustDomain string) string {
|
||||||
if namespace == "" {
|
if namespace == "" {
|
||||||
namespace = "default"
|
namespace = "default"
|
||||||
}
|
}
|
||||||
|
if partition == "" {
|
||||||
if subset == "" {
|
partition = "default"
|
||||||
return fmt.Sprintf("%s.%s.%s.internal.%s", service, namespace, datacenter, trustDomain)
|
|
||||||
} else {
|
|
||||||
return fmt.Sprintf("%s.%s.%s.%s.internal.%s", subset, service, namespace, datacenter, trustDomain)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch partition {
|
||||||
|
case "default":
|
||||||
|
if subset == "" {
|
||||||
|
return dotJoin(service, namespace, datacenter, internal, trustDomain)
|
||||||
|
} else {
|
||||||
|
return dotJoin(subset, service, namespace, datacenter, internal, trustDomain)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if subset == "" {
|
||||||
|
return dotJoin(service, namespace, partition, datacenter, internalVersion, trustDomain)
|
||||||
|
} else {
|
||||||
|
return dotJoin(subset, service, namespace, partition, datacenter, internalVersion, trustDomain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dotJoin(parts ...string) string {
|
||||||
|
return strings.Join(parts, ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
func QuerySNI(service string, datacenter string, trustDomain string) string {
|
func QuerySNI(service string, datacenter string, trustDomain string) string {
|
||||||
|
@ -38,5 +61,5 @@ func QuerySNI(service string, datacenter string, trustDomain string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TargetSNI(target *structs.DiscoveryTarget, trustDomain string) string {
|
func TargetSNI(target *structs.DiscoveryTarget, trustDomain string) string {
|
||||||
return ServiceSNI(target.Service, target.ServiceSubset, target.Namespace, target.Datacenter, trustDomain)
|
return ServiceSNI(target.Service, target.ServiceSubset, target.Namespace, target.Partition, target.Datacenter, trustDomain)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,10 @@ const (
|
||||||
testTrustDomain1 = "5fcd4b81-a2ca-405a-ac62-0fac602c1949.consul"
|
testTrustDomain1 = "5fcd4b81-a2ca-405a-ac62-0fac602c1949.consul"
|
||||||
testTrustDomain2 = "d2e1a32e-5733-47f2-a9dd-6cf271aab5b7.consul"
|
testTrustDomain2 = "d2e1a32e-5733-47f2-a9dd-6cf271aab5b7.consul"
|
||||||
|
|
||||||
testTrustDomainSuffix1 = "internal.5fcd4b81-a2ca-405a-ac62-0fac602c1949.consul"
|
testTrustDomainSuffix1 = internal + ".5fcd4b81-a2ca-405a-ac62-0fac602c1949.consul"
|
||||||
testTrustDomainSuffix2 = "internal.d2e1a32e-5733-47f2-a9dd-6cf271aab5b7.consul"
|
testTrustDomainSuffix1WithPart = internalVersion + ".5fcd4b81-a2ca-405a-ac62-0fac602c1949.consul"
|
||||||
|
testTrustDomainSuffix2 = internal + ".d2e1a32e-5733-47f2-a9dd-6cf271aab5b7.consul"
|
||||||
|
testTrustDomainSuffix2WithPart = internalVersion + ".d2e1a32e-5733-47f2-a9dd-6cf271aab5b7.consul"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUpstreamSNI(t *testing.T) {
|
func TestUpstreamSNI(t *testing.T) {
|
||||||
|
@ -101,19 +103,35 @@ func TestDatacenterSNI(t *testing.T) {
|
||||||
func TestServiceSNI(t *testing.T) {
|
func TestServiceSNI(t *testing.T) {
|
||||||
// empty namespace, empty subset
|
// empty namespace, empty subset
|
||||||
require.Equal(t, "api.default.foo."+testTrustDomainSuffix1,
|
require.Equal(t, "api.default.foo."+testTrustDomainSuffix1,
|
||||||
ServiceSNI("api", "", "", "foo", testTrustDomain1))
|
ServiceSNI("api", "", "", "", "foo", testTrustDomain1))
|
||||||
|
|
||||||
// set namespace, empty subset
|
// set namespace, empty subset
|
||||||
require.Equal(t, "api.neighbor.foo."+testTrustDomainSuffix2,
|
require.Equal(t, "api.neighbor.foo."+testTrustDomainSuffix2,
|
||||||
ServiceSNI("api", "", "neighbor", "foo", testTrustDomain2))
|
ServiceSNI("api", "", "neighbor", "", "foo", testTrustDomain2))
|
||||||
|
|
||||||
// empty namespace, set subset
|
// empty namespace, set subset
|
||||||
require.Equal(t, "v2.api.default.foo."+testTrustDomainSuffix1,
|
require.Equal(t, "v2.api.default.foo."+testTrustDomainSuffix1,
|
||||||
ServiceSNI("api", "v2", "", "foo", testTrustDomain1))
|
ServiceSNI("api", "v2", "", "", "foo", testTrustDomain1))
|
||||||
|
|
||||||
// set namespace, set subset
|
// set namespace, set subset
|
||||||
require.Equal(t, "canary.api.neighbor.foo."+testTrustDomainSuffix2,
|
require.Equal(t, "canary.api.neighbor.foo."+testTrustDomainSuffix2,
|
||||||
ServiceSNI("api", "canary", "neighbor", "foo", testTrustDomain2))
|
ServiceSNI("api", "canary", "neighbor", "", "foo", testTrustDomain2))
|
||||||
|
|
||||||
|
// empty namespace, empty subset, set partition
|
||||||
|
require.Equal(t, "api.default.part1.foo."+testTrustDomainSuffix1WithPart,
|
||||||
|
ServiceSNI("api", "", "", "part1", "foo", testTrustDomain1))
|
||||||
|
|
||||||
|
// set namespace, empty subset, set partition
|
||||||
|
require.Equal(t, "api.neighbor.part1.foo."+testTrustDomainSuffix2WithPart,
|
||||||
|
ServiceSNI("api", "", "neighbor", "part1", "foo", testTrustDomain2))
|
||||||
|
|
||||||
|
// empty namespace, set subset, set partition
|
||||||
|
require.Equal(t, "v2.api.default.part1.foo."+testTrustDomainSuffix1WithPart,
|
||||||
|
ServiceSNI("api", "v2", "", "part1", "foo", testTrustDomain1))
|
||||||
|
|
||||||
|
// set namespace, set subset, set partition
|
||||||
|
require.Equal(t, "canary.api.neighbor.part1.foo."+testTrustDomainSuffix2WithPart,
|
||||||
|
ServiceSNI("api", "canary", "neighbor", "part1", "foo", testTrustDomain2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQuerySNI(t *testing.T) {
|
func TestQuerySNI(t *testing.T) {
|
||||||
|
|
|
@ -1868,7 +1868,7 @@ func TestState_WatchesAndUpdates(t *testing.T) {
|
||||||
// should not be used in DC-local calls.
|
// should not be used in DC-local calls.
|
||||||
require.Equal(t, snap.ConnectProxy.PassthroughUpstreams, map[string]ServicePassthroughAddrs{
|
require.Equal(t, snap.ConnectProxy.PassthroughUpstreams, map[string]ServicePassthroughAddrs{
|
||||||
db.String(): {
|
db.String(): {
|
||||||
SNI: connect.ServiceSNI("db", "", structs.IntentionDefaultNamespace, snap.Datacenter, snap.Roots.TrustDomain),
|
SNI: connect.ServiceSNI("db", "", structs.IntentionDefaultNamespace, "", snap.Datacenter, snap.Roots.TrustDomain),
|
||||||
SpiffeID: connect.SpiffeIDService{
|
SpiffeID: connect.SpiffeIDService{
|
||||||
Host: snap.Roots.TrustDomain,
|
Host: snap.Roots.TrustDomain,
|
||||||
Namespace: db.NamespaceOrDefault(),
|
Namespace: db.NamespaceOrDefault(),
|
||||||
|
|
|
@ -87,12 +87,7 @@ func (s *handlerUpstreams) handleUpdateUpstreams(ctx context.Context, u cache.Up
|
||||||
svc.Name = dst
|
svc.Name = dst
|
||||||
}
|
}
|
||||||
|
|
||||||
sni := connect.ServiceSNI(
|
sni := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), svc.PartitionOrDefault(), snap.Datacenter, snap.Roots.TrustDomain)
|
||||||
svc.Name,
|
|
||||||
"",
|
|
||||||
svc.NamespaceOrDefault(),
|
|
||||||
snap.Datacenter,
|
|
||||||
snap.Roots.TrustDomain)
|
|
||||||
|
|
||||||
spiffeID := connect.SpiffeIDService{
|
spiffeID := connect.SpiffeIDService{
|
||||||
Host: snap.Roots.TrustDomain,
|
Host: snap.Roots.TrustDomain,
|
||||||
|
|
|
@ -211,6 +211,7 @@ type DiscoveryTarget struct {
|
||||||
Service string `json:",omitempty"`
|
Service string `json:",omitempty"`
|
||||||
ServiceSubset string `json:",omitempty"`
|
ServiceSubset string `json:",omitempty"`
|
||||||
Namespace string `json:",omitempty"`
|
Namespace string `json:",omitempty"`
|
||||||
|
Partition string `json:",omitempty"`
|
||||||
Datacenter string `json:",omitempty"`
|
Datacenter string `json:",omitempty"`
|
||||||
|
|
||||||
MeshGateway MeshGatewayConfig `json:",omitempty"`
|
MeshGateway MeshGatewayConfig `json:",omitempty"`
|
||||||
|
|
|
@ -306,7 +306,7 @@ func (s *ResourceGenerator) makeGatewayServiceClusters(
|
||||||
clusters := make([]proto.Message, 0, len(services))
|
clusters := make([]proto.Message, 0, len(services))
|
||||||
|
|
||||||
for svc := range services {
|
for svc := range services {
|
||||||
clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
resolver, hasResolver := resolvers[svc]
|
resolver, hasResolver := resolvers[svc]
|
||||||
|
|
||||||
var loadBalancer *structs.LoadBalancer
|
var loadBalancer *structs.LoadBalancer
|
||||||
|
@ -345,7 +345,7 @@ func (s *ResourceGenerator) makeGatewayServiceClusters(
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := gatewayClusterOpts{
|
opts := gatewayClusterOpts{
|
||||||
name: connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain),
|
name: connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain),
|
||||||
hostnameEndpoints: subsetHostnameEndpoints,
|
hostnameEndpoints: subsetHostnameEndpoints,
|
||||||
onlyPassing: subset.OnlyPassing,
|
onlyPassing: subset.OnlyPassing,
|
||||||
connectTimeout: resolver.ConnectTimeout,
|
connectTimeout: resolver.ConnectTimeout,
|
||||||
|
|
|
@ -246,7 +246,7 @@ func (s *ResourceGenerator) endpointsFromServicesAndResolvers(
|
||||||
|
|
||||||
// now generate the load assignment for all subsets
|
// now generate the load assignment for all subsets
|
||||||
for subsetName, groups := range clusterEndpoints {
|
for subsetName, groups := range clusterEndpoints {
|
||||||
clusterName := connect.ServiceSNI(svc.Name, subsetName, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName := connect.ServiceSNI(svc.Name, subsetName, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
la := makeLoadAssignment(
|
la := makeLoadAssignment(
|
||||||
clusterName,
|
clusterName,
|
||||||
groups,
|
groups,
|
||||||
|
|
|
@ -1013,7 +1013,7 @@ func (s *ResourceGenerator) makeTerminatingGatewayListener(
|
||||||
// Make a FilterChain for each linked service
|
// Make a FilterChain for each linked service
|
||||||
// Match on the cluster name,
|
// Match on the cluster name,
|
||||||
for _, svc := range cfgSnap.TerminatingGateway.ValidServices() {
|
for _, svc := range cfgSnap.TerminatingGateway.ValidServices() {
|
||||||
clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
|
|
||||||
// Resolvers are optional.
|
// Resolvers are optional.
|
||||||
resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc]
|
resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc]
|
||||||
|
@ -1048,7 +1048,7 @@ func (s *ResourceGenerator) makeTerminatingGatewayListener(
|
||||||
if hasResolver {
|
if hasResolver {
|
||||||
// generate 1 filter chain for each service subset
|
// generate 1 filter chain for each service subset
|
||||||
for subsetName := range resolver.Subsets {
|
for subsetName := range resolver.Subsets {
|
||||||
subsetClusterName := connect.ServiceSNI(svc.Name, subsetName, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
subsetClusterName := connect.ServiceSNI(svc.Name, subsetName, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
|
|
||||||
subsetClusterChain, err := s.makeFilterChainTerminatingGateway(
|
subsetClusterChain, err := s.makeFilterChainTerminatingGateway(
|
||||||
cfgSnap,
|
cfgSnap,
|
||||||
|
|
|
@ -77,7 +77,7 @@ func (s *ResourceGenerator) routesFromSnapshotTerminatingGateway(cfgSnap *proxyc
|
||||||
|
|
||||||
var resources []proto.Message
|
var resources []proto.Message
|
||||||
for _, svc := range cfgSnap.TerminatingGateway.ValidServices() {
|
for _, svc := range cfgSnap.TerminatingGateway.ValidServices() {
|
||||||
clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc]
|
resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc]
|
||||||
|
|
||||||
svcConfig := cfgSnap.TerminatingGateway.ServiceConfigs[svc]
|
svcConfig := cfgSnap.TerminatingGateway.ServiceConfigs[svc]
|
||||||
|
@ -109,7 +109,7 @@ func (s *ResourceGenerator) routesFromSnapshotTerminatingGateway(cfgSnap *proxyc
|
||||||
|
|
||||||
// If there is a service-resolver for this service then also setup routes for each subset
|
// If there is a service-resolver for this service then also setup routes for each subset
|
||||||
for name := range resolver.Subsets {
|
for name := range resolver.Subsets {
|
||||||
clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
|
||||||
route, err := makeNamedDefaultRouteWithLB(clusterName, lb, true)
|
route, err := makeNamedDefaultRouteWithLB(clusterName, lb, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Logger.Error("failed to make route", "cluster", clusterName, "error", err)
|
s.Logger.Error("failed to make route", "cluster", clusterName, "error", err)
|
||||||
|
|
Loading…
Reference in New Issue