Skip to content

Commit 799b00d

Browse files
distinguish the host is inner or outer host of K8s cluster (#10)
1 parent a83f734 commit 799b00d

File tree

2 files changed

+62
-47
lines changed

2 files changed

+62
-47
lines changed

chaos.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package kubernetes
22

33
import (
44
"context"
5+
"fmt"
56
"math/rand"
67
"net"
78
"time"
89

9-
"github.com/coredns/coredns/plugin"
1010
"github.com/coredns/coredns/request"
1111
"github.com/miekg/dns"
1212
api "k8s.io/api/core/v1"
@@ -50,7 +50,7 @@ func (p *PodInfo) IsOverdue() bool {
5050

5151
func (k Kubernetes) chaosDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg, state request.Request, podInfo *PodInfo) (int, error) {
5252
if podInfo.Action == ActionError {
53-
return dns.RcodeServerFailure, nil
53+
return dns.RcodeServerFailure, fmt.Errorf("dns chaos error")
5454
}
5555

5656
// return random IP
@@ -156,7 +156,7 @@ func (k Kubernetes) getChaosPod(ip string) (*PodInfo, error) {
156156
}
157157

158158
// needChaos judges weather should do chaos for the request
159-
func (k Kubernetes) needChaos(podInfo *PodInfo, state request.Request) bool {
159+
func (k Kubernetes) needChaos(podInfo *PodInfo, records []dns.RR, err error) bool {
160160
if podInfo == nil {
161161
return false
162162
}
@@ -165,21 +165,30 @@ func (k Kubernetes) needChaos(podInfo *PodInfo, state request.Request) bool {
165165
return true
166166
}
167167

168-
// FIXME: this function is wrong, need to fix it
169-
qname := state.QName()
170-
zone := plugin.Zones(k.Zones).Matches(qname)
168+
if err != nil {
169+
// not found in cluster, is outer host
170+
if k.IsNameError(err) {
171+
if podInfo.Scope == ScopeOuter {
172+
return true
173+
}
174+
return false
175+
}
176+
177+
// can't judge the host is outer or inner host, ignore chaos
178+
return false
179+
}
171180

172-
log.Infof("qname: %s, zone: %s, scope: %s, zones: %s", qname, zone, podInfo.Scope, k.Zones)
173-
if zone == "" {
174-
// is outer host
181+
if len(records) == 0 {
182+
// not found in cluster, is outer host {
175183
if podInfo.Scope == ScopeOuter {
176184
return true
177185
}
178-
} else {
179-
// is inner host
180-
if podInfo.Scope == ScopeInner {
181-
return true
182-
}
186+
return false
187+
}
188+
189+
// is inner host
190+
if podInfo.Scope == ScopeInner {
191+
return true
183192
}
184193

185194
return false

handler.go

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,60 @@ import (
1313
func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
1414
state := request.Request{W: w, Req: r}
1515
sourceIP := state.IP()
16-
log.Infof("k8s ServeDNS, source IP: %s", sourceIP)
16+
log.Infof("k8s ServeDNS, source IP: %s, state: %v", sourceIP, state)
1717

1818
chaosPod, err := k.getChaosPod(sourceIP)
1919
if err != nil {
2020
log.Infof("fail to get pod information from cluster, IP: %s, error: %v", sourceIP, err)
2121
}
22-
if k.needChaos(chaosPod, state) {
22+
23+
records, extra, zone, err := k.getRecords(ctx, state)
24+
log.Infof("records: %v, err: %v", records, err)
25+
26+
if k.needChaos(chaosPod, records, err) {
2327
return k.chaosDNS(ctx, w, r, state, chaosPod)
2428
}
2529

30+
if k.IsNameError(err) {
31+
if k.Fall.Through(state.Name()) {
32+
return plugin.NextOrFailure(k.Name(), k.Next, ctx, w, r)
33+
}
34+
if !k.APIConn.HasSynced() {
35+
// If we haven't synchronized with the kubernetes cluster, return server failure
36+
return plugin.BackendError(ctx, &k, zone, dns.RcodeServerFailure, state, nil /* err */, plugin.Options{})
37+
}
38+
return plugin.BackendError(ctx, &k, zone, dns.RcodeNameError, state, nil /* err */, plugin.Options{})
39+
}
40+
if err != nil {
41+
return dns.RcodeServerFailure, err
42+
}
43+
44+
if len(records) == 0 {
45+
return plugin.BackendError(ctx, &k, zone, dns.RcodeSuccess, state, nil, plugin.Options{})
46+
}
47+
48+
m := new(dns.Msg)
49+
m.SetReply(r)
50+
m.Authoritative = true
51+
m.Answer = append(m.Answer, records...)
52+
m.Extra = append(m.Extra, extra...)
53+
54+
w.WriteMsg(m)
55+
return dns.RcodeSuccess, nil
56+
}
57+
58+
// get records from cache
59+
func (k Kubernetes) getRecords(ctx context.Context, state request.Request) ([]dns.RR, []dns.RR, string, error) {
2660
qname := state.QName()
2761
zone := plugin.Zones(k.Zones).Matches(qname)
28-
if zone == "" {
29-
return plugin.NextOrFailure(k.Name(), k.Next, ctx, w, r)
30-
}
62+
3163
zone = qname[len(qname)-len(zone):] // maintain case of original query
3264
state.Zone = zone
3365

3466
var (
3567
records []dns.RR
3668
extra []dns.RR
69+
err error
3770
)
3871

3972
switch state.QType() {
@@ -68,34 +101,7 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
68101
_, err = plugin.A(ctx, &k, zone, fake, nil, plugin.Options{})
69102
}
70103

71-
if k.IsNameError(err) {
72-
if k.Fall.Through(state.Name()) {
73-
return plugin.NextOrFailure(k.Name(), k.Next, ctx, w, r)
74-
}
75-
if !k.APIConn.HasSynced() {
76-
// If we haven't synchronized with the kubernetes cluster, return server failure
77-
return plugin.BackendError(ctx, &k, zone, dns.RcodeServerFailure, state, nil /* err */, plugin.Options{})
78-
}
79-
return plugin.BackendError(ctx, &k, zone, dns.RcodeNameError, state, nil /* err */, plugin.Options{})
80-
}
81-
if err != nil {
82-
return dns.RcodeServerFailure, err
83-
}
84-
85-
if len(records) == 0 {
86-
return plugin.BackendError(ctx, &k, zone, dns.RcodeSuccess, state, nil, plugin.Options{})
87-
}
88-
89-
log.Infof("records %v", records)
90-
91-
m := new(dns.Msg)
92-
m.SetReply(r)
93-
m.Authoritative = true
94-
m.Answer = append(m.Answer, records...)
95-
m.Extra = append(m.Extra, extra...)
96-
97-
w.WriteMsg(m)
98-
return dns.RcodeSuccess, nil
104+
return records, extra, zone, err
99105
}
100106

101107
// Name implements the Handler interface.

0 commit comments

Comments
 (0)