Commit d714e1bb authored by Geoff Simmons's avatar Geoff Simmons

Add the nameTtl object to the BackendConfig CRD.

Its two fields are mapped directly to the ttl and ttl_from parameters
of VMOD dynamic.
parent dd639a1f
......@@ -45,6 +45,19 @@ spec:
between-bytes-timeout:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
nameTtl:
type: object
properties:
ttl:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
from:
type: string
enum:
- cfg
- dns
- min
- max
dnsRetryDelay:
type: string
pattern: '^\d+(\.\d+)?(ms|[smhdwy])$'
......
......@@ -23,7 +23,9 @@ apps:
threshold: 3
initial: 3
# Configuration specific to ExternalName Services
dnsRetryDelay: 25s
nameTtl:
ttl: 1s
from: cfg
domainUsageTimeout: 3h
firstLookupTimeout: 20s
resolverTimeout: 1m
......@@ -81,7 +83,9 @@ apps:
# outstanding DNS queries. Queries above the limit are queued.
# - followDNSRedirects (boolean): whether DNS queries follow redirects
# (CNAME and DNAME). Default true
dnsRetryDelay: 20s
nameTtl:
ttl: 1s
from: min
domainUsageTimeout: 1h
firstLookupTimeout: 15s
resolverTimeout: 45s
......
......@@ -8,6 +8,9 @@ apps:
tls:
verify: false
authority: caffeine.org
nameTtl:
ttl: 1s
from: min
coffee:
image: uplex/https-echo
......
......@@ -12,4 +12,8 @@ kubectl port-forward svc/varnish-ingress ${LOCALPORT}:80 >/dev/null &
trap 'kill $(jobs -p)' EXIT
wait_for_port ${LOCALPORT}
# Give VMOD dynamic and DNS time to determine the IP address of the
# ExternalName Service.
sleep 10
varnishtest ${TESTOPTS} -Dlocalport=${LOCALPORT} cafe.vtc
......@@ -450,6 +450,7 @@ type BackendConfigSpec struct {
Probe *ProbeSpec `json:"probe,omitempty"`
Director *DirectorSpec `json:"director,omitempty"`
TLS *TLSSpec `json:"tls,omitempty"`
NameTTL *NameTTLSpec `json:"nameTtl,omitempty"`
HostHeader string `json:"host-header,omitempty"`
ConnectTimeout string `json:"connect-timeout,omitempty"`
FirstByteTimeout string `json:"first-byte-timeout,omitempty"`
......@@ -500,6 +501,30 @@ type TLSSpec struct {
CASecret string `json:"caSecret,omitempty"`
}
// NameTTLFromType is a enumeration of the ways that the name TTL
// specified in the BackendConfig can be evaluated with respect to DNS
// TTL.
type NameTTLFromType string
const (
// FromCfg to use the TTL from the BackendConfig only (or the
// default)
FromCfg NameTTLFromType = "cfg"
// FromDNS to use the TTL from DNS only
FromDNS = "dns"
// FromMax to use the maximum of DNS TTL and the configured TTL
FromMax = "max"
// FromMin to use the minimum of DNS TTL and the configured TTL
FromMin = "min"
)
// NameTTLSpec corresponds to spec.nameTtl in a BackendConfig, and
// configures the TTL for name lookups.
type NameTTLSpec struct {
TTL *string `json:"ttl,omitempty"`
From NameTTLFromType `json:"from,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// BackendConfigList is a list of BackendConfig Custom Resources.
......
......@@ -198,6 +198,11 @@ func (in *BackendConfigSpec) DeepCopyInto(out *BackendConfigSpec) {
*out = new(TLSSpec)
(*in).DeepCopyInto(*out)
}
if in.NameTTL != nil {
in, out := &in.NameTTL, &out.NameTTL
*out = new(NameTTLSpec)
(*in).DeepCopyInto(*out)
}
if in.MaxConnections != nil {
in, out := &in.MaxConnections, &out.MaxConnections
*out = new(int32)
......@@ -315,6 +320,27 @@ func (in *MatchFlagsType) DeepCopy() *MatchFlagsType {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NameTTLSpec) DeepCopyInto(out *NameTTLSpec) {
*out = *in
if in.TTL != nil {
in, out := &in.TTL, &out.TTL
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NameTTLSpec.
func (in *NameTTLSpec) DeepCopy() *NameTTLSpec {
if in == nil {
return nil
}
out := new(NameTTLSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProbeSpec) DeepCopyInto(out *ProbeSpec) {
*out = *in
......
......@@ -58,7 +58,6 @@ const (
varnishSvcKey = annotationPrefix + "varnish-svc"
defACLcomparand = "client.ip"
defACLfailStatus = uint16(403)
defDNSRetryDelay = "30s"
defMax2ndTTL = "5m"
defStickTblSz = 128
defMaxConn = 2000
......@@ -352,7 +351,6 @@ func (worker *NamespaceWorker) getVCLSvc(
Addresses: addrs,
ExternalName: extName,
ExternalPort: extPort,
DNSRetryDelay: defDNSRetryDelay,
FollowDNSRedirects: true,
}
nsLister := worker.listers.bcfg.BackendConfigs(svcNamespace)
......@@ -428,6 +426,22 @@ BCfgs:
if bcfg.Spec.FollowDNSRedirects != nil {
vclSvc.FollowDNSRedirects = *bcfg.Spec.FollowDNSRedirects
}
if bcfg.Spec.NameTTL != nil {
vclSvc.NameTTL = &vcl.NameTTLSpec{}
if bcfg.Spec.NameTTL.TTL != nil {
vclSvc.NameTTL.TTL = *bcfg.Spec.NameTTL.TTL
}
switch bcfg.Spec.NameTTL.From {
case vcr_v1alpha1.FromCfg:
vclSvc.NameTTL.From = vcl.FromCfg
case vcr_v1alpha1.FromDNS:
vclSvc.NameTTL.From = vcl.FromDNS
case vcr_v1alpha1.FromMin:
vclSvc.NameTTL.From = vcl.FromMin
case vcr_v1alpha1.FromMax:
vclSvc.NameTTL.From = vcl.FromMax
}
}
var onload *haproxy.OnloadSpec
if bcfg.Spec.TLS != nil {
......
......@@ -84,9 +84,13 @@ 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",
NameTTL: &NameTTLSpec{
TTL: "2h",
From: FromCfg,
},
DNSRetryDelay: "30s",
FollowDNSRedirects: true,
Probe: &Probe{
......@@ -107,9 +111,12 @@ var extTequilaSvc = Service{
}
var extMetaxaSvc = Service{
Name: "metaxa-svc",
ExternalName: "metaxa.example.com",
ExternalPort: "8080",
Name: "metaxa-svc",
ExternalName: "metaxa.example.com",
ExternalPort: "8080",
NameTTL: &NameTTLSpec{
From: FromMax,
},
DNSRetryDelay: "30s",
FollowDNSRedirects: true,
Probe: &Probe{
......
......@@ -146,6 +146,46 @@ func (dir Director) hash(hash hash.Hash) {
hash.Write([]byte{byte(dir.Type)})
}
// NameTTLFrom is a enumeration of the ways that the name TTL that was
// specified in the BackendConfig can be evaluated with respect to DNS
// TTL. This value is mapped directly to the ttl_from parameter for
// VMOD dynamic.
type NameTTLFrom uint8
const (
// FromCfg corresponds to the enum value cfg in VMOD dynamic.
FromCfg NameTTLFrom = iota
// FromDNS corresponds to enum dns in VMOD dynamic
FromDNS
// FromMin corresponds to enum min in VMOD dynamic.
FromMin
// FromMax corresponds to enum max in VMOD dynamic.
FromMax
)
func (from NameTTLFrom) String() string {
switch from {
case FromCfg:
return "cfg"
case FromDNS:
return "dns"
case FromMin:
return "min"
case FromMax:
return "max"
default:
return "__INVALID_TTL_FROM__"
}
}
// NameTTLSpec encapsulates the TTL configuration used for VMOD
// dynamic. Its fields are mapped directly to the ttl and ttl_from
// paramater of the VMOD.
type NameTTLSpec struct {
TTL string
From NameTTLFrom
}
// Service represents either a backend Service (Endpoints to which
// requests are routed) or a Varnish Service (with addresses for the
// admin ports).
......@@ -154,6 +194,7 @@ type Service struct {
Addresses []Address
Probe *Probe
Director *Director
NameTTL *NameTTLSpec
Authority *string
ExternalName string
ExternalPort string
......@@ -187,6 +228,10 @@ func (svc Service) hash(hash hash.Hash) {
if svc.Authority != nil {
hash.Write([]byte(*svc.Authority))
}
if svc.NameTTL != nil {
hash.Write([]byte(svc.NameTTL.TTL))
hash.Write([]byte{byte(svc.NameTTL.From)})
}
hash.Write([]byte(svc.ExternalName))
hash.Write([]byte(svc.ExternalPort))
hash.Write([]byte(svc.HostHeader))
......
......@@ -53,18 +53,18 @@ sub vcl_init {
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_vodka-svc_resolver.use()
, ttl_from = dns
, retry_after = 30s
, 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_whiskey-svc_resolver.use()
, ttl_from = dns
, retry_after = 30s
, port = "81"
);
......
......@@ -41,9 +41,9 @@ sub vcl_init {
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_metaxa-svc_resolver.use()
, ttl_from = max
, retry_after = 30s
, port = "8080"
, host_header = "metaxa.example.org"
, connect_timeout = 2s
......@@ -57,9 +57,9 @@ sub vcl_init {
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_tequila-svc_resolver.use()
, ttl = 2h
, retry_after = 30s
, port = "88"
, host_header = "tequila.example.org"
, connect_timeout = 1s
......
......@@ -164,9 +164,9 @@ sub vcl_init {
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_metaxa-svc_resolver.use()
, ttl_from = max
, retry_after = 30s
, port = "8080"
, host_header = "metaxa.example.org"
, connect_timeout = 2s
......@@ -180,9 +180,9 @@ sub vcl_init {
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_tequila-svc_resolver.use()
, ttl = 2h
, retry_after = 30s
, port = "88"
, host_header = "tequila.example.org"
, connect_timeout = 1s
......
......@@ -156,10 +156,21 @@ sub vcl_init {
new {{resolverName $svc}} = dynamic.resolver();
{{resolverName $svc}}.set_resolution_type(STUB);
new {{dirName $svc}} = dynamic.director(
ttl_from = dns,
ttl = {{.DNSRetryDelay}},
resolver = {{resolverName $svc}}.use()
{{- with $svc}}
{{- if .NameTTL }}
{{- if .NameTTL.TTL }}
, ttl = {{ .NameTTL.TTL }}
{{- end }}
{{- if .NameTTL.From }}
, ttl_from = {{ .NameTTL.From }}
{{- end }}
{{- else }}
, ttl_from = dns
{{- end }}
{{- if .DNSRetryDelay }}
, retry_after = {{ .DNSRetryDelay }}
{{- end }}
{{- if .ExternalPort}}
, port = "{{.ExternalPort}}"
{{- end}}
......
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