forked from ionos-cloud/coredns-externaldns
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.go
More file actions
232 lines (207 loc) · 5.26 KB
/
Copy pathsetup.go
File metadata and controls
232 lines (207 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
package externaldns
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/coredns/caddy"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/transfer"
)
// Config holds the plugin configuration
type Config struct {
// Core settings
Namespace string
TTL uint32
Zones []string
// SOA configuration
SOA SOAConfig
// ConfigMap settings for zone serial persistence
ConfigMap ConfigMapConfig
}
// SOAConfig holds SOA record configuration
type SOAConfig struct {
Nameserver string // NS field
Mailbox string // MBOX field
Refresh uint32 // Refresh interval
Retry uint32 // Retry interval
Expire uint32 // Expire time
MinTTL uint32 // Minimum TTL
}
// ConfigMapConfig holds ConfigMap settings
type ConfigMapConfig struct {
Name string // ConfigMap name
Namespace string // ConfigMap namespace
}
// DefaultConfig returns a configuration with sensible defaults
func DefaultConfig() *Config {
return &Config{
Namespace: "",
TTL: 300,
SOA: SOAConfig{
Nameserver: "ns1.example.com",
Mailbox: "admin.example.com",
Refresh: 3600,
Retry: 1800,
Expire: 1209600,
MinTTL: 300,
},
ConfigMap: ConfigMapConfig{
Name: "coredns-externaldns-zone-serials",
Namespace: "",
},
}
}
// Validate checks if the configuration is valid
func (c *Config) Validate() error {
if c.TTL == 0 {
return fmt.Errorf("TTL cannot be zero")
}
if c.SOA.Nameserver == "" {
return fmt.Errorf("SOA nameserver cannot be empty")
}
if c.SOA.Mailbox == "" {
return fmt.Errorf("SOA mailbox cannot be empty")
}
if c.ConfigMap.Name == "" {
return fmt.Errorf("ConfigMap name cannot be empty")
}
return nil
}
// init registers this plugin with CoreDNS
func init() {
plugin.Register("externaldns", setup)
}
// setup sets up the externaldns plugin
func setup(c *caddy.Controller) error {
ed, err := parseExternalDNS(c)
if err != nil {
return plugin.Error("externaldns", err)
}
// get the transfer plugin, so we can send notifies and send notifies on startup as well.
c.OnStartup(func() error {
t := dnsserver.GetConfig(c).Handler("transfer")
if t == nil {
return nil
}
ed.transfer = t.(*transfer.Transfer) // if found this must be OK.
return nil
})
// Start the plugin
err = ed.Start(context.Background())
if err != nil {
return plugin.Error("externaldns", err)
}
// Add the plugin to CoreDNS
dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
ed.Next = next
return ed
})
// Register shutdown handler
c.OnShutdown(func() error {
ed.Stop()
return nil
})
return nil
}
// parseExternalDNS parses the plugin configuration
func parseExternalDNS(c *caddy.Controller) (*Plugin, error) {
config := DefaultConfig()
for c.Next() {
// Parse zone names
config.Zones = append(config.Zones, plugin.OriginsFromArgsOrServerBlock(c.RemainingArgs(), c.ServerBlockKeys)...)
for c.NextBlock() {
switch c.Val() {
// Core settings
case "namespace":
if !c.NextArg() {
return nil, c.ArgErr()
}
config.Namespace = c.Val()
case "ttl":
if !c.NextArg() {
return nil, c.ArgErr()
}
t, err := strconv.ParseUint(c.Val(), 10, 32)
if err != nil {
return nil, c.Errf("invalid TTL: %v", err)
}
config.TTL = uint32(t)
// SOA configuration
case "soa_ns", "soa_nameserver":
if !c.NextArg() {
return nil, c.ArgErr()
}
config.SOA.Nameserver = c.Val()
case "soa_mbox", "soa_mailbox":
if !c.NextArg() {
return nil, c.ArgErr()
}
config.SOA.Mailbox = c.Val()
case "soa_refresh":
if !c.NextArg() {
return nil, c.ArgErr()
}
r, err := strconv.ParseUint(c.Val(), 10, 32)
if err != nil {
return nil, c.Errf("invalid SOA refresh: %v", err)
}
config.SOA.Refresh = uint32(r)
case "soa_retry":
if !c.NextArg() {
return nil, c.ArgErr()
}
r, err := strconv.ParseUint(c.Val(), 10, 32)
if err != nil {
return nil, c.Errf("invalid SOA retry: %v", err)
}
config.SOA.Retry = uint32(r)
case "soa_expire":
if !c.NextArg() {
return nil, c.ArgErr()
}
e, err := strconv.ParseUint(c.Val(), 10, 32)
if err != nil {
return nil, c.Errf("invalid SOA expire: %v", err)
}
config.SOA.Expire = uint32(e)
case "soa_minttl":
if !c.NextArg() {
return nil, c.ArgErr()
}
m, err := strconv.ParseUint(c.Val(), 10, 32)
if err != nil {
return nil, c.Errf("invalid SOA minttl: %v", err)
}
config.SOA.MinTTL = uint32(m)
// ConfigMap configuration
case "configmap_name":
if !c.NextArg() {
return nil, c.ArgErr()
}
config.ConfigMap.Name = c.Val()
case "configmap_namespace":
if !c.NextArg() {
return nil, c.ArgErr()
}
config.ConfigMap.Namespace = c.Val()
// Authoritative Zones
case "authoritative_zones":
if !c.NextArg() {
return nil, c.ArgErr()
}
config.Zones = strings.Split(c.Val(), ",")
default:
return nil, c.Errf("unknown property: %s", c.Val())
}
}
}
// Validate configuration
if err := config.Validate(); err != nil {
return nil, c.Errf("configuration validation failed: %v", err)
}
// Create plugin with structured configuration
plugin := New(config)
return plugin, nil
}