Reengineered code.

This commit is contained in:
2025-08-13 22:28:17 +02:00
parent 840e17d1da
commit fe17c55bd0

View File

@@ -61,7 +61,94 @@ func FetchNetboxIPAddresses(apiBaseURL, token string) ([]IPAddress, error) {
return filtered, nil
}
func CreateDnsMasqConfig(writeConfig bool) {
var apiBaseURL string
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: %s <run|serve> [flags]\n", os.Args[0])
os.Exit(1)
}
subCmd := os.Args[1]
// Prepare a FlagSet for subcommands, sharing the same flags
flags := flag.NewFlagSet(subCmd, flag.ExitOnError)
var apiURL string
var outputFormat string
var outputFile string
var outputDir string
var dryRun bool
var listenAddr string
flags.StringVar(&apiURL, "api-url", "https://netbox.koszewscy.waw.pl/api", "NetBox API URL to fetch IP addresses")
flags.StringVar(&outputFormat, "output-format", "hosts", "output format: config or hosts")
flags.StringVar(&outputFile, "output-file", "", "output file name (overrides default)")
flags.StringVar(&outputDir, "output-dir", "", "output base directory (overrides default)")
flags.BoolVar(&dryRun, "dry-run", false, "if set, do not write to dnsmasq config file, just print the output")
flags.StringVar(&listenAddr, "listen", ":8080", "address and port to listen on (e.g. :8080 or 127.0.0.1:8080)")
flags.Parse(os.Args[2:])
apiBaseURL = apiURL
// Set defaults based on output format
var defaultDir, defaultFile string
switch outputFormat {
case "hosts":
defaultDir = "/etc"
defaultFile = "hosts.netbox"
case "config":
defaultDir = "/etc/dnsmasq.d"
defaultFile = "netbox.conf"
default:
log.Fatalf("Unknown output format: %s", outputFormat)
}
dir := defaultDir
file := defaultFile
if outputDir != "" {
dir = outputDir
}
if outputFile != "" {
file = outputFile
}
switch subCmd {
case "run":
if listenAddr != ":8080" && listenAddr != "" {
log.Fatalf("The --listen flag is only valid with the 'serve' subcommand.")
}
if dryRun {
log.Println("Dry run mode enabled, not writing to dnsmasq config file.")
CreateDnsMasqConfig(true, outputFormat, dir, file)
} else {
CreateDnsMasqConfig(false, outputFormat, dir, file)
}
case "serve":
http.HandleFunc("/update-dnsmasq", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte("Method not allowed"))
return
}
CreateDnsMasqConfig(false, outputFormat, dir, file)
cmd := exec.Command("systemctl", "restart", "dnsmasq.service")
if err := cmd.Run(); err != nil {
log.Printf("Failed to restart dnsmasq.service: %v", err)
w.Write([]byte("\nWarning: Failed to restart dnsmasq.service.\n"))
}
w.Write([]byte("DNSMasq config updated."))
})
log.Printf("Starting web service on %s...", listenAddr)
if err := http.ListenAndServe(listenAddr, nil); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
default:
fmt.Fprintf(os.Stderr, "Unknown subcommand: %s\n", subCmd)
os.Exit(1)
}
}
// Update CreateDnsMasqConfig to accept new parameters
func CreateDnsMasqConfig(writeConfig bool, outputFormat, dir, file string) {
token := os.Getenv("NETBOX_TOKEN")
if token == "" {
home := os.Getenv("HOME")
@@ -86,53 +173,26 @@ func CreateDnsMasqConfig(writeConfig bool) {
log.Fatalf("Error fetching IP addresses: %v", err)
}
dir := "/etc/dnsmasq.d"
if stat, err := os.Stat(dir); err == nil && stat.IsDir() && !writeConfig {
file, err := os.Create(dir + "/netbox.conf")
f, err := os.Create(path.Join(dir, file))
if err != nil {
log.Fatalf("Failed to create netbox.conf: %v", err)
log.Fatalf("Failed to create %s: %v", file, err)
}
defer file.Close()
defer f.Close()
for _, ip := range ips {
fmt.Fprintf(file, "address=/%s/%s\n", ip.DNSName, ip.Address)
if outputFormat == "hosts" {
fmt.Fprintf(f, "%s\t%s\n", ip.Address, ip.DNSName)
} else {
fmt.Fprintf(f, "address=/%s/%s\n", ip.DNSName, ip.Address)
}
}
} else {
for _, ip := range ips {
if outputFormat == "hosts" {
fmt.Printf("%s\t%s\n", ip.Address, ip.DNSName)
} else {
fmt.Printf("address=/%s/%s\n", ip.DNSName, ip.Address)
}
}
}
var apiBaseURL string
func main() {
listenAddr := flag.String("listen", ":8080", "address and port to listen on (e.g. :8080 or 127.0.0.1:8080)")
flag.StringVar(&apiBaseURL, "api-url", "https://netbox.koszewscy.waw.pl/api", "NetBox API URL to fetch IP addresses")
dryRun := flag.Bool("dry-run", false, "if set, do not write to dnsmasq config file, just print the output")
flag.Parse()
if *dryRun {
log.Println("Dry run mode enabled, not writing to dnsmasq config file.")
CreateDnsMasqConfig(true)
return
}
http.HandleFunc("/update-dnsmasq", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte("Method not allowed"))
return
}
CreateDnsMasqConfig(false)
cmd := exec.Command("systemctl", "restart", "dnsmasq.service")
if err := cmd.Run(); err != nil {
log.Printf("Failed to restart dnsmasq.service: %v", err)
w.Write([]byte("\nWarning: Failed to restart dnsmasq.service.\n"))
}
w.Write([]byte("DNSMasq config updated."))
})
log.Printf("Starting web service on %s...", *listenAddr)
if err := http.ListenAndServe(*listenAddr, nil); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
}