dnsmasq-netbox-connector/internal/config/dnsmasq.go

97 lines
2.3 KiB
Go
Raw Normal View History

2024-10-03 16:30:23 +00:00
package config
import (
"fmt"
"os"
"path"
"strings"
)
const (
leaseFileKey = "dhcp-leasefile"
rangeKey = "dhcp-range"
confFileKey = "conf-file"
confDirKey = "conf-dir"
)
func tryParseLineOption(line, key string) (string, bool) {
if !strings.HasPrefix(line, key) {
return "", false
}
_, val, found := strings.Cut(line, "=")
return val, found
}
type dnsmasqConfOptions struct {
leaseFile string
rangeStart string
rangeEnd string
}
func defaultDNSMasqOptions() map[string]string {
return map[string]string{
confDirKey: "/etc/dnsmasq.d",
confFileKey: "",
leaseFileKey: "/var/lib/misc/dnsmasq.leases",
rangeKey: "",
}
}
func parseDNSMasqConfFile(content string, options map[string]string) {
for _, l := range strings.Split(content, "\n") {
for key := range options {
newVal, found := tryParseLineOption(l, key)
if found {
options[key] = newVal
}
}
}
}
func parseDNSMasqOptions(rootFileContent string) (dnsmasqConfOptions, error) {
rawOptions := defaultDNSMasqOptions()
// start with parsing the root file
parseDNSMasqConfFile(rootFileContent, rawOptions)
// get all additional conf files in the provided directory
confDir := rawOptions[confDirKey]
if confDir != "" {
entries, err := os.ReadDir(confDir)
if err != nil {
return dnsmasqConfOptions{}, fmt.Errorf("failed to get list of additional config files: %w", err)
}
for _, e := range entries {
if e.IsDir() || !strings.HasSuffix(e.Name(), ".conf") {
continue
}
fileContent, err := os.ReadFile(path.Join(confDir, e.Name()))
if err != nil {
return dnsmasqConfOptions{}, fmt.Errorf("failed to read sub config file: %w", err)
}
parseDNSMasqConfFile(string(fileContent), rawOptions)
}
}
// get any additional config file
if additionalFile := rawOptions[confFileKey]; additionalFile != "" {
filecontent, err := os.ReadFile(additionalFile)
if err != nil {
return dnsmasqConfOptions{}, fmt.Errorf("failed to read additional config file: %w", err)
}
parseDNSMasqConfFile(string(filecontent), rawOptions)
}
dhcpRange := strings.Split(rawOptions[rangeKey], ",")
if len(dhcpRange) < 2 {
return dnsmasqConfOptions{}, fmt.Errorf("invalid value for DHCP range: %s", rawOptions[rangeKey])
}
return dnsmasqConfOptions{
leaseFile: rawOptions[leaseFileKey],
rangeStart: dhcpRange[0],
rangeEnd: dhcpRange[1],
}, nil
}