Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy MX and SRV records with priority #54

Merged
merged 5 commits into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ records:
type: CNAME
ttl: 600
content: pixie.porkbun.com
- type: MX
host: bacontest42.com
content: in1-smtp.messagingengine.com
ttl: 600
priority: 10
- type: MX
host: bacontest42.com
content: in2-smtp.messagingengine.com
ttl: 600
priority: 20
29 changes: 27 additions & 2 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ records:
type: CNAME
ttl: 600
content: pixie.porkbun.com
- type: MX
host: bacontest42.com
content: in1-smtp.messagingengine.com
ttl: 600
priority: 10
`)
if err != nil {
t.Fatal("could not seed config to temp file", err)
Expand All @@ -26,8 +31,8 @@ records:
t.Fatal("could not read config file", err)
}

if len(config.Records) != 2 {
t.Fatal("expected 2 records after deployment, got", len(config.Records))
if len(config.Records) != 3 {
t.Fatal("expected 3 records after deployment, got", len(config.Records))
}
}

Expand Down Expand Up @@ -140,3 +145,23 @@ records:
t.Fatal("expected error when a record is missing content field", err)
}
}

func TestInvalidConfigInvalidPriority(t *testing.T) {
configFile, err := SeedConfigToTempFile(`
domain: bacontest42.com
records:
- host: bacontest42.com
type: ALIAS
ttl: 600
content: pixie.porkbun.com
priority: 20
`)
if err != nil {
t.Fatal("could not seed config to temp file", err)
}

_, err = ReadFile(configFile)
if err == nil {
t.Fatal("priority is not allowed on ALIAS records", err)
}
}
39 changes: 32 additions & 7 deletions pkg/config/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ import (
"strings"
)

type Record struct {
Name string `yaml:"host"`
Type string `yaml:"type"`
Ttl int `yaml:"ttl"`
Data string `yaml:"content"`
}

const (
// Record types that are allowed. Found in Porkbun's API documentation.
TYPE_ALLOWLIST = "A, MX, CNAME, ALIAS, TXT, NS, AAAA, SRV, TLSA, CAA, HTTPS, SVCB"
// Record types that are allowed to have a priority. Found in Porkbun's web app.
PRIORITY_ALLOWLIST = "MX, SRV"
)

type Record struct {
Name string `yaml:"host"`
Type string `yaml:"type"`
Ttl int `yaml:"ttl"`
Data string `yaml:"content"`
Priority int `yaml:"priority"`
}

func (r Record) GetName() string {
return r.Name
}
Expand All @@ -33,6 +37,10 @@ func (r Record) GetData() string {
return r.Data
}

func (r Record) GetPriority() string {
return fmt.Sprint(r.Priority)
}

func (r Record) Validate() error {
if r.Name == "" {
return fmt.Errorf("host is required")
Expand All @@ -53,6 +61,10 @@ func (r Record) Validate() error {
return fmt.Errorf("content is required")
}

if r.Priority != 0 && !isPriorityAllowed(r) {
return fmt.Errorf("priority must be one of %v", PRIORITY_ALLOWLIST)
}

return nil
}

Expand All @@ -69,4 +81,17 @@ func isTypeAllowed(r Record) bool {
return true
}

func isPriorityAllowed(r Record) bool {
allowedPriorities := make(map[string]bool)
for _, t := range strings.Split(PRIORITY_ALLOWLIST, ", ") {
allowedPriorities[t] = true
}

if _, ok := allowedPriorities[r.Type]; !ok {
return false
}

return true
}

var _ dns.Record = Record{}
3 changes: 3 additions & 0 deletions pkg/dns/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ type Record interface {
GetType() string
GetTtl() string
GetData() string
GetPriority() string
}

func RecordEquals(l Record, r Record) bool {
equal := l.GetName() == r.GetName()
equal = equal && l.GetType() == r.GetType()
equal = equal && l.GetTtl() == r.GetTtl()
equal = equal && l.GetData() == r.GetData()
equal = equal && l.GetPriority() == r.GetPriority()
return equal
}

Expand All @@ -26,5 +28,6 @@ func RecordHash(r Record) string {
r.GetType(),
r.GetTtl(),
r.GetData(),
r.GetPriority(),
}, "-")
}
4 changes: 4 additions & 0 deletions pkg/providers/porkbun/porkbun.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func (p PorkProvider) CreateRecord(domain string, newRecord dns.Record) error {
Content: newRecord.GetData(),
}

if newRecord.GetPriority() != "0" {
porkRecord.Priority = newRecord.GetPriority()
}

_, err := p.Api.CreateRecord(domain, porkRecord)
return err
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/providers/porkbun/record/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ func (r Record) GetData() string {
return r.Content
}

func (r Record) GetPriority() string {
return r.Priority
}

var _ dns.Record = Record{}