Skip to content

Commit

Permalink
Merge pull request #12 from jmesserli/feature/primary-port
Browse files Browse the repository at this point in the history
feat: allow specifying a port for the primaries
  • Loading branch information
jmesserli authored Jul 11, 2024
2 parents 1eb05ae + bac782f commit 8854e76
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 90 deletions.
5 changes: 3 additions & 2 deletions config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
},
"namespaces": {
"dns": {
"masters": [
"primaries": [
{
"name": "ns1.example.com",
"ip": "192.168.0.1",
"port": 54,
"dotted_mail": "user.example.com",
"zones": [
"example.com",
Expand All @@ -26,7 +27,7 @@
]
}
],
"additional_slaves": {
"additional_secondaries": {
"f.f.f.f.f.f.f.f.f.f.f.f.ip6.arpa": [
"ffff:fff:fff::21",
"ffff:fff:fff::22"
Expand Down
23 changes: 12 additions & 11 deletions config/config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,21 @@ type ZoneInclude struct {
IncludeFiles []string `json:"include_files"`
}

type AdditionalSlavesConfig = map[string][]string

type MasterConfig struct {
Name string `json:"name"`
IP string `json:"ip"`
DottedEmail string `json:"dotted_mail"`
Zones []string `json:"zones"`
DnssecZones []string `json:"dnssec_zones"`
Includes []ZoneInclude `json:"includes"`
AdditionalSlaves AdditionalSlavesConfig `json:"additional_slaves"`
type AdditionalSecondariesConfig = map[string][]string

type PrimaryConfig struct {
Name string `json:"name"`
IP string `json:"ip"`
Port int `json:"port"`
DottedEmail string `json:"dotted_mail"`
Zones []string `json:"zones"`
DnssecZones []string `json:"dnssec_zones"`
Includes []ZoneInclude `json:"includes"`
AdditionalSecondaries AdditionalSecondariesConfig `json:"additional_secondaries"`
}

type DNSNamespaceConfig struct {
Masters []MasterConfig `json:"masters"`
Primaries []PrimaryConfig `json:"primaries"`
}

type NamespaceConfig struct {
Expand Down
128 changes: 70 additions & 58 deletions ns/dns/configgenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,54 @@ import (
type zoneType string

const (
zoneSlave zoneType = "slave"
zoneMaster zoneType = "master"
zoneSecondary zoneType = "slave"
zonePrimary zoneType = "master"
)

type templateZone struct {
Name string
Type zoneType
IsSlave bool
IsSecondary bool
IsDnssecEnabled bool
MasterIP string
PrimaryIP string
PrimaryPort int
TransferAcls []string
NotifyMasters []string
NotifyPrimaries []string
}

type aclMasterType string
type aclPrimaryType string

const (
listAcl aclMasterType = "acl"
listMaster aclMasterType = "masters"
listAcl aclPrimaryType = "acl"
listPrimaries aclPrimaryType = "masters"
)

type aclMastersList struct {
Type aclMasterType
type primaryIPAndPort struct {
IP string
Port int
}

type aclPrimaryList struct {
Type aclPrimaryType
Name string
Entries []string
Entries []primaryIPAndPort
}

type configTemplateVars struct {
ServerName string
ServerIP string
GeneratedAt string
Zones []templateZone
AclMasterLists []aclMastersList
ServerName string
ServerIP string
GeneratedAt string
Zones []templateZone
AclPrimaryLists []aclPrimaryList
}

const defaultAclName = "nx-slaves-acl"
const defaultMastersName = "nx-slaves-masters"
const defaultAclName = "nx-secondary-acl"
const defaultPrimariesName = "nx-secondary-primaries"

func generateStandardAclMasterLists(masterIps []string) []aclMastersList {
return []aclMastersList{
{Type: listAcl, Name: defaultAclName, Entries: masterIps},
{Type: listMaster, Name: defaultMastersName, Entries: masterIps},
func generateStandardAclPrimaryLists(primaries []primaryIPAndPort) []aclPrimaryList {
return []aclPrimaryList{
{Type: listAcl, Name: defaultAclName, Entries: primaries},
{Type: listPrimaries, Name: defaultPrimariesName, Entries: primaries},
}
}

Expand All @@ -68,20 +74,25 @@ func canonicalizeZoneName(zone string) string {
return hex.EncodeToString(hasher.Sum(nil))[:8]
}

func getAdditionalAclMasterName(zone string, ty aclMasterType) string {
func getAdditionalAclPrimaryName(zone string, ty aclPrimaryType) string {
canonicalZone := canonicalizeZoneName(zone)

return fmt.Sprintf("nx-slaves-%s-%s", ty, canonicalZone)
return fmt.Sprintf("nx-secondary-%s-%s", ty, canonicalZone)
}

func generateAdditionalAclMasterLists(masterConfig *config.MasterConfig) []aclMastersList {
var lists []aclMastersList
func generateAdditionalAclPrimaryLists(primaryConfig *config.PrimaryConfig) []aclPrimaryList {
var lists []aclPrimaryList

if primaryConfig.AdditionalSecondaries != nil {
for zone, secondaries := range primaryConfig.AdditionalSecondaries {
var secondariesWithPorts []primaryIPAndPort
for _, secondary := range secondaries {
secondariesWithPorts = append(secondariesWithPorts, primaryIPAndPort{IP: secondary}) // port is empty for now
}

if masterConfig.AdditionalSlaves != nil {
for zone, slaves := range masterConfig.AdditionalSlaves {
lists = append(lists, []aclMastersList{
{Type: listAcl, Name: getAdditionalAclMasterName(zone, listAcl), Entries: slaves},
{Type: listMaster, Name: getAdditionalAclMasterName(zone, listMaster), Entries: slaves},
lists = append(lists, []aclPrimaryList{
{Type: listAcl, Name: getAdditionalAclPrimaryName(zone, listAcl), Entries: secondariesWithPorts},
{Type: listPrimaries, Name: getAdditionalAclPrimaryName(zone, listPrimaries), Entries: secondariesWithPorts},
}...)
}
}
Expand All @@ -103,61 +114,62 @@ func GenerateConfigs(zones []string, conf *config.NXConfig) {
templateVars := configTemplateVars{
GeneratedAt: time.Now().Format(time.RFC3339),
}
for _, currentMaster := range conf.Namespaces.DNS.Masters {
templateVars.ServerName = currentMaster.Name
templateVars.ServerIP = currentMaster.IP
for _, currentPrimary := range conf.Namespaces.DNS.Primaries {
templateVars.ServerName = currentPrimary.Name
templateVars.ServerIP = currentPrimary.IP
var templateZones []templateZone

for _, zonesMaster := range conf.Namespaces.DNS.Masters {
isMaster := zonesMaster.Name == currentMaster.Name
masterZoneType := zoneMaster
if !isMaster {
masterZoneType = zoneSlave
for _, zonesPrimary := range conf.Namespaces.DNS.Primaries {
isPrimary := zonesPrimary.Name == currentPrimary.Name
serverZoneType := zonePrimary
if !isPrimary {
serverZoneType = zoneSecondary
}

for _, zone := range zonesMaster.Zones {
for _, zone := range zonesPrimary.Zones {
if !util.SliceContainsString(zones, zone) {
continue
}

transferAcls := []string{defaultAclName}
notifyMasters := []string{defaultMastersName}
notifyPrimaries := []string{defaultPrimariesName}

_, hasAdditionalSlaves := currentMaster.AdditionalSlaves[zone]
if hasAdditionalSlaves {
transferAcls = append(transferAcls, getAdditionalAclMasterName(zone, listAcl))
notifyMasters = append(notifyMasters, getAdditionalAclMasterName(zone, listMaster))
_, hasAdditionalSecondaries := currentPrimary.AdditionalSecondaries[zone]
if hasAdditionalSecondaries {
transferAcls = append(transferAcls, getAdditionalAclPrimaryName(zone, listAcl))
notifyPrimaries = append(notifyPrimaries, getAdditionalAclPrimaryName(zone, listPrimaries))
}

dnssecEnabled := util.SliceContainsString(zonesMaster.DnssecZones, zone)
dnssecEnabled := util.SliceContainsString(zonesPrimary.DnssecZones, zone)

templateZones = append(templateZones, templateZone{
IsSlave: !isMaster,
IsSecondary: !isPrimary,
IsDnssecEnabled: dnssecEnabled,
MasterIP: zonesMaster.IP,
PrimaryIP: zonesPrimary.IP,
PrimaryPort: zonesPrimary.Port,
Name: zone,
Type: masterZoneType,
Type: serverZoneType,
TransferAcls: transferAcls,
NotifyMasters: notifyMasters,
NotifyPrimaries: notifyPrimaries,
})
}
}

templateVars.Zones = templateZones

var masterIPsWithoutCurrent = make([]string, 0, len(conf.Namespaces.DNS.Masters)-1)
for _, master := range conf.Namespaces.DNS.Masters {
if master.IP != currentMaster.IP {
masterIPsWithoutCurrent = append(masterIPsWithoutCurrent, master.IP)
var primaryIpsWithoutCurrent = make([]primaryIPAndPort, 0, len(conf.Namespaces.DNS.Primaries)-1)
for _, primary := range conf.Namespaces.DNS.Primaries {
if primary.IP != currentPrimary.IP {
primaryIpsWithoutCurrent = append(primaryIpsWithoutCurrent, primaryIPAndPort{IP: primary.IP, Port: primary.Port})
}
}

aclMastersLists := generateStandardAclMasterLists(masterIPsWithoutCurrent)
aclMastersLists = append(aclMastersLists, generateAdditionalAclMasterLists(&currentMaster)...)
templateVars.AclMasterLists = aclMastersLists
aclPrimaryLists := generateStandardAclPrimaryLists(primaryIpsWithoutCurrent)
aclPrimaryLists = append(aclPrimaryLists, generateAdditionalAclPrimaryLists(&currentPrimary)...)
templateVars.AclPrimaryLists = aclPrimaryLists

_, err = cw.WriteTemplate(
fmt.Sprintf("generated/bind-config/%s.conf", currentMaster.Name),
fmt.Sprintf("generated/bind-config/%s.conf", currentPrimary.Name),
templateVars,
)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions ns/dns/zonegenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,13 @@ func GenerateZones(addresses []model.IPAddress, defaultSoaInfo SOAInfo, conf *co
templateArgs.ZoneName = zone

soaInfo := defaultSoaInfo
masterConf := util.FindMasterForZone(*conf, zone)
if masterConf != nil {
soaInfo.DottedMailResponsible = masterConf.DottedEmail
soaInfo.NameserverFQDN = fmt.Sprintf("%s.", masterConf.Name)
primaryConf := util.FindPrimaryForZone(*conf, zone)
if primaryConf != nil {
soaInfo.DottedMailResponsible = primaryConf.DottedEmail
soaInfo.NameserverFQDN = fmt.Sprintf("%s.", primaryConf.Name)

var includes []string
for _, include := range masterConf.Includes {
for _, include := range primaryConf.Includes {
if include.Zone == zone {
includes = append(includes, include.IncludeFiles...)
}
Expand Down
20 changes: 10 additions & 10 deletions templates/bind-config.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* Start of config for nameserver {{ .ServerName }}
*/

/* acl and master lists */
{{ range $aclMaster := .AclMasterLists -}}
{{ $aclMaster.Type }} "{{$aclMaster.Name}}" {
{{ range $ip := $aclMaster.Entries }} {{ $ip }};
/* acl and primary lists */
{{ range $aclPrimary := .AclPrimaryLists -}}
{{ $aclPrimary.Type }} "{{$aclPrimary.Name}}" {
{{ range $entry := $aclPrimary.Entries }} {{ $entry.IP }}{{ if and ($entry.Port) (eq $aclPrimary.Type "masters") }} port {{ $entry.Port }}{{ end }};
{{ end -}}
};
{{ end }}
Expand All @@ -16,21 +16,21 @@
zone "{{ $zone.Name }}" {
type {{ $zone.Type }};
file "/
{{- if $zone.IsSlave -}}
{{- if $zone.IsSecondary -}}
var/cache/bind
{{- else -}}
etc/bind/zones
{{- end -}}
/{{ $zone.Name }}.db";
{{- if $zone.IsSlave }}
masters { {{ $zone.MasterIP }}; };
{{- if $zone.IsSecondary }}
masters { {{ $zone.PrimaryIP }}{{ if $zone.PrimaryPort }} port {{ $zone.PrimaryPort }}{{ end }}; };
transfer-source {{ $.ServerIP }};
{{- else }}
allow-transfer { {{ range $transfer := $zone.TransferAcls }}"{{ $transfer }}"; {{ end -}} };
also-notify { {{ range $master := $zone.NotifyMasters }}"{{ $master }}"; {{ end -}} };
allow-transfer { {{ range $transferAcl := $zone.TransferAcls }}"{{ $transferAcl }}"; {{ end -}} };
also-notify { {{ range $primaryAcl := $zone.NotifyPrimaries }}"{{ $primaryAcl }}"; {{ end -}} };
notify yes;
{{- end -}}
{{- if and ($zone.IsDnssecEnabled) (not $zone.IsSlave) }}
{{- if and ($zone.IsDnssecEnabled) (not $zone.IsSecondary) }}
/* This zone is DNSSEC enabled */
dnssec-policy default;
inline-signing yes;
Expand Down
8 changes: 4 additions & 4 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ func SliceContainsString(slice []string, value string) bool {
return false
}

func FindMasterForZone(conf config.NXConfig, zone string) *config.MasterConfig {
for _, master := range conf.Namespaces.DNS.Masters {
if SliceContainsString(master.Zones, zone) {
return &master
func FindPrimaryForZone(conf config.NXConfig, zone string) *config.PrimaryConfig {
for _, primary := range conf.Namespaces.DNS.Primaries {
if SliceContainsString(primary.Zones, zone) {
return &primary
}
}

Expand Down

0 comments on commit 8854e76

Please sign in to comment.