Skip to content

Commit

Permalink
dns: better config (#1273)
Browse files Browse the repository at this point in the history
* change config struct

* make use of new config

* add registry for reflection

* update docs

* simplify hooks docs
  • Loading branch information
BeryJu authored Nov 3, 2024
1 parent fff90ae commit d89be61
Show file tree
Hide file tree
Showing 21 changed files with 187 additions and 92 deletions.
23 changes: 23 additions & 0 deletions docs/content/docs/_gravity-hook-env.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
### `gravity` Object

#### `log(msg: any)`

Logs a message to the stdout of the Gravity node this hook is run on.

#### `node: string`

The identifier of the node this hook is run on.

#### `version: string`

The version of Gravity on the node this hook is run on.

#### `role`

A reference to the [Role instance](https://pkg.go.dev/beryju.io/gravity/pkg/instance#RoleInstance) this hook was triggered by.

### `net` Object

#### `parseIP(ip: string, family: string)`

Parse an IP address from the string `ip` and return it as an array of bytes. `family` determines if the IP should be parsed as IPv4 or IPv6.</p>
2 changes: 1 addition & 1 deletion docs/content/docs/dhcp/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Called after the DHCP response is generated.

## Environment

{{< gravity-hook-env >}}
{{< readfile "/docs/_gravity-hook-env.md" >}}

### `dhcp` Object

Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/dns/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ Called after the DNS response is generated.

## Environment

{{< gravity-hook-env >}}
{{< readfile "/docs/_gravity-hook-env.md" >}}
15 changes: 12 additions & 3 deletions docs/content/docs/dns/zones.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The order of handler matters; Gravity will send a query to each handler in the o
The handler configuration consists of a list of individual handler configurations. All list entries require a `type` attribute which must match one of the headers listed below. For example:

```yaml
- cache_ttl: "3600"
- cache_ttl: 3600
to: 8.8.8.8:53
type: forward_blocky
- to: 8.8.8.8:53
Expand Down Expand Up @@ -50,6 +50,8 @@ Forward queries to another DNS server.

Multiple servers should be separated by `;`. For example `8.8.8.8:53;1.1.1.1`.

Starting with Gravity 0.14, this can also be set as a JSON/YAML array using `[8.8.8.8:53, 1.1.1.1:53]` instead of a semicolon-separated string.

- `cache_ttl`: Optional TTL to cache responses in etcd.

Defaults to 0. Attempts to cache for the TTL of the response.
Expand All @@ -72,6 +74,8 @@ Forward queries to another DNS server via Blocky for advert/privacy blocking.

Multiple servers should be separated by `;`. For example `8.8.8.8:53;1.1.1.1`.

Starting with Gravity 0.14, this can also be set as a JSON/YAML array using `[8.8.8.8:53, 1.1.1.1:53]` instead of a semicolon-separated string.

- `cache_ttl`: Optional TTL to cache responses in etcd

Defaults to 0. Attempts to cache for the TTL of the response.
Expand All @@ -82,6 +86,8 @@ Forward queries to another DNS server via Blocky for advert/privacy blocking.

Entries beginning with http:// or https:// are downloaded when the DNS Role is started. Can also be set to an inline list of domains to block/allow. Multiple entries should be separated by a `;`.

Starting with Gravity 0.14, this can also be set as a JSON/YAML array using `[https://foo, https://bar]` instead of a semicolon-separated string.

By default, these blocklists are loaded:

- https://adaway.org/hosts.txt
Expand All @@ -98,7 +104,10 @@ Forward queries to another DNS server via Blocky for advert/privacy blocking.
```yaml
- type: forward_blocky
to: 8.8.8.8
blocklists: https://adaway.org/hosts.txt
blocklists:
- https://adaway.org/hosts.txt
allowlists:
- exception.com
```

### `coredns`
Expand Down Expand Up @@ -131,4 +140,4 @@ Resolve queries by using a variety of CoreDNS Plugins. See [here](https://coredn

## Hooks

Optional hooks to dynamically modify requests and responses. See [Hooks](./hooks.md)
Optional hooks to dynamically modify requests and responses. See [Hooks](../hooks)
18 changes: 0 additions & 18 deletions docs/layouts/shortcodes/gravity-hook-env.html

This file was deleted.

20 changes: 10 additions & 10 deletions pkg/roles/dns/api_zones.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ type APIZonesGetInput struct {
Name string `query:"name" description:"Optionally get DNS Zone by name"`
}
type APIZone struct {
Name string `json:"name" required:"true"`
HandlerConfigs []map[string]string `json:"handlerConfigs" required:"true"`
DefaultTTL uint32 `json:"defaultTTL" required:"true"`
Authoritative bool `json:"authoritative" required:"true"`
Hook string `json:"hook" required:"true"`
Name string `json:"name" required:"true"`
HandlerConfigs []map[string]interface{} `json:"handlerConfigs" required:"true"`
DefaultTTL uint32 `json:"defaultTTL" required:"true"`
Authoritative bool `json:"authoritative" required:"true"`
Hook string `json:"hook" required:"true"`
}
type APIZonesGetOutput struct {
Zones []APIZone `json:"zones" required:"true"`
Expand Down Expand Up @@ -73,11 +73,11 @@ func (r *Role) APIZonesGet() usecase.Interactor {
}

type APIZonesPutInput struct {
Name string `query:"zone" required:"true" maxLength:"255"`
HandlerConfigs []map[string]string `json:"handlerConfigs" required:"true"`
DefaultTTL uint32 `json:"defaultTTL" required:"true"`
Authoritative bool `json:"authoritative" required:"true"`
Hook string `json:"hook" required:"true"`
Name string `query:"zone" required:"true" maxLength:"255"`
HandlerConfigs []map[string]interface{} `json:"handlerConfigs" required:"true"`
DefaultTTL uint32 `json:"defaultTTL" required:"true"`
Authoritative bool `json:"authoritative" required:"true"`
Hook string `json:"hook" required:"true"`
}

func (r *Role) APIZonesPut() usecase.Interactor {
Expand Down
4 changes: 2 additions & 2 deletions pkg/roles/dns/api_zones_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestAPIZonesPut(t *testing.T) {
assert.NoError(t, role.APIZonesPut().Interact(ctx, dns.APIZonesPutInput{
Name: strings.TrimSuffix(name, "."),
Authoritative: true,
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand All @@ -61,7 +61,7 @@ func TestAPIZonesPut(t *testing.T) {
),
dns.Zone{
Authoritative: true,
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down
23 changes: 23 additions & 0 deletions pkg/roles/dns/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,26 @@ type Handler interface {
Handle(w *utils.FakeDNSWriter, r *utils.DNSRequest) *dns.Msg
Identifier() string
}

type HandlerConstructor func(z *Zone, rawConfig map[string]interface{}) Handler

var HandlerRegistry = newRegistry()

type handlerRegistry struct {
handlers map[string]HandlerConstructor
}

func newRegistry() handlerRegistry {
return handlerRegistry{
handlers: make(map[string]HandlerConstructor),
}
}

func (hn handlerRegistry) Add(identifier string, h HandlerConstructor) {
hn.handlers[identifier] = h
}

func (hn handlerRegistry) Find(identifier string) (HandlerConstructor, bool) {
c, ok := hn.handlers[identifier]
return c, ok
}
12 changes: 9 additions & 3 deletions pkg/roles/dns/handler_coredns.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,26 @@ import (
const CoreDNSType = "coredns"

type CoreDNS struct {
c map[string]string
c map[string]interface{}
log *zap.Logger
instance *caddy.Instance
srv *dnsserver.Server
}

func NewCoreDNS(z *Zone, rawConfig map[string]string) *CoreDNS {
func init() {
HandlerRegistry.Add(CoreDNSType, func(z *Zone, rawConfig map[string]interface{}) Handler {
return NewCoreDNS(z, rawConfig)
})
}

func NewCoreDNS(z *Zone, rawConfig map[string]interface{}) *CoreDNS {
core := &CoreDNS{
c: rawConfig,
}
core.log = z.log.With(zap.String("handler", core.Identifier()))
dnsserver.Quiet = true
corefile := caddy.CaddyfileInput{
Contents: []byte(core.c["config"]),
Contents: []byte(core.c["config"].(string)),
Filepath: "in-memory",
ServerTypeName: "dns",
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/roles/dns/handler_coredns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestRoleDNSHandlerCoreDNS(t *testing.T) {
".",
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "coredns",
"config": CoreDNSConfig,
Expand Down
8 changes: 7 additions & 1 deletion pkg/roles/dns/handler_etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ type EtcdHandler struct {
lookupKey func(k *storage.Key, qname string, r *utils.DNSRequest) []dns.RR
}

func NewEtcdHandler(z *Zone, config map[string]string) *EtcdHandler {
func init() {
HandlerRegistry.Add(EtcdType, func(z *Zone, rawConfig map[string]interface{}) Handler {
return NewEtcdHandler(z, rawConfig)
})
}

func NewEtcdHandler(z *Zone, config map[string]interface{}) *EtcdHandler {
eh := &EtcdHandler{
z: z,
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/roles/dns/handler_etcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestRoleDNS_Etcd(t *testing.T) {
TestZone,
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down Expand Up @@ -82,7 +82,7 @@ func TestRoleDNS_Etcd_Root(t *testing.T) {
TestZone,
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down Expand Up @@ -136,7 +136,7 @@ func TestRoleDNS_Etcd_Wildcard(t *testing.T) {
TestZone,
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down Expand Up @@ -190,7 +190,7 @@ func TestRoleDNS_Etcd_CNAME(t *testing.T) {
TestZone,
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down Expand Up @@ -271,7 +271,7 @@ func TestRoleDNS_Etcd_WildcardNested(t *testing.T) {
TestZone,
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down Expand Up @@ -325,7 +325,7 @@ func TestRoleDNS_Etcd_MixedCase(t *testing.T) {
"eXaMpLe.CoM.",
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down Expand Up @@ -379,7 +379,7 @@ func TestRoleDNS_Etcd_MixedCase_Reverse(t *testing.T) {
TestZone,
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "etcd",
},
Expand Down
38 changes: 32 additions & 6 deletions pkg/roles/dns/handler_forward_blocky.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@ const BlockyForwarderType = "forward_blocky"

type BlockyForwarder struct {
*IPForwarderHandler
c map[string]string
c map[string]interface{}
b *server.Server
log *zap.Logger
st time.Time
cfg *config.Config
}

func init() {
HandlerRegistry.Add(BlockyForwarderType, func(z *Zone, rawConfig map[string]interface{}) Handler {
return NewBlockyForwarder(z, rawConfig)
})
}

func HTTPByteSource(url string) config.BytesSource {
return config.BytesSource{
Type: config.BytesSourceTypeHttp,
Expand All @@ -45,7 +51,7 @@ func TextByteSource(content string) config.BytesSource {
}
}

func NewBlockyForwarder(z *Zone, rawConfig map[string]string) *BlockyForwarder {
func NewBlockyForwarder(z *Zone, rawConfig map[string]interface{}) *BlockyForwarder {
bfwd := &BlockyForwarder{
IPForwarderHandler: NewIPForwarderHandler(z, rawConfig),
c: rawConfig,
Expand Down Expand Up @@ -80,7 +86,17 @@ func (bfwd *BlockyForwarder) Identifier() string {
}

func (bfwd *BlockyForwarder) getConfig() (*config.Config, error) {
forwarders := strings.Split(bfwd.c["to"], ";")
forwarders := []string{}
switch v := bfwd.c["to"].(type) {
case string:
forwarders = strings.Split(v, ";")
case []interface{}:
for _, fwd := range v {
if f, ok := fwd.(string); ok {
forwarders = append(forwarders, f)
}
}
}
upstreams := make([]config.Upstream, len(forwarders))
for idx, fwd := range forwarders {
us, err := config.ParseUpstream(fwd)
Expand Down Expand Up @@ -163,10 +179,20 @@ func (bfwd *BlockyForwarder) getConfig() (*config.Config, error) {
return &cfg, nil
}

func (bfwd *BlockyForwarder) getLists(raw string) []config.BytesSource {
func (bfwd *BlockyForwarder) getLists(raw interface{}) []config.BytesSource {
list := []config.BytesSource{}
lists := strings.Split(raw, ";")
for _, rl := range lists {
rawLists := []string{}
switch v := raw.(type) {
case string:
rawLists = strings.Split(v, ";")
case []interface{}:
for _, rl := range v {
if r, ok := rl.(string); ok {
rawLists = append(rawLists, r)
}
}
}
for _, rl := range rawLists {
if strings.HasPrefix(rl, "http") {
list = append(list, HTTPByteSource(rl))
} else {
Expand Down
4 changes: 2 additions & 2 deletions pkg/roles/dns/handler_forward_blocky_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestRoleDNS_BlockyForwarder(t *testing.T) {
".",
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "forward_blocky",
"blocklists": "http://127.0.0.1:9005/blocky_file.txt",
Expand Down Expand Up @@ -83,7 +83,7 @@ func TestRoleDNS_BlockyForwarder_Allow(t *testing.T) {
".",
).String(),
tests.MustJSON(dns.Zone{
HandlerConfigs: []map[string]string{
HandlerConfigs: []map[string]interface{}{
{
"type": "forward_blocky",
"blocklists": "http://127.0.0.1:9005/blocky_file.txt",
Expand Down
Loading

0 comments on commit d89be61

Please sign in to comment.