Commit 0f1ea9c5 authored by Geoff Simmons's avatar Geoff Simmons

Update BackendConfig with parameters for ExternalName Services.

These correspond to properties that can be set in VMOD dynamic.
Currently we have:

dnsRetryDelay: this is set as the ttl in the VMOD. Since we get
DNS TTLs from the server, it effectively sets the retry delay
after a lookup gets negative results. More recent versions of the
VMOD have a separate parameter for this purpose, so this should be
updated soon.

domainUsageTimeout: corresponds to the domain_usage_timeout param
of the VMOD director.

firstLookupTimeout: corresponds to the first_lookup_timeout param
of the VMOD director.

resolverTimeout: set with the .set_timeout() method of the VMOD
resolver object.

resolverIdleTimeout: set with the .set_idle_timeout() method of the
VMOD resolver object.

maxDNSQueries: set with the .set_limit_outstanding_queries() method
of the VMOD resolver object.

followDNSRedirects: set with the .set_follow_redirects() method of
the VMOD resolver object.
parent 20124907
......@@ -44,6 +44,21 @@ spec:
between-bytes-timeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
dnsRetryDelay:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
domainUsageTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
firstLookupTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
resolverIdleTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
resolverTimeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
proxy-header:
type: integer
minimum: 1
......@@ -51,6 +66,12 @@ spec:
max-connections:
type: integer
minimum: 1
maxDNSQueries:
type: integer
minimum: 0
maximum: 65535
followDNSRedirects:
type: boolean
probe:
type: object
properties:
......
......@@ -45,6 +45,28 @@ spec:
initial: 1
window: 3
threshold: 2
# Configuration specific to ExternalName Services:
# - dnsRetryDelay (VCL duration): delay until a DNS lookup is retried
# after a lookup gets negative results. Default 30s
# - domainUsageTimeout (VCL duration): delay until an unused domain
# and its backends are removed. Default 2h
# - firstLookupTimeout (VCL duration): delay until a lookup is failed
# when a domain is requested the first time and there is no response
# from the name service. Default 10s
# - resolverTimeout (VCL duration): timeout for DNS lookups
# - resolverIdleTimeout (VCL duration): timeout for idle DNS connections
# (no outstanding responses and no pending queries)
# - maxDNSQueries (integer >= 0 and <= 65535): maximum number of
# outstanding DNS queries. Queries above the limit are queued.
# - followDNSRedirects (boolean): whether DNS queries follow redirects
# (CNAME and DNAME). Default true
dnsRetryDelay: 20s
domainUsageTimeout: 1h
firstLookupTimeout: 15s
resolverTimeout: 45s
resolverIdleTimeout: 5m
maxDNSQueries: 100
followDNSRedirects: true
---
apiVersion: "ingress.varnish-cache.org/v1alpha1"
kind: BackendConfig
......@@ -73,3 +95,10 @@ spec:
interval: 3s
window: 4
threshold: 3
# Configuration specific to ExternalName Services
dnsRetryDelay: 25s
domainUsageTimeout: 3h
firstLookupTimeout: 20s
resolverTimeout: 1m
resolverIdleTimeout: 10m
maxDNSQueries: 200
......@@ -438,8 +438,15 @@ type BackendConfigSpec struct {
ConnectTimeout string `json:"connect-timeout,omitempty"`
FirstByteTimeout string `json:"first-byte-timeout,omitempty"`
BetweenBytesTimeout string `json:"between-bytes-timeout,omitempty"`
DNSRetryDelay string `json:"dnsRetryDelay,omitempty"`
DomainUsageTimeout string `json:"domainUsageTimeout,omitempty"`
FirstLookupTimeout string `json:"firstLookupTimeout,omitempty"`
ResolverIdleTimeout string `json:"resolverIdleTimeout,omitempty"`
ResolverTimeout string `json:"resolverTimeout,omitempty"`
MaxConnections *int32 `json:"max-connections,omitempty"`
ProxyHeader *int32 `json:"proxy-header,omitempty"`
MaxDNSQueries *int32 `json:"maxDNSQueries,omitempty"`
FollowDNSRedirects *bool `json:"followDNSRedirects,omitempty"`
}
// DirectorType specfies the class of director to be used, see:
......
// +build !ignore_autogenerated
/*
* Copyright (c) 2019 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2020 UPLEX Nils Goroll Systemoptimierung
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
......@@ -202,6 +202,16 @@ func (in *BackendConfigSpec) DeepCopyInto(out *BackendConfigSpec) {
*out = new(int32)
**out = **in
}
if in.MaxDNSQueries != nil {
in, out := &in.MaxDNSQueries, &out.MaxDNSQueries
*out = new(int32)
**out = **in
}
if in.FollowDNSRedirects != nil {
in, out := &in.FollowDNSRedirects, &out.FollowDNSRedirects
*out = new(bool)
**out = **in
}
return
}
......
......@@ -56,6 +56,7 @@ const (
varnishSvcKey = annotationPrefix + "varnish-svc"
defACLcomparand = "client.ip"
defACLfailStatus = uint16(403)
defDNSRetryDelay = "30s"
)
func (worker *NamespaceWorker) filterVarnishIngSvcs(
......@@ -313,10 +314,12 @@ func (worker *NamespaceWorker) getVCLSvc(
svcNamespace = "default"
}
vclSvc := vcl.Service{
Name: svcNamespace + "/" + svcName,
Addresses: addrs,
ExternalName: extName,
ExternalPort: extPort,
Name: svcNamespace + "/" + svcName,
Addresses: addrs,
ExternalName: extName,
ExternalPort: extPort,
DNSRetryDelay: defDNSRetryDelay,
FollowDNSRedirects: true,
}
nsLister := worker.listers.bcfg.BackendConfigs(svcNamespace)
bcfgs, err := nsLister.List(labels.Everything())
......@@ -341,6 +344,14 @@ BCfgs:
return vclSvc, nil, nil
}
if bcfg.Spec.Director != nil {
if extName != "" {
return vclSvc, nil,
fmt.Errorf("Service %s/%s, BackendConfig "+
"%s/%s: director may not be set for "+
"an ExternalName Service",
svcNamespace, svcName,
bcfg.Namespace, bcfg.Name)
}
vclSvc.Director = &vcl.Director{
Type: vcl.GetDirectorType(
string(bcfg.Spec.Director.Type)),
......@@ -358,12 +369,25 @@ BCfgs:
vclSvc.ConnectTimeout = bcfg.Spec.ConnectTimeout
vclSvc.FirstByteTimeout = bcfg.Spec.FirstByteTimeout
vclSvc.BetweenBytesTimeout = bcfg.Spec.BetweenBytesTimeout
vclSvc.DomainUsageTimeout = bcfg.Spec.DomainUsageTimeout
vclSvc.FirstLookupTimeout = bcfg.Spec.FirstLookupTimeout
vclSvc.ResolverIdleTimeout = bcfg.Spec.ResolverIdleTimeout
vclSvc.ResolverTimeout = bcfg.Spec.ResolverTimeout
if bcfg.Spec.DNSRetryDelay != "" {
vclSvc.DNSRetryDelay = bcfg.Spec.DNSRetryDelay
}
if bcfg.Spec.MaxConnections != nil {
vclSvc.MaxConnections = uint32(*bcfg.Spec.MaxConnections)
}
if bcfg.Spec.ProxyHeader != nil {
vclSvc.ProxyHeader = uint8(*bcfg.Spec.ProxyHeader)
}
if bcfg.Spec.MaxDNSQueries != nil {
vclSvc.MaxDNSQueries = uint16(*bcfg.Spec.MaxDNSQueries)
}
if bcfg.Spec.FollowDNSRedirects != nil {
vclSvc.FollowDNSRedirects = *bcfg.Spec.FollowDNSRedirects
}
return vclSvc, bcfg, nil
}
......
......@@ -34,15 +34,19 @@ import (
)
var extWhiskeySvc = Service{
Name: "whiskey-svc",
ExternalName: "whiskey.example.com",
ExternalPort: "81",
Name: "whiskey-svc",
ExternalName: "whiskey.example.com",
ExternalPort: "81",
DNSRetryDelay: "30s",
FollowDNSRedirects: true,
}
var extVodkaSvc = Service{
Name: "vodka-svc",
ExternalName: "vodka.example.com",
ExternalPort: "8888",
Name: "vodka-svc",
ExternalName: "vodka.example.com",
ExternalPort: "8888",
DNSRetryDelay: "30s",
FollowDNSRedirects: true,
}
var barSpec = Spec{
......@@ -98,9 +102,11 @@ func TestExternalNameSvc(t *testing.T) {
}
var extTequilaSvc = Service{
Name: "tequila-svc",
ExternalName: "tequila.example.com",
ExternalPort: "88",
Name: "tequila-svc",
ExternalName: "tequila.example.com",
ExternalPort: "88",
DNSRetryDelay: "30s",
FollowDNSRedirects: true,
Probe: &Probe{
URL: "/shot/",
ExpResponse: 418,
......@@ -119,9 +125,11 @@ var extTequilaSvc = Service{
}
var extMetaxaSvc = Service{
Name: "metaxa-svc",
ExternalName: "metaxa.example.com",
ExternalPort: "8080",
Name: "metaxa-svc",
ExternalName: "metaxa.example.com",
ExternalPort: "8080",
DNSRetryDelay: "30s",
FollowDNSRedirects: true,
Probe: &Probe{
Request: []string{
"GET /the-worm/ HTTP/1.1",
......
......@@ -147,8 +147,15 @@ type Service struct {
ConnectTimeout string
FirstByteTimeout string
BetweenBytesTimeout string
DNSRetryDelay string
DomainUsageTimeout string
FirstLookupTimeout string
ResolverIdleTimeout string
ResolverTimeout string
MaxConnections uint32
MaxDNSQueries uint16
ProxyHeader uint8
FollowDNSRedirects bool
}
func (svc Service) hash(hash hash.Hash) {
......@@ -168,10 +175,19 @@ func (svc Service) hash(hash hash.Hash) {
hash.Write([]byte(svc.ConnectTimeout))
hash.Write([]byte(svc.FirstByteTimeout))
hash.Write([]byte(svc.BetweenBytesTimeout))
hash.Write([]byte(svc.DNSRetryDelay))
hash.Write([]byte(svc.DomainUsageTimeout))
hash.Write([]byte(svc.FirstLookupTimeout))
hash.Write([]byte(svc.ResolverIdleTimeout))
hash.Write([]byte(svc.ResolverTimeout))
hash.Write([]byte{byte(svc.ProxyHeader)})
maxConnBytes := make([]byte, 4)
binary.BigEndian.PutUint32(maxConnBytes, svc.MaxConnections)
hash.Write(maxConnBytes)
hashUint16(svc.MaxDNSQueries, hash)
if svc.FollowDNSRedirects {
hash.Write([]byte{1})
}
}
// interface for sorting []Service
......
......@@ -70,6 +70,9 @@ var fMap = template.FuncMap{
"dirName": func(svc Service) string {
return directorName(svc)
},
"resolverName": func(svc Service) string {
return resolverName(svc)
},
"urlMatcher": func(rule Rule) string {
return urlMatcher(rule)
},
......@@ -285,6 +288,10 @@ func directorName(svc Service) string {
return mangle(svc.Name + "_director")
}
func resolverName(svc Service) string {
return mangle(svc.Name + "_resolver")
}
func urlMatcher(rule Rule) string {
return mangle(strings.Replace(rule.Host, ".", "_", -1) + "_url")
}
......
......@@ -54,19 +54,21 @@ sub vcl_init {
vk8s_tea-svc_director.add_backend(vk8s_tea-svc_192_0_2_3
);
new vk8s_resolver = dynamic.resolver();
vk8s_resolver.set_resolution_type(STUB);
new vk8s_vodka-svc_resolver = dynamic.resolver();
vk8s_vodka-svc_resolver.set_resolution_type(STUB);
new vk8s_vodka-svc_director = dynamic.director(
ttl_from = dns,
ttl = 30s,
resolver = vk8s_resolver.use()
resolver = vk8s_vodka-svc_resolver.use()
, port = "8888"
);
new vk8s_whiskey-svc_resolver = dynamic.resolver();
vk8s_whiskey-svc_resolver.set_resolution_type(STUB);
new vk8s_whiskey-svc_director = dynamic.director(
ttl_from = dns,
ttl = 30s,
resolver = vk8s_resolver.use()
resolver = vk8s_whiskey-svc_resolver.use()
, port = "81"
);
......
......@@ -42,12 +42,12 @@ sub vcl_init {
vk8s_hosts.add("\Qmetaxa.example.edu\E(:\d+)?");
vk8s_hosts.compile();
new vk8s_resolver = dynamic.resolver();
vk8s_resolver.set_resolution_type(STUB);
new vk8s_metaxa-svc_resolver = dynamic.resolver();
vk8s_metaxa-svc_resolver.set_resolution_type(STUB);
new vk8s_metaxa-svc_director = dynamic.director(
ttl_from = dns,
ttl = 30s,
resolver = vk8s_resolver.use()
resolver = vk8s_metaxa-svc_resolver.use()
, port = "8080"
, host_header = "metaxa.example.org"
, connect_timeout = 2s
......@@ -58,10 +58,12 @@ sub vcl_init {
, probe = vk8s_metaxa-svc_probe
);
new vk8s_tequila-svc_resolver = dynamic.resolver();
vk8s_tequila-svc_resolver.set_resolution_type(STUB);
new vk8s_tequila-svc_director = dynamic.director(
ttl_from = dns,
ttl = 30s,
resolver = vk8s_resolver.use()
resolver = vk8s_tequila-svc_resolver.use()
, port = "88"
, host_header = "tequila.example.org"
, connect_timeout = 1s
......
......@@ -112,15 +112,13 @@ sub vcl_init {
{{dirName $svc}}.reconfigure();
{{- end}}
{{end}}
{{- if gt (len .ExtSvcs) 0 }}
new vk8s_resolver = dynamic.resolver();
vk8s_resolver.set_resolution_type(STUB);
{{- end}}
{{- range $name, $svc := .ExtSvcs}}
new {{resolverName $svc}} = dynamic.resolver();
{{resolverName $svc}}.set_resolution_type(STUB);
new {{dirName $svc}} = dynamic.director(
ttl_from = dns,
ttl = 30s,
resolver = vk8s_resolver.use()
ttl = {{.DNSRetryDelay}},
resolver = {{resolverName $svc}}.use()
{{- with $svc}}
{{- if .ExternalPort}}
, port = "{{.ExternalPort}}"
......@@ -137,6 +135,12 @@ sub vcl_init {
{{- if .BetweenBytesTimeout}}
, between_bytes_timeout = {{.BetweenBytesTimeout}}
{{- end}}
{{- if .DomainUsageTimeout}}
, domain_usage_timeout = {{.DomainUsageTimeout}}
{{- end}}
{{- if .FirstLookupTimeout}}
, first_lookup_timeout = {{.FirstLookupTimeout}}
{{- end}}
{{- if .ProxyHeader}}
, proxy_header = {{.ProxyHeader}}
{{- end}}
......@@ -148,6 +152,18 @@ sub vcl_init {
{{- end}}
{{- end}}
);
{{- if .ResolverIdleTimeout}}
{{resolverName $svc}}.set_idle_timeout({{.ResolverIdleTimeout}});
{{- end }}
{{- if .ResolverTimeout}}
{{resolverName $svc}}.set_timeout({{.ResolverTimeout}});
{{- end }}
{{- if .MaxDNSQueries}}
{{resolverName $svc}}.set_limit_outstanding_queries({{.MaxDNSQueries}});
{{- end }}
{{- if not .FollowDNSRedirects}}
{{resolverName $svc}}.set_follow_redirects(REDIRECTS_DO_NOT_FOLLOW);
{{- end }}
{{end}}
{{- range $rule := .Rules}}
new {{urlMatcher $rule}} = re2.set(posix_syntax=true, anchor=start);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment