diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..4dbfd2df --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +.dockerignore +# TODO: uncomment when applications no longer use git to get version information +#.git/ +.github/ +.gitignore +.goreleaser.yml +/*.env* +.golangci.yaml +build/ +CONTRIBUTING.md +Dockerfile +docs/ +LICENSE* +Makefile.maker.yaml +README.md +report.html +shell.nix +/testing/ diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6a16925d..500eaf5b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,7 +24,7 @@ jobs: with: go-version: "1.19" - name: Make all check - run: GO_BUILDFLAGS='-mod vendor' make all check + run: make build-all check lint: name: Lint runs-on: ubuntu-latest @@ -36,7 +36,7 @@ jobs: with: go-version: "1.19" - name: Run gofmt, go vet, staticcheck - run: GO_BUILDFLAGS='-mod vendor' make static-check + run: make static-check test: name: Test needs: @@ -50,7 +50,7 @@ jobs: with: go-version: "1.19" - name: Run tests and generate coverage report - run: GO_BUILDFLAGS='-mod vendor' make build/cover.out + run: make build/cover.out - name: Upload coverage report to Coveralls env: COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 00000000..2b87861d --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,119 @@ +################################################################################ +# This file is AUTOGENERATED with # +# Edit Makefile.maker.yaml instead. # +################################################################################ + +run: + deadline: 3m # 1m by default + modules-download-mode: readonly + +output: + # Do not print lines of code with issue. + print-issued-lines: false + +issues: + exclude: + # It is idiomatic Go to reuse the name 'err' with ':=' for subsequent errors. + # Ref: https://go.dev/doc/effective_go#redeclaration + - 'declaration of "err" shadows declaration at' + exclude-rules: + - path: _test\.go + linters: + - bodyclose + # '0' disables the following options. + max-issues-per-linter: 0 + max-same-issues: 0 + +linters-settings: + dupl: + # Tokens count to trigger issue, 150 by default. + threshold: 100 + errcheck: + # Report about assignment of errors to blank identifier. + check-blank: true + # Report about not checking of errors in type assertions. + check-type-assertions: true + forbidigo: + forbid: + # ioutil package has been deprecated: https://github.com/golang/go/issues/42026 + - ^ioutil\..*$ + gocritic: + enabled-checks: + - boolExprSimplify + - builtinShadow + - emptyStringTest + - evalOrder + - httpNoBody + - importShadow + - initClause + - methodExprCall + - paramTypeCombine + - preferFilepathJoin + - ptrToRefParam + - redundantSprint + - returnAfterHttpError + - stringConcatSimplify + - timeExprSimplify + - truncateCmp + - typeAssertChain + - typeUnparen + - unnamedResult + - unnecessaryBlock + - unnecessaryDefer + - weakCond + - yodaStyleExpr + goimports: + # Put local imports after 3rd-party packages. + local-prefixes: github.com/sapcc/hermes + gosec: + excludes: + # gosec wants us to set a short ReadHeaderTimeout to avoid Slowloris attacks, but doing so would expose us to Keep-Alive race conditions (see https://iximiuz.com/en/posts/reverse-proxy-http-keep-alive-and-502s/) + - G112 + # created file permissions are restricted by umask if necessary + - G306 + govet: + # Report about shadowed variables. + check-shadowing: true + nolintlint: + require-specific: true + usestdlibvars: + http-method: true + http-status-code: true + time-weekday: true + time-month: true + time-layout: true + crypto-hash: true + default-rpc-path: true + whitespace: + # Enforce newlines (or comments) after multi-line function signatures. + multi-func: true + +linters: + # We use 'disable-all' and enable linters explicitly so that a newer version + # does not introduce new linters unexpectedly. + disable-all: true + enable: + - bodyclose + - dupl + - errcheck + - exportloopref + - forbidigo + - gocritic + - gofmt + - goimports + - gosec + - gosimple + - govet + - ineffassign + - misspell + - nolintlint + - rowserrcheck + - sqlclosecheck + - staticcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - usestdlibvars + - whitespace diff --git a/.gopath/src/github.com/sapcc/hermes b/.gopath/src/github.com/sapcc/hermes deleted file mode 120000 index c866b868..00000000 --- a/.gopath/src/github.com/sapcc/hermes +++ /dev/null @@ -1 +0,0 @@ -../../../.. \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index d60892c2..cd72c610 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,25 @@ -FROM keppel.eu-de-1.cloud.sap/ccloud-dockerhub-mirror/library/alpine:latest -MAINTAINER "Nathan Oyler " -LABEL source_repository="https://github.com/sapcc/hermes" +FROM golang:1.19.2-alpine3.16 as builder -RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 +RUN apk add --no-cache gcc git make musl-dev -ADD build/docker.tar / -ENTRYPOINT ["/usr/bin/hermes"] +COPY . /src +ARG BININFO_BUILD_DATE BININFO_COMMIT_HASH BININFO_VERSION # provided to 'make install' +RUN make -C /src install PREFIX=/pkg + +################################################################################ + +FROM alpine:3.16 + +RUN apk add --no-cache ca-certificates +COPY --from=builder /pkg/ /usr/ + +ARG BININFO_BUILD_DATE BININFO_COMMIT_HASH BININFO_VERSION +LABEL source_repository="https://github.com/sapcc/hermes" \ + org.opencontainers.image.url="https://github.com/sapcc/hermes" \ + org.opencontainers.image.created=${BININFO_BUILD_DATE} \ + org.opencontainers.image.revision=${BININFO_COMMIT_HASH} \ + org.opencontainers.image.version=${BININFO_VERSION} + +USER nobody:nobody +WORKDIR /var/empty +ENTRYPOINT [ "/usr/bin/hermes" ] diff --git a/Makefile b/Makefile index a10ded0f..5cdc9710 100644 --- a/Makefile +++ b/Makefile @@ -1,43 +1,55 @@ -PKG = github.com/sapcc/hermes -PREFIX := /usr -DATE ?= $(shell date +%FT%T%z) -VERSION ?= $(shell git describe --tags --always --dirty --match=v* 2> /dev/null || \ - cat $(CURDIR)/.version 2> /dev/null || echo v0) -GOPATH = $(CURDIR)/.gopath -GO = GOPATH=$(CURDIR)/.gopath GOBIN=$(CURDIR)/build go -BIN = $(GOPATH)/bin -BASE = $(GOPATH)/src/$(PKG) -PKGS = $(or $(PKG),$(shell cd $(BASE) && env GOPATH=$(GOPATH) $(GO) list ./... | grep -v "^$(PKG)/vendor/")) -TESTPKGS = $(shell env GOPATH=$(GOPATH) $(GO) list -f '{{ if or .TestGoFiles .XTestGoFiles }}{{ .ImportPath }}{{ end }}' $(PKGS)) - -GODOC = godoc -GOFMT = gofmt -#GLIDE = glide -TIMEOUT = 15 -V = 0 -# Quiets info, comment out to debug -#Q = $(if $(filter 1,$V),,@) -M = $(shell printf "\033[34;1m▶\033[0m") - - -.PHONY: all -#all: fmt lint vendor | $(BASE) ; $(info $(M) building executable…) @ ## Build program binary -all: fmt | $(BASE) ; $(info $(M) building executable…) @ ## Build program binary - $Q cd $(BASE) && $(GO) install \ - -tags release \ - -ldflags '-X $(PKG)/cmd.Version=$(VERSION) -X $(PKG)/cmd.BuildDate=$(DATE)' - -$(BASE): ; $(info $(M) setting GOPATH…) -# @mkdir -p $(dir $@) -# @ln -sf $(CURDIR) $@ - -# which packages to measure coverage for? -GO_COVERPKGS := $(shell go list $(PKG)/pkg/... | grep -v plugins) -# output files from `go test` -GO_COVERFILES := $(patsubst %,build/%.cover.out,$(subst /,_,$(TESTPKGS))) - -check: all static-check build/cover.html FORCE - @echo -e "\e[1;32m>> All tests successful.\e[0m" +################################################################################ +# This file is AUTOGENERATED with # +# Edit Makefile.maker.yaml instead. # +################################################################################ + +MAKEFLAGS=--warn-undefined-variables +# /bin/sh is dash on Debian which does not support all features of ash/bash +# to fix that we use /bin/bash only on Debian to not break Alpine +ifneq (,$(wildcard /etc/os-release)) # check file existence + ifneq ($(shell grep -c debian /etc/os-release),0) + SHELL := /bin/bash + endif +endif + +default: build-all + +GO_BUILDFLAGS = +GO_LDFLAGS = +GO_TESTENV = + +# These definitions are overridable, e.g. to provide fixed version/commit values when +# no .git directory is present or to provide a fixed build date for reproducability. +BININFO_VERSION ?= $(shell git describe --tags --always --abbrev=7) +BININFO_COMMIT_HASH ?= $(shell git rev-parse --verify HEAD) +BININFO_BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") + +build-all: build/hermes + +build/hermes: FORCE + go build $(GO_BUILDFLAGS) -ldflags '-s -w -X github.com/sapcc/go-api-declarations/bininfo.binName=hermes -X github.com/sapcc/go-api-declarations/bininfo.version=$(BININFO_VERSION) -X github.com/sapcc/go-api-declarations/bininfo.commit=$(BININFO_COMMIT_HASH) -X github.com/sapcc/go-api-declarations/bininfo.buildDate=$(BININFO_BUILD_DATE) $(GO_LDFLAGS)' -o build/hermes . + +DESTDIR = +ifeq ($(shell uname -s),Darwin) + PREFIX = /usr/local +else + PREFIX = /usr +endif + +install: FORCE build/hermes + install -d -m 0755 "$(DESTDIR)$(PREFIX)/bin" + install -m 0755 build/hermes "$(DESTDIR)$(PREFIX)/bin/hermes" + +# which packages to test with "go test" +GO_TESTPKGS := $(shell go list -f '{{if or .TestGoFiles .XTestGoFiles}}{{.ImportPath}}{{end}}' ./...) +# which packages to measure coverage for +GO_COVERPKGS := $(shell go list ./...) +# to get around weird Makefile syntax restrictions, we need variables containing a space and comma +space := $(null) $(null) +comma := , + +check: FORCE build-all static-check build/cover.html + @printf "\e[1;32m>> All checks successful.\e[0m\n" prepare-static-check: FORCE @if ! hash golangci-lint 2>/dev/null; then printf "\e[1;36m>> Installing golangci-lint (this may take a while)...\e[0m\n"; go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest; fi @@ -46,121 +58,51 @@ static-check: FORCE prepare-static-check @printf "\e[1;36m>> golangci-lint\e[0m\n" @golangci-lint run -build/cover.out: $(GO_COVERFILES) - pkg/test/util/gocovcat.go $(GO_COVERFILES) > $@ +build/cover.out: FORCE | build + @printf "\e[1;36m>> go test\e[0m\n" + @env $(GO_TESTENV) go test $(GO_BUILDFLAGS) -ldflags '-s -w -X github.com/sapcc/go-api-declarations/bininfo.binName=hermes -X github.com/sapcc/go-api-declarations/bininfo.version=$(BININFO_VERSION) -X github.com/sapcc/go-api-declarations/bininfo.commit=$(BININFO_COMMIT_HASH) -X github.com/sapcc/go-api-declarations/bininfo.buildDate=$(BININFO_BUILD_DATE) $(GO_LDFLAGS)' -shuffle=on -p 1 -coverprofile=$@ -covermode=count -coverpkg=$(subst $(space),$(comma),$(GO_COVERPKGS)) $(GO_TESTPKGS) build/cover.html: build/cover.out - $(GO) tool cover -html $< -o $@ - -# Tools - -GOLINT = $(BIN)/golint -$(BIN)/golint: | $(BASE) ; $(info $(M) building golint…) - $Q go get golang.org/x/lint/golint - -GOCOVMERGE = $(BIN)/gocovmerge -$(BIN)/gocovmerge: | $(BASE) ; $(info $(M) building gocovmerge…) - $Q go get github.com/wadey/gocovmerge - -GOCOV = $(BIN)/gocov -$(BIN)/gocov: | $(BASE) ; $(info $(M) building gocov…) - $Q go get github.com/axw/gocov/... - -GOCOVXML = $(BIN)/gocov-xml -$(BIN)/gocov-xml: | $(BASE) ; $(info $(M) building gocov-xml…) - $Q go get github.com/AlekSi/gocov-xml - -GO2XUNIT = $(BIN)/go2xunit -$(BIN)/go2xunit: | $(BASE) ; $(info $(M) building go2xunit…) - $Q go get github.com/tebeka/go2xunit - - -# Tests - -TEST_TARGETS := test-default test-bench test-short test-verbose test-race -.PHONY: $(TEST_TARGETS) test-xml check test tests -test-bench: ARGS=-run=__absolutelynothing__ -bench=. ## Run benchmarks -test-short: ARGS=-short ## Run only short tests -test-verbose: ARGS=-v ## Run tests in verbose mode with coverage reporting -test-race: ARGS=-race ## Run tests with race detector -$(TEST_TARGETS): NAME=$(MAKECMDGOALS:test-%=%) -$(TEST_TARGETS): test -#check test tests: fmt lint vendor | $(BASE) ; $(info $(M) running $(NAME:%=% )tests…) @ ## Run tests -check test tests: fmt | $(BASE) ; $(info $(M) running $(NAME:%=% )tests…) @ ## Run tests - $Q cd $(BASE) && $(GO) test ./... -timeout $(TIMEOUT)s $(ARGS) $(TESTPKGS) - -test-xml: fmt lint vendor | $(BASE) $(GO2XUNIT) ; $(info $(M) running $(NAME:%=% )tests…) @ ## Run tests with xUnit output - $Q cd $(BASE) && 2>&1 $(GO) test -timeout 20s -v $(TESTPKGS) | tee test/tests.output - $(GO2XUNIT) -fail -input test/tests.output -output test/tests.xml - -COVERAGE_MODE = atomic -COVERAGE_PROFILE = $(COVERAGE_DIR)/profile.out -COVERAGE_XML = $(COVERAGE_DIR)/coverage.xml -COVERAGE_HTML = $(COVERAGE_DIR)/index.html -.PHONY: test-coverage test-coverage-tools -test-coverage-tools: | $(GOCOVMERGE) $(GOCOV) $(GOCOVXML) -test-coverage: COVERAGE_DIR := $(CURDIR)/test/coverage.$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") -test-coverage: fmt lint vendor test-coverage-tools | $(BASE) ; $(info $(M) running coverage tests…) @ ## Run coverage tests - $Q mkdir -p $(COVERAGE_DIR)/coverage - $Q cd $(BASE) && for pkg in $(TESTPKGS); do \ - $(GO) test \ - -coverpkg=$$($(GO) list -f '{{ join .Deps "\n" }}' $$pkg | \ - grep '^$(PKG)/' | grep -v '^$(PKG)/vendor/' | \ - tr '\n' ',')$$pkg \ - -covermode=$(COVERAGE_MODE) \ - -coverprofile="$(COVERAGE_DIR)/coverage/`echo $$pkg | tr "/" "-"`.cover" $$pkg ;\ - done - $Q $(GOCOVMERGE) $(COVERAGE_DIR)/coverage/*.cover > $(COVERAGE_PROFILE) - $Q $(GO) tool cover -html=$(COVERAGE_PROFILE) -o $(COVERAGE_HTML) - $Q $(GOCOV) convert $(COVERAGE_PROFILE) | $(GOCOVXML) > $(COVERAGE_XML) - -.PHONY: lint -lint: vendor | $(BASE) $(GOLINT) ; $(info $(M) running golint…) @ ## Run golint - $Q cd $(BASE) && ret=0 && for pkg in $(PKGS); do \ - test -z "$$($(GOLINT) $$pkg | tee /dev/stderr)" || ret=1 ; \ - done ; exit $$ret - -.PHONY: fmt -fmt: ; $(info $(M) running gofmt…) @ ## Run gofmt on all source files - @ret=0 && for d in $$($(GO) list -f '{{.Dir}}' ./... | grep -v /vendor/); do \ - $(GOFMT) -l -w $$d/*.go || ret=$$? ; \ - done ; exit $$ret - -# Dependency management -vendor: - @# vendoring by https://github.com/holocm/golangvend - golangvend - -# Misc - -.PHONY: clean -clean: ; $(info $(M) cleaning…) @ ## Cleanup everything -# @rm -rf $(GOPATH) - @rm -rf bin - @rm -rf test/tests.* test/coverage.* - -.PHONY: help -help: - @grep -E '^[ a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ - awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' - -.PHONY: version -version: - @echo $(VERSION) - -build/docker.tar: clean test - make GO_LDFLAGS="-s -w -linkmode external -extldflags -static" DESTDIR='$(CURDIR)/build/install' install - ( cd build/install && tar cf - . ) > build/docker.tar - -DOCKER := docker -DOCKER_IMAGE := sapcc/hermes -DOCKER_TAG := latest - -docker: build/docker.tar - $(DOCKER) build -t "$(DOCKER_IMAGE):$(DOCKER_TAG)" . - -install: all - #install -D -m 0755 build/hermes "$(DESTDIR)$(PREFIX)/bin/hermes" - install -D -m 0755 $(CURDIR)/build/hermes "$(DESTDIR)$(PREFIX)/bin/hermes" + @printf "\e[1;36m>> go tool cover > build/cover.html\e[0m\n" + @go tool cover -html $< -o $@ + +build: + @mkdir $@ + +tidy-deps: FORCE + go mod tidy + go mod verify + +license-headers: FORCE + @if ! hash addlicense 2>/dev/null; then printf "\e[1;36m>> Installing addlicense...\e[0m\n"; go install github.com/google/addlicense@latest; fi + find * \( -name vendor -type d -prune \) -o \( -name \*.go -exec addlicense -c "SAP SE" -- {} + \) + +clean: FORCE + git clean -dxf build + +help: FORCE + @printf "\n" + @printf "\e[1mUsage:\e[0m\n" + @printf " make \e[36m\e[0m\n" + @printf "\n" + @printf "\e[1mGeneral\e[0m\n" + @printf " \e[36mhelp\e[0m Display this help.\n" + @printf "\n" + @printf "\e[1mBuild\e[0m\n" + @printf " \e[36mbuild-all\e[0m Build all binaries.\n" + @printf " \e[36mbuild/hermes\e[0m Build hermes.\n" + @printf " \e[36minstall\e[0m Install all binaries. This option understands the conventional 'DESTDIR' and 'PREFIX' environment variables for choosing install locations.\n" + @printf "\n" + @printf "\e[1mTest\e[0m\n" + @printf " \e[36mcheck\e[0m Run the test suite (unit tests and golangci-lint).\n" + @printf " \e[36mprepare-static-check\e[0m Install golangci-lint. This is used in CI, you should probably install golangci-lint using your package manager.\n" + @printf " \e[36mstatic-check\e[0m Run golangci-lint.\n" + @printf " \e[36mbuild/cover.out\e[0m Run tests and generate coverage report.\n" + @printf " \e[36mbuild/cover.html\e[0m Generate an HTML file with source code annotations from the coverage report.\n" + @printf "\n" + @printf "\e[1mDevelopment\e[0m\n" + @printf " \e[36mtidy-deps\e[0m Run go mod tidy and go mod verify.\n" + @printf " \e[36mlicense-headers\e[0m Add license headers to all .go files excluding the vendor directory.\n" + @printf " \e[36mclean\e[0m Run git clean.\n" .PHONY: FORCE diff --git a/Makefile.maker.yaml b/Makefile.maker.yaml new file mode 100644 index 00000000..6cb81a83 --- /dev/null +++ b/Makefile.maker.yaml @@ -0,0 +1,15 @@ +# Configuration file for + +metadata: + url: https://github.com/sapcc/hermes + +binaries: + - name: hermes + fromPackage: . + installTo: bin/ + +dockerfile: + enabled: true + +golangciLint: + createConfig: true diff --git a/go.mod b/go.mod index 6b1d77c9..01796134 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -35,7 +34,6 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect - github.com/sapcc/go-bits v0.0.0-20220806113733-304e620cef60 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -44,7 +42,6 @@ require ( golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/protobuf v1.28.1 // indirect - gopkg.in/h2non/gock.v1 v1.1.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index eeb1b178..069d50b3 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -127,7 +126,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -147,16 +146,10 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gophercloud/gophercloud v0.24.0 h1:jDsIMGJ1KZpAjYfQgGI2coNQj5Q83oPzuiGJRFWgMzw= -github.com/gophercloud/gophercloud v0.24.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= -github.com/gophercloud/gophercloud v0.25.0 h1:C3Oae7y0fUVQGSsBrb3zliAjdX+riCSEh4lNMejFNI4= -github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= github.com/gophercloud/gophercloud v1.0.0 h1:9nTGx0jizmHxDobe4mck89FyQHVyA3CaXLIUSGJjP9k= github.com/gophercloud/gophercloud v1.0.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= -github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -181,19 +174,17 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -203,17 +194,10 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E= github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.0-beta.8 h1:dy81yyLYJDwMTifq24Oi/IslOslRrDSb3jwDggjz3Z0= -github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -227,10 +211,7 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= -github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -241,7 +222,6 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= @@ -249,40 +229,26 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/sapcc/go-api-declarations v1.1.0 h1:xZDnW0LmpAqCX7j8TJ+V3gnBmV4CjXviFxnjISCxUcE= -github.com/sapcc/go-api-declarations v1.1.0/go.mod h1:zS+2xqmbtAyQxQz1liJp0qxDgop78fb4Sfk/IB0PvH0= -github.com/sapcc/go-api-declarations v1.2.0 h1:ypzrA7dc18VgtOLVaZnJ8vJ26T3ZFskr/2JLzgInd9s= -github.com/sapcc/go-api-declarations v1.2.0/go.mod h1:zS+2xqmbtAyQxQz1liJp0qxDgop78fb4Sfk/IB0PvH0= -github.com/sapcc/go-api-declarations v1.3.0 h1:4FMj0UR+Pydil1cpIewa068w/55mqvg3+/ILy3hGQ0g= -github.com/sapcc/go-api-declarations v1.3.0/go.mod h1:EA4x5xxJGyG/3JTteUOYBg6cJLJgsBHrDj3ryfNU4dQ= github.com/sapcc/go-api-declarations v1.4.0 h1:6X1DYraMthwvrRW1hXyH785Jg7pUXmM2cb6F8RD06ag= github.com/sapcc/go-api-declarations v1.4.0/go.mod h1:EA4x5xxJGyG/3JTteUOYBg6cJLJgsBHrDj3ryfNU4dQ= -github.com/sapcc/go-bits v0.0.0-20220806113733-304e620cef60 h1:8myjz+E8YBJqFRMGG0HijCC8QgY4y08brRtItTU49DQ= -github.com/sapcc/go-bits v0.0.0-20220806113733-304e620cef60/go.mod h1:nD1KaopEUstj07W5bAQ8N+aqXogG1QQ6a/G1zs6wRZE= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44= -github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -293,14 +259,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= -github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -456,10 +417,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -528,7 +487,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -619,8 +577,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -629,10 +585,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= -gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= -gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -643,10 +595,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 9d0d4889..37b77dd1 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -55,10 +55,10 @@ func setupTest(t *testing.T) http.Handler { //create test driver with the domains and projects from start-data.sql keystone := identity.Mock{} - storage := storage.Mock{} + storageInterface := storage.Mock{} prometheus.DefaultRegisterer = prometheus.NewPedanticRegistry() - router, _ := NewV1Handler(keystone, storage) + router, _ := NewV1Handler(keystone, storageInterface) return router } diff --git a/pkg/api/core.go b/pkg/api/core.go index e972d45d..173dbb16 100644 --- a/pkg/api/core.go +++ b/pkg/api/core.go @@ -39,12 +39,12 @@ type v1Provider struct { // NewV1Handler creates a http.Handler that serves the Hermes v1 API. // It also returns the VersionData for this API version which is needed for the // version advertisement on "GET /". -func NewV1Handler(keystone identity.Identity, storage storage.Storage) (http.Handler, VersionData) { +func NewV1Handler(keystone identity.Identity, storageInterface storage.Storage) (http.Handler, VersionData) { r := mux.NewRouter() p := &v1Provider{ keystone: keystone, - storage: storage, + storage: storageInterface, } p.versionData = VersionData{ Status: "CURRENT", diff --git a/pkg/api/server.go b/pkg/api/server.go index 672eef36..dfb07dcd 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -34,9 +34,9 @@ import ( ) // Server Set up and start the API server, hooking it up to the API router -func Server(keystone identity.Identity, storage storage.Storage) error { +func Server(keystone identity.Identity, storageInterface storage.Storage) error { fmt.Println("API") - mainRouter := setupRouter(keystone, storage) + mainRouter := setupRouter(keystone, storageInterface) http.Handle("/", mainRouter) @@ -50,14 +50,17 @@ func Server(keystone identity.Identity, storage storage.Storage) error { MaxAge: 600, }) handler := c.Handler(mainRouter) - return http.ListenAndServe(listenaddress, handler) + //TODO: Gosec complains about the HTTP server not being cleanly + //interruptible. I've silenced this alert for now, but this should be + //migrated to use github.com/sapcc/go-bits/httpext.ListenAndServeContext. + return http.ListenAndServe(listenaddress, handler) //nolint:gosec } -func setupRouter(keystone identity.Identity, storage storage.Storage) http.Handler { +func setupRouter(keystone identity.Identity, storageInterface storage.Storage) http.Handler { mainRouter := mux.NewRouter() //hook up the v1 API (this code is structured so that a newer API version can //be added easily later) - v1Router, v1VersionData := NewV1Handler(keystone, storage) + v1Router, v1VersionData := NewV1Handler(keystone, storageInterface) mainRouter.PathPrefix("/v1/").Handler(v1Router) //add the version advertisement that lists all available API versions diff --git a/pkg/api/util.go b/pkg/api/util.go index a4081625..ae0daa58 100644 --- a/pkg/api/util.go +++ b/pkg/api/util.go @@ -55,13 +55,15 @@ func ReturnJSON(w http.ResponseWriter, code int, data interface{}) { payload = bytes.Replace(payload, []byte("\\u0026"), []byte("&"), -1) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) + return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) _, err = w.Write(payload) if err != nil { - util.LogDebug("Issue with writing payload when returning Json") - http.Error(w, err.Error(), http.StatusInternalServerError) + // It's too late to write this as a 5xx response since we've already + // started writing a 2xx response, so this can only be logged. + util.LogError("Issue with writing payload when returning JSON: %s", err.Error()) } } @@ -72,7 +74,7 @@ func ReturnError(w http.ResponseWriter, err error) bool { return false } - http.Error(w, err.Error(), 500) + http.Error(w, err.Error(), http.StatusInternalServerError) return true } diff --git a/pkg/hermes/events.go b/pkg/hermes/events.go index 3f090849..9b8b26ff 100644 --- a/pkg/hermes/events.go +++ b/pkg/hermes/events.go @@ -176,7 +176,7 @@ func eventsList(eventDetails []*cadf.Event, details bool) ([]*ListEvent, error) } // GetEvent returns the CADF detail for event with the specified ID -func GetEvent(eventID string, tenantID string, keystoneDriver identity.Identity, eventStore storage.Storage) (*cadf.Event, error) { +func GetEvent(eventID, tenantID string, keystoneDriver identity.Identity, eventStore storage.Storage) (*cadf.Event, error) { event, err := eventStore.GetEvent(eventID, tenantID) return event, err diff --git a/pkg/identity/keystone_cache.go b/pkg/identity/keystone_cache.go index 6f3272d7..2983bf9d 100644 --- a/pkg/identity/keystone_cache.go +++ b/pkg/identity/keystone_cache.go @@ -76,7 +76,7 @@ func init() { } } -func updateCache(cache *cache, key string, value string) { +func updateCache(cache *cache, key, value string) { cache.Lock() cache.m[key] = value cache.Unlock() @@ -134,10 +134,10 @@ func getCachedToken(cache *keystoneTokenCache, id string) *keystoneToken { cache.RUnlock() cache.Lock() for _, elem := range elemsToRemove { - cache.eList.Remove(elem) // Remove the cached expiry time from the sorted list - time := (elem.Value).(time.Time) //nolint:errcheck - tokenIDs := cache.eMap[time] - delete(cache.eMap, time) // Remove the cached expiry time from the time:tokenIDs map + cache.eList.Remove(elem) // Remove the cached expiry time from the sorted list + timeToRemove := (elem.Value).(time.Time) //nolint:errcheck + tokenIDs := cache.eMap[timeToRemove] + delete(cache.eMap, timeToRemove) // Remove the cached expiry time from the time:tokenIDs map for _, tokenID := range tokenIDs { delete(cache.tMap, tokenID) // Remove all the cached tokens } diff --git a/pkg/storage/elasticsearch.go b/pkg/storage/elasticsearch.go index fe0af84f..33081f1d 100644 --- a/pkg/storage/elasticsearch.go +++ b/pkg/storage/elasticsearch.go @@ -104,7 +104,7 @@ var esFieldMapping = map[string]string{ // FilterQuery takes filter requests, and adds their filter to the ElasticSearch Query // Handle Filter, Negation of Filter !, and or values separated by , -func FilterQuery(filter string, filtername string, query *elastic.BoolQuery) *elastic.BoolQuery { +func FilterQuery(filter, filtername string, query *elastic.BoolQuery) *elastic.BoolQuery { switch { case strings.HasPrefix(filter, "!"): filter = filter[1:] @@ -213,7 +213,7 @@ func (es ElasticSearch) GetEvents(filter *EventFilter, tenantID string) ([]*cadf } // GetEvent Returns EventDetail for a single event. -func (es ElasticSearch) GetEvent(eventID string, tenantID string) (*cadf.Event, error) { +func (es ElasticSearch) GetEvent(eventID, tenantID string) (*cadf.Event, error) { index := indexName(tenantID) util.LogDebug("Looking for event %s in index %s", eventID, index) diff --git a/pkg/storage/interface.go b/pkg/storage/interface.go index ddf38dea..7b227e3d 100644 --- a/pkg/storage/interface.go +++ b/pkg/storage/interface.go @@ -65,7 +65,7 @@ type Response struct { type Storage interface { /********** requests to ElasticSearch **********/ GetEvents(filter *EventFilter, tenantID string) ([]*cadf.Event, int, error) - GetEvent(eventID string, tenantID string) (*cadf.Event, error) + GetEvent(eventID, tenantID string) (*cadf.Event, error) GetAttributes(filter *AttributeFilter, tenantID string) ([]string, error) MaxLimit() uint } diff --git a/pkg/storage/mock.go b/pkg/storage/mock.go index e4748eeb..dbabd3c8 100644 --- a/pkg/storage/mock.go +++ b/pkg/storage/mock.go @@ -46,7 +46,7 @@ func (m Mock) GetEvents(filter *EventFilter, tenantID string) ([]*cadf.Event, in } // GetEvent Mock with static data -func (m Mock) GetEvent(eventID string, tenantID string) (*cadf.Event, error) { +func (m Mock) GetEvent(eventID, tenantID string) (*cadf.Event, error) { var parsedEvent cadf.Event err := json.Unmarshal(mockEvent, &parsedEvent) return &parsedEvent, err diff --git a/pkg/storage/mock_test.go b/pkg/storage/mock_test.go index 36843efc..ef6e455d 100644 --- a/pkg/storage/mock_test.go +++ b/pkg/storage/mock_test.go @@ -28,8 +28,8 @@ import ( func Test_MockStorage_EventDetail(t *testing.T) { // both params are ignored - eventDetail, error := Mock{}.GetEvent("d5eed458-6666-58ec-ad06-8d3cf6bafca1", "b3b70c8271a845709f9a03030e705da7") - assert.Nil(t, error) + eventDetail, err := Mock{}.GetEvent("d5eed458-6666-58ec-ad06-8d3cf6bafca1", "b3b70c8271a845709f9a03030e705da7") + assert.Nil(t, err) tt := []struct { name string jsonPath string @@ -55,9 +55,9 @@ func Test_MockStorage_EventDetail(t *testing.T) { } func Test_MockStorage_Events(t *testing.T) { - eventsList, total, error := Mock{}.GetEvents(&EventFilter{}, "b3b70c8271a845709f9a03030e705da7") + eventsList, total, err := Mock{}.GetEvents(&EventFilter{}, "b3b70c8271a845709f9a03030e705da7") - assert.Nil(t, error) + assert.Nil(t, err) assert.Equal(t, total, 4) assert.Equal(t, len(eventsList), 4) assert.Equal(t, cadf.SuccessOutcome, eventsList[0].Outcome) @@ -66,9 +66,9 @@ func Test_MockStorage_Events(t *testing.T) { } func Test_MockStorage__Attributes(t *testing.T) { - attributesList, error := Mock{}.GetAttributes(&AttributeFilter{}, "b3b70c8271a845709f9a03030e705da7") + attributesList, err := Mock{}.GetAttributes(&AttributeFilter{}, "b3b70c8271a845709f9a03030e705da7") - assert.Nil(t, error) + assert.Nil(t, err) assert.Equal(t, len(attributesList), 6) assert.Equal(t, "compute/server", attributesList[0]) assert.Equal(t, "network/floatingip", attributesList[4]) diff --git a/pkg/test/http.go b/pkg/test/http.go index ad11b5e6..dfb865ec 100644 --- a/pkg/test/http.go +++ b/pkg/test/http.go @@ -66,6 +66,10 @@ func (r APIRequest) Check(t *testing.T, handler http.Handler) { if err != nil { t.Fatal(err) } + err = response.Body.Close() + if err != nil { + t.Fatal(err) + } if response.StatusCode != r.ExpectStatusCode { t.Errorf("%s %s: expected status code %d, got %d", diff --git a/pkg/test/util/gocovcat.go b/pkg/test/util/gocovcat.go deleted file mode 100755 index bb03f87f..00000000 --- a/pkg/test/util/gocovcat.go +++ /dev/null @@ -1,87 +0,0 @@ -///usr/bin/env go run "$0" "$@"; exit $? - -// Copyright 2017 Luke Shumaker -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// Command gocovcat combines multiple go cover runs, and prints the -// result on stdout. -package main - -import ( - "bufio" - "fmt" - "os" - "sort" - "strconv" - "strings" -) - -func handleErr(err error) { - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } -} - -func main() { - modeBool := false - blocks := map[string]int{} - for _, filename := range os.Args[1:] { - file, err := os.Open(filename) - handleErr(err) - buf := bufio.NewScanner(file) - for buf.Scan() { - line := buf.Text() - - if strings.HasPrefix(line, "mode: ") { - m := strings.TrimPrefix(line, "mode: ") - switch m { - case "set": - modeBool = true - case "count", "atomic": - // do nothing - default: - fmt.Fprintf(os.Stderr, "Unrecognized mode: %s\n", m) - os.Exit(1) - } - } else { - sp := strings.LastIndexByte(line, ' ') - block := line[:sp] - cntStr := line[sp+1:] - cnt, err := strconv.Atoi(cntStr) - handleErr(err) - blocks[block] += cnt - } - } - handleErr(buf.Err()) - } - keys := make([]string, 0, len(blocks)) - for key := range blocks { - keys = append(keys, key) - } - sort.Strings(keys) - modeStr := "count" - if modeBool { - modeStr = "set" - } - fmt.Printf("mode: %s\n", modeStr) - for _, block := range keys { - cnt := blocks[block] - if modeBool && cnt > 1 { - cnt = 1 - } - fmt.Printf("%s %d\n", block, cnt) - } -} diff --git a/pkg/util/hacks.go b/pkg/util/hacks.go index fcf718c0..2aef93d8 100644 --- a/pkg/util/hacks.go +++ b/pkg/util/hacks.go @@ -34,7 +34,7 @@ func init() { //where you definitely don't want to turn off certificate verification.) if os.Getenv("HERMES_INSECURE") == "1" { tlsConf := &tls.Config{ - InsecureSkipVerify: true, + InsecureSkipVerify: true, //nolint:gosec // intentional usage of InsecureSkipVerify } http.DefaultTransport = &http.Transport{ TLSClientConfig: tlsConf,