From dfba1b2bd329669b5e31ec44c7de6c8ef28b955d Mon Sep 17 00:00:00 2001 From: Sergey G Date: Mon, 7 Aug 2023 19:43:26 +0200 Subject: [PATCH] refactor: split on subcommands --- Dockerfile | 1 + cmd/cname.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++ cmd/subdomain.go | 38 ++++++++++++++++++ go.mod | 10 +++-- go.sum | 20 +++++++--- main.go | 68 ++++++------------------------- 6 files changed, 173 insertions(+), 65 deletions(-) create mode 100644 cmd/cname.go create mode 100644 cmd/subdomain.go diff --git a/Dockerfile b/Dockerfile index d1e373d..1daf075 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,5 @@ RUN go build -ldflags="-w -s" -o /go-avahi-cname # STAGE 2: build the container to run FROM scratch COPY --from=builder /go-avahi-cname /go-avahi-cname +EXPOSE 5353/udp ENTRYPOINT ["/go-avahi-cname"] diff --git a/cmd/cname.go b/cmd/cname.go new file mode 100644 index 0000000..18ef257 --- /dev/null +++ b/cmd/cname.go @@ -0,0 +1,101 @@ +package cmd + +import ( + "context" + "fmt" + "log" + "os" + "time" + + "github.com/grishy/go-avahi-cname/publisher" + "github.com/miekg/dns" + "github.com/urfave/cli/v2" +) + +func formatCname(hostnameFqdn string, cnames []string) []string { + log.Println("Formating CNAMEs:") + + for i, cname := range cnames { + if !dns.IsFqdn(cname) { + cnames[i] = dns.Fqdn(cname + "." + hostnameFqdn) + + log.Printf(" > '%s' (added current FQDN)", cnames[i]) + continue + } + + log.Printf(" > '%s'", cname) + } + + return cnames +} + +func publishing(ctx context.Context, publisher *publisher.Publisher, ttl, interval uint32, cnames []string) { + resendDuration := time.Duration(interval) * time.Second + log.Printf("Publishing every %v and CNAME TTL=%ds.", resendDuration, ttl) + + // To start publishing immediately + // https://github.com/golang/go/issues/17601 + if err := publisher.PublishCNAMES(cnames, ttl); err != nil { + log.Fatalf("can't publish CNAMEs: %v", err) + } + + for { + select { + case <-time.Tick(resendDuration): + if err := publisher.PublishCNAMES(cnames, ttl); err != nil { + log.Fatalf("can't publish CNAMEs: %v", err) + } + case <-ctx.Done(): + fmt.Println() + log.Println("Closing publisher...") + if err := publisher.Close(); err != nil { + log.Fatalf("Can't close publisher: %v", err) + } + os.Exit(0) + } + } +} + +func cnameCmd(ctx context.Context, ttl, interval uint32, cnames []string) { + +} + +func CmdCname(ctx context.Context) *cli.Command { + return &cli.Command{ + Name: "cname", + Usage: "anonse CNAME via Avahi", + Flags: []cli.Flag{ + &cli.UintFlag{ + Name: "ttl", + Value: 600, + EnvVars: []string{"CNAME_TTL"}, + Usage: "TTL of CNAME record in seconds", + }, + &cli.UintFlag{ + Name: "interval", + Value: 300, + EnvVars: []string{"CNAME_INTERVAL"}, + Usage: "Interval of sending CNAME record in seconds", + }, + }, + Action: func(cCtx *cli.Context) error { + ttl := uint32(cCtx.Uint("ttl")) + interval := uint32(cCtx.Uint("interval")) + cnames := cCtx.Args().Slice() + + if len(cnames) == 0 { + log.Fatal("CNAMEs are not specified") + } + + log.Println("Creating publisher") + publisher, err := publisher.NewPublisher() + if err != nil { + log.Fatalf("Can't create publisher: %v", err) + } + + formattedCname := formatCname(publisher.Fqdn(), cnames) + publishing(ctx, publisher, ttl, interval, formattedCname) + return nil + }, + } +} diff --git a/cmd/subdomain.go b/cmd/subdomain.go new file mode 100644 index 0000000..9abe5c1 --- /dev/null +++ b/cmd/subdomain.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "context" + + "github.com/urfave/cli/v2" +) + +func CmdSubdomain(ctx context.Context) *cli.Command { + return &cli.Command{ + Name: "subdomain", + Usage: "reply on all subdomains queries", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "domain", + Value: "", + EnvVars: []string{"SUBDOMAIN_DOMAIN"}, + Usage: "Domain name to publish", + }, + &cli.StringSliceFlag{ + Name: "ifaces", + Value: nil, + EnvVars: []string{"SUBDOMAIN_IFACES"}, + Usage: "Interface for listening and publishing", + }, + &cli.BoolFlag{ + Name: "use-avahi", + Value: true, + EnvVars: []string{"SUBDOMAIN_USE_AVAHI"}, + Usage: "Use avahi for sending CNAMEs or plain DNS", + }, + }, + Action: func(cCtx *cli.Context) error { + + return nil + }, + } +} diff --git a/go.mod b/go.mod index 91d9a26..e811d4e 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,15 @@ require ( github.com/godbus/dbus/v5 v5.1.0 github.com/holoplot/go-avahi v1.0.1 github.com/miekg/dns v1.1.55 + github.com/urfave/cli/v2 v2.25.7 ) require ( + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.12.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/tools v0.11.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/tools v0.12.0 // indirect ) diff --git a/go.sum b/go.sum index f299854..141e9e2 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -5,12 +7,18 @@ github.com/holoplot/go-avahi v1.0.1 h1:XcqR2keL4qWRnlxHD5CAOdWpLFZJ+EOUK0vEuylfv github.com/holoplot/go-avahi v1.0.1/go.mod h1:qH5psEKb0DK+BRplMfc+RY4VMOlbf6mqfxgpMy6aP0M= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= -golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= diff --git a/main.go b/main.go index 0316344..8123cfa 100644 --- a/main.go +++ b/main.go @@ -2,72 +2,28 @@ package main import ( "context" - "fmt" "log" "os" "os/signal" - "time" - "github.com/grishy/go-avahi-cname/publisher" - "github.com/miekg/dns" + "github.com/grishy/go-avahi-cname/cmd" + "github.com/urfave/cli/v2" ) -const TTL = uint32(10 * 60) // in seconds - -func formatCname(hostnameFqdn string, cnames []string) []string { - log.Println("Formating CNAMEs:") - - for i, cname := range cnames { - if !dns.IsFqdn(cname) { - cnames[i] = dns.Fqdn(cname + "." + hostnameFqdn) - - log.Printf(" > '%s' (added current FQDN)", cnames[i]) - continue - } - - log.Printf(" > '%s'", cname) - } - - return cnames -} - -func publishing(ctx context.Context, publisher *publisher.Publisher, cnames []string) { - resendDuration := time.Duration(TTL/2) * time.Second - log.Printf("Publishing every %v and CNAME TTL=%ds.", resendDuration, TTL) - - // To start publishing immediately - // https://github.com/golang/go/issues/17601 - if err := publisher.PublishCNAMES(cnames, TTL); err != nil { - log.Fatalf("can't publish CNAMEs: %v", err) - } - - for { - select { - case <-time.Tick(resendDuration): - if err := publisher.PublishCNAMES(cnames, TTL); err != nil { - log.Fatalf("can't publish CNAMEs: %v", err) - } - case <-ctx.Done(): - fmt.Println() - log.Println("Closing publisher...") - if err := publisher.Close(); err != nil { - log.Fatalf("Can't close publisher: %v", err) - } - os.Exit(0) - } - } -} - func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) defer stop() - log.Println("Creating publisher") - publisher, err := publisher.NewPublisher() - if err != nil { - log.Fatalf("Can't create publisher: %v", err) + app := &cli.App{ + Name: "go-avahi-cname", + Usage: "make an explosive entrance", + Commands: []*cli.Command{ + cmd.CmdCname(ctx), + cmd.CmdSubdomain(ctx), + }, } - cnames := formatCname(publisher.Fqdn(), os.Args[1:]) - publishing(ctx, publisher, cnames) + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } }