146 lines
3.4 KiB
Go
146 lines
3.4 KiB
Go
// Copyright (c) 2026 Sławomir Koszewski. All rights reserved.
|
|
// Use of this source code is governed by the MIT License
|
|
// that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
|
|
miab "gitea.koszewscy.waw.pl/koszewscy/mailinabox-go"
|
|
)
|
|
|
|
|
|
func usage() {
|
|
fmt.Fprintf(os.Stderr, `Usage: miab <command> [options]
|
|
|
|
Commands:
|
|
list [--type TYPE] List custom DNS records
|
|
set [--type TYPE] <name> <value> Set (replace) a DNS record
|
|
add [--type TYPE] <name> <value> Add a DNS record
|
|
delete [--type TYPE] <name> [value] Delete a DNS record
|
|
|
|
Credentials: any empty parameter falls back to environment variables.
|
|
MIAB_HOST / MAILINABOX_BASE_URL Mail-in-a-Box hostname (MIAB_HOST takes precedence;
|
|
hostname is parsed from MAILINABOX_BASE_URL if set)
|
|
MIAB_USERNAME / MAILINABOX_EMAIL Admin email address
|
|
MIAB_PASSWORD / MAILINABOX_PASSWORD Admin password
|
|
`)
|
|
}
|
|
|
|
func miabClient() *miab.Client {
|
|
c, err := miab.NewClient("", "", "")
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
return c
|
|
}
|
|
|
|
func main() {
|
|
flag.Usage = usage
|
|
flag.Parse()
|
|
|
|
if flag.NArg() < 1 {
|
|
usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
cmd := flag.Arg(0)
|
|
args := flag.Args()[1:]
|
|
|
|
switch cmd {
|
|
case "list":
|
|
runList(args)
|
|
case "set":
|
|
runSet(args)
|
|
case "delete":
|
|
runDelete(args)
|
|
case "add":
|
|
runAdd(args)
|
|
default:
|
|
fmt.Fprintf(os.Stderr, "miab: unknown command %q\n", cmd)
|
|
usage()
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func runList(args []string) {
|
|
fs := flag.NewFlagSet("list", flag.ExitOnError)
|
|
recordType := fs.String("type", "", "Filter by record type (e.g. A, TXT, MX)")
|
|
fs.Parse(args)
|
|
|
|
client := miabClient()
|
|
records, err := client.ListRecords(*recordType)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "miab: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if *recordType != "" {
|
|
fmt.Printf("Custom %s records:\n", *recordType)
|
|
} else {
|
|
fmt.Println("Custom DNS records:")
|
|
}
|
|
for _, r := range records {
|
|
fmt.Printf(" - %s (%s): %s\n", r.Name, r.Type, r.Value)
|
|
}
|
|
}
|
|
|
|
func runSet(args []string) {
|
|
fs := flag.NewFlagSet("set", flag.ExitOnError)
|
|
recordType := fs.String("type", "A", "Record type (e.g. A, TXT)")
|
|
fs.Parse(args)
|
|
|
|
if fs.NArg() < 2 {
|
|
fmt.Fprintln(os.Stderr, "miab set: usage: set [--type TYPE] <name> <value>")
|
|
os.Exit(1)
|
|
}
|
|
name, value := fs.Arg(0), fs.Arg(1)
|
|
|
|
client := miabClient()
|
|
if err := client.SetRecord(name, *recordType, value); err != nil {
|
|
fmt.Fprintf(os.Stderr, "miab: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func runDelete(args []string) {
|
|
fs := flag.NewFlagSet("delete", flag.ExitOnError)
|
|
recordType := fs.String("type", "A", "Record type (e.g. A, TXT)")
|
|
fs.Parse(args)
|
|
|
|
if fs.NArg() < 1 {
|
|
fmt.Fprintln(os.Stderr, "miab delete: usage: delete [--type TYPE] <name> [value]")
|
|
os.Exit(1)
|
|
}
|
|
name := fs.Arg(0)
|
|
value := fs.Arg(1)
|
|
|
|
client := miabClient()
|
|
if err := client.DeleteRecord(name, *recordType, value); err != nil {
|
|
fmt.Fprintf(os.Stderr, "miab: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func runAdd(args []string) {
|
|
fs := flag.NewFlagSet("add", flag.ExitOnError)
|
|
recordType := fs.String("type", "A", "Record type (e.g. A, TXT)")
|
|
fs.Parse(args)
|
|
|
|
if fs.NArg() < 2 {
|
|
fmt.Fprintln(os.Stderr, "miab add: usage: add [--type TYPE] <name> <value>")
|
|
os.Exit(1)
|
|
}
|
|
name, value := fs.Arg(0), fs.Arg(1)
|
|
|
|
client := miabClient()
|
|
if err := client.AddRecord(name, *recordType, value); err != nil {
|
|
fmt.Fprintf(os.Stderr, "miab: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|