Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport of [NET-10952] fix cluster dns lookup family to gracefully handle ipv6 into release/1.19.x #21720

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/21703.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
jwt-provider: change dns lookup family from the default of AUTO which would prefer ipv6 to ALL if LOGICAL_DNS is used or PREFER_IPV4 if STRICT_DNS is used to gracefully handle transitions to ipv6.
```
22 changes: 21 additions & 1 deletion agent/xds/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,12 @@ func makeJWTProviderCluster(p *structs.JWTProviderConfigEntry) (*envoy_cluster_v
return nil, err
}

discoveryType := makeJWKSDiscoveryClusterType(p.JSONWebKeySet.Remote)
lookupFamily := makeJWKSClusterDNSLookupFamilyType(discoveryType)
cluster := &envoy_cluster_v3.Cluster{
Name: makeJWKSClusterName(p.Name),
ClusterDiscoveryType: makeJWKSDiscoveryClusterType(p.JSONWebKeySet.Remote),
ClusterDiscoveryType: discoveryType,
DnsLookupFamily: lookupFamily,
LoadAssignment: &envoy_endpoint_v3.ClusterLoadAssignment{
ClusterName: makeJWKSClusterName(p.Name),
Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{
Expand Down Expand Up @@ -278,6 +281,23 @@ func makeJWKSDiscoveryClusterType(r *structs.RemoteJWKS) *envoy_cluster_v3.Clust
return ct
}

func makeJWKSClusterDNSLookupFamilyType(r *envoy_cluster_v3.Cluster_Type) envoy_cluster_v3.Cluster_DnsLookupFamily {
// When using LOGICAL_DNS we want to use the Cluster_ALL lookup family which will fetch all the ip addresses for a given hostname and then
// try to connect to each one and will create the cluster based on the first one that passes.
// When using STRICT_DNS we want to use the CLUSTER_V4_PREFERRED lookup family which will prefer
// creating clusters using ipv4 addresses if those are available.
// Otherwise we fallback to Cluser_AUTO which will use the default behavior, and will be ignored as per the documentation.
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-enum-config-cluster-v3-cluster-dnslookupfamily
switch r.Type {
case envoy_cluster_v3.Cluster_LOGICAL_DNS:
return envoy_cluster_v3.Cluster_ALL
case envoy_cluster_v3.Cluster_STRICT_DNS:
return envoy_cluster_v3.Cluster_V4_PREFERRED
default:
return envoy_cluster_v3.Cluster_AUTO
}
}

func makeJWTCertValidationContext(p *structs.JWKSCluster) *envoy_tls_v3.CertificateValidationContext {
vc := &envoy_tls_v3.CertificateValidationContext{}
if p == nil || p.TLSCertificates == nil {
Expand Down
50 changes: 50 additions & 0 deletions agent/xds/clusters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,56 @@ func TestMakeJWKSDiscoveryClusterType(t *testing.T) {
}
}

func TestMakeJWKSClusterDNSLookupFamilyType(t *testing.T) {
tests := map[string]struct {
clusterType *envoy_cluster_v3.Cluster_Type
expectedDNSLookupFamily envoy_cluster_v3.Cluster_DnsLookupFamily
}{
// strict dns and logical dns are the only ones that are different
"jwks with strict dns": {
clusterType: &envoy_cluster_v3.Cluster_Type{
Type: envoy_cluster_v3.Cluster_STRICT_DNS,
},
expectedDNSLookupFamily: envoy_cluster_v3.Cluster_V4_PREFERRED,
},
"jwks with logical dns": {
clusterType: &envoy_cluster_v3.Cluster_Type{
Type: envoy_cluster_v3.Cluster_LOGICAL_DNS,
},
expectedDNSLookupFamily: envoy_cluster_v3.Cluster_ALL,
},
// all should be auto from here down
"jwks with cluster EDS": {
clusterType: &envoy_cluster_v3.Cluster_Type{
Type: envoy_cluster_v3.Cluster_EDS,
},
expectedDNSLookupFamily: envoy_cluster_v3.Cluster_AUTO,
},
"jwks with static dns": {
clusterType: &envoy_cluster_v3.Cluster_Type{
Type: envoy_cluster_v3.Cluster_STATIC,
},
expectedDNSLookupFamily: envoy_cluster_v3.Cluster_AUTO,
},

"jwks with original dst": {
clusterType: &envoy_cluster_v3.Cluster_Type{
Type: envoy_cluster_v3.Cluster_ORIGINAL_DST,
},
expectedDNSLookupFamily: envoy_cluster_v3.Cluster_AUTO,
},
}

for name, tt := range tests {
tt := tt
t.Run(name, func(t *testing.T) {
actualDNSLookupFamily := makeJWKSClusterDNSLookupFamilyType(tt.clusterType)

require.Equal(t, tt.expectedDNSLookupFamily, actualDNSLookupFamily)
})
}
}

func TestParseJWTRemoteURL(t *testing.T) {
tests := map[string]struct {
uri string
Expand Down
Loading