mw/kubernetes: add configurable TTL (#995)
* mw/kubernetes: add configurable TTL Add ttl option to kubernetes. This defaults to 5s but allows configuration to go up to 3600. Configure the tests so that a few actually check for the 5s, while the rest use the TTL of 303 which is ignored by the checking code. Fixes #935 * fix tests * and more
This commit is contained in:
parent
01f6e8cba5
commit
4049ed4f4b
6 changed files with 90 additions and 27 deletions
|
@ -28,6 +28,7 @@ kubernetes [ZONES...] {
|
||||||
labels EXPRESSION
|
labels EXPRESSION
|
||||||
pods POD-MODE
|
pods POD-MODE
|
||||||
upstream ADDRESS...
|
upstream ADDRESS...
|
||||||
|
ttl TTL
|
||||||
fallthrough
|
fallthrough
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -62,6 +63,8 @@ kubernetes [ZONES...] {
|
||||||
* `upstream` **ADDRESS [ADDRESS...]** defines the upstream resolvers used for resolving services
|
* `upstream` **ADDRESS [ADDRESS...]** defines the upstream resolvers used for resolving services
|
||||||
that point to external hosts (External Services). **ADDRESS** can be an ip, an ip:port, or a path
|
that point to external hosts (External Services). **ADDRESS** can be an ip, an ip:port, or a path
|
||||||
to a file structured like resolv.conf.
|
to a file structured like resolv.conf.
|
||||||
|
* `ttl` allows you to set a custom TTL for responses. The default (and allowed minimum) is to use
|
||||||
|
5 seconds, the maximum is capped at 3600 seconds.
|
||||||
* `fallthrough` If a query for a record in the cluster zone results in NXDOMAIN, normally that is
|
* `fallthrough` If a query for a record in the cluster zone results in NXDOMAIN, normally that is
|
||||||
what the response will be. However, if you specify this option, the query will instead be passed
|
what the response will be. However, if you specify this option, the query will instead be passed
|
||||||
on down the middleware chain, which can include another middleware to handle the query.
|
on down the middleware chain, which can include another middleware to handle the query.
|
||||||
|
|
|
@ -16,33 +16,33 @@ var dnsTestCases = map[string](test.Case){
|
||||||
Qname: "svc1.testns.svc.cluster.local.", Qtype: dns.TypeA,
|
Qname: "svc1.testns.svc.cluster.local.", Qtype: dns.TypeA,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.A("svc1.testns.svc.cluster.local. 0 IN A 10.0.0.1"),
|
test.A("svc1.testns.svc.cluster.local. 5 IN A 10.0.0.1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"A Service (wildcard)": {
|
"A Service (wildcard)": {
|
||||||
Qname: "svc1.*.svc.cluster.local.", Qtype: dns.TypeA,
|
Qname: "svc1.*.svc.cluster.local.", Qtype: dns.TypeA,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.A("svc1.*.svc.cluster.local. 0 IN A 10.0.0.1"),
|
test.A("svc1.*.svc.cluster.local. 5 IN A 10.0.0.1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"SRV Service (wildcard)": {
|
"SRV Service (wildcard)": {
|
||||||
Qname: "svc1.*.svc.cluster.local.", Qtype: dns.TypeSRV,
|
Qname: "svc1.*.svc.cluster.local.", Qtype: dns.TypeSRV,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{test.SRV("svc1.*.svc.cluster.local. 0 IN SRV 0 100 80 svc1.testns.svc.cluster.local.")},
|
Answer: []dns.RR{test.SRV("svc1.*.svc.cluster.local. 303 IN SRV 0 100 80 svc1.testns.svc.cluster.local.")},
|
||||||
Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local. 0 IN A 10.0.0.1")},
|
Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local. 303 IN A 10.0.0.1")},
|
||||||
},
|
},
|
||||||
"SRV Service (wildcards)": {
|
"SRV Service (wildcards)": {
|
||||||
Qname: "*.any.svc1.*.svc.cluster.local.", Qtype: dns.TypeSRV,
|
Qname: "*.any.svc1.*.svc.cluster.local.", Qtype: dns.TypeSRV,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{test.SRV("*.any.svc1.*.svc.cluster.local. 0 IN SRV 0 100 80 svc1.testns.svc.cluster.local.")},
|
Answer: []dns.RR{test.SRV("*.any.svc1.*.svc.cluster.local. 303 IN SRV 0 100 80 svc1.testns.svc.cluster.local.")},
|
||||||
Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local. 0 IN A 10.0.0.1")},
|
Extra: []dns.RR{test.A("svc1.testns.svc.cluster.local. 303 IN A 10.0.0.1")},
|
||||||
},
|
},
|
||||||
"A Service (wildcards)": {
|
"A Service (wildcards)": {
|
||||||
Qname: "*.any.svc1.*.svc.cluster.local.", Qtype: dns.TypeA,
|
Qname: "*.any.svc1.*.svc.cluster.local.", Qtype: dns.TypeA,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.A("*.any.svc1.*.svc.cluster.local. 0 IN A 10.0.0.1"),
|
test.A("*.any.svc1.*.svc.cluster.local. 303 IN A 10.0.0.1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"SRV Service Not udp/tcp": {
|
"SRV Service Not udp/tcp": {
|
||||||
|
@ -56,37 +56,37 @@ var dnsTestCases = map[string](test.Case){
|
||||||
Qname: "_http._tcp.svc1.testns.svc.cluster.local.", Qtype: dns.TypeSRV,
|
Qname: "_http._tcp.svc1.testns.svc.cluster.local.", Qtype: dns.TypeSRV,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.SRV("_http._tcp.svc1.testns.svc.cluster.local. 0 IN SRV 0 100 80 svc1.testns.svc.cluster.local."),
|
test.SRV("_http._tcp.svc1.testns.svc.cluster.local. 303 IN SRV 0 100 80 svc1.testns.svc.cluster.local."),
|
||||||
},
|
},
|
||||||
Extra: []dns.RR{
|
Extra: []dns.RR{
|
||||||
test.A("svc1.testns.svc.cluster.local. 0 IN A 10.0.0.1"),
|
test.A("svc1.testns.svc.cluster.local. 303 IN A 10.0.0.1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"A Service (Headless)": {
|
"A Service (Headless)": {
|
||||||
Qname: "hdls1.testns.svc.cluster.local.", Qtype: dns.TypeA,
|
Qname: "hdls1.testns.svc.cluster.local.", Qtype: dns.TypeA,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.A("hdls1.testns.svc.cluster.local. 0 IN A 172.0.0.2"),
|
test.A("hdls1.testns.svc.cluster.local. 303 IN A 172.0.0.2"),
|
||||||
test.A("hdls1.testns.svc.cluster.local. 0 IN A 172.0.0.3"),
|
test.A("hdls1.testns.svc.cluster.local. 303 IN A 172.0.0.3"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"SRV Service (Headless)": {
|
"SRV Service (Headless)": {
|
||||||
Qname: "_http._tcp.hdls1.testns.svc.cluster.local.", Qtype: dns.TypeSRV,
|
Qname: "_http._tcp.hdls1.testns.svc.cluster.local.", Qtype: dns.TypeSRV,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.SRV("_http._tcp.hdls1.testns.svc.cluster.local. 0 IN SRV 0 50 80 172-0-0-2.hdls1.testns.svc.cluster.local."),
|
test.SRV("_http._tcp.hdls1.testns.svc.cluster.local. 303 IN SRV 0 50 80 172-0-0-2.hdls1.testns.svc.cluster.local."),
|
||||||
test.SRV("_http._tcp.hdls1.testns.svc.cluster.local. 0 IN SRV 0 50 80 172-0-0-3.hdls1.testns.svc.cluster.local."),
|
test.SRV("_http._tcp.hdls1.testns.svc.cluster.local. 303 IN SRV 0 50 80 172-0-0-3.hdls1.testns.svc.cluster.local."),
|
||||||
},
|
},
|
||||||
Extra: []dns.RR{
|
Extra: []dns.RR{
|
||||||
test.A("172-0-0-2.hdls1.testns.svc.cluster.local. 0 IN A 172.0.0.2"),
|
test.A("172-0-0-2.hdls1.testns.svc.cluster.local. 303 IN A 172.0.0.2"),
|
||||||
test.A("172-0-0-3.hdls1.testns.svc.cluster.local. 0 IN A 172.0.0.3"),
|
test.A("172-0-0-3.hdls1.testns.svc.cluster.local. 303 IN A 172.0.0.3"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"CNAME External": {
|
"CNAME External": {
|
||||||
Qname: "external.testns.svc.cluster.local.", Qtype: dns.TypeCNAME,
|
Qname: "external.testns.svc.cluster.local.", Qtype: dns.TypeCNAME,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.CNAME("external.testns.svc.cluster.local. 0 IN CNAME ext.interwebs.test."),
|
test.CNAME("external.testns.svc.cluster.local. 303 IN CNAME ext.interwebs.test."),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"AAAA Service (existing service)": {
|
"AAAA Service (existing service)": {
|
||||||
|
|
|
@ -40,6 +40,7 @@ type Kubernetes struct {
|
||||||
Namespaces map[string]bool
|
Namespaces map[string]bool
|
||||||
podMode string
|
podMode string
|
||||||
Fallthrough bool
|
Fallthrough bool
|
||||||
|
ttl uint32
|
||||||
|
|
||||||
primaryZoneIndex int
|
primaryZoneIndex int
|
||||||
interfaceAddrsFunc func() net.IP
|
interfaceAddrsFunc func() net.IP
|
||||||
|
@ -55,6 +56,7 @@ func New(zones []string) *Kubernetes {
|
||||||
k.interfaceAddrsFunc = func() net.IP { return net.ParseIP("127.0.0.1") }
|
k.interfaceAddrsFunc = func() net.IP { return net.ParseIP("127.0.0.1") }
|
||||||
k.podMode = podModeDisabled
|
k.podMode = podModeDisabled
|
||||||
k.Proxy = proxy.Proxy{}
|
k.Proxy = proxy.Proxy{}
|
||||||
|
k.ttl = defaultTTL
|
||||||
|
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
@ -382,7 +384,7 @@ func (k *Kubernetes) findServices(r recordRequest, zone string) (services []msg.
|
||||||
if !(match(r.port, p.Name) && match(r.protocol, string(p.Protocol))) {
|
if !(match(r.port, p.Name) && match(r.protocol, string(p.Protocol))) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s := msg.Service{Host: addr.IP, Port: int(p.Port)}
|
s := msg.Service{Host: addr.IP, Port: int(p.Port), TTL: k.ttl}
|
||||||
s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name, endpointHostname(addr)}, "/")
|
s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name, endpointHostname(addr)}, "/")
|
||||||
|
|
||||||
err = nil
|
err = nil
|
||||||
|
@ -397,7 +399,7 @@ func (k *Kubernetes) findServices(r recordRequest, zone string) (services []msg.
|
||||||
|
|
||||||
// External service
|
// External service
|
||||||
if svc.Spec.ExternalName != "" {
|
if svc.Spec.ExternalName != "" {
|
||||||
s := msg.Service{Key: strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/"), Host: svc.Spec.ExternalName}
|
s := msg.Service{Key: strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/"), Host: svc.Spec.ExternalName, TTL: k.ttl}
|
||||||
if t, _ := s.HostType(); t == dns.TypeCNAME {
|
if t, _ := s.HostType(); t == dns.TypeCNAME {
|
||||||
s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/")
|
s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/")
|
||||||
services = append(services, s)
|
services = append(services, s)
|
||||||
|
@ -416,7 +418,7 @@ func (k *Kubernetes) findServices(r recordRequest, zone string) (services []msg.
|
||||||
|
|
||||||
err = nil
|
err = nil
|
||||||
|
|
||||||
s := msg.Service{Host: svc.Spec.ClusterIP, Port: int(p.Port)}
|
s := msg.Service{Host: svc.Spec.ClusterIP, Port: int(p.Port), TTL: k.ttl}
|
||||||
s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/")
|
s.Key = strings.Join([]string{zonePath, Svc, svc.Namespace, svc.Name}, "/")
|
||||||
|
|
||||||
services = append(services, s)
|
services = append(services, s)
|
||||||
|
@ -455,4 +457,6 @@ const (
|
||||||
Svc = "svc"
|
Svc = "svc"
|
||||||
// Pod is the DNS schema for kubernetes pods
|
// Pod is the DNS schema for kubernetes pods
|
||||||
Pod = "pod"
|
Pod = "pod"
|
||||||
|
// defaultTTL to apply to all answers.
|
||||||
|
defaultTTL = 5
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package kubernetes
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -174,6 +175,19 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, dnsControlOpts, error) {
|
||||||
return nil, opts, err
|
return nil, opts, err
|
||||||
}
|
}
|
||||||
k8s.Proxy = proxy.NewLookup(ups)
|
k8s.Proxy = proxy.NewLookup(ups)
|
||||||
|
case "ttl":
|
||||||
|
args := c.RemainingArgs()
|
||||||
|
if len(args) == 0 {
|
||||||
|
return nil, opts, c.ArgErr()
|
||||||
|
}
|
||||||
|
t, err := strconv.Atoi(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, opts, err
|
||||||
|
}
|
||||||
|
if t < 5 || t > 3600 {
|
||||||
|
return nil, opts, c.Errf("ttl must be in range [5, 3600]: %d", t)
|
||||||
|
}
|
||||||
|
k8s.ttl = uint32(t)
|
||||||
default:
|
default:
|
||||||
return nil, opts, c.Errf("unknown property '%s'", c.Val())
|
return nil, opts, c.Errf("unknown property '%s'", c.Val())
|
||||||
}
|
}
|
||||||
|
|
45
middleware/kubernetes/setup_ttl_test.go
Normal file
45
middleware/kubernetes/setup_ttl_test.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package kubernetes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mholt/caddy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKubernetesParseTTL(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string // Corefile data as string
|
||||||
|
expectedTTL uint32 // expected count of defined zones.
|
||||||
|
shouldErr bool
|
||||||
|
}{
|
||||||
|
{`kubernetes cluster.local {
|
||||||
|
ttl 56
|
||||||
|
}`, 56, false},
|
||||||
|
{`kubernetes cluster.local`, defaultTTL, false},
|
||||||
|
{`kubernetes cluster.local {
|
||||||
|
ttl -1
|
||||||
|
}`, 0, true},
|
||||||
|
{`kubernetes cluster.local {
|
||||||
|
ttl 3601
|
||||||
|
}`, 0, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range tests {
|
||||||
|
c := caddy.NewTestController("dns", tc.input)
|
||||||
|
k, _, err := kubernetesParse(c)
|
||||||
|
if err != nil && !tc.shouldErr {
|
||||||
|
t.Fatalf("Test %d: Expected no error, got %q", i, err)
|
||||||
|
}
|
||||||
|
if err == nil && tc.shouldErr {
|
||||||
|
t.Fatalf("Test %d: Expected error, got none", i)
|
||||||
|
}
|
||||||
|
if err != nil && tc.shouldErr {
|
||||||
|
// input should error
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if k.ttl != tc.expectedTTL {
|
||||||
|
t.Errorf("Test %d: Expected TTl to be %d, got %d", i, tc.expectedTTL, k.ttl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ var dnsTestCases = []test.Case{
|
||||||
Qname: "svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA,
|
Qname: "svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.A("svc-1-a.test-1.svc.cluster.local. 303 IN A 10.0.0.100"),
|
test.A("svc-1-a.test-1.svc.cluster.local. 5 IN A 10.0.0.100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -535,9 +535,7 @@ var dnsTestCasesFallthrough = []test.Case{
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeSRV", "headless-svc", "test-1"),
|
Answer: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeSRV", "headless-svc", "test-1"),
|
||||||
[]dns.RR{
|
[]dns.RR{
|
||||||
test.SRV("_c-port._UDP.*.test-1.svc.cluster.local. 303 IN SRV 0 33 1234 svc-c.test-1.svc.cluster.local."),
|
test.SRV("_c-port._UDP.*.test-1.svc.cluster.local. 303 IN SRV 0 33 1234 svc-c.test-1.svc.cluster.local.")}...),
|
||||||
}...),
|
|
||||||
|
|
||||||
Extra: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeA", "headless-svc", "test-1"),
|
Extra: append(srvResponse("_c-port._UDP.*.test-1.svc.cluster.local.", "TypeA", "headless-svc", "test-1"),
|
||||||
[]dns.RR{
|
[]dns.RR{
|
||||||
test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
|
test.A("svc-c.test-1.svc.cluster.local. 303 IN A 10.0.0.115"),
|
||||||
|
@ -626,14 +624,14 @@ var dnsTestCasesFallthrough = []test.Case{
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.A("example.net. 303 IN A 13.14.15.16"),
|
test.A("example.net. 303 IN A 13.14.15.16"),
|
||||||
test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
|
test.CNAME("ext-svc.test-1.svc.cluster.local. 303 IN CNAME example.net."),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Qname: "ext-svc.test-1.svc.cluster.local.", Qtype: dns.TypeCNAME,
|
Qname: "ext-svc.test-1.svc.cluster.local.", Qtype: dns.TypeCNAME,
|
||||||
Rcode: dns.RcodeSuccess,
|
Rcode: dns.RcodeSuccess,
|
||||||
Answer: []dns.RR{
|
Answer: []dns.RR{
|
||||||
test.CNAME("ext-svc.test-1.svc.cluster.local. 0 IN CNAME example.net."),
|
test.CNAME("ext-svc.test-1.svc.cluster.local. 303 IN CNAME example.net."),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -855,7 +853,7 @@ func srvResponse(qname, responsetype, namespace, name string) []dns.RR {
|
||||||
ip := strings.Replace(result[i], ".", "-", -1)
|
ip := strings.Replace(result[i], ".", "-", -1)
|
||||||
t := strconv.Itoa(100 / (lr + 1))
|
t := strconv.Itoa(100 / (lr + 1))
|
||||||
if responsetype == "TypeA" {
|
if responsetype == "TypeA" {
|
||||||
rr = append(rr, test.A(ip+"."+namespace+"."+name+".svc.cluster.local. 0 IN A "+result[i]))
|
rr = append(rr, test.A(ip+"."+namespace+"."+name+".svc.cluster.local. 303 IN A "+result[i]))
|
||||||
}
|
}
|
||||||
if responsetype == "TypeSRV" && namespace == "headless-svc" {
|
if responsetype == "TypeSRV" && namespace == "headless-svc" {
|
||||||
rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 1234 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
|
rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 1234 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
|
||||||
|
@ -864,7 +862,6 @@ func srvResponse(qname, responsetype, namespace, name string) []dns.RR {
|
||||||
rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 443 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
|
rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 443 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
|
||||||
rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 80 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
|
rr = append(rr, test.SRV(qname+" 303 IN SRV 0 "+t+" 80 "+ip+"."+namespace+"."+name+".svc.cluster.local."))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return rr
|
return rr
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue