Skip to content

Commit

Permalink
Merge pull request #3503 from renuka-fernando/choreo-dns-resolution-o…
Browse files Browse the repository at this point in the history
…ptions

Make typed_dns_resolver_config configurable in Envoy Cluster configuration
  • Loading branch information
renuka-fernando authored Mar 27, 2024
2 parents ee657c6 + 14bc3b5 commit 10e5e6f
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 3 deletions.
10 changes: 10 additions & 0 deletions adapter/config/default_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ var defaultConfig = &Config{
DNS: upstreamDNS{
DNSRefreshRate: 5000,
RespectDNSTtl: false,
DNSResolver: dnsResolverConfig{
ResolverType: "",
CAres: cAres{
Resolvers: []socketAddress{},
UseResolversAsFallback: false,
FilterUnroutableFamilies: false,
UseTCPForDNSLookups: false,
NoDefaultSearchDomain: false,
},
},
},
},
Connection: connection{
Expand Down
10 changes: 10 additions & 0 deletions adapter/config/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ func ReadConfigs() (*Config, error) {
pkgconf.ResolveConfigEnvValues(reflect.ValueOf(&(adapterConfig.GlobalAdapter)).Elem(), "GlobalAdapter", true)
pkgconf.ResolveConfigEnvValues(reflect.ValueOf(&(adapterConfig.Enforcer)).Elem(), "Enforcer", false)
pkgconf.ResolveConfigEnvValues(reflect.ValueOf(&(adapterConfig.Analytics)).Elem(), "Analytics", false)

err = adapterConfig.validateConfig()
if err != nil {
logger.Fatal("Error parsing the configuration: ", err)
return
}
})
return adapterConfig, e
}
Expand Down Expand Up @@ -242,6 +248,10 @@ func (config *Config) resolveJWTGeneratorConfig() error {
return nil
}

func (config *Config) validateConfig() error {
return config.Envoy.Upstream.DNS.DNSResolver.ResolverType.isValid()
}

func printDeprecatedWarningLog(deprecatedTerm, currentTerm string) {
logger.Warnf("%s is deprecated. Use %s instead", deprecatedTerm, currentTerm)
}
38 changes: 38 additions & 0 deletions adapter/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package config

import (
"fmt"
"sync"
"time"
)
Expand Down Expand Up @@ -266,6 +267,43 @@ type upstreamHealth struct {
type upstreamDNS struct {
DNSRefreshRate int32
RespectDNSTtl bool
DNSResolver dnsResolverConfig `toml:"DNSResolver"`
}

type dnsResolverConfig struct {
ResolverType dnsResolverType
CAres cAres
}

type dnsResolverType string

const (
// DNSResolverCAres is the c-ares DNS resolver type
DNSResolverCAres dnsResolverType = "c-ares"
)

func (r dnsResolverType) isValid() error {
switch r {
case DNSResolverCAres: // if required we can include DNS_RESOLVER_APPLE here
return nil
case "": // for Envoy default settings
return nil
}
return fmt.Errorf("invalid DNS resolver type: %q, supported types [%q]", r, DNSResolverCAres)
}

type cAres struct {
Resolvers []socketAddress
UseResolversAsFallback bool
FilterUnroutableFamilies bool
UseTCPForDNSLookups bool
NoDefaultSearchDomain bool
}

type socketAddress struct {
Protocol string
Address string
Port uint32
}

type upstreamRetry struct {
Expand Down
76 changes: 76 additions & 0 deletions adapter/internal/oasparser/envoyconf/dns_resolver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
*
* 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 envoyconf

import (
"fmt"

corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
caresv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/network/dns_resolver/cares/v3"
"github.com/wso2/product-microgateway/adapter/config"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
)

func getDNSResolverConf() (*corev3.TypedExtensionConfig, error) {
conf, _ := config.ReadConfigs()
var dnsResolverConf proto.Message

switch conf.Envoy.Upstream.DNS.DNSResolver.ResolverType {
case "": // Use Envoy default settings
return nil, nil
case config.DNSResolverCAres:
resolvers := []*corev3.Address{}
for _, resolver := range conf.Envoy.Upstream.DNS.DNSResolver.CAres.Resolvers {
protocol := corev3.SocketAddress_Protocol_value[resolver.Protocol]
resolvers = append(resolvers, &corev3.Address{
Address: &corev3.Address_SocketAddress{
SocketAddress: &corev3.SocketAddress{
Protocol: corev3.SocketAddress_Protocol(protocol),
Address: resolver.Address,
PortSpecifier: &corev3.SocketAddress_PortValue{
PortValue: resolver.Port,
},
},
},
})
}

dnsResolverConf = &caresv3.CaresDnsResolverConfig{
Resolvers: resolvers,
UseResolversAsFallback: conf.Envoy.Upstream.DNS.DNSResolver.CAres.UseResolversAsFallback,
FilterUnroutableFamilies: conf.Envoy.Upstream.DNS.DNSResolver.CAres.FilterUnroutableFamilies,
DnsResolverOptions: &corev3.DnsResolverOptions{
UseTcpForDnsLookups: conf.Envoy.Upstream.DNS.DNSResolver.CAres.UseTCPForDNSLookups,
NoDefaultSearchDomain: conf.Envoy.Upstream.DNS.DNSResolver.CAres.NoDefaultSearchDomain,
},
}
// case config.DNS_RESOLVER_APPLE: // If required we can support other resolvers here
default:
return nil, fmt.Errorf("unsupported DNS resolver type: %s", conf.Envoy.Upstream.DNS.DNSResolver.ResolverType)
}

dnsResolverConfPbAny, err := anypb.New(dnsResolverConf)
if err != nil {
return nil, err
}

return &corev3.TypedExtensionConfig{
Name: "Upstream DNS resolver",
TypedConfig: dnsResolverConfPbAny,
}, nil
}
6 changes: 6 additions & 0 deletions adapter/internal/oasparser/envoyconf/routes_with_clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,11 @@ func processEndpoints(clusterName string, clusterDetails *model.EndpointCluster,
}
conf, _ := config.ReadConfigs()

dnsResolverConf, err := getDNSResolverConf()
if err != nil {
return nil, nil, err
}

cluster := clusterv3.Cluster{
Name: clusterName,
ConnectTimeout: ptypes.DurationProto(timeout * time.Second),
Expand All @@ -576,6 +581,7 @@ func processEndpoints(clusterName string, clusterDetails *model.EndpointCluster,
TransportSocketMatches: transportSocketMatches,
DnsRefreshRate: durationpb.New(time.Duration(conf.Envoy.Upstream.DNS.DNSRefreshRate) * time.Millisecond),
RespectDnsTtl: conf.Envoy.Upstream.DNS.RespectDNSTtl,
TypedDnsResolverConfig: dnsResolverConf,
}

if len(clusterDetails.Endpoints) > 1 {
Expand Down
24 changes: 21 additions & 3 deletions resources/conf/config.toml.template
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,30 @@ retainKeys = ["self_validate_jwt", "issuer", "claim_mappings", "consumer_key_cla
# Disable SSL verification
disableSslVerification = false

[router.upstream.dns]
# DNS refresh rate in miliseconds
[router.upstream.dNS]
# DNS refresh rate in milliseconds
dNSRefreshRate = 5000
# set cluster’s DNS refresh rate to resource record’s TTL which comes from DNS resolution
respectDNSTtl = false


[router.upstream.dNS.DNSResolver]
# DNS resolver type. Available options: "c-ares"
resolverType = "c-ares"
[router.upstream.dNS.DNSResolver.cAres]
# Use the system DNS resolver as a fallback when the c-ares resolver fails. If false the resolvers listed in the resolvers list will override the default system resolvers.
useResolversAsFallback = false
# If there are no available network interfaces for a given IP family, filter those addresses from the results
filterUnroutableFamilies = false
# Use TCP for all DNS queries instead of the default protocol UDP.
useTCPForDNSLookups = false
# Do not use the default search domains; only query hostnames as-is or as aliases.
noDefaultSearchDomain = false
[[router.upstream.dNS.DNSResolver.cAres.resolvers]]
# Available options: "UDP", "TCP"
protocol = "TCP"
address = "0.0.0.0"
port = 53

# health configs for upstream clusters
[router.upstream.health]
# time in seconds to wait for a health check response
Expand Down

0 comments on commit 10e5e6f

Please sign in to comment.