lint: multiple warns cleanup

This commit is contained in:
Umputun
2021-04-09 15:05:22 -05:00
parent 220f966720
commit 9029b4d60f
14 changed files with 157 additions and 75 deletions

80
.golangci.yml Normal file
View File

@@ -0,0 +1,80 @@
run:
timeout: 5m
output:
format: tab
skip-dirs:
- vendor
skip-files:
- app/proxy/middleware/compress.go
- app/proxy/middleware/compress_test.go
linters-settings:
govet:
check-shadowing: true
golint:
min-confidence: 0.1
maligned:
suggest-new: true
goconst:
min-len: 2
min-occurrences: 2
misspell:
locale: US
lll:
line-length: 140
gocritic:
enabled-tags:
- performance
- style
- experimental
disabled-checks:
- wrapperFunc
- hugeParam
- rangeValCopy
- singleCaseSwitch
- ifElseChain
linters:
enable:
- megacheck
- golint
- govet
- unconvert
- megacheck
- structcheck
- gas
- gocyclo
- dupl
- misspell
- unparam
- varcheck
- deadcode
- typecheck
- ineffassign
- varcheck
- stylecheck
- gochecknoinits
- scopelint
- gocritic
- nakedret
- gosimple
- prealloc
fast: false
disable-all: true
issues:
exclude-rules:
- text: "at least one file in a package should have a package comment"
linters:
- stylecheck
- text: "should have a package comment, unless it's in another file for this package"
linters:
- golint
- path: _test\.go
linters:
- gosec
- dupl
exclude-use-default: false
service:
golangci-lint-version: 1.31.x

View File

@@ -18,12 +18,12 @@ import (
// Service implements discovery with multiple providers and url matcher
type Service struct {
providers []Provider
mappers []UrlMapper
mappers []URLMapper
lock sync.RWMutex
}
// UrlMapper contains all info about source and destination routes
type UrlMapper struct {
// URLMapper contains all info about source and destination routes
type URLMapper struct {
Server string
SrcMatch regexp.Regexp
Dst string
@@ -34,7 +34,7 @@ type UrlMapper struct {
// Provider defines sources of mappers
type Provider interface {
Events(ctx context.Context) (res <-chan struct{})
List() (res []UrlMapper, err error)
List() (res []URLMapper, err error)
ID() ProviderID
}
@@ -57,7 +57,7 @@ func NewService(providers []Provider) *Service {
// and updating all mappers on each event
func (s *Service) Run(ctx context.Context) error {
var evChs []<-chan struct{}
evChs := make([]<-chan struct{}, 0, len(s.providers))
for _, p := range s.providers {
evChs = append(evChs, p.Events(ctx))
}
@@ -73,7 +73,7 @@ func (s *Service) Run(ctx context.Context) error {
log.Printf("[INFO] match for %s: %s %s %s", m.ProviderID, m.Server, m.SrcMatch.String(), m.Dst)
}
s.lock.Lock()
s.mappers = make([]UrlMapper, len(lst))
s.mappers = make([]URLMapper, len(lst))
copy(s.mappers, lst)
s.lock.Unlock()
}
@@ -111,14 +111,14 @@ func (s *Service) Servers() (servers []string) {
}
// Mappers return list of all mappers
func (s *Service) Mappers() (mappers []UrlMapper) {
func (s *Service) Mappers() (mappers []URLMapper) {
s.lock.RLock()
defer s.lock.RUnlock()
mappers = append(mappers, s.mappers...)
return mappers
}
func (s *Service) mergeLists() (res []UrlMapper) {
func (s *Service) mergeLists() (res []URLMapper) {
for _, p := range s.providers {
lst, err := p.List()
if err != nil {
@@ -134,13 +134,13 @@ func (s *Service) mergeLists() (res []UrlMapper) {
}
// extendRule from /something/blah->http://example.com/api to ^/something/blah/(.*)->http://example.com/api/$1
func (s *Service) extendRule(m UrlMapper) UrlMapper {
func (s *Service) extendRule(m URLMapper) URLMapper {
src := m.SrcMatch.String()
if strings.Contains(m.Dst, "$1") || strings.Contains(src, "(") || !strings.HasSuffix(src, "/") {
return m
}
res := UrlMapper{
res := URLMapper{
Server: m.Server,
Dst: strings.TrimSuffix(m.Dst, "/") + "/$1",
ProviderID: m.ProviderID,

View File

@@ -18,8 +18,8 @@ func TestService_Do(t *testing.T) {
res <- struct{}{}
return res
},
ListFunc: func() ([]UrlMapper, error) {
return []UrlMapper{
ListFunc: func() ([]URLMapper, error) {
return []URLMapper{
{Server: "*", SrcMatch: *regexp.MustCompile("^/api/svc1/(.*)"), Dst: "http://127.0.0.1:8080/blah1/$1"},
{Server: "*", SrcMatch: *regexp.MustCompile("^/api/svc2/(.*)"), Dst: "http://127.0.0.2:8080/blah2/$1/abc"},
}, nil
@@ -32,8 +32,8 @@ func TestService_Do(t *testing.T) {
EventsFunc: func(ctx context.Context) <-chan struct{} {
return make(chan struct{}, 1)
},
ListFunc: func() ([]UrlMapper, error) {
return []UrlMapper{
ListFunc: func() ([]URLMapper, error) {
return []URLMapper{
{Server: "localhost", SrcMatch: *regexp.MustCompile("/api/svc3/xyz"), Dst: "http://127.0.0.3:8080/blah3/xyz"},
}, nil
},
@@ -73,8 +73,8 @@ func TestService_Match(t *testing.T) {
res <- struct{}{}
return res
},
ListFunc: func() ([]UrlMapper, error) {
return []UrlMapper{
ListFunc: func() ([]URLMapper, error) {
return []URLMapper{
{SrcMatch: *regexp.MustCompile("^/api/svc1/(.*)"), Dst: "http://127.0.0.1:8080/blah1/$1"},
{Server: "m.example.com", SrcMatch: *regexp.MustCompile("^/api/svc2/(.*)"),
Dst: "http://127.0.0.2:8080/blah2/$1/abc"},
@@ -88,8 +88,8 @@ func TestService_Match(t *testing.T) {
EventsFunc: func(ctx context.Context) <-chan struct{} {
return make(chan struct{}, 1)
},
ListFunc: func() ([]UrlMapper, error) {
return []UrlMapper{
ListFunc: func() ([]URLMapper, error) {
return []URLMapper{
{SrcMatch: *regexp.MustCompile("/api/svc3/xyz"), Dst: "http://127.0.0.3:8080/blah3/xyz"},
}, nil
},
@@ -136,8 +136,8 @@ func TestService_Servers(t *testing.T) {
res <- struct{}{}
return res
},
ListFunc: func() ([]UrlMapper, error) {
return []UrlMapper{
ListFunc: func() ([]URLMapper, error) {
return []URLMapper{
{SrcMatch: *regexp.MustCompile("^/api/svc1/(.*)"), Dst: "http://127.0.0.1:8080/blah1/$1"},
{Server: "m.example.com", SrcMatch: *regexp.MustCompile("^/api/svc2/(.*)"),
Dst: "http://127.0.0.2:8080/blah2/$1/abc"},
@@ -151,8 +151,8 @@ func TestService_Servers(t *testing.T) {
EventsFunc: func(ctx context.Context) <-chan struct{} {
return make(chan struct{}, 1)
},
ListFunc: func() ([]UrlMapper, error) {
return []UrlMapper{
ListFunc: func() ([]URLMapper, error) {
return []URLMapper{
{Server: "xx.reproxy.io", SrcMatch: *regexp.MustCompile("/api/svc3/xyz"), Dst: "http://127.0.0.3:8080/blah3/xyz"},
}, nil
},
@@ -177,35 +177,36 @@ func TestService_Servers(t *testing.T) {
func TestService_extendRule(t *testing.T) {
tbl := []struct {
inp UrlMapper
out UrlMapper
inp URLMapper
out URLMapper
}{
{
UrlMapper{SrcMatch: *regexp.MustCompile("/")},
UrlMapper{SrcMatch: *regexp.MustCompile("^/(.*)"), Dst: "/$1"},
URLMapper{SrcMatch: *regexp.MustCompile("/")},
URLMapper{SrcMatch: *regexp.MustCompile("^/(.*)"), Dst: "/$1"},
},
{
UrlMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
URLMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
SrcMatch: *regexp.MustCompile("/api/blah/"), Dst: "http://localhost:8080/"},
UrlMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
URLMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
SrcMatch: *regexp.MustCompile("^/api/blah/(.*)"), Dst: "http://localhost:8080/$1"},
},
{
UrlMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
URLMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
SrcMatch: *regexp.MustCompile("/api/blah/(.*)/xxx/(.*_)"), Dst: "http://localhost:8080/$1/$2"},
UrlMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
URLMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
SrcMatch: *regexp.MustCompile("/api/blah/(.*)/xxx/(.*_)"), Dst: "http://localhost:8080/$1/$2"},
},
{
UrlMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
URLMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
SrcMatch: *regexp.MustCompile("/api/blah"), Dst: "http://localhost:8080/xxx"},
UrlMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
URLMapper{Server: "m.example.com", PingURL: "http://example.com/ping", ProviderID: "docker",
SrcMatch: *regexp.MustCompile("/api/blah"), Dst: "http://localhost:8080/xxx"},
},
}
svc := &Service{}
for i, tt := range tbl {
tt := tt
t.Run(strconv.Itoa(i), func(t *testing.T) {
res := svc.extendRule(tt.inp)
assert.Equal(t, tt.out, res)

View File

@@ -63,13 +63,13 @@ func (d *Docker) Events(ctx context.Context) (res <-chan struct{}) {
}
// List all containers and make url mappers
func (d *Docker) List() ([]discovery.UrlMapper, error) {
func (d *Docker) List() ([]discovery.URLMapper, error) {
containers, err := d.listContainers()
if err != nil {
return nil, err
}
var res []discovery.UrlMapper
res := make([]discovery.URLMapper, 0, len(containers))
for _, c := range containers {
srcURL := fmt.Sprintf("^/api/%s/(.*)", c.Name)
destURL := fmt.Sprintf("http://%s:%d/$1", c.IP, c.Port)
@@ -95,11 +95,12 @@ func (d *Docker) List() ([]discovery.UrlMapper, error) {
return nil, errors.Wrapf(err, "invalid src regex %s", srcURL)
}
res = append(res, discovery.UrlMapper{Server: server, SrcMatch: *srcRegex, Dst: destURL, PingURL: pingURL})
res = append(res, discovery.URLMapper{Server: server, SrcMatch: *srcRegex, Dst: destURL, PingURL: pingURL})
}
return res, nil
}
// ID returns providers id
func (d *Docker) ID() discovery.ProviderID { return discovery.PIDocker }
// activate starts blocking listener for all docker events

View File

@@ -64,7 +64,7 @@ func (d *File) Events(ctx context.Context) <-chan struct{} {
}
// List all src dst pairs
func (d *File) List() (res []discovery.UrlMapper, err error) {
func (d *File) List() (res []discovery.URLMapper, err error) {
var fileConf map[string][]struct {
SourceRoute string `yaml:"route"`
@@ -91,7 +91,7 @@ func (d *File) List() (res []discovery.UrlMapper, err error) {
if srv == "default" {
srv = "*"
}
mapper := discovery.UrlMapper{Server: srv, SrcMatch: *rx, Dst: f.Dest, PingURL: f.Ping}
mapper := discovery.URLMapper{Server: srv, SrcMatch: *rx, Dst: f.Dest, PingURL: f.Ping}
res = append(res, mapper)
}
}
@@ -104,4 +104,5 @@ func (d *File) List() (res []discovery.UrlMapper, err error) {
return res, nil
}
// ID returns providers id
func (d *File) ID() discovery.ProviderID { return discovery.PIFile }

View File

@@ -17,7 +17,7 @@ func TestFile_Events(t *testing.T) {
tmp, err := ioutil.TempFile(os.TempDir(), "reproxy-events")
require.NoError(t, err)
tmp.Close()
_ = tmp.Close()
defer os.Remove(tmp.Name())
f := File{

View File

@@ -23,19 +23,19 @@ func (s *Static) Events(_ context.Context) <-chan struct{} {
}
// List all src dst pairs
func (s *Static) List() (res []discovery.UrlMapper, err error) {
func (s *Static) List() (res []discovery.URLMapper, err error) {
parse := func(inp string) (discovery.UrlMapper, error) {
parse := func(inp string) (discovery.URLMapper, error) {
elems := strings.Split(inp, ",")
if len(elems) != 4 {
return discovery.UrlMapper{}, errors.Errorf("invalid rule %q", inp)
return discovery.URLMapper{}, errors.Errorf("invalid rule %q", inp)
}
rx, err := regexp.Compile(strings.TrimSpace(elems[1]))
if err != nil {
return discovery.UrlMapper{}, errors.Wrapf(err, "can't parse regex %s", elems[1])
return discovery.URLMapper{}, errors.Wrapf(err, "can't parse regex %s", elems[1])
}
return discovery.UrlMapper{
return discovery.URLMapper{
Server: strings.TrimSpace(elems[0]),
SrcMatch: *rx,
Dst: strings.TrimSpace(elems[2]),
@@ -53,4 +53,5 @@ func (s *Static) List() (res []discovery.UrlMapper, err error) {
return res, nil
}
// ID returns providers id
func (s *Static) ID() discovery.ProviderID { return discovery.PIStatic }

View File

@@ -24,7 +24,7 @@ var _ Provider = &ProviderMock{}
// IDFunc: func() ProviderID {
// panic("mock out the ID method")
// },
// ListFunc: func() ([]UrlMapper, error) {
// ListFunc: func() ([]URLMapper, error) {
// panic("mock out the List method")
// },
// }
@@ -41,7 +41,7 @@ type ProviderMock struct {
IDFunc func() ProviderID
// ListFunc mocks the List method.
ListFunc func() ([]UrlMapper, error)
ListFunc func() ([]URLMapper, error)
// calls tracks calls to the methods.
calls struct {
@@ -120,7 +120,7 @@ func (mock *ProviderMock) IDCalls() []struct {
}
// List calls ListFunc.
func (mock *ProviderMock) List() ([]UrlMapper, error) {
func (mock *ProviderMock) List() ([]URLMapper, error) {
if mock.ListFunc == nil {
panic("ProviderMock.ListFunc: method is nil but Provider.List was just called")
}

View File

@@ -35,7 +35,7 @@ var opts struct {
Key string `long:"key" env:"KEY" description:"path to key.pem file"`
ACMELocation string `long:"acme-location" env:"ACME_LOCATION" description:"dir where certificates will be stored by autocert manager" default:"./var/acme"`
ACMEEmail string `long:"acme-email" env:"ACME_EMAIL" description:"admin email for certificate notifications"`
RedirHttpPort int `long:"http-port" env:"HTTP_PORT" default:"80" description:"http port for redirect to https and acme challenge test"`
RedirHTTPPort int `long:"http-port" env:"HTTP_PORT" default:"80" description:"http port for redirect to https and acme challenge test"`
FQDNs []string `long:"fqdn" env:"ACME_FQDN" env-delim:"," description:"FQDN(s) for ACME certificates"`
} `group:"ssl" namespace:"ssl" env-namespace:"SSL"`
@@ -90,12 +90,6 @@ func main() {
setupLog(opts.Dbg)
catchSignal()
defer func() {
if x := recover(); x != nil {
log.Printf("[WARN] run time panic:\n%v", x)
panic(x)
}
}()
providers, err := makeProviders()
if err != nil {
@@ -114,12 +108,18 @@ func main() {
log.Fatalf("[ERROR] failed to make config of ssl server params, %v", err)
}
defer func() {
if x := recover(); x != nil {
log.Printf("[WARN] run time panic:\n%v", x)
panic(x)
}
}()
accessLog := makeAccessLogWriter()
defer func() {
if err := accessLog.Close(); err != nil {
log.Printf("[WARN] can't close access log, %v", err)
}
}()
px := &proxy.Http{
@@ -137,7 +137,7 @@ func main() {
DisableSignature: opts.NoSignature,
}
if err := px.Run(context.Background()); err != nil {
log.Fatalf("[ERROR] proxy server failed, %v", err)
log.Fatalf("[ERROR] proxy server failed, %v", err) //nolint gocritic
}
}
@@ -184,13 +184,13 @@ func makeSSLConfig() (config proxy.SSLConfig, err error) {
config.SSLMode = proxy.SSLStatic
config.Cert = opts.SSL.Cert
config.Key = opts.SSL.Key
config.RedirHttpPort = opts.SSL.RedirHttpPort
config.RedirHTTPPort = opts.SSL.RedirHTTPPort
case "auto":
config.SSLMode = proxy.SSLAuto
config.ACMELocation = opts.SSL.ACMELocation
config.ACMEEmail = opts.SSL.ACMEEmail
config.FQDNs = opts.SSL.FQDNs
config.RedirHttpPort = opts.SSL.RedirHttpPort
config.RedirHTTPPort = opts.SSL.RedirHTTPPort
}
return config, err
}

View File

@@ -25,10 +25,10 @@ func (h *Http) healthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(fn)
}
func (h *Http) healthHandler(w http.ResponseWriter, r *http.Request) {
func (h *Http) healthHandler(w http.ResponseWriter, _ *http.Request) {
// runs pings in parallel
check := func(mappers []discovery.UrlMapper) (ok bool, valid int, total int, errs []string) {
check := func(mappers []discovery.URLMapper) (ok bool, valid int, total int, errs []string) {
outCh := make(chan error, 8)
var pinged int32
var wg sync.WaitGroup
@@ -37,7 +37,7 @@ func (h *Http) healthHandler(w http.ResponseWriter, r *http.Request) {
continue
}
wg.Add(1)
go func(m discovery.UrlMapper) {
go func(m discovery.URLMapper) {
defer wg.Done()
atomic.AddInt32(&pinged, 1)

View File

@@ -134,7 +134,7 @@ func NewCompressor(level int, types ...string) *Compressor {
// SetEncoder can be used to set the implementation of a compression algorithm.
//
// The encoding should be a standardised identifier. See:
// The encoding should be a standardized identifier. See:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding
//
// For example, add the Brotli algortithm:
@@ -354,7 +354,7 @@ func (cw *compressResponseWriter) Flush() {
// If the underlying writer has a compression flush signature,
// call this Flush() method instead
if f, ok := cw.writer().(compressFlusher); ok {
f.Flush()
_ = f.Flush()
// Also flush the underlying response writer
if f, ok := cw.ResponseWriter.(http.Flusher); ok {

View File

@@ -12,9 +12,7 @@ import (
"strings"
"time"
"github.com/go-pkgz/lgr"
log "github.com/go-pkgz/lgr"
"github.com/go-pkgz/rest"
R "github.com/go-pkgz/rest"
"github.com/gorilla/handlers"
"github.com/pkg/errors"
@@ -24,7 +22,7 @@ import (
)
// Http is a proxy server for both http and https
type Http struct {
type Http struct { //nolint golint
Matcher
Address string
TimeOut time.Duration
@@ -44,7 +42,7 @@ type Http struct {
type Matcher interface {
Match(srv, src string) (string, bool)
Servers() (servers []string)
Mappers() (mappers []discovery.UrlMapper)
Mappers() (mappers []discovery.URLMapper)
}
// Run the lister and request's router, activate rest server
@@ -71,7 +69,7 @@ func (h *Http) Run(ctx context.Context) error {
}()
handler := R.Wrap(h.proxyHandler(),
R.Recoverer(lgr.Default()),
R.Recoverer(log.Default()),
h.signatureHandler,
R.Ping,
h.healthMiddleware,
@@ -97,11 +95,11 @@ func (h *Http) Run(ctx context.Context) error {
httpsServer = h.makeHTTPSServer(h.Address, handler)
httpsServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
httpServer = h.makeHTTPServer(h.toHttp(h.Address, h.SSLConfig.RedirHttpPort), h.httpToHTTPSRouter())
httpServer = h.makeHTTPServer(h.toHTTP(h.Address, h.SSLConfig.RedirHTTPPort), h.httpToHTTPSRouter())
httpServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
go func() {
log.Printf("[INFO] activate http redirect server on %s", h.toHttp(h.Address, h.SSLConfig.RedirHttpPort))
log.Printf("[INFO] activate http redirect server on %s", h.toHTTP(h.Address, h.SSLConfig.RedirHTTPPort))
err := httpServer.ListenAndServe()
log.Printf("[WARN] http redirect server terminated, %s", err)
}()
@@ -114,11 +112,11 @@ func (h *Http) Run(ctx context.Context) error {
httpsServer = h.makeHTTPSAutocertServer(h.Address, handler, m)
httpsServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
httpServer = h.makeHTTPServer(h.toHttp(h.Address, h.SSLConfig.RedirHttpPort), h.httpChallengeRouter(m))
httpServer = h.makeHTTPServer(h.toHTTP(h.Address, h.SSLConfig.RedirHTTPPort), h.httpChallengeRouter(m))
httpServer.ErrorLog = log.ToStdLogger(log.Default(), "WARN")
go func() {
log.Printf("[INFO] activate http challenge server on port %s", h.toHttp(h.Address, h.SSLConfig.RedirHttpPort))
log.Printf("[INFO] activate http challenge server on port %s", h.toHTTP(h.Address, h.SSLConfig.RedirHTTPPort))
err := httpServer.ListenAndServe()
log.Printf("[WARN] http challenge server terminated, %s", err)
}()
@@ -154,7 +152,7 @@ func (h *Http) proxyHandler() http.HandlerFunc {
})
if h.AssetsLocation != "" && h.AssetsWebRoot != "" {
fs, err := rest.FileServer(h.AssetsWebRoot, h.AssetsLocation)
fs, err := R.FileServer(h.AssetsWebRoot, h.AssetsLocation)
if err == nil {
assetsHandler = func(w http.ResponseWriter, r *http.Request) {
fs.ServeHTTP(w, r)
@@ -186,7 +184,7 @@ func (h *Http) proxyHandler() http.HandlerFunc {
}
}
func (h *Http) toHttp(address string, httpPort int) string {
func (h *Http) toHTTP(address string, httpPort int) string {
rx := regexp.MustCompile(`(.*):(\d*)`)
return rx.ReplaceAllString(address, "$1:") + strconv.Itoa(httpPort)
}

View File

@@ -171,7 +171,7 @@ func TestHttp_toHttp(t *testing.T) {
for i, tt := range tbl {
tt := tt
t.Run(strconv.Itoa(i), func(t *testing.T) {
assert.Equal(t, tt.res, h.toHttp(tt.addr, tt.port))
assert.Equal(t, tt.res, h.toHTTP(tt.addr, tt.port))
})
}

View File

@@ -34,7 +34,7 @@ type SSLConfig struct {
ACMELocation string
ACMEEmail string
FQDNs []string
RedirHttpPort int
RedirHTTPPort int
}
// httpToHTTPSRouter creates new router which does redirect from http to https server