Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ run:

linters:
enable:
- errcheck
- gocyclo
- misspell
- revive
- govet
- gosec
- staticcheck
formatters:
enable:
- gofmt
Expand Down
19 changes: 14 additions & 5 deletions build/codeCheck.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
#!/usr/bin/env bash
set -e -o pipefail

## ensure golangci-lint - https://golangci-lint.run
golangci="$(go env GOPATH)/bin/golangci-lint"
if ! ${golangci} version &> /dev/null; then
echo "Installing golangci-lint binary to ${golangci}"
curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin
echo "done"
fi

## run golangci-lint - all config in .golangci.yml
lintRun=$(${golangci} run --show-stats ./...)
lintRet=$?
echo "golangci-lint ${lintRun}"
exit $lintRet
echo "Running golangci-lint ..."
${golangci} run --show-stats ./...

## ensure gvulncheck
govulncheck="$(go env GOPATH)/bin/govulncheck"
if ! ${govulncheck} -version &> /dev/null; then
echo "Installing govulncheck binary to ${govulncheck}"
go install golang.org/x/vuln/cmd/govulncheck@latest
fi

## run govulncheck
echo "Running govulncheck ..."
${govulncheck} -show verbose ./...
6 changes: 5 additions & 1 deletion command/check/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ type Command struct {

// Run is a function to run the command
func (c *Command) Run(args []string) int {
var showHelp bool
var err error

// init flags
if err = c.setupFlags(args); err != nil {
if showHelp, err = c.setupFlags(args); err != nil {
c.Log.Error("failed to init flags", "err", err)
return 1
}
if showHelp {
return 0
}

// check ip
if err = c.checkIP(); err != nil {
Expand Down
14 changes: 7 additions & 7 deletions command/check/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

// setupFlags initializes the instance configuration
func (c *Command) setupFlags(args []string) error {
func (c *Command) setupFlags(args []string) (bool, error) {
var cmdFlags *flag.FlagSet // instance flagset
var err error

Expand All @@ -33,17 +33,17 @@ func (c *Command) setupFlags(args []string) error {
cmdFlags.StringVar(&c.config.ipbe, "ipbe", "ipify",
"IP lookup backend")

// parse flags and ignore error
// parse flags and catch help
if err = cmdFlags.Parse(args); err != nil {
if stderrors.Is(err, flag.ErrHelp) {
return nil
return true, nil
}
return fmt.Errorf("parse check flags: %w", err)
return false, fmt.Errorf("parse check flags: %w", err)
}

// check for remaining garbage
if cmdFlags.NArg() > 0 {
return internalerrors.ErrUnknownArg
return false, internalerrors.ErrUnknownArg
}

// default to v4 if not specified
Expand All @@ -53,8 +53,8 @@ func (c *Command) setupFlags(args []string) error {

// init ip backend
if c.ip, err = internal.GetIPBackend(c.config.ipbe); err != nil {
return fmt.Errorf("init ip backend: %w", err)
return false, fmt.Errorf("init ip backend: %w", err)
}

return nil
return false, nil
}
16 changes: 13 additions & 3 deletions command/check/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ func TestSetupFlagsDefaultsToIPv4(t *testing.T) {

cmd := &Command{Self: "ipman"}

if err := cmd.setupFlags(nil); err != nil {
showHelp, err := cmd.setupFlags(nil)
if err != nil {
t.Fatalf("setupFlags() error = %v", err)
}
if showHelp {
t.Fatal("setupFlags() unexpectedly requested help")
}

if !cmd.config.v4 {
t.Fatal("setupFlags() did not default to IPv4")
Expand All @@ -34,10 +38,13 @@ func TestSetupFlagsReturnsParseError(t *testing.T) {

cmd := &Command{Self: "ipman"}

err := cmd.setupFlags([]string{"-unknown"})
showHelp, err := cmd.setupFlags([]string{"-unknown"})
if err == nil {
t.Fatal("setupFlags() error = nil, want parse failure")
}
if showHelp {
t.Fatal("setupFlags() unexpectedly requested help")
}

if !strings.Contains(err.Error(), "parse check flags") {
t.Fatalf("setupFlags() error = %v, want contextual parse error", err)
Expand All @@ -49,10 +56,13 @@ func TestSetupFlagsRejectsTrailingArgs(t *testing.T) {

cmd := &Command{Self: "ipman"}

err := cmd.setupFlags([]string{"extra"})
showHelp, err := cmd.setupFlags([]string{"extra"})
if err == nil {
t.Fatal("setupFlags() error = nil, want trailing arg failure")
}
if showHelp {
t.Fatal("setupFlags() unexpectedly requested help")
}

if err != internalerrors.ErrUnknownArg {
t.Fatalf("setupFlags() error = %v, want %v", err, internalerrors.ErrUnknownArg)
Expand Down
6 changes: 5 additions & 1 deletion command/update/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ type Command struct {

// Run is a function to run the command
func (c *Command) Run(args []string) int {
var showHelp bool
var err error

// init flags
if err = c.setupFlags(args); err != nil {
if showHelp, err = c.setupFlags(args); err != nil {
c.Log.Error("failed to init flags", "err", err)
return 1
}
if showHelp {
return 0
}

// attempt to update p
if err = c.updateIP(); err != nil {
Expand Down
18 changes: 9 additions & 9 deletions command/update/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

// setupFlags initializes the instance configuration
func (c *Command) setupFlags(args []string) error {
func (c *Command) setupFlags(args []string) (bool, error) {
var cmdFlags *flag.FlagSet // instance flagset
var err error

Expand Down Expand Up @@ -45,23 +45,23 @@ func (c *Command) setupFlags(args []string) error {
cmdFlags.StringVar(&c.config.dnsbe, "dnsbe", "cloudflare",
"DNS update backend")

// parse flags and ignore error
// parse flags and catch help
if err = cmdFlags.Parse(args); err != nil {
if stderrors.Is(err, flag.ErrHelp) {
return nil
return true, nil
}
return fmt.Errorf("parse update flags: %w", err)
return false, fmt.Errorf("parse update flags: %w", err)
}

// check for remaining garbage
if cmdFlags.NArg() > 0 {
return internalerrors.ErrUnknownArg
return false, internalerrors.ErrUnknownArg
}

// check zone and attempt to get from environment
if c.config.zone == "" {
if c.config.zone = os.Getenv("IPMAN_DNS_ZONE"); c.config.zone == "" {
return internalerrors.ErrMissingZone
return false, internalerrors.ErrMissingZone
}
}

Expand All @@ -82,12 +82,12 @@ func (c *Command) setupFlags(args []string) error {

// init ip backend
if c.ip, err = internal.GetIPBackend(c.config.ipbe); err != nil {
return fmt.Errorf("init ip backend: %w", err)
return false, fmt.Errorf("init ip backend: %w", err)
}

// init dns backend
if c.dns, err = internal.GetDNSBackend(c.config.dnsbe); err != nil {
return fmt.Errorf("init dns backend: %w", err)
return false, fmt.Errorf("init dns backend: %w", err)
}

// set backend access key if needed
Expand All @@ -105,5 +105,5 @@ func (c *Command) setupFlags(args []string) error {
c.config.ttl = c.dns.RecordTTL()
}

return nil
return false, nil
}
16 changes: 13 additions & 3 deletions command/update/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ func TestSetupFlagsLoadsZoneFromEnv(t *testing.T) {

cmd := &Command{Self: "ipman"}

if err := cmd.setupFlags(nil); err != nil {
showHelp, err := cmd.setupFlags(nil)
if err != nil {
t.Fatalf("setupFlags() error = %v", err)
}
if showHelp {
t.Fatal("setupFlags() unexpectedly requested help")
}

if got := cmd.config.zone; got != "example.com" {
t.Fatalf("setupFlags() zone = %q, want %q", got, "example.com")
Expand All @@ -34,10 +38,13 @@ func TestSetupFlagsReturnsParseError(t *testing.T) {

cmd := &Command{Self: "ipman"}

err := cmd.setupFlags([]string{"-ttl=bad"})
showHelp, err := cmd.setupFlags([]string{"-ttl=bad"})
if err == nil {
t.Fatal("setupFlags() error = nil, want parse failure")
}
if showHelp {
t.Fatal("setupFlags() unexpectedly requested help")
}

if !strings.Contains(err.Error(), "parse update flags") {
t.Fatalf("setupFlags() error = %v, want contextual parse error", err)
Expand All @@ -49,10 +56,13 @@ func TestSetupFlagsRequiresZoneWhenUnset(t *testing.T) {

cmd := &Command{Self: "ipman"}

err := cmd.setupFlags(nil)
showHelp, err := cmd.setupFlags(nil)
if err == nil {
t.Fatal("setupFlags() error = nil, want missing zone failure")
}
if showHelp {
t.Fatal("setupFlags() unexpectedly requested help")
}

if err != internalerrors.ErrMissingZone {
t.Fatalf("setupFlags() error = %v, want %v", err, internalerrors.ErrMissingZone)
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module github.com/leprechau/ipman

go 1.21
go 1.25.0

require github.com/go-resty/resty/v2 v2.13.1
require github.com/go-resty/resty/v2 v2.17.2

require golang.org/x/net v0.27.0 // indirect
require golang.org/x/net v0.52.0 // indirect
56 changes: 6 additions & 50 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,50 +1,6 @@
github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk=
github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
7 changes: 6 additions & 1 deletion internal/dns/cloudflare/config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package cloudflare

import (
"time"

"github.com/go-resty/resty/v2"
"github.com/leprechau/ipman/internal/dns"
)

const requestTimeout = 30 * time.Second

// Config contains backend configuration
type Config struct {
apiToken string
Expand All @@ -21,7 +25,8 @@ func DefaultConfig() *Config {
recordTTL: 600,
client: resty.New().
SetHeader("Accept", "application/json").
SetBaseURL("https://api.cloudflare.com/client/v4"),
SetBaseURL("https://api.cloudflare.com/client/v4").
SetTimeout(requestTimeout),
}
}

Expand Down
7 changes: 6 additions & 1 deletion internal/dns/godaddy/config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package godaddy

import (
"time"

"github.com/go-resty/resty/v2"
"github.com/leprechau/ipman/internal/dns"
)

const requestTimeout = 30 * time.Second

// Config contains backend configuration
type Config struct {
accessKey string
Expand All @@ -21,7 +25,8 @@ func DefaultConfig() *Config {
recordTTL: 600,
client: resty.New().
SetHeader("Accept", "application/json").
SetBaseURL("https://api.godaddy.com/v1"),
SetBaseURL("https://api.godaddy.com/v1").
SetTimeout(requestTimeout),
}
}

Expand Down
Loading
Loading