diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
commit | 0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch) | |
tree | 7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /workhorse | |
parent | 72123183a20411a36d607d70b12d57c484394c8e (diff) | |
download | gitlab-ce-0ea3fcec397b69815975647f5e2aa5fe944a8486.tar.gz |
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'workhorse')
89 files changed, 969 insertions, 752 deletions
diff --git a/workhorse/cmd/gitlab-resize-image/png/reader.go b/workhorse/cmd/gitlab-resize-image/png/reader.go index 8229454ee3b..c2c6a0899c2 100644 --- a/workhorse/cmd/gitlab-resize-image/png/reader.go +++ b/workhorse/cmd/gitlab-resize-image/png/reader.go @@ -5,7 +5,6 @@ import ( "encoding/binary" "fmt" "io" - "io/ioutil" "os" ) @@ -53,7 +52,7 @@ func (r *Reader) Read(p []byte) (int, error) { chunkLen := int64(binary.BigEndian.Uint32(header[:4])) if chunkType := string(header[4:]); chunkType == "iCCP" { debug("!! iCCP chunk found; skipping") - if _, err := io.CopyN(ioutil.Discard, r.underlying, chunkLen+crcLen); err != nil { + if _, err := io.CopyN(io.Discard, r.underlying, chunkLen+crcLen); err != nil { return 0, err } continue diff --git a/workhorse/cmd/gitlab-resize-image/png/reader_test.go b/workhorse/cmd/gitlab-resize-image/png/reader_test.go index 2b2d5df24e9..69dacbc865e 100644 --- a/workhorse/cmd/gitlab-resize-image/png/reader_test.go +++ b/workhorse/cmd/gitlab-resize-image/png/reader_test.go @@ -5,7 +5,6 @@ import ( "hash/crc64" "image" "io" - "io/ioutil" "os" "testing" @@ -85,9 +84,9 @@ func requireValidImage(t *testing.T, r io.Reader, expected string) { } func requireStreamUnchanged(t *testing.T, actual io.Reader, expected io.Reader) { - actualBytes, err := ioutil.ReadAll(actual) + actualBytes, err := io.ReadAll(actual) require.NoError(t, err) - expectedBytes, err := ioutil.ReadAll(expected) + expectedBytes, err := io.ReadAll(expected) require.NoError(t, err) table := crc64.MakeTable(crc64.ISO) diff --git a/workhorse/config_test.go b/workhorse/config_test.go index 0c0072322ac..a6a1bdd7187 100644 --- a/workhorse/config_test.go +++ b/workhorse/config_test.go @@ -3,7 +3,6 @@ package main import ( "flag" "io" - "io/ioutil" "net/url" "os" "testing" @@ -24,7 +23,7 @@ func TestDefaultConfig(t *testing.T) { } func TestConfigFile(t *testing.T) { - f, err := ioutil.TempFile("", "workhorse-config-test") + f, err := os.CreateTemp("", "workhorse-config-test") require.NoError(t, err) defer os.Remove(f.Name()) @@ -47,6 +46,15 @@ certificate = "/path/to/certificate" key = "/path/to/private/key" min_version = "tls1.1" max_version = "tls1.2" +[[listeners]] +network = "tcp" +addr = "localhost:3444" +[metrics_listener] +network = "tcp" +addr = "localhost:3445" +[metrics_listener.tls] +certificate = "/path/to/certificate" +key = "/path/to/private/key" ` _, err = io.WriteString(f, data) require.NoError(t, err) @@ -66,14 +74,69 @@ max_version = "tls1.2" require.Equal(t, []string{"10.0.0.1/8"}, cfg.TrustedCIDRsForPropagation) require.Equal(t, 60*time.Second, cfg.ShutdownTimeout.Duration) - require.Len(t, cfg.Listeners, 1) - listener := cfg.Listeners[0] - require.Equal(t, "/path/to/certificate", listener.Tls.Certificate) - require.Equal(t, "/path/to/private/key", listener.Tls.Key) - require.Equal(t, "tls1.1", listener.Tls.MinVersion) - require.Equal(t, "tls1.2", listener.Tls.MaxVersion) - require.Equal(t, "tcp", listener.Network) - require.Equal(t, "localhost:3443", listener.Addr) + listenerConfigs := []config.ListenerConfig{ + { + Network: "tcp", + Addr: "localhost:3445", + Tls: &config.TlsConfig{ + Certificate: "/path/to/certificate", + Key: "/path/to/private/key", + }, + }, + { + Network: "tcp", + Addr: "localhost:3443", + Tls: &config.TlsConfig{ + Certificate: "/path/to/certificate", + Key: "/path/to/private/key", + MinVersion: "tls1.1", + MaxVersion: "tls1.2", + }, + }, + { + Network: "tcp", + Addr: "localhost:3444", + }, + } + + require.Len(t, cfg.Listeners, 2) + require.NotNil(t, cfg.MetricsListener) + + for i, cfg := range []config.ListenerConfig{*cfg.MetricsListener, cfg.Listeners[0], cfg.Listeners[1]} { + require.Equal(t, listenerConfigs[i].Network, cfg.Network) + require.Equal(t, listenerConfigs[i].Addr, cfg.Addr) + } + + for i, cfg := range []config.ListenerConfig{*cfg.MetricsListener, cfg.Listeners[0]} { + require.Equal(t, listenerConfigs[i].Tls.Certificate, cfg.Tls.Certificate) + require.Equal(t, listenerConfigs[i].Tls.Key, cfg.Tls.Key) + require.Equal(t, listenerConfigs[i].Tls.MinVersion, cfg.Tls.MinVersion) + require.Equal(t, listenerConfigs[i].Tls.MaxVersion, cfg.Tls.MaxVersion) + } + + require.Nil(t, cfg.Listeners[1].Tls) +} + +func TestTwoMetricsAddrsAreSpecifiedError(t *testing.T) { + f, err := os.CreateTemp("", "workhorse-config-test") + require.NoError(t, err) + defer os.Remove(f.Name()) + + data := ` +[metrics_listener] +network = "tcp" +addr = "localhost:3445" +` + _, err = io.WriteString(f, data) + require.NoError(t, err) + require.NoError(t, f.Close()) + + args := []string{ + "-config", f.Name(), + "-prometheusListenAddr", "prometheus listen addr", + } + _, _, err = buildConfig("test", args) + require.EqualError(t, err, "configFile: both prometheusListenAddr and metrics_listener can't be specified") } func TestConfigErrorHelp(t *testing.T) { @@ -215,6 +278,7 @@ func TestConfigFlagParsing(t *testing.T) { APICILongPollingDuration: 234 * time.Second, PropagateCorrelationID: true, ImageResizerConfig: config.DefaultImageResizerConfig, + MetricsListener: &config.ListenerConfig{Network: "tcp", Addr: "prometheus listen addr"}, } require.Equal(t, expectedCfg, cfg) } diff --git a/workhorse/gitaly_test.go b/workhorse/gitaly_test.go index 38e807f45cc..838e5ecb2fd 100644 --- a/workhorse/gitaly_test.go +++ b/workhorse/gitaly_test.go @@ -5,7 +5,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" "math/rand" "net" "net/http" @@ -651,7 +650,7 @@ func TestGetArchiveProxiedToGitalySuccessfully(t *testing.T) { _, err := os.Stat(tc.archivePath) require.True(t, os.IsNotExist(err), "expected 'does not exist', got: %v", err) } else { - cachedArchive, err := ioutil.ReadFile(tc.archivePath) + cachedArchive, err := os.ReadFile(tc.archivePath) require.NoError(t, err) require.Equal(t, expectedBody, string(cachedArchive)) } diff --git a/workhorse/go.mod b/workhorse/go.mod index 01dc6e468bc..0e102180cb6 100644 --- a/workhorse/go.mod +++ b/workhorse/go.mod @@ -1,16 +1,16 @@ module gitlab.com/gitlab-org/gitlab/workhorse -go 1.16 +go 1.17 require ( - github.com/Azure/azure-storage-blob-go v0.13.0 + github.com/Azure/azure-storage-blob-go v0.14.0 github.com/BurntSushi/toml v0.3.1 github.com/FZambia/sentinel v1.0.0 - github.com/alecthomas/chroma v0.7.3 - github.com/aws/aws-sdk-go v1.38.35 + github.com/alecthomas/chroma v0.10.0 + github.com/aws/aws-sdk-go v1.43.31 github.com/disintegration/imaging v1.6.2 github.com/getsentry/raven-go v0.2.0 - github.com/golang-jwt/jwt/v4 v4.0.0 + github.com/golang-jwt/jwt/v4 v4.4.1 github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 github.com/golang/protobuf v1.5.2 github.com/gomodule/redigo v2.0.0+incompatible @@ -23,19 +23,95 @@ require ( github.com/prometheus/client_golang v1.12.1 github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1 github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a - github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500 // indirect github.com/sirupsen/logrus v1.8.1 github.com/smartystreets/goconvey v1.6.4 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.10.0-rc1.0.20220426135705-ccfab390f7c3 gitlab.com/gitlab-org/golang-archive-zip v0.1.1 - gitlab.com/gitlab-org/labkit v1.14.0 - gocloud.dev v0.23.0 + gitlab.com/gitlab-org/labkit v1.15.0 + gocloud.dev v0.25.0 golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 - golang.org/x/net v0.0.0-20211008194852-3b03d305991f + golang.org/x/net v0.0.0-20220401154927-543a649e0bdd golang.org/x/tools v0.1.5 - google.golang.org/grpc v1.40.0 - google.golang.org/protobuf v1.27.1 + google.golang.org/grpc v1.45.0 + google.golang.org/protobuf v1.28.0 honnef.co/go/tools v0.1.3 ) + +require ( + cloud.google.com/go v0.100.2 // indirect + cloud.google.com/go/compute v1.5.0 // indirect + cloud.google.com/go/monitoring v1.4.0 // indirect + cloud.google.com/go/profiler v0.1.0 // indirect + cloud.google.com/go/trace v1.2.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.10 // indirect + github.com/Azure/azure-pipeline-go v0.2.3 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.22 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.17 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/DataDog/datadog-go v4.4.0+incompatible // indirect + github.com/DataDog/sketches-go v1.0.0 // indirect + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect + github.com/beevik/ntp v0.3.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect + github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/client9/reopen v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dlclark/regexp2 v1.4.0 // indirect + github.com/go-ole/go-ole v1.2.4 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/go-cmp v0.5.7 // indirect + github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/google/wire v0.5.0 // indirect + github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect + github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 // indirect + github.com/lightstep/lightstep-tracer-go v0.25.0 // indirect + github.com/mattn/go-ieproxy v0.0.6 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mitchellh/reflectwalk v1.0.0 // indirect + github.com/oklog/ulid/v2 v2.0.2 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/philhofer/fwd v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect + github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500 // indirect + github.com/shirou/gopsutil/v3 v3.21.2 // indirect + github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect + github.com/tinylib/msgp v1.1.2 // indirect + github.com/tklauser/go-sysconf v0.3.4 // indirect + github.com/tklauser/numcpus v0.2.1 // indirect + github.com/uber/jaeger-client-go v2.29.1+incompatible // indirect + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect + go.opencensus.io v0.23.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect + golang.org/x/mod v0.5.0 // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/api v0.74.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/workhorse/go.sum b/workhorse/go.sum index ed959f44889..61f11579d18 100644 --- a/workhorse/go.sum +++ b/workhorse/go.sum @@ -22,21 +22,43 @@ cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPT cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.92.2 h1:podK44+0gcW5rWGMjJiPH0+rzkCTQx/zT0qF5CLqVkM= cloud.google.com/go v0.92.2/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.5.0/go.mod h1:c4nNYR1qdq7eaZ+jSc5fonrQN2k3M7sWATcYTiakjEo= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= +cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= +cloud.google.com/go/monitoring v1.4.0 h1:05+IuNMbh40hbxcqQ4SnynbwZbLG1Wc9dysIJxnfv7U= +cloud.google.com/go/monitoring v1.4.0/go.mod h1:y6xnxfwI3hTFWOdkOaD7nfJVlwuC3/mS/5kvtT131p4= cloud.google.com/go/profiler v0.1.0 h1:MG/rxKC1MztRfEWMGYKFISxyZak5hNh29f0A/z2tvWk= cloud.google.com/go/profiler v0.1.0/go.mod h1:D7S7LV/zKbRWkOzYL1b5xytpqt8Ikd/v/yvf1/Tx2pQ= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -44,47 +66,68 @@ cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.10.3/go.mod h1:FUcc28GpGxxACoklPsE1sCtbkY4Ix+ro7yvw+h82Jn4= +cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= +cloud.google.com/go/secretmanager v1.3.0/go.mod h1:+oLTkouyiYiabAQNugCeTS3PAArGiMJuBqvJnJsyH+U= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.15.0 h1:Ljj+ZXVEhCr/1+4ZhvtteN1ND7UUsNTlduGclLh8GO0= cloud.google.com/go/storage v1.15.0/go.mod h1:mjjQMoxxyGH7Jr8K5qrx6N2O0AHsczI61sMNn03GIZI= -cloud.google.com/go/trace v0.1.0 h1:nUGUK79FOkN0UGUXhBmVBkbu1PYsHe0YyFSPLOD9Npg= +cloud.google.com/go/storage v1.21.0 h1:HwnT2u2D309SFDHQII6m18HlrCi3jAXhUMTLOWXYH14= +cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= cloud.google.com/go/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= +cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= +cloud.google.com/go/trace v1.2.0 h1:oIaB4KahkIUOpLSAAjEJ8y2desbjY/x/RfP4O3KAtTI= +cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= -contrib.go.opencensus.io/exporter/stackdriver v0.13.8 h1:lIFYmQsqejvlq+GobFUbC5F0prD5gvhP6r0gWLZRDq4= contrib.go.opencensus.io/exporter/stackdriver v0.13.8/go.mod h1:huNtlWx75MwO7qMs0KrMxPZXzNNWebav1Sq/pm02JdQ= +contrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys= +contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-amqp-common-go/v3 v3.1.0/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0= +github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= +github.com/Azure/azure-amqp-common-go/v3 v3.2.2/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v54.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v59.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= github.com/Azure/azure-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= -github.com/Azure/azure-storage-blob-go v0.13.0 h1:lgWHvFh+UYBNVQLFHXkvul2f6yOPA9PIH82RTG2cSwc= +github.com/Azure/azure-service-bus-go v0.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= +github.com/Azure/azure-storage-blob-go v0.14.0 h1:1BCg74AmVdYwO3dlKwtFU1V0wU2PZdREkXvAmZJRUlM= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= github.com/Azure/go-amqp v0.13.0/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs= github.com/Azure/go-amqp v0.13.4/go.mod h1:wbpCKA8tR5MLgRyIu+bb+S6ECdIDdYJ0NlpFE9xsBPI= github.com/Azure/go-amqp v0.13.7/go.mod h1:wbpCKA8tR5MLgRyIu+bb+S6ECdIDdYJ0NlpFE9xsBPI= +github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-amqp v0.16.4/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22 h1:bXiQwDjrRmBQOE67bwlvUKAC1EU1yZTPQ38c+bstZws= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= -github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.7 h1:8DQB8yl7aLQuP+nuR5e2RO6454OvFlSTXXaNHshc16s= +github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.17 h1:esOPl2dhcz9P3jqBSJ8tPGEj2EqzPPT6zfyuloiogKY= +github.com/Azure/go-autorest/autorest/adal v0.9.17/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.9 h1:Y2CgdzitFDsdMwYMzf9LIZWrrTFysqbRc7b94XVVJ78= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.9/go.mod h1:hg3/1yw0Bq87O3KvvnJoAh34/0zbP7SFizX/qN5JvjU= github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 h1:dMOmEJfkLKW/7JsokJqkyoYSgmR08hi9KrhjZb+JALY= github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= @@ -114,6 +157,7 @@ github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8 github.com/FZambia/sentinel v1.0.0 h1:KJ0ryjKTZk5WMp0dXvSdNqp3lFaW1fNFuEYfrkLOYIc= github.com/FZambia/sentinel v1.0.0/go.mod h1:ytL1Am/RLlAoAXG6Kj5LNuw/TRRQrv2rt2FT26vP5gI= github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= @@ -137,15 +181,8 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= -github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= -github.com/alecthomas/chroma v0.7.3 h1:NfdAERMy+esYQs8OXk0I868/qDxxCEo7FMz1WIqMAeI= -github.com/alecthomas/chroma v0.7.3/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM= -github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= -github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= -github.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE= -github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= -github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= +github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -169,12 +206,53 @@ github.com/aws/aws-sdk-go v1.17.4/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.38.35 h1:7AlAO0FC+8nFjxiGKEmq0QLpiA8/XFr6eIxgRTwkdTg= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= +github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.16.2 h1:fqlCk6Iy3bnCumtrLz9r3mJ/2gUT0pJ0wLFVIdWh+JA= +github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 h1:SdK4Ppk5IzLs64ZMvr6MrSficMtjY2oS0WOORXTlxwU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM= +github.com/aws/aws-sdk-go-v2/config v1.15.3 h1:5AlQD0jhVXlGzwo+VORKiUuogkG7pQcLJNzIzK7eodw= +github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= +github.com/aws/aws-sdk-go-v2/credentials v1.11.2 h1:RQQ5fzclAKJyY5TvF+fkjJEwzK4hnxQCLOu5JXzDmQo= +github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 h1:LWPg5zjHV9oz/myQr4wMs0gi4CjnDN/ILmyZUFYXZsU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 h1:ir7iEq78s4txFGgwcLqD6q9IIPzTQNRJXulJd9h/zQo= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3/go.mod h1:0dHuD2HZZSiwfJSy1FO5bX1hQ1TxVV1QXXjpn3XUE44= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 h1:onz/VaaxZ7Z4V+WIN9Txly9XLTmoOh1oJ8XcAC3pako= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 h1:9stUQR/u2KXU6HkFJYlqnZEjBnbgrVbG6I5HN09xZh0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 h1:by9P+oy3P/CwggN4ClnW2D4oL91QV7pBzBICi1chZvQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 h1:T4pFel53bkHjL2mMo+4DKE6r6AuoZnM0fg7k1/ratr4= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 h1:I0dcwWitE752hVSMrsLCxqNQ+UdEp3nACx2bYNMQq+k= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 h1:Gh1Gpyh01Yvn7ilO/b/hr01WgNpaszfbKMUgqM186xQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 h1:BKjwCJPnANbkwQ8vzSbaZDKawwagDubrH/z/c0X+kbQ= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3/go.mod h1:Bm/v2IaN6rZ+Op7zX+bOUMdL4fsrYZiD0dsjLhNKwZc= +github.com/aws/aws-sdk-go-v2/service/kms v1.16.3/go.mod h1:QuiHPBqlOFCi4LqdSskYYAWpQlx3PKmohy+rE2F+o5g= +github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 h1:rMPtwA7zzkSQZhhz9U3/SoIDz/NZ7Q+iRn4EIO8rSyU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3/go.mod h1:g1qvDuRsJY+XghsV6zg00Z4KJ7DtFFCx8fJD2a491Ak= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4/go.mod h1:PJc8s+lxyU8rrre0/4a0pn2wgwiDvOEzoOjcJUBr67o= +github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw= +github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3/go.mod h1:skmQo0UPvsjsuYYSYMVmrPc1HWCbHUJyrCEp+ZaLzqM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1/go.mod h1:NR/xoKjdbRJ+qx0pMR4mI+N/H1I1ynHwXnO6FowXJc0= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 h1:frW4ikGcxfAEDfmQqWgMLp+F1n4nRo9sF39OcIb5BkQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 h1:cJGRyzCSVwZC7zZZ1xbx9m32UnrKydRYhOvcD1NYP9Q= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= +github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= +github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw= github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -208,7 +286,11 @@ github.com/cloudflare/tableflip v1.2.2/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= @@ -222,19 +304,19 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= -github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -247,8 +329,9 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= -github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= +github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dpotapov/go-spnego v0.0.0-20190506202455-c2c609116ad0/go.mod h1:P4f4MSk7h52F2PK0lCapn5+fu47Uf8aRdxDSqgezxZE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -268,6 +351,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/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= @@ -276,13 +360,13 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/getsentry/raven-go v0.1.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/raven-go v0.1.2/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= @@ -297,6 +381,7 @@ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NB github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/git-lfs/git-lfs v1.5.1-0.20210304194248-2e1d981afbe3/go.mod h1:8Xqs4mqL7o6xEnaXckIgELARTeK7RYtm3pBab7S79Js= github.com/git-lfs/gitobj/v2 v2.0.1/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8COmU45ncAxw= @@ -356,9 +441,11 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= +github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw= github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= @@ -416,13 +503,16 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/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.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/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.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v1.0.0 h1:B5kVOzJ1hBgnevTgIWhSTatQ3608yu/2NnU0Ta1d0kY= github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.2 h1:HCfx+dQzwN9XbGTHF8qJ+67WN8glL9FTWV5rraCJ/jU= +github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/go-replayers/httpreplay v1.1.1 h1:H91sIMlt1NZzN7R+/ASswyouLJfW0WLW7fhyUFvDEkY= +github.com/google/go-replayers/httpreplay v1.1.1/go.mod h1:gN9GeLIs7l6NUoVaSSnv2RiqK1NiwAmD0MrKeC9IIks= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -432,6 +522,8 @@ github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.m github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -445,6 +537,7 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210125172800-10e9aeb4a998/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -456,13 +549,17 @@ github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -481,6 +578,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= +github.com/hanwen/go-fuse/v2 v2.1.0/go.mod h1:oRyA5eK+pvJyv5otpO/DgccS8y/RvYMaO00GgRLGryc= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -532,6 +631,7 @@ github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfG github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= @@ -551,15 +651,18 @@ github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCM github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= github.com/jackc/pgtype v1.9.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.14.1/go.mod h1:RgDuE4Z34o7XE92RpLsvFiOEfrAUT0Xt2KxvX73W06M= +github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= @@ -618,6 +721,7 @@ github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -631,6 +735,7 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 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/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= @@ -641,6 +746,7 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go v0.0.0-20190104134018-ecaeb7a21d47/go.mod h1:4bKN42efkbNYMZlvDfxGDxzl066GhpvIircZDsm8Y+Y= github.com/libgit2/git2go/v31 v31.4.12/go.mod h1:c/rkJcBcUFx6wHaT++UwNpKvIsmPNqCeQ/vzO4DrEec= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= @@ -661,8 +767,10 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-ieproxy v0.0.3/go.mod h1:6ZpRmhBaYuBX1U2za+9rC9iCGLsSp2tftelZne7CPko= +github.com/mattn/go-ieproxy v0.0.6 h1:tVDlituRyeHMMkHpGpUu8CJG+hxPMwbYCkIUK2PUCbo= +github.com/mattn/go-ieproxy v0.0.6/go.mod h1:6ZpRmhBaYuBX1U2za+9rC9iCGLsSp2tftelZne7CPko= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -670,7 +778,6 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -699,6 +806,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -706,6 +814,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.0.0-20151014174947-eeaced052adb/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -769,6 +878,7 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -838,7 +948,6 @@ github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBa github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a h1:iLcLb5Fwwz7g/DLK89F+uQBDeAhHhwdzB5fSlVdhGcM= github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shabbyrobe/gocovmerge v0.0.0-20180507124511-f6ea450bfb63/go.mod h1:n+VKSARF5y/tS9XFSP7vWDfS+GUC5vs/YT7M5XDTUEM= github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500 h1:WnNuhiq+FOY3jNj6JXFT+eLN3CQ/oPIsDPRanvwsmbI= @@ -956,8 +1065,8 @@ gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkf gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= gitlab.com/gitlab-org/labkit v1.4.1/go.mod h1:x5JO5uvdX4t6e/TZXLXZnFL5AcKz2uLLd3uKXZcuO4k= gitlab.com/gitlab-org/labkit v1.5.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= -gitlab.com/gitlab-org/labkit v1.14.0 h1:LSrvHgybidPyH8fHnsy1GBghrLR4kFObFrtZwUfCgAI= -gitlab.com/gitlab-org/labkit v1.14.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= +gitlab.com/gitlab-org/labkit v1.15.0 h1:rMdhIdONc7bcd5qGRtWav6iInpeDmavDmP9A1tai92k= +gitlab.com/gitlab-org/labkit v1.15.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= @@ -977,21 +1086,26 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -gocloud.dev v0.23.0 h1:u/6F8slWwaZPgGpjpNp0jzH+1P/M2ri7qEP3lFgbqBE= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= gocloud.dev v0.23.0/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= +gocloud.dev v0.25.0 h1:Y7vDq8xj7SyM848KXf32Krda2e6jQ4CLh/mTeCSqXtk= +gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1012,14 +1126,17 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1063,8 +1180,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1121,8 +1239,16 @@ golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f h1:1scJEYZBaF48BaG6tYbtxmLcXqwYGSfGcMoStTqkkIw= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220401154927-543a649e0bdd h1:zYlwaUHTmxuf6H7hwO2dgwqozQmH7zf4x+/qql4oVWc= +golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1139,8 +1265,13 @@ golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a h1:4Kd8OPUx1xgUwrHDaviWZO8MsgoZTZYC3g+8m16RBww= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1198,7 +1329,6 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1240,13 +1370,28 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/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-20220110181412-a018aaa089fe/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-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY= +golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1263,6 +1408,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1382,8 +1528,23 @@ google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59t google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0 h1:ECJUVngj71QI6XEm7b1sAf8BljU5inEhMbKPR8Lxhhk= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= +google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.68.0/go.mod h1:sOM8pTpwgflXRhz+oC8H2Dr+UcbMqkPPWNJo88Q7TH8= +google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1446,6 +1607,7 @@ google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQ google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -1454,8 +1616,38 @@ google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c h1:iLQakcwWG3k/++1q/46apVb1sUQ3IqIdn9yUE6eh/xA= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220204002441-d6cc3cc0770e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de h1:9Ti5SG2U4cAcluryUo/sFay3TQKoxiFMfaT0pbizU7k= +google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1487,8 +1679,11 @@ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1502,8 +1697,9 @@ 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.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/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= gopkg.in/DataDog/dd-trace-go.v1 v1.7.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg= gopkg.in/DataDog/dd-trace-go.v1 v1.30.0/go.mod h1:SnKViq44dv/0gjl9RpkP0Y2G3BJSRkp6eYdCSu39iI8= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= @@ -1547,8 +1743,9 @@ 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-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 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= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/workhorse/internal/api/api.go b/workhorse/internal/api/api.go index 8954923ad75..a536435a587 100644 --- a/workhorse/internal/api/api.go +++ b/workhorse/internal/api/api.go @@ -156,8 +156,6 @@ type Response struct { ShowAllRefs bool // Detects whether an artifact is used for code intelligence ProcessLsif bool - // Detects whether LSIF artifact will be parsed with references - ProcessLsifReferences bool // The maximum accepted size in bytes of the upload MaximumSize int64 } @@ -263,26 +261,22 @@ func (api *API) newRequest(r *http.Request, suffix string) (*http.Request, error // PreAuthorize performs a pre-authorization check against the API for the given HTTP request // -// If `outErr` is set, the other fields will be nil and it should be treated as -// a 500 error. +// If the returned *http.Response is not nil, the caller is responsible for closing its body // -// If httpResponse is present, the caller is responsible for closing its body -// -// authResponse will only be present if the authorization check was successful -func (api *API) PreAuthorize(suffix string, r *http.Request) (httpResponse *http.Response, authResponse *Response, outErr error) { +// Only upon successful authorization do we return a non-nil *Response +func (api *API) PreAuthorize(suffix string, r *http.Request) (_ *http.Response, _ *Response, err error) { authReq, err := api.newRequest(r, suffix) if err != nil { return nil, nil, fmt.Errorf("preAuthorizeHandler newUpstreamRequest: %v", err) } - httpResponse, err = api.doRequestWithoutRedirects(authReq) + httpResponse, err := api.doRequestWithoutRedirects(authReq) if err != nil { return nil, nil, fmt.Errorf("preAuthorizeHandler: do request: %v", err) } defer func() { - if outErr != nil { + if err != nil { httpResponse.Body.Close() - httpResponse = nil } }() requestsCounter.WithLabelValues(strconv.Itoa(httpResponse.StatusCode), authReq.Method).Inc() @@ -293,17 +287,43 @@ func (api *API) PreAuthorize(suffix string, r *http.Request) (httpResponse *http return httpResponse, nil, nil } - authResponse = &Response{} + authResponse := &Response{} // The auth backend validated the client request and told us additional // request metadata. We must extract this information from the auth // response body. if err := json.NewDecoder(httpResponse.Body).Decode(authResponse); err != nil { - return httpResponse, nil, fmt.Errorf("preAuthorizeHandler: decode authorization response: %v", err) + return nil, nil, fmt.Errorf("preAuthorizeHandler: decode authorization response: %v", err) } return httpResponse, authResponse, nil } +// PreAuthorizeFixedPath makes an internal Workhorse API call to a fixed +// path, using the HTTP headers of r. +func (api *API) PreAuthorizeFixedPath(r *http.Request, method string, path string) (*Response, error) { + authReq, err := http.NewRequestWithContext(r.Context(), method, api.URL.String(), nil) + if err != nil { + return nil, fmt.Errorf("construct auth request: %w", err) + } + authReq.Header = helper.HeaderClone(r.Header) + + failureResponse, apiResponse, err := api.PreAuthorize(path, authReq) + if err != nil { + return nil, fmt.Errorf("PreAuthorize: %w", err) + } + + // We don't need the contents of failureResponse but we are responsible + // for closing it. Part of the reason PreAuthorizeFixedPath exists is to + // hide this awkwardness. + failureResponse.Body.Close() + + if apiResponse == nil { + return nil, fmt.Errorf("no api response: status %d", failureResponse.StatusCode) + } + + return apiResponse, nil +} + func (api *API) PreAuthorizeHandler(next HandleFunc, suffix string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { httpResponse, authResponse, err := api.PreAuthorize(suffix, r) diff --git a/workhorse/internal/api/block_test.go b/workhorse/internal/api/block_test.go index 85ad54f3cfd..0beb401d2f5 100644 --- a/workhorse/internal/api/block_test.go +++ b/workhorse/internal/api/block_test.go @@ -1,7 +1,7 @@ package api import ( - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" @@ -46,7 +46,7 @@ func TestBlocker(t *testing.T) { rw.Flush() body := rw.Result().Body - data, err := ioutil.ReadAll(body) + data, err := io.ReadAll(body) require.NoError(t, err) require.NoError(t, body.Close()) diff --git a/workhorse/internal/artifacts/entry_test.go b/workhorse/internal/artifacts/entry_test.go index 800125eec91..709fd5f57a7 100644 --- a/workhorse/internal/artifacts/entry_test.go +++ b/workhorse/internal/artifacts/entry_test.go @@ -4,7 +4,6 @@ import ( "archive/zip" "encoding/base64" "fmt" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -36,7 +35,7 @@ func testEntryServer(t *testing.T, archive string, entry string) *httptest.Respo } func TestDownloadingFromValidArchive(t *testing.T) { - tempFile, err := ioutil.TempFile("", "uploads") + tempFile, err := os.CreateTemp("", "uploads") require.NoError(t, err) defer tempFile.Close() defer os.Remove(tempFile.Name()) @@ -63,9 +62,7 @@ func TestDownloadingFromValidArchive(t *testing.T) { } func TestDownloadingFromValidHTTPArchive(t *testing.T) { - tempDir, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempDir) + tempDir := t.TempDir() f, err := os.Create(filepath.Join(tempDir, "archive.zip")) require.NoError(t, err) @@ -97,10 +94,9 @@ func TestDownloadingFromValidHTTPArchive(t *testing.T) { } func TestDownloadingNonExistingFile(t *testing.T) { - tempFile, err := ioutil.TempFile("", "uploads") + tempFile, err := os.CreateTemp(t.TempDir(), "uploads") require.NoError(t, err) defer tempFile.Close() - defer os.Remove(tempFile.Name()) archive := zip.NewWriter(tempFile) defer archive.Close() @@ -121,9 +117,7 @@ func TestIncompleteApiResponse(t *testing.T) { } func TestDownloadingFromNonExistingHTTPArchive(t *testing.T) { - tempDir, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempDir) + tempDir := t.TempDir() fileServer := httptest.NewServer(http.FileServer(http.Dir(tempDir))) defer fileServer.Close() diff --git a/workhorse/internal/badgateway/roundtripper.go b/workhorse/internal/badgateway/roundtripper.go index 86337e80f28..240a4ebc86b 100644 --- a/workhorse/internal/badgateway/roundtripper.go +++ b/workhorse/internal/badgateway/roundtripper.go @@ -4,7 +4,7 @@ import ( "bytes" "fmt" "html/template" - "io/ioutil" + "io" "net/http" "strings" "time" @@ -60,7 +60,7 @@ func (t *roundTripper) RoundTrip(r *http.Request) (*http.Response, error) { message, contentType = developmentModeResponse(err) } - injectedResponse.Body = ioutil.NopCloser(strings.NewReader(message)) + injectedResponse.Body = io.NopCloser(strings.NewReader(message)) injectedResponse.Header.Set("Content-Type", contentType) return injectedResponse, nil diff --git a/workhorse/internal/badgateway/roundtripper_test.go b/workhorse/internal/badgateway/roundtripper_test.go index fc7132f9bd7..b59cb8d2c5b 100644 --- a/workhorse/internal/badgateway/roundtripper_test.go +++ b/workhorse/internal/badgateway/roundtripper_test.go @@ -2,7 +2,7 @@ package badgateway import ( "errors" - "io/ioutil" + "io" "net/http" "testing" @@ -45,7 +45,7 @@ func TestErrorPage502(t *testing.T) { require.NoError(t, err, "perform roundtrip") defer response.Body.Close() - body, err := ioutil.ReadAll(response.Body) + body, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, tc.contentType, response.Header.Get("content-type"), "content type") diff --git a/workhorse/internal/config/config.go b/workhorse/internal/config/config.go index e83f55f43bf..3ce88f449a9 100644 --- a/workhorse/internal/config/config.go +++ b/workhorse/internal/config/config.go @@ -120,6 +120,7 @@ type Config struct { TrustedCIDRsForXForwardedFor []string `toml:"trusted_cidrs_for_x_forwarded_for"` TrustedCIDRsForPropagation []string `toml:"trusted_cidrs_for_propagation"` Listeners []ListenerConfig `toml:"listeners"` + MetricsListener *ListenerConfig `toml:"metrics_listener"` } var DefaultImageResizerConfig = ImageResizerConfig{ diff --git a/workhorse/internal/git/archive.go b/workhorse/internal/git/archive.go index e1d03828b63..5dcbb7f262e 100644 --- a/workhorse/internal/git/archive.go +++ b/workhorse/internal/git/archive.go @@ -7,7 +7,6 @@ package git import ( "fmt" "io" - "io/ioutil" "net/http" "os" "path" @@ -180,7 +179,7 @@ func prepareArchiveTempfile(dir string, prefix string) (*os.File, error) { if err := os.MkdirAll(dir, 0700); err != nil { return nil, err } - return ioutil.TempFile(dir, prefix) + return os.CreateTemp(dir, prefix) } func finalizeCachedArchive(tempFile *os.File, archivePath string) error { diff --git a/workhorse/internal/git/archive_test.go b/workhorse/internal/git/archive_test.go index b96d5fdec85..b87800f492c 100644 --- a/workhorse/internal/git/archive_test.go +++ b/workhorse/internal/git/archive_test.go @@ -1,8 +1,8 @@ package git import ( - "io/ioutil" "net/http/httptest" + "os" "testing" "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -40,7 +40,7 @@ func TestParseBasename(t *testing.T) { } func TestFinalizeArchive(t *testing.T) { - tempFile, err := ioutil.TempFile("", "gitlab-workhorse-test") + tempFile, err := os.CreateTemp("", "gitlab-workhorse-test") if err != nil { t.Fatal(err) } diff --git a/workhorse/internal/git/upload-pack_test.go b/workhorse/internal/git/upload-pack_test.go index 9ffc7117790..d1184f95d88 100644 --- a/workhorse/internal/git/upload-pack_test.go +++ b/workhorse/internal/git/upload-pack_test.go @@ -5,10 +5,8 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http/httptest" - "os" "path/filepath" "testing" "time" @@ -57,7 +55,7 @@ func TestUploadPackTimesOut(t *testing.T) { } defer conn.Close() - _, _ = io.Copy(ioutil.Discard, conn) + _, _ = io.Copy(io.Discard, conn) return &gitalypb.PostUploadPackWithSidechannelResponse{}, nil }, }) @@ -75,8 +73,7 @@ func TestUploadPackTimesOut(t *testing.T) { func startSmartHTTPServer(t testing.TB, s gitalypb.SmartHTTPServiceServer) string { t.Helper() - tmp, err := ioutil.TempDir("", "") - require.NoError(t, err) + tmp := t.TempDir() socket := filepath.Join(tmp, "gitaly.sock") ln, err := net.Listen("unix", socket) @@ -90,7 +87,6 @@ func startSmartHTTPServer(t testing.TB, s gitalypb.SmartHTTPServiceServer) strin t.Cleanup(func() { srv.GracefulStop() - require.NoError(t, os.RemoveAll(tmp), "error removing temp dir %q", tmp) }) return fmt.Sprintf("%s://%s", ln.Addr().Network(), ln.Addr().String()) diff --git a/workhorse/internal/helper/helpers.go b/workhorse/internal/helper/helpers.go index f9b46181579..33318407f88 100644 --- a/workhorse/internal/helper/helpers.go +++ b/workhorse/internal/helper/helpers.go @@ -3,7 +3,7 @@ package helper import ( "bytes" "errors" - "io/ioutil" + "io" "mime" "net" "net/http" @@ -197,12 +197,12 @@ func ReadRequestBody(w http.ResponseWriter, r *http.Request, maxBodySize int64) limitedBody := http.MaxBytesReader(w, r.Body, maxBodySize) defer limitedBody.Close() - return ioutil.ReadAll(limitedBody) + return io.ReadAll(limitedBody) } func CloneRequestWithNewBody(r *http.Request, body []byte) *http.Request { newReq := *r - newReq.Body = ioutil.NopCloser(bytes.NewReader(body)) + newReq.Body = io.NopCloser(bytes.NewReader(body)) newReq.Header = HeaderClone(r.Header) newReq.ContentLength = int64(len(body)) return &newReq diff --git a/workhorse/internal/helper/tempfile.go b/workhorse/internal/helper/tempfile.go index d8fc0d44698..f5864f549d0 100644 --- a/workhorse/internal/helper/tempfile.go +++ b/workhorse/internal/helper/tempfile.go @@ -2,12 +2,11 @@ package helper import ( "io" - "io/ioutil" "os" ) func ReadAllTempfile(r io.Reader) (tempfile *os.File, err error) { - tempfile, err = ioutil.TempFile("", "gitlab-workhorse-read-all-tempfile") + tempfile, err = os.CreateTemp("", "gitlab-workhorse-read-all-tempfile") if err != nil { return nil, err } diff --git a/workhorse/internal/helper/writeafterreader.go b/workhorse/internal/helper/writeafterreader.go index 7df2279a86a..3626d70e493 100644 --- a/workhorse/internal/helper/writeafterreader.go +++ b/workhorse/internal/helper/writeafterreader.go @@ -3,7 +3,6 @@ package helper import ( "fmt" "io" - "io/ioutil" "os" "sync" ) @@ -131,7 +130,7 @@ func (w *coupledWriter) tempfileWrite(data []byte) (int, error) { } func (*coupledWriter) newTempfile() (tempfile *os.File, err error) { - tempfile, err = ioutil.TempFile("", "gitlab-workhorse-coupledWriter") + tempfile, err = os.CreateTemp("", "gitlab-workhorse-coupledWriter") if err != nil { return nil, err } diff --git a/workhorse/internal/helper/writeafterreader_test.go b/workhorse/internal/helper/writeafterreader_test.go index 67cb3e6e542..c3da428184b 100644 --- a/workhorse/internal/helper/writeafterreader_test.go +++ b/workhorse/internal/helper/writeafterreader_test.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "testing" "testing/iotest" ) @@ -14,7 +13,7 @@ func TestBusyReader(t *testing.T) { r := testReader(testData) br, _ := NewWriteAfterReader(r, &bytes.Buffer{}) - result, err := ioutil.ReadAll(br) + result, err := io.ReadAll(br) if err != nil { t.Fatal(err) } @@ -27,7 +26,7 @@ func TestBusyReader(t *testing.T) { func TestFirstWriteAfterReadDone(t *testing.T) { writeRecorder := &bytes.Buffer{} br, cw := NewWriteAfterReader(&bytes.Buffer{}, writeRecorder) - if _, err := io.Copy(ioutil.Discard, br); err != nil { + if _, err := io.Copy(io.Discard, br); err != nil { t.Fatalf("copy from busyreader: %v", err) } testData := "test data" @@ -53,7 +52,7 @@ func TestWriteDelay(t *testing.T) { } // Unblock the coupled writer by draining the reader - if _, err := io.Copy(ioutil.Discard, br); err != nil { + if _, err := io.Copy(io.Discard, br); err != nil { t.Fatalf("copy from busyreader: %v", err) } // Now it is no longer an error if 'w' receives a Write() diff --git a/workhorse/internal/httprs/httprs.go b/workhorse/internal/httprs/httprs.go index a38230c1968..f7767d2ee28 100644 --- a/workhorse/internal/httprs/httprs.go +++ b/workhorse/internal/httprs/httprs.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "github.com/mitchellh/copystructure" @@ -148,7 +147,7 @@ func (r *HttpReadSeeker) Seek(offset int64, whence int) (int64, error) { if r.r != nil { // Try to read, which is cheaper than doing a request if r.pos < offset && offset-r.pos <= shortSeekBytes { - _, err := io.CopyN(ioutil.Discard, r, offset-r.pos) + _, err := io.CopyN(io.Discard, r, offset-r.pos) if err != nil { return 0, err } diff --git a/workhorse/internal/httprs/httprs_test.go b/workhorse/internal/httprs/httprs_test.go index e26d2d21215..9dcfe75219b 100644 --- a/workhorse/internal/httprs/httprs_test.go +++ b/workhorse/internal/httprs/httprs_test.go @@ -3,7 +3,6 @@ package httprs import ( "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -49,7 +48,7 @@ type fakeRoundTripper struct { func (f *fakeRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { fw := &fakeResponseWriter{h: http.Header{}} var err error - fw.tmp, err = ioutil.TempFile(os.TempDir(), "httprs") + fw.tmp, err = os.CreateTemp(os.TempDir(), "httprs") if err != nil { return nil, err } @@ -79,7 +78,7 @@ type RSFactory func() *HttpReadSeeker func newRSFactory(flags int) RSFactory { return func() *HttpReadSeeker { - tmp, err := ioutil.TempFile(os.TempDir(), "httprs") + tmp, err := os.CreateTemp(os.TempDir(), "httprs") if err != nil { return nil } @@ -111,11 +110,9 @@ func newRSFactory(flags int) RSFactory { func TestHttpWebServer(t *testing.T) { Convey("Scenario: testing WebServer", t, func() { - dir, err := ioutil.TempDir("", "webserver") - So(err, ShouldBeNil) - defer os.RemoveAll(dir) + dir := t.TempDir() - err = ioutil.WriteFile(filepath.Join(dir, "file"), make([]byte, 10000), 0755) + err := os.WriteFile(filepath.Join(dir, "file"), make([]byte, 10000), 0755) So(err, ShouldBeNil) server := httptest.NewServer(http.FileServer(http.Dir(dir))) diff --git a/workhorse/internal/imageresizer/image_resizer_test.go b/workhorse/internal/imageresizer/image_resizer_test.go index 8f5c8b2a6eb..f16df77f002 100644 --- a/workhorse/internal/imageresizer/image_resizer_test.go +++ b/workhorse/internal/imageresizer/image_resizer_test.go @@ -5,7 +5,7 @@ import ( "encoding/json" "image" "image/png" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -184,7 +184,7 @@ func TestServeOriginalImageWhenSourceImageFormatIsNotAllowed(t *testing.T) { cfg := config.DefaultImageResizerConfig // SVG images are not allowed to be resized svgImagePath := "../../testdata/image.svg" - svgImage, err := ioutil.ReadFile(svgImagePath) + svgImage, err := os.ReadFile(svgImagePath) require.NoError(t, err) // ContentType is no longer used to perform the format validation. // To make the test more strict, we'll use allowed, but incorrect ContentType. @@ -193,7 +193,7 @@ func TestServeOriginalImageWhenSourceImageFormatIsNotAllowed(t *testing.T) { resp := requestScaledImage(t, nil, params, cfg) require.Equal(t, http.StatusOK, resp.StatusCode) - responseData, err := ioutil.ReadAll(resp.Body) + responseData, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, svgImage, responseData, "expected original image") } @@ -201,7 +201,7 @@ func TestServeOriginalImageWhenSourceImageFormatIsNotAllowed(t *testing.T) { func TestServeOriginalImageWhenSourceImageIsTooSmall(t *testing.T) { content := []byte("PNG") // 3 bytes only, invalid as PNG/JPEG image - img, err := ioutil.TempFile("", "*.png") + img, err := os.CreateTemp("", "*.png") require.NoError(t, err) defer img.Close() @@ -216,7 +216,7 @@ func TestServeOriginalImageWhenSourceImageIsTooSmall(t *testing.T) { resp := requestScaledImage(t, nil, params, cfg) require.Equal(t, http.StatusOK, resp.StatusCode) - responseData, err := ioutil.ReadAll(resp.Body) + responseData, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, content, responseData, "expected original image") } diff --git a/workhorse/internal/lsif_transformer/parser/cache.go b/workhorse/internal/lsif_transformer/parser/cache.go index 395069cd217..ec64fd21aa8 100644 --- a/workhorse/internal/lsif_transformer/parser/cache.go +++ b/workhorse/internal/lsif_transformer/parser/cache.go @@ -3,7 +3,6 @@ package parser import ( "encoding/binary" "io" - "io/ioutil" "os" ) @@ -15,8 +14,8 @@ type cache struct { chunkSize int64 } -func newCache(tempDir, filename string, data interface{}) (*cache, error) { - f, err := ioutil.TempFile(tempDir, filename) +func newCache(filename string, data interface{}) (*cache, error) { + f, err := os.CreateTemp("", filename) if err != nil { return nil, err } diff --git a/workhorse/internal/lsif_transformer/parser/cache_test.go b/workhorse/internal/lsif_transformer/parser/cache_test.go index 23a2ac6e9a9..c5d4479d973 100644 --- a/workhorse/internal/lsif_transformer/parser/cache_test.go +++ b/workhorse/internal/lsif_transformer/parser/cache_test.go @@ -1,7 +1,7 @@ package parser import ( - "io/ioutil" + "io" "testing" "github.com/stretchr/testify/require" @@ -13,7 +13,7 @@ type chunk struct { } func TestCache(t *testing.T) { - cache, err := newCache("", "test-chunks", chunk{}) + cache, err := newCache("test-chunks", chunk{}) require.NoError(t, err) defer cache.Close() @@ -21,7 +21,7 @@ func TestCache(t *testing.T) { require.NoError(t, cache.SetEntry(1, &c)) require.NoError(t, cache.setOffset(0)) - content, err := ioutil.ReadAll(cache.file) + content, err := io.ReadAll(cache.file) require.NoError(t, err) expected := []byte{0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x2, 0x0} diff --git a/workhorse/internal/lsif_transformer/parser/docs.go b/workhorse/internal/lsif_transformer/parser/docs.go index c626e07d3fe..f87bc7fd86c 100644 --- a/workhorse/internal/lsif_transformer/parser/docs.go +++ b/workhorse/internal/lsif_transformer/parser/docs.go @@ -35,8 +35,8 @@ type Metadata struct { Root string `json:"projectRoot"` } -func NewDocs(config Config) (*Docs, error) { - ranges, err := NewRanges(config) +func NewDocs() (*Docs, error) { + ranges, err := NewRanges() if err != nil { return nil, err } diff --git a/workhorse/internal/lsif_transformer/parser/docs_test.go b/workhorse/internal/lsif_transformer/parser/docs_test.go index 57dca8e773d..24e3eba8ac5 100644 --- a/workhorse/internal/lsif_transformer/parser/docs_test.go +++ b/workhorse/internal/lsif_transformer/parser/docs_test.go @@ -14,7 +14,7 @@ func createLine(id, label, uri string) []byte { } func TestParse(t *testing.T) { - d, err := NewDocs(Config{}) + d, err := NewDocs() require.NoError(t, err) defer d.Close() @@ -31,7 +31,7 @@ func TestParse(t *testing.T) { } func TestParseContainsLine(t *testing.T) { - d, err := NewDocs(Config{}) + d, err := NewDocs() require.NoError(t, err) defer d.Close() @@ -44,7 +44,7 @@ func TestParseContainsLine(t *testing.T) { } func TestParsingVeryLongLine(t *testing.T) { - d, err := NewDocs(Config{}) + d, err := NewDocs() require.NoError(t, err) defer d.Close() diff --git a/workhorse/internal/lsif_transformer/parser/hovers.go b/workhorse/internal/lsif_transformer/parser/hovers.go index a13c7e4c5c2..33d45829295 100644 --- a/workhorse/internal/lsif_transformer/parser/hovers.go +++ b/workhorse/internal/lsif_transformer/parser/hovers.go @@ -2,7 +2,6 @@ package parser import ( "encoding/json" - "io/ioutil" "os" ) @@ -36,10 +35,8 @@ type ResultSetRef struct { RefId Id `json:"inV"` } -func NewHovers(config Config) (*Hovers, error) { - tempPath := config.TempPath - - file, err := ioutil.TempFile(tempPath, "hovers") +func NewHovers() (*Hovers, error) { + file, err := os.CreateTemp("", "hovers") if err != nil { return nil, err } @@ -48,7 +45,7 @@ func NewHovers(config Config) (*Hovers, error) { return nil, err } - offsets, err := newCache(tempPath, "hovers-indexes", Offset{}) + offsets, err := newCache("hovers-indexes", Offset{}) if err != nil { return nil, err } diff --git a/workhorse/internal/lsif_transformer/parser/hovers_test.go b/workhorse/internal/lsif_transformer/parser/hovers_test.go index 3037be103af..5b2166c07a1 100644 --- a/workhorse/internal/lsif_transformer/parser/hovers_test.go +++ b/workhorse/internal/lsif_transformer/parser/hovers_test.go @@ -19,7 +19,7 @@ func TestHoversRead(t *testing.T) { } func setupHovers(t *testing.T) *Hovers { - h, err := NewHovers(Config{}) + h, err := NewHovers() require.NoError(t, err) require.NoError(t, h.Read("hoverResult", []byte(`{"id":"2","label":"hoverResult","result":{"contents": ["hello"]}}`))) diff --git a/workhorse/internal/lsif_transformer/parser/parser.go b/workhorse/internal/lsif_transformer/parser/parser.go index 085e7a856aa..2e4f925950c 100644 --- a/workhorse/internal/lsif_transformer/parser/parser.go +++ b/workhorse/internal/lsif_transformer/parser/parser.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "gitlab.com/gitlab-org/labkit/log" @@ -22,18 +21,14 @@ type Parser struct { pr *io.PipeReader } -type Config struct { - TempPath string -} - -func NewParser(ctx context.Context, r io.Reader, config Config) (io.ReadCloser, error) { - docs, err := NewDocs(config) +func NewParser(ctx context.Context, r io.Reader) (io.ReadCloser, error) { + docs, err := NewDocs() if err != nil { return nil, err } // ZIP files need to be seekable. Don't hold it all in RAM, use a tempfile - tempFile, err := ioutil.TempFile(config.TempPath, Lsif) + tempFile, err := os.CreateTemp("", Lsif) if err != nil { return nil, err } diff --git a/workhorse/internal/lsif_transformer/parser/parser_test.go b/workhorse/internal/lsif_transformer/parser/parser_test.go index 3a4d72360e2..6887f699cb3 100644 --- a/workhorse/internal/lsif_transformer/parser/parser_test.go +++ b/workhorse/internal/lsif_transformer/parser/parser_test.go @@ -6,7 +6,6 @@ import ( "context" "encoding/json" "io" - "io/ioutil" "os" "path/filepath" "testing" @@ -26,13 +25,13 @@ func TestGenerate(t *testing.T) { } func verifyCorrectnessOf(t *testing.T, tmpDir, fileName string) { - file, err := ioutil.ReadFile(filepath.Join(tmpDir, fileName)) + file, err := os.ReadFile(filepath.Join(tmpDir, fileName)) require.NoError(t, err) var buf bytes.Buffer require.NoError(t, json.Indent(&buf, file, "", " ")) - expected, err := ioutil.ReadFile(filepath.Join("testdata/expected/", fileName)) + expected, err := os.ReadFile(filepath.Join("testdata/expected/", fileName)) require.NoError(t, err) require.Equal(t, string(expected), buf.String()) @@ -43,7 +42,7 @@ func createFiles(t *testing.T, filePath, tmpDir string) { file, err := os.Open(filePath) require.NoError(t, err) - parser, err := NewParser(context.Background(), file, Config{}) + parser, err := NewParser(context.Background(), file) require.NoError(t, err) zipFileName := tmpDir + ".zip" diff --git a/workhorse/internal/lsif_transformer/parser/performance_test.go b/workhorse/internal/lsif_transformer/parser/performance_test.go index 5a12d90072f..f4adb7a52be 100644 --- a/workhorse/internal/lsif_transformer/parser/performance_test.go +++ b/workhorse/internal/lsif_transformer/parser/performance_test.go @@ -3,7 +3,6 @@ package parser import ( "context" "io" - "io/ioutil" "os" "runtime" "testing" @@ -22,10 +21,10 @@ func BenchmarkGenerate(b *testing.B) { file, err := os.Open(filePath) require.NoError(b, err) - parser, err := NewParser(context.Background(), file, Config{}) + parser, err := NewParser(context.Background(), file) require.NoError(b, err) - _, err = io.Copy(ioutil.Discard, parser) + _, err = io.Copy(io.Discard, parser) require.NoError(b, err) require.NoError(b, parser.Close()) }) diff --git a/workhorse/internal/lsif_transformer/parser/ranges.go b/workhorse/internal/lsif_transformer/parser/ranges.go index 3786e15186e..0b4bd588e16 100644 --- a/workhorse/internal/lsif_transformer/parser/ranges.go +++ b/workhorse/internal/lsif_transformer/parser/ranges.go @@ -50,18 +50,18 @@ type SerializedRange struct { References []SerializedReference `json:"references,omitempty"` } -func NewRanges(config Config) (*Ranges, error) { - hovers, err := NewHovers(config) +func NewRanges() (*Ranges, error) { + hovers, err := NewHovers() if err != nil { return nil, err } - references, err := NewReferences(config) + references, err := NewReferences() if err != nil { return nil, err } - cache, err := newCache(config.TempPath, "ranges", Range{}) + cache, err := newCache("ranges", Range{}) if err != nil { return nil, err } diff --git a/workhorse/internal/lsif_transformer/parser/ranges_test.go b/workhorse/internal/lsif_transformer/parser/ranges_test.go index c1400ba61da..807945b41b1 100644 --- a/workhorse/internal/lsif_transformer/parser/ranges_test.go +++ b/workhorse/internal/lsif_transformer/parser/ranges_test.go @@ -42,7 +42,7 @@ func TestSerialize(t *testing.T) { } func setup(t *testing.T) (*Ranges, func()) { - r, err := NewRanges(Config{}) + r, err := NewRanges() require.NoError(t, err) require.NoError(t, r.Read("range", []byte(`{"id":1,"label":"range","start":{"line":1,"character":2}}`))) diff --git a/workhorse/internal/lsif_transformer/parser/references.go b/workhorse/internal/lsif_transformer/parser/references.go index 39c34105fd1..815f6dfff49 100644 --- a/workhorse/internal/lsif_transformer/parser/references.go +++ b/workhorse/internal/lsif_transformer/parser/references.go @@ -19,15 +19,13 @@ type SerializedReference struct { Path string `json:"path"` } -func NewReferences(config Config) (*References, error) { - tempPath := config.TempPath - - items, err := newCache(tempPath, "references", Item{}) +func NewReferences() (*References, error) { + items, err := newCache("references", Item{}) if err != nil { return nil, err } - offsets, err := newCache(tempPath, "references-offsets", ReferencesOffset{}) + offsets, err := newCache("references-offsets", ReferencesOffset{}) if err != nil { return nil, err } diff --git a/workhorse/internal/lsif_transformer/parser/references_test.go b/workhorse/internal/lsif_transformer/parser/references_test.go index 7b47513bc53..0bf18e44c01 100644 --- a/workhorse/internal/lsif_transformer/parser/references_test.go +++ b/workhorse/internal/lsif_transformer/parser/references_test.go @@ -12,7 +12,7 @@ func TestReferencesStore(t *testing.T) { refId = 3 ) - r, err := NewReferences(Config{}) + r, err := NewReferences() require.NoError(t, err) err = r.Store(refId, []Item{{Line: 2, DocId: docId}, {Line: 3, DocId: docId}}) @@ -30,7 +30,7 @@ func TestReferencesStore(t *testing.T) { func TestReferencesStoreEmpty(t *testing.T) { const refId = 3 - r, err := NewReferences(Config{}) + r, err := NewReferences() require.NoError(t, err) err = r.Store(refId, []Item{}) diff --git a/workhorse/internal/secret/jwt.go b/workhorse/internal/secret/jwt.go index 804f3a9aba9..ce0de6ca38d 100644 --- a/workhorse/internal/secret/jwt.go +++ b/workhorse/internal/secret/jwt.go @@ -7,7 +7,7 @@ import ( ) var ( - DefaultClaims = jwt.StandardClaims{Issuer: "gitlab-workhorse"} + DefaultClaims = jwt.RegisteredClaims{Issuer: "gitlab-workhorse"} ) func JWTTokenString(claims jwt.Claims) (string, error) { diff --git a/workhorse/internal/secret/secret.go b/workhorse/internal/secret/secret.go index e8c7c25393c..664f07a52c0 100644 --- a/workhorse/internal/secret/secret.go +++ b/workhorse/internal/secret/secret.go @@ -3,7 +3,7 @@ package secret import ( "encoding/base64" "fmt" - "io/ioutil" + "os" "sync" ) @@ -57,7 +57,7 @@ func setBytes() ([]byte, error) { return theSecret.bytes, nil } - base64Bytes, err := ioutil.ReadFile(theSecret.path) + base64Bytes, err := os.ReadFile(theSecret.path) if err != nil { return nil, fmt.Errorf("secret.setBytes: read %q: %v", theSecret.path, err) } diff --git a/workhorse/internal/senddata/contentprocessor/contentprocessor_test.go b/workhorse/internal/senddata/contentprocessor/contentprocessor_test.go index b009cda1a24..ce7f7921589 100644 --- a/workhorse/internal/senddata/contentprocessor/contentprocessor_test.go +++ b/workhorse/internal/senddata/contentprocessor/contentprocessor_test.go @@ -2,7 +2,6 @@ package contentprocessor import ( "io" - "io/ioutil" "net/http" "net/http/httptest" "testing" @@ -306,7 +305,7 @@ func makeRequest(t *testing.T, handler http.HandlerFunc, body string, dispositio SetContentHeaders(handler).ServeHTTP(rw, req) resp := rw.Result() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, body, string(respBody)) diff --git a/workhorse/internal/senddata/writer_test.go b/workhorse/internal/senddata/writer_test.go index fd6f7df5e64..b0c808c6158 100644 --- a/workhorse/internal/senddata/writer_test.go +++ b/workhorse/internal/senddata/writer_test.go @@ -2,7 +2,6 @@ package senddata import ( "io" - "io/ioutil" "net/http" "net/http/httptest" "strings" @@ -47,7 +46,7 @@ func TestWriter(t *testing.T) { recorder.Flush() body := recorder.Result().Body - data, err := ioutil.ReadAll(body) + data, err := io.ReadAll(body) require.NoError(t, err) require.NoError(t, body.Close()) diff --git a/workhorse/internal/sendfile/sendfile.go b/workhorse/internal/sendfile/sendfile.go index 75e497f0564..07b1789445a 100644 --- a/workhorse/internal/sendfile/sendfile.go +++ b/workhorse/internal/sendfile/sendfile.go @@ -9,7 +9,6 @@ package sendfile import ( "fmt" "io" - "io/ioutil" "net/http" "regexp" @@ -128,7 +127,7 @@ func sendFileFromDisk(w http.ResponseWriter, r *http.Request, file string) { countSendFileMetrics(fi.Size(), r) if contentTypeHeaderPresent { - data, err := ioutil.ReadAll(io.LimitReader(content, headers.MaxDetectSize)) + data, err := io.ReadAll(io.LimitReader(content, headers.MaxDetectSize)) if err != nil { helper.Fail500(w, r, fmt.Errorf("content type detection: %v", err)) return diff --git a/workhorse/internal/sendfile/sendfile_test.go b/workhorse/internal/sendfile/sendfile_test.go index f01bee0b799..002de7f9f3e 100644 --- a/workhorse/internal/sendfile/sendfile_test.go +++ b/workhorse/internal/sendfile/sendfile_test.go @@ -1,9 +1,10 @@ package sendfile import ( - "io/ioutil" + "io" "net/http" "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/require" @@ -15,7 +16,7 @@ func TestResponseWriter(t *testing.T) { upstreamResponse := "hello world" fixturePath := "testdata/sent-file.txt" - fixtureContent, err := ioutil.ReadFile(fixturePath) + fixtureContent, err := os.ReadFile(fixturePath) require.NoError(t, err) testCases := []struct { @@ -52,7 +53,7 @@ func TestResponseWriter(t *testing.T) { rw.Flush() body := rw.Result().Body - data, err := ioutil.ReadAll(body) + data, err := io.ReadAll(body) require.NoError(t, err) require.NoError(t, body.Close()) @@ -90,7 +91,7 @@ func TestSuccessOverrideContentHeadersFeatureEnabled(t *testing.T) { func TestSuccessOverrideContentHeadersRangeRequestFeatureEnabled(t *testing.T) { fixturePath := "../../testdata/forgedfile.png" - fixtureContent, err := ioutil.ReadFile(fixturePath) + fixtureContent, err := os.ReadFile(fixturePath) require.NoError(t, err) r, err := http.NewRequest("GET", "/foo", nil) @@ -113,7 +114,7 @@ func TestSuccessOverrideContentHeadersRangeRequestFeatureEnabled(t *testing.T) { resp := rw.Result() body := resp.Body - data, err := ioutil.ReadAll(body) + data, err := io.ReadAll(body) require.NoError(t, err) require.NoError(t, body.Close()) @@ -138,7 +139,7 @@ func TestSuccessInlineWhitelistedTypesFeatureEnabled(t *testing.T) { } func makeRequest(t *testing.T, fixturePath string, httpHeaders map[string]string) *http.Response { - fixtureContent, err := ioutil.ReadFile(fixturePath) + fixtureContent, err := os.ReadFile(fixturePath) require.NoError(t, err) r, err := http.NewRequest("GET", "/foo", nil) @@ -161,7 +162,7 @@ func makeRequest(t *testing.T, fixturePath string, httpHeaders map[string]string resp := rw.Result() body := resp.Body - data, err := ioutil.ReadAll(body) + data, err := io.ReadAll(body) require.NoError(t, err) require.NoError(t, body.Close()) diff --git a/workhorse/internal/sendurl/sendurl_test.go b/workhorse/internal/sendurl/sendurl_test.go index cc77fff0bfd..bca6b7d3075 100644 --- a/workhorse/internal/sendurl/sendurl_test.go +++ b/workhorse/internal/sendurl/sendurl_test.go @@ -3,7 +3,6 @@ package sendurl import ( "encoding/base64" "fmt" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -40,7 +39,7 @@ func testEntryServer(t *testing.T, requestURL string, httpHeaders http.Header, a serveFile := func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "GET", r.Method) - tempFile, err := ioutil.TempFile("", "download_file") + tempFile, err := os.CreateTemp("", "download_file") require.NoError(t, err) require.NoError(t, os.Remove(tempFile.Name())) defer tempFile.Close() diff --git a/workhorse/internal/staticpages/deploy_page.go b/workhorse/internal/staticpages/deploy_page.go index 35ebafa66e1..3dc2d982981 100644 --- a/workhorse/internal/staticpages/deploy_page.go +++ b/workhorse/internal/staticpages/deploy_page.go @@ -1,8 +1,8 @@ package staticpages import ( - "io/ioutil" "net/http" + "os" "path/filepath" "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" @@ -12,7 +12,7 @@ func (s *Static) DeployPage(handler http.Handler) http.Handler { deployPage := filepath.Join(s.DocumentRoot, "index.html") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - data, err := ioutil.ReadFile(deployPage) + data, err := os.ReadFile(deployPage) if err != nil { handler.ServeHTTP(w, r) return diff --git a/workhorse/internal/staticpages/deploy_page_test.go b/workhorse/internal/staticpages/deploy_page_test.go index bc413880184..52ac69da23c 100644 --- a/workhorse/internal/staticpages/deploy_page_test.go +++ b/workhorse/internal/staticpages/deploy_page_test.go @@ -1,7 +1,6 @@ package staticpages import ( - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -14,11 +13,7 @@ import ( ) func TestIfNoDeployPageExist(t *testing.T) { - dir, err := ioutil.TempDir("", "deploy") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() w := httptest.NewRecorder() @@ -33,14 +28,10 @@ func TestIfNoDeployPageExist(t *testing.T) { } func TestIfDeployPageExist(t *testing.T) { - dir, err := ioutil.TempDir("", "deploy") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() deployPage := "DEPLOY" - ioutil.WriteFile(filepath.Join(dir, "index.html"), []byte(deployPage), 0600) + os.WriteFile(filepath.Join(dir, "index.html"), []byte(deployPage), 0600) w := httptest.NewRecorder() diff --git a/workhorse/internal/staticpages/error_pages.go b/workhorse/internal/staticpages/error_pages.go index 6b86e21940b..e0ba7a5ceef 100644 --- a/workhorse/internal/staticpages/error_pages.go +++ b/workhorse/internal/staticpages/error_pages.go @@ -3,8 +3,8 @@ package staticpages import ( "encoding/json" "fmt" - "io/ioutil" "net/http" + "os" "path/filepath" "github.com/prometheus/client_golang/prometheus" @@ -97,7 +97,7 @@ func (s *errorPageResponseWriter) writeHTML() (string, []byte) { errorPageFile := filepath.Join(s.path, fmt.Sprintf("%d.html", s.status)) // check if custom error page exists, serve this page instead - if data, err := ioutil.ReadFile(errorPageFile); err == nil { + if data, err := os.ReadFile(errorPageFile); err == nil { return "text/html; charset=utf-8", data } } diff --git a/workhorse/internal/staticpages/error_pages_test.go b/workhorse/internal/staticpages/error_pages_test.go index c9927668fcc..12c268fb40b 100644 --- a/workhorse/internal/staticpages/error_pages_test.go +++ b/workhorse/internal/staticpages/error_pages_test.go @@ -2,7 +2,6 @@ package staticpages import ( "fmt" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -15,14 +14,10 @@ import ( ) func TestIfErrorPageIsPresented(t *testing.T) { - dir, err := ioutil.TempDir("", "error_page") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() errorPage := "ERROR" - ioutil.WriteFile(filepath.Join(dir, "404.html"), []byte(errorPage), 0600) + os.WriteFile(filepath.Join(dir, "404.html"), []byte(errorPage), 0600) w := httptest.NewRecorder() h := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { @@ -42,11 +37,7 @@ func TestIfErrorPageIsPresented(t *testing.T) { } func TestIfErrorPassedIfNoErrorPageIsFound(t *testing.T) { - dir, err := ioutil.TempDir("", "error_page") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() w := httptest.NewRecorder() errorResponse := "ERROR" @@ -63,14 +54,10 @@ func TestIfErrorPassedIfNoErrorPageIsFound(t *testing.T) { } func TestIfErrorPageIsIgnoredInDevelopment(t *testing.T) { - dir, err := ioutil.TempDir("", "error_page") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() errorPage := "ERROR" - ioutil.WriteFile(filepath.Join(dir, "500.html"), []byte(errorPage), 0600) + os.WriteFile(filepath.Join(dir, "500.html"), []byte(errorPage), 0600) w := httptest.NewRecorder() serverError := "Interesting Server Error" @@ -86,14 +73,10 @@ func TestIfErrorPageIsIgnoredInDevelopment(t *testing.T) { } func TestIfErrorPageIsIgnoredIfCustomError(t *testing.T) { - dir, err := ioutil.TempDir("", "error_page") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() errorPage := "ERROR" - ioutil.WriteFile(filepath.Join(dir, "500.html"), []byte(errorPage), 0600) + os.WriteFile(filepath.Join(dir, "500.html"), []byte(errorPage), 0600) w := httptest.NewRecorder() serverError := "Interesting Server Error" @@ -121,14 +104,10 @@ func TestErrorPageInterceptedByContentType(t *testing.T) { } for _, tc := range testCases { - dir, err := ioutil.TempDir("", "error_page") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() errorPage := "ERROR" - ioutil.WriteFile(filepath.Join(dir, "500.html"), []byte(errorPage), 0600) + os.WriteFile(filepath.Join(dir, "500.html"), []byte(errorPage), 0600) w := httptest.NewRecorder() serverError := "Interesting Server Error" diff --git a/workhorse/internal/staticpages/servefile_test.go b/workhorse/internal/staticpages/servefile_test.go index 67675beccf8..231c0e59068 100644 --- a/workhorse/internal/staticpages/servefile_test.go +++ b/workhorse/internal/staticpages/servefile_test.go @@ -3,7 +3,6 @@ package staticpages import ( "bytes" "compress/gzip" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -26,11 +25,7 @@ func TestServingNonExistingFile(t *testing.T) { } func TestServingDirectory(t *testing.T) { - dir, err := ioutil.TempDir("", "deploy") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() httpRequest, _ := http.NewRequest("GET", "/file", nil) w := httptest.NewRecorder() @@ -64,16 +59,12 @@ func TestExecutingHandlerWhenNoFileFound(t *testing.T) { } func TestServingTheActualFile(t *testing.T) { - dir, err := ioutil.TempDir("", "deploy") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() httpRequest, _ := http.NewRequest("GET", "/file", nil) fileContent := "STATIC" - ioutil.WriteFile(filepath.Join(dir, "file"), []byte(fileContent), 0600) + os.WriteFile(filepath.Join(dir, "file"), []byte(fileContent), 0600) w := httptest.NewRecorder() st := &Static{DocumentRoot: dir} @@ -121,11 +112,7 @@ func TestExcludedPaths(t *testing.T) { } func testServingThePregzippedFile(t *testing.T, enableGzip bool) { - dir, err := ioutil.TempDir("", "deploy") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() httpRequest, _ := http.NewRequest("GET", "/file", nil) @@ -140,8 +127,8 @@ func testServingThePregzippedFile(t *testing.T, enableGzip bool) { fileGzip.Write([]byte(fileContent)) fileGzip.Close() - ioutil.WriteFile(filepath.Join(dir, "file.gz"), fileGzipContent.Bytes(), 0600) - ioutil.WriteFile(filepath.Join(dir, "file"), []byte(fileContent), 0600) + os.WriteFile(filepath.Join(dir, "file.gz"), fileGzipContent.Bytes(), 0600) + os.WriteFile(filepath.Join(dir, "file"), []byte(fileContent), 0600) w := httptest.NewRecorder() st := &Static{DocumentRoot: dir} diff --git a/workhorse/internal/testhelper/gitaly.go b/workhorse/internal/testhelper/gitaly.go index 747d5e6d078..488fb2eaf01 100644 --- a/workhorse/internal/testhelper/gitaly.go +++ b/workhorse/internal/testhelper/gitaly.go @@ -4,7 +4,7 @@ import ( "bytes" "fmt" "io" - "io/ioutil" + "os" "path" "strings" "sync" @@ -49,10 +49,10 @@ var ( func init() { var err error - if GitalyReceivePackResponseMock, err = ioutil.ReadFile(path.Join(RootDir(), "testdata/receive-pack-fixture.txt")); err != nil { + if GitalyReceivePackResponseMock, err = os.ReadFile(path.Join(RootDir(), "testdata/receive-pack-fixture.txt")); err != nil { log.WithError(err).Fatal("Unable to read pack response") } - if GitalyUploadPackResponseMock, err = ioutil.ReadFile(path.Join(RootDir(), "testdata/upload-pack-fixture.txt")); err != nil { + if GitalyUploadPackResponseMock, err = os.ReadFile(path.Join(RootDir(), "testdata/upload-pack-fixture.txt")); err != nil { log.WithError(err).Fatal("Unable to read pack response") } } diff --git a/workhorse/internal/testhelper/testhelper.go b/workhorse/internal/testhelper/testhelper.go index 6bbdfddcd60..6ea5c1c73e1 100644 --- a/workhorse/internal/testhelper/testhelper.go +++ b/workhorse/internal/testhelper/testhelper.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -121,7 +120,7 @@ func RootDir() string { func LoadFile(t *testing.T, filePath string) string { t.Helper() - content, err := ioutil.ReadFile(path.Join(RootDir(), filePath)) + content, err := os.ReadFile(path.Join(RootDir(), filePath)) require.NoError(t, err) return string(content) } @@ -129,7 +128,7 @@ func LoadFile(t *testing.T, filePath string) string { func ReadAll(t *testing.T, r io.Reader) []byte { t.Helper() - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) require.NoError(t, err) return b } @@ -152,7 +151,7 @@ func ParseJWT(token *jwt.Token) (interface{}, error) { // UploadClaims represents the JWT claim for upload parameters type UploadClaims struct { Upload map[string]string `json:"upload"` - jwt.StandardClaims + jwt.RegisteredClaims } func Retry(t testing.TB, timeout time.Duration, fn func() error) { @@ -176,7 +175,7 @@ func SetupStaticFileHelper(t *testing.T, fpath, content, directory string) strin require.NoError(t, os.MkdirAll(path.Join(absDocumentRoot, path.Dir(fpath)), 0755), "create document root") staticFile := path.Join(absDocumentRoot, fpath) - require.NoError(t, ioutil.WriteFile(staticFile, []byte(content), 0666), "write file content") + require.NoError(t, os.WriteFile(staticFile, []byte(content), 0666), "write file content") return absDocumentRoot } diff --git a/workhorse/internal/upload/artifacts_store_test.go b/workhorse/internal/upload/artifacts_store_test.go index 97e66fc37a4..7032313fbde 100644 --- a/workhorse/internal/upload/artifacts_store_test.go +++ b/workhorse/internal/upload/artifacts_store_test.go @@ -6,7 +6,7 @@ import ( "crypto/md5" "encoding/hex" "fmt" - "io/ioutil" + "io" "mime/multipart" "net/http" "net/http/httptest" @@ -56,16 +56,11 @@ func testUploadArtifactsFromTestZip(t *testing.T, ts *httptest.Server) *httptest } func TestUploadHandlerSendingToExternalStorage(t *testing.T) { - tempPath, err := ioutil.TempDir("", "uploads") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tempPath) + tempPath := t.TempDir() archiveData, md5 := createTestZipArchive(t) - archiveFile, err := ioutil.TempFile("", "artifact.zip") + archiveFile, err := os.CreateTemp(tempPath, "artifact.zip") require.NoError(t, err) - defer os.Remove(archiveFile.Name()) _, err = archiveFile.Write(archiveData) require.NoError(t, err) archiveFile.Close() @@ -75,7 +70,7 @@ func TestUploadHandlerSendingToExternalStorage(t *testing.T) { storeServerMux.HandleFunc("/url/put", func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "PUT", r.Method) - receivedData, err := ioutil.ReadAll(r.Body) + receivedData, err := io.ReadAll(r.Body) require.NoError(t, err) require.Equal(t, archiveData, receivedData) @@ -135,11 +130,7 @@ func TestUploadHandlerSendingToExternalStorage(t *testing.T) { } func TestUploadHandlerSendingToExternalStorageAndStorageServerUnreachable(t *testing.T) { - tempPath, err := ioutil.TempDir("", "uploads") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tempPath) + tempPath := t.TempDir() responseProcessor := func(w http.ResponseWriter, r *http.Request) { t.Fatal("it should not be called") @@ -161,11 +152,7 @@ func TestUploadHandlerSendingToExternalStorageAndStorageServerUnreachable(t *tes } func TestUploadHandlerSendingToExternalStorageAndInvalidURLIsUsed(t *testing.T) { - tempPath, err := ioutil.TempDir("", "uploads") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tempPath) + tempPath := t.TempDir() responseProcessor := func(w http.ResponseWriter, r *http.Request) { t.Fatal("it should not be called") diff --git a/workhorse/internal/upload/artifacts_upload_test.go b/workhorse/internal/upload/artifacts_upload_test.go index 96eb3810673..c94129092c6 100644 --- a/workhorse/internal/upload/artifacts_upload_test.go +++ b/workhorse/internal/upload/artifacts_upload_test.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "mime/multipart" "net/http" "net/http/httptest" @@ -72,7 +71,7 @@ func testArtifactsUploadServer(t *testing.T, authResponse *api.Response, bodyPro return } - _, err := ioutil.ReadFile(r.FormValue("file.path")) + _, err := os.ReadFile(r.FormValue("file.path")) if err != nil { t.Fatal("Expected file to be readable") return @@ -85,7 +84,7 @@ func testArtifactsUploadServer(t *testing.T, authResponse *api.Response, bodyPro } if r.FormValue("metadata.path") != "" { - metadata, err := ioutil.ReadFile(r.FormValue("metadata.path")) + metadata, err := os.ReadFile(r.FormValue("metadata.path")) if err != nil { t.Fatal("Expected metadata to be readable") return @@ -96,7 +95,7 @@ func testArtifactsUploadServer(t *testing.T, authResponse *api.Response, bodyPro return } defer gz.Close() - metadata, err = ioutil.ReadAll(gz) + metadata, err = io.ReadAll(gz) if err != nil { t.Fatal("Expected metadata to be valid") return @@ -130,8 +129,7 @@ type testServer struct { } func setupWithTmpPath(t *testing.T, filename string, includeFormat bool, format string, authResponse *api.Response, bodyProcessor func(w http.ResponseWriter, r *http.Request)) *testServer { - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) + tempPath := t.TempDir() if authResponse == nil { authResponse = &api.Response{TempPath: tempPath} @@ -147,7 +145,6 @@ func setupWithTmpPath(t *testing.T, filename string, includeFormat bool, format cleanup := func() { ts.Close() - require.NoError(t, os.RemoveAll(tempPath)) require.NoError(t, writer.Close()) } @@ -292,8 +289,7 @@ func TestUploadFormProcessing(t *testing.T) { } func TestLsifFileProcessing(t *testing.T) { - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) + tempPath := t.TempDir() s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil) defer s.cleanup() @@ -312,8 +308,7 @@ func TestLsifFileProcessing(t *testing.T) { } func TestInvalidLsifFileProcessing(t *testing.T) { - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) + tempPath := t.TempDir() s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil) defer s.cleanup() diff --git a/workhorse/internal/upload/artifacts_uploader.go b/workhorse/internal/upload/artifacts_uploader.go index c1c49638e21..a8c944a1d33 100644 --- a/workhorse/internal/upload/artifacts_uploader.go +++ b/workhorse/internal/upload/artifacts_uploader.go @@ -17,6 +17,7 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/api" "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/lsif_transformer/parser" "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination" "gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts" ) @@ -35,7 +36,9 @@ var zipSubcommandsErrorsCounter = promauto.NewCounterVec( }, []string{"error"}) type artifactsUploadProcessor struct { - format string + format string + processLSIF bool + tempDir string SavedFileTracker } @@ -43,26 +46,23 @@ type artifactsUploadProcessor struct { // Artifacts is like a Multipart but specific for artifacts upload. func Artifacts(myAPI *api.API, h http.Handler, p Preparer) http.Handler { return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) { - opts, err := p.Prepare(a) - if err != nil { - helper.Fail500(w, r, fmt.Errorf("UploadArtifacts: error preparing file storage options")) - return - } - format := r.URL.Query().Get(ArtifactFormatKey) - - mg := &artifactsUploadProcessor{format: format, SavedFileTracker: SavedFileTracker{Request: r}} - interceptMultipartFiles(w, r, h, a, mg, opts) + mg := &artifactsUploadProcessor{ + format: format, + processLSIF: a.ProcessLsif, + tempDir: a.TempPath, + SavedFileTracker: SavedFileTracker{Request: r}, + } + interceptMultipartFiles(w, r, h, mg, &eagerAuthorizer{a}, p) }, "/authorize") } func (a *artifactsUploadProcessor) generateMetadataFromZip(ctx context.Context, file *destination.FileHandler) (*destination.FileHandler, error) { - metaReader, metaWriter := io.Pipe() - defer metaWriter.Close() - metaOpts := &destination.UploadOpts{ - LocalTempPath: os.TempDir(), - TempFilePrefix: "metadata.gz", + LocalTempPath: a.tempDir, + } + if metaOpts.LocalTempPath == "" { + metaOpts.LocalTempPath = os.TempDir() } fileName := file.LocalPath @@ -73,24 +73,22 @@ func (a *artifactsUploadProcessor) generateMetadataFromZip(ctx context.Context, zipMd := exec.CommandContext(ctx, "gitlab-zip-metadata", fileName) zipMd.Stderr = log.ContextLogger(ctx).Writer() zipMd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} - zipMd.Stdout = metaWriter + + zipMdOut, err := zipMd.StdoutPipe() + if err != nil { + return nil, err + } + defer zipMdOut.Close() if err := zipMd.Start(); err != nil { return nil, err } defer helper.CleanUpProcessGroup(zipMd) - type saveResult struct { - error - *destination.FileHandler + fh, err := destination.Upload(ctx, zipMdOut, -1, "metadata.gz", metaOpts) + if err != nil { + return nil, err } - done := make(chan saveResult) - go func() { - var result saveResult - result.FileHandler, result.error = destination.Upload(ctx, metaReader, -1, metaOpts) - - done <- result - }() if err := zipMd.Wait(); err != nil { st, ok := helper.ExitStatus(err) @@ -110,17 +108,15 @@ func (a *artifactsUploadProcessor) generateMetadataFromZip(ctx context.Context, } } - metaWriter.Close() - result := <-done - return result.FileHandler, result.error + return fh, nil } func (a *artifactsUploadProcessor) ProcessFile(ctx context.Context, formName string, file *destination.FileHandler, writer *multipart.Writer) error { // ProcessFile for artifacts requires file form-data field name to eq `file` - if formName != "file" { return fmt.Errorf("invalid form field: %q", formName) } + if a.Count() > 0 { return fmt.Errorf("artifacts request contains more than one file") } @@ -136,7 +132,6 @@ func (a *artifactsUploadProcessor) ProcessFile(ctx context.Context, formName str return nil } - // TODO: can we rely on disk for shipping metadata? Not if we split workhorse and rails in 2 different PODs metadata, err := a.generateMetadataFromZip(ctx, file) if err != nil { return err @@ -158,6 +153,12 @@ func (a *artifactsUploadProcessor) ProcessFile(ctx context.Context, formName str return nil } -func (a *artifactsUploadProcessor) Name() string { - return "artifacts" +func (a *artifactsUploadProcessor) Name() string { return "artifacts" } + +func (a *artifactsUploadProcessor) TransformContents(ctx context.Context, filename string, r io.Reader) (io.ReadCloser, error) { + if a.processLSIF { + return parser.NewParser(ctx, r) + } + + return a.SavedFileTracker.TransformContents(ctx, filename, r) } diff --git a/workhorse/internal/upload/body_uploader.go b/workhorse/internal/upload/body_uploader.go index 6fb201fe677..4b5152c283c 100644 --- a/workhorse/internal/upload/body_uploader.go +++ b/workhorse/internal/upload/body_uploader.go @@ -2,7 +2,7 @@ package upload import ( "fmt" - "io/ioutil" + "io" "net/http" "net/url" "strings" @@ -23,7 +23,7 @@ func RequestBody(rails PreAuthorizer, h http.Handler, p Preparer) http.Handler { return } - fh, err := destination.Upload(r.Context(), r.Body, r.ContentLength, opts) + fh, err := destination.Upload(r.Context(), r.Body, r.ContentLength, "upload", opts) if err != nil { helper.Fail500(w, r, fmt.Errorf("RequestBody: upload failed: %v", err)) return @@ -42,7 +42,7 @@ func RequestBody(rails PreAuthorizer, h http.Handler, p Preparer) http.Handler { // Hijack body body := data.Encode() - r.Body = ioutil.NopCloser(strings.NewReader(body)) + r.Body = io.NopCloser(strings.NewReader(body)) r.ContentLength = int64(len(body)) r.Header.Set("Content-Type", "application/x-www-form-urlencoded") diff --git a/workhorse/internal/upload/body_uploader_test.go b/workhorse/internal/upload/body_uploader_test.go index 35772be5bc3..837d119e72e 100644 --- a/workhorse/internal/upload/body_uploader_test.go +++ b/workhorse/internal/upload/body_uploader_test.go @@ -3,7 +3,6 @@ package upload import ( "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -32,7 +31,7 @@ func TestRequestBody(t *testing.T) { resp := testUpload(&rails{}, &alwaysLocalPreparer{}, echoProxy(t, fileLen), body) require.Equal(t, http.StatusOK, resp.StatusCode) - uploadEcho, err := ioutil.ReadAll(resp.Body) + uploadEcho, err := io.ReadAll(resp.Body) require.NoError(t, err, "Can't read response body") require.Equal(t, fileContent, string(uploadEcho)) @@ -44,7 +43,7 @@ func TestRequestBodyCustomPreparer(t *testing.T) { resp := testUpload(&rails{}, &alwaysLocalPreparer{}, echoProxy(t, fileLen), body) require.Equal(t, http.StatusOK, resp.StatusCode) - uploadEcho, err := ioutil.ReadAll(resp.Body) + uploadEcho, err := io.ReadAll(resp.Body) require.NoError(t, err, "Can't read response body") require.Equal(t, fileContent, string(uploadEcho)) } diff --git a/workhorse/internal/upload/destination/destination.go b/workhorse/internal/upload/destination/destination.go index b18b6e22a99..5e145e2cb2a 100644 --- a/workhorse/internal/upload/destination/destination.go +++ b/workhorse/internal/upload/destination/destination.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "strconv" "time" @@ -54,7 +53,7 @@ type FileHandler struct { type uploadClaims struct { Upload map[string]string `json:"upload"` - jwt.StandardClaims + jwt.RegisteredClaims } // SHA256 hash of the handled file @@ -97,7 +96,7 @@ func (fh *FileHandler) GitLabFinalizeFields(prefix string) (map[string]string, e signedData[hashName] = hash } - claims := uploadClaims{Upload: signedData, StandardClaims: secret.DefaultClaims} + claims := uploadClaims{Upload: signedData, RegisteredClaims: secret.DefaultClaims} jwtData, err := secret.JWTTokenString(claims) if err != nil { return nil, err @@ -113,9 +112,9 @@ type consumer interface { // Upload persists the provided reader content to all the location specified in opts. A cleanup will be performed once ctx is Done // Make sure the provided context will not expire before finalizing upload with GitLab Rails. -func Upload(ctx context.Context, reader io.Reader, size int64, opts *UploadOpts) (*FileHandler, error) { +func Upload(ctx context.Context, reader io.Reader, size int64, name string, opts *UploadOpts) (*FileHandler, error) { fh := &FileHandler{ - Name: opts.TempFilePrefix, + Name: name, RemoteID: opts.RemoteID, RemoteURL: opts.RemoteURL, } @@ -199,13 +198,13 @@ func Upload(ctx context.Context, reader io.Reader, size int64, opts *UploadOpts) } logger := log.WithContextFields(ctx, log.Fields{ - "copied_bytes": fh.Size, - "is_local": opts.IsLocalTempFile(), - "is_multipart": opts.IsMultipart(), - "is_remote": !opts.IsLocalTempFile(), - "remote_id": opts.RemoteID, - "temp_file_prefix": opts.TempFilePrefix, - "client_mode": clientMode, + "copied_bytes": fh.Size, + "is_local": opts.IsLocalTempFile(), + "is_multipart": opts.IsMultipart(), + "is_remote": !opts.IsLocalTempFile(), + "remote_id": opts.RemoteID, + "client_mode": clientMode, + "filename": fh.Name, }) if opts.IsLocalTempFile() { @@ -226,7 +225,7 @@ func (fh *FileHandler) newLocalFile(ctx context.Context, opts *UploadOpts) (cons return nil, fmt.Errorf("newLocalFile: mkdir %q: %v", opts.LocalTempPath, err) } - file, err := ioutil.TempFile(opts.LocalTempPath, opts.TempFilePrefix) + file, err := os.CreateTemp(opts.LocalTempPath, "gitlab-workhorse-upload") if err != nil { return nil, fmt.Errorf("newLocalFile: create file: %v", err) } diff --git a/workhorse/internal/upload/destination/destination_test.go b/workhorse/internal/upload/destination/destination_test.go index ddf0ea24d60..6ebe163468b 100644 --- a/workhorse/internal/upload/destination/destination_test.go +++ b/workhorse/internal/upload/destination/destination_test.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "path" "strconv" @@ -43,12 +42,10 @@ func TestUploadWrongSize(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp") - require.NoError(t, err) - defer os.RemoveAll(tmpFolder) + tmpFolder := t.TempDir() - opts := &destination.UploadOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file"} - fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize+1, opts) + opts := &destination.UploadOpts{LocalTempPath: tmpFolder} + fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize+1, "upload", opts) require.Error(t, err) _, isSizeError := err.(destination.SizeError) require.True(t, isSizeError, "Should fail with SizeError") @@ -59,12 +56,10 @@ func TestUploadWithKnownSizeExceedLimit(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp") - require.NoError(t, err) - defer os.RemoveAll(tmpFolder) + tmpFolder := t.TempDir() - opts := &destination.UploadOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file", MaximumSize: test.ObjectSize - 1} - fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, opts) + opts := &destination.UploadOpts{LocalTempPath: tmpFolder, MaximumSize: test.ObjectSize - 1} + fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, "upload", opts) require.Error(t, err) _, isSizeError := err.(destination.SizeError) require.True(t, isSizeError, "Should fail with SizeError") @@ -75,12 +70,10 @@ func TestUploadWithUnknownSizeExceedLimit(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp") - require.NoError(t, err) - defer os.RemoveAll(tmpFolder) + tmpFolder := t.TempDir() - opts := &destination.UploadOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file", MaximumSize: test.ObjectSize - 1} - fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), -1, opts) + opts := &destination.UploadOpts{LocalTempPath: tmpFolder, MaximumSize: test.ObjectSize - 1} + fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), -1, "upload", opts) require.Equal(t, err, destination.ErrEntityTooLarge) require.Nil(t, fh) } @@ -117,7 +110,7 @@ func TestUploadWrongETag(t *testing.T) { osStub.InitiateMultipartUpload(test.ObjectPath) } ctx, cancel := context.WithCancel(context.Background()) - fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, opts) + fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, "upload", opts) require.Nil(t, fh) require.Error(t, err) require.Equal(t, 1, osStub.PutsCnt(), "File not uploaded") @@ -139,9 +132,7 @@ func TestUpload(t *testing.T) { remoteMultipart ) - tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp") - require.NoError(t, err) - defer os.RemoveAll(tmpFolder) + tmpFolder := t.TempDir() tests := []struct { name string @@ -191,13 +182,12 @@ func TestUpload(t *testing.T) { if spec.local { opts.LocalTempPath = tmpFolder - opts.TempFilePrefix = "test-file" } ctx, cancel := context.WithCancel(context.Background()) defer cancel() - fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts) + fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, "upload", &opts) require.NoError(t, err) require.NotNil(t, fh) @@ -211,9 +201,6 @@ func TestUpload(t *testing.T) { dir := path.Dir(fh.LocalPath) require.Equal(t, opts.LocalTempPath, dir) - filename := path.Base(fh.LocalPath) - beginsWithPrefix := strings.HasPrefix(filename, opts.TempFilePrefix) - require.True(t, beginsWithPrefix, fmt.Sprintf("LocalPath filename %q do not begin with TempFilePrefix %q", filename, opts.TempFilePrefix)) } else { require.Empty(t, fh.LocalPath, "LocalPath must be empty for non local uploads") } @@ -291,7 +278,7 @@ func TestUploadWithS3WorkhorseClient(t *testing.T) { MaximumSize: tc.maxSize, } - _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), tc.objectSize, &opts) + _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), tc.objectSize, "upload", &opts) if tc.expectedErr == nil { require.NoError(t, err) @@ -305,8 +292,7 @@ func TestUploadWithS3WorkhorseClient(t *testing.T) { } func TestUploadWithAzureWorkhorseClient(t *testing.T) { - mux, bucketDir, cleanup := test.SetupGoCloudFileBucket(t, "azblob") - defer cleanup() + mux, bucketDir := test.SetupGoCloudFileBucket(t, "azblob") ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -324,7 +310,7 @@ func TestUploadWithAzureWorkhorseClient(t *testing.T) { }, } - _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts) + _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, "upload", &opts) require.NoError(t, err) test.GoCloudObjectExists(t, bucketDir, remoteObject) @@ -349,7 +335,7 @@ func TestUploadWithUnknownGoCloudScheme(t *testing.T) { }, } - _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts) + _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, "upload", &opts) require.Error(t, err) } @@ -375,7 +361,7 @@ func TestUploadMultipartInBodyFailure(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts) + fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, "upload", &opts) require.Nil(t, fh) require.Error(t, err) require.EqualError(t, err, test.MultipartUploadInternalError().Error()) @@ -431,10 +417,6 @@ func TestUploadRemoteFileWithLimit(t *testing.T) { var opts destination.UploadOpts for _, remoteType := range remoteTypes { - tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp") - require.NoError(t, err) - defer os.RemoveAll(tmpFolder) - osStub, ts := test.StartObjectStore() defer ts.Close() @@ -468,7 +450,7 @@ func TestUploadRemoteFileWithLimit(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - fh, err := destination.Upload(ctx, strings.NewReader(tc.testData), tc.objectSize, &opts) + fh, err := destination.Upload(ctx, strings.NewReader(tc.testData), tc.objectSize, "upload", &opts) if tc.expectedErr == nil { require.NoError(t, err) diff --git a/workhorse/internal/upload/destination/filestore/filestore_test.go b/workhorse/internal/upload/destination/filestore/filestore_test.go index ec67eae96b9..6f0425809fe 100644 --- a/workhorse/internal/upload/destination/filestore/filestore_test.go +++ b/workhorse/internal/upload/destination/filestore/filestore_test.go @@ -2,7 +2,6 @@ package filestore import ( "context" - "io/ioutil" "os" "strings" "testing" @@ -12,7 +11,7 @@ import ( ) func TestConsume(t *testing.T) { - f, err := ioutil.TempFile("", "filestore-local-file") + f, err := os.CreateTemp("", "filestore-local-file") if f != nil { defer os.Remove(f.Name()) } @@ -32,7 +31,7 @@ func TestConsume(t *testing.T) { require.NoError(t, err) require.Equal(t, int64(len(content)), n) - consumedContent, err := ioutil.ReadFile(f.Name()) + consumedContent, err := os.ReadFile(f.Name()) require.NoError(t, err) require.Equal(t, content, string(consumedContent)) } diff --git a/workhorse/internal/upload/destination/objectstore/gocloud_object_test.go b/workhorse/internal/upload/destination/objectstore/gocloud_object_test.go index 57b3a35b41e..55d886087be 100644 --- a/workhorse/internal/upload/destination/objectstore/gocloud_object_test.go +++ b/workhorse/internal/upload/destination/objectstore/gocloud_object_test.go @@ -15,8 +15,7 @@ import ( ) func TestGoCloudObjectUpload(t *testing.T) { - mux, _, cleanup := test.SetupGoCloudFileBucket(t, "azuretest") - defer cleanup() + mux, _ := test.SetupGoCloudFileBucket(t, "azuretest") ctx, cancel := context.WithCancel(context.Background()) deadline := time.Now().Add(testTimeout) diff --git a/workhorse/internal/upload/destination/objectstore/multipart.go b/workhorse/internal/upload/destination/objectstore/multipart.go index 4c5b64b27ee..df336d2d901 100644 --- a/workhorse/internal/upload/destination/objectstore/multipart.go +++ b/workhorse/internal/upload/destination/objectstore/multipart.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" @@ -66,7 +65,7 @@ func (m *Multipart) Upload(ctx context.Context, r io.Reader) error { } } - n, err := io.Copy(ioutil.Discard, r) + n, err := io.Copy(io.Discard, r) if err != nil { return fmt.Errorf("drain pipe: %v", err) } @@ -93,19 +92,19 @@ func (m *Multipart) Delete() { } func (m *Multipart) readAndUploadOnePart(ctx context.Context, partURL string, putHeaders map[string]string, src io.Reader, partNumber int) (*completeMultipartUploadPart, error) { - file, err := ioutil.TempFile("", "part-buffer") + file, err := os.CreateTemp("", "part-buffer") if err != nil { return nil, fmt.Errorf("create temporary buffer file: %v", err) } defer file.Close() if err := os.Remove(file.Name()); err != nil { - return nil, err + return nil, fmt.Errorf("remove temporary buffer file: %v", err) } n, err := io.Copy(file, src) if err != nil { - return nil, err + return nil, fmt.Errorf("copy to temporary buffer file: %v", err) } if n == 0 { return nil, nil diff --git a/workhorse/internal/upload/destination/objectstore/multipart_test.go b/workhorse/internal/upload/destination/objectstore/multipart_test.go index 4aff3467e30..2a5161e42e7 100644 --- a/workhorse/internal/upload/destination/objectstore/multipart_test.go +++ b/workhorse/internal/upload/destination/objectstore/multipart_test.go @@ -2,7 +2,7 @@ package objectstore_test import ( "context" - "io/ioutil" + "io" "net/http" "net/http/httptest" "strings" @@ -22,7 +22,7 @@ func TestMultipartUploadWithUpcaseETags(t *testing.T) { var putCnt, postCnt int ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := ioutil.ReadAll(r.Body) + _, err := io.ReadAll(r.Body) require.NoError(t, err) defer r.Body.Close() diff --git a/workhorse/internal/upload/destination/objectstore/object.go b/workhorse/internal/upload/destination/objectstore/object.go index b7c4f12f009..68c566861af 100644 --- a/workhorse/internal/upload/destination/objectstore/object.go +++ b/workhorse/internal/upload/destination/objectstore/object.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "net/http" "gitlab.com/gitlab-org/labkit/mask" @@ -53,7 +52,7 @@ func newObject(putURL, deleteURL string, putHeaders map[string]string, size int6 func (o *Object) Upload(ctx context.Context, r io.Reader) error { // we should prevent pr.Close() otherwise it may shadow error set with pr.CloseWithError(err) - req, err := http.NewRequest(http.MethodPut, o.putURL, ioutil.NopCloser(r)) + req, err := http.NewRequest(http.MethodPut, o.putURL, io.NopCloser(r)) if err != nil { return fmt.Errorf("PUT %q: %v", mask.URL(o.putURL), err) diff --git a/workhorse/internal/upload/destination/objectstore/s3_object_test.go b/workhorse/internal/upload/destination/objectstore/s3_object_test.go index b81b0ae2024..0ed14a2e844 100644 --- a/workhorse/internal/upload/destination/objectstore/s3_object_test.go +++ b/workhorse/internal/upload/destination/objectstore/s3_object_test.go @@ -4,8 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" - "os" "path/filepath" "strings" "sync" @@ -47,9 +45,7 @@ func TestS3ObjectUpload(t *testing.T) { defer ts.Close() deadline := time.Now().Add(testTimeout) - tmpDir, err := ioutil.TempDir("", "workhorse-test-") - require.NoError(t, err) - defer os.Remove(tmpDir) + tmpDir := t.TempDir() objectName := filepath.Join(tmpDir, "s3-test-data") ctx, cancel := context.WithCancel(context.Background()) @@ -87,9 +83,7 @@ func TestConcurrentS3ObjectUpload(t *testing.T) { defer artifactsServer.Close() deadline := time.Now().Add(testTimeout) - tmpDir, err := ioutil.TempDir("", "workhorse-test-") - require.NoError(t, err) - defer os.Remove(tmpDir) + tmpDir := t.TempDir() var wg sync.WaitGroup @@ -136,9 +130,7 @@ func TestS3ObjectUploadCancel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) deadline := time.Now().Add(testTimeout) - tmpDir, err := ioutil.TempDir("", "workhorse-test-") - require.NoError(t, err) - defer os.Remove(tmpDir) + tmpDir := t.TempDir() objectName := filepath.Join(tmpDir, "s3-test-data") @@ -160,9 +152,7 @@ func TestS3ObjectUploadLimitReached(t *testing.T) { defer ts.Close() deadline := time.Now().Add(testTimeout) - tmpDir, err := ioutil.TempDir("", "workhorse-test-") - require.NoError(t, err) - defer os.Remove(tmpDir) + tmpDir := t.TempDir() objectName := filepath.Join(tmpDir, "s3-test-data") object, err := objectstore.NewS3Object(objectName, creds, config) diff --git a/workhorse/internal/upload/destination/objectstore/s3_session.go b/workhorse/internal/upload/destination/objectstore/s3_session.go index aa38f18ed7a..d71b38eb22e 100644 --- a/workhorse/internal/upload/destination/objectstore/s3_session.go +++ b/workhorse/internal/upload/destination/objectstore/s3_session.go @@ -10,6 +10,8 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "gitlab.com/gitlab-org/gitlab/workhorse/internal/config" + + "gitlab.com/gitlab-org/labkit/fips" ) type s3Session struct { @@ -61,8 +63,9 @@ func setupS3Session(s3Credentials config.S3Credentials, s3Config config.S3Config } cfg := &aws.Config{ - Region: aws.String(s3Config.Region), - S3ForcePathStyle: aws.Bool(s3Config.PathStyle), + Region: aws.String(s3Config.Region), + S3ForcePathStyle: aws.Bool(s3Config.PathStyle), + S3DisableContentMD5Validation: aws.Bool(fips.Enabled()), } // In case IAM profiles aren't being used, use the static credentials diff --git a/workhorse/internal/upload/destination/objectstore/test/gocloud_stub.go b/workhorse/internal/upload/destination/objectstore/test/gocloud_stub.go index cf22075e407..bff0eabaee5 100644 --- a/workhorse/internal/upload/destination/objectstore/test/gocloud_stub.go +++ b/workhorse/internal/upload/destination/objectstore/test/gocloud_stub.go @@ -2,9 +2,7 @@ package test import ( "context" - "io/ioutil" "net/url" - "os" "testing" "github.com/stretchr/testify/require" @@ -20,18 +18,14 @@ func (o *dirOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket return fileblob.OpenBucket(o.tmpDir, nil) } -func SetupGoCloudFileBucket(t *testing.T, scheme string) (m *blob.URLMux, bucketDir string, cleanup func()) { - tmpDir, err := ioutil.TempDir("", "") - require.NoError(t, err) +func SetupGoCloudFileBucket(t *testing.T, scheme string) (m *blob.URLMux, bucketDir string) { + tmpDir := t.TempDir() mux := new(blob.URLMux) fake := &dirOpener{tmpDir: tmpDir} mux.RegisterBucket(scheme, fake) - cleanup = func() { - os.RemoveAll(tmpDir) - } - return mux, tmpDir, cleanup + return mux, tmpDir } func GoCloudObjectExists(t *testing.T, bucketDir string, objectName string) { diff --git a/workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go b/workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go index d51a2de7456..1a380bd5083 100644 --- a/workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go +++ b/workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go @@ -6,7 +6,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "strconv" @@ -22,7 +21,8 @@ type partsEtagMap map[int]string // Instead of storing objects it will just save md5sum. type ObjectstoreStub struct { // bucket contains md5sum of uploaded objects - bucket map[string]string + bucket map[string]string + contents map[string][]byte // overwriteMD5 contains overwrites for md5sum that should be return instead of the regular hash overwriteMD5 map[string]string // multipart is a map of MultipartUploads @@ -48,6 +48,7 @@ func StartObjectStoreWithCustomMD5(md5Hashes map[string]string) (*ObjectstoreStu multipart: make(map[string]partsEtagMap), overwriteMD5: make(map[string]string), headers: make(map[string]*http.Header), + contents: make(map[string][]byte), } for k, v := range md5Hashes { @@ -82,6 +83,15 @@ func (o *ObjectstoreStub) GetObjectMD5(path string) string { return o.bucket[path] } +// GetObject returns the contents of the uploaded object. The caller must +// not modify the byte slice. +func (o *ObjectstoreStub) GetObject(path string) []byte { + o.m.Lock() + defer o.m.Unlock() + + return o.contents[path] +} + // GetHeader returns a given HTTP header of the object uploaded to the path func (o *ObjectstoreStub) GetHeader(path, key string) string { o.m.Lock() @@ -154,11 +164,11 @@ func (o *ObjectstoreStub) putObject(w http.ResponseWriter, r *http.Request) { etag, overwritten := o.overwriteMD5[objectPath] if !overwritten { + buf, _ := io.ReadAll(r.Body) + o.contents[objectPath] = buf hasher := md5.New() - io.Copy(hasher, r.Body) - - checksum := hasher.Sum(nil) - etag = hex.EncodeToString(checksum) + hasher.Write(buf) + etag = hex.EncodeToString(hasher.Sum(nil)) } o.headers[objectPath] = &r.Header @@ -196,7 +206,7 @@ func (o *ObjectstoreStub) completeMultipartUpload(w http.ResponseWriter, r *http return } - buf, err := ioutil.ReadAll(r.Body) + buf, err := io.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), 500) return diff --git a/workhorse/internal/upload/destination/objectstore/test/s3_stub.go b/workhorse/internal/upload/destination/objectstore/test/s3_stub.go index 6b83426b852..6a6b4662904 100644 --- a/workhorse/internal/upload/destination/objectstore/test/s3_stub.go +++ b/workhorse/internal/upload/destination/objectstore/test/s3_stub.go @@ -1,7 +1,6 @@ package test import ( - "io/ioutil" "net/http/httptest" "os" "strings" @@ -76,7 +75,7 @@ func S3ObjectExists(t *testing.T, sess *session.Session, config config.S3Config, require.NoError(t, err) require.Equal(t, int64(len(expectedBytes)), numBytes) - output, err := ioutil.ReadFile(tmpfile.Name()) + output, err := os.ReadFile(tmpfile.Name()) require.NoError(t, err) require.Equal(t, []byte(expectedBytes), output) @@ -124,13 +123,10 @@ func S3ObjectDoesNotExist(t *testing.T, sess *session.Session, config config.S3C } func downloadObject(t *testing.T, sess *session.Session, config config.S3Config, objectName string, handler func(tmpfile *os.File, numBytes int64, err error)) { - tmpDir, err := ioutil.TempDir("", "workhorse-test-") - require.NoError(t, err) - defer os.Remove(tmpDir) + tmpDir := t.TempDir() - tmpfile, err := ioutil.TempFile(tmpDir, "s3-output") + tmpfile, err := os.CreateTemp(tmpDir, "s3-output") require.NoError(t, err) - defer os.Remove(tmpfile.Name()) downloadSvc := s3manager.NewDownloader(sess) numBytes, err := downloadSvc.Download(tmpfile, &s3.GetObjectInput{ diff --git a/workhorse/internal/upload/destination/reader_test.go b/workhorse/internal/upload/destination/reader_test.go index a26f7746a13..40ff76d3866 100644 --- a/workhorse/internal/upload/destination/reader_test.go +++ b/workhorse/internal/upload/destination/reader_test.go @@ -2,7 +2,7 @@ package destination import ( "fmt" - "io/ioutil" + "io" "strings" "testing" "testing/iotest" @@ -19,7 +19,7 @@ func TestHardLimitReader(t *testing.T) { }, ) - out, err := ioutil.ReadAll(r) + out, err := io.ReadAll(r) require.NoError(t, err) require.Equal(t, text, string(out)) } diff --git a/workhorse/internal/upload/destination/upload_opts.go b/workhorse/internal/upload/destination/upload_opts.go index 77a8927d34f..b2223fac912 100644 --- a/workhorse/internal/upload/destination/upload_opts.go +++ b/workhorse/internal/upload/destination/upload_opts.go @@ -29,8 +29,6 @@ type ObjectStorageConfig struct { // UploadOpts represents all the options available for saving a file to object store type UploadOpts struct { - // TempFilePrefix is the prefix used to create temporary local file - TempFilePrefix string // LocalTempPath is the directory where to write a local copy of the file LocalTempPath string // RemoteID is the remote ObjectID provided by GitLab diff --git a/workhorse/internal/upload/destination/upload_opts_test.go b/workhorse/internal/upload/destination/upload_opts_test.go index 24a372495c6..fd9e56db194 100644 --- a/workhorse/internal/upload/destination/upload_opts_test.go +++ b/workhorse/internal/upload/destination/upload_opts_test.go @@ -283,8 +283,7 @@ func TestUseWorkhorseClientEnabled(t *testing.T) { } func TestGoCloudConfig(t *testing.T) { - mux, _, cleanup := test.SetupGoCloudFileBucket(t, "azblob") - defer cleanup() + mux, _ := test.SetupGoCloudFileBucket(t, "azblob") tests := []struct { name string diff --git a/workhorse/internal/upload/exif.go b/workhorse/internal/upload/exif.go new file mode 100644 index 00000000000..e77afb24502 --- /dev/null +++ b/workhorse/internal/upload/exif.go @@ -0,0 +1,91 @@ +package upload + +import ( + "context" + "io" + "net/http" + "os" + + "gitlab.com/gitlab-org/labkit/log" + "golang.org/x/image/tiff" + + "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/exif" +) + +func handleExifUpload(ctx context.Context, r io.Reader, filename string, imageType exif.FileType) (io.ReadCloser, error) { + tmpfile, err := os.CreateTemp("", "exifremove") + if err != nil { + return nil, err + } + go func() { + <-ctx.Done() + tmpfile.Close() + }() + if err := os.Remove(tmpfile.Name()); err != nil { + return nil, err + } + + _, err = io.Copy(tmpfile, r) + if err != nil { + return nil, err + } + + if _, err := tmpfile.Seek(0, io.SeekStart); err != nil { + return nil, err + } + + isValidType := false + switch imageType { + case exif.TypeJPEG: + isValidType = isJPEG(tmpfile) + case exif.TypeTIFF: + isValidType = isTIFF(tmpfile) + } + + if _, err := tmpfile.Seek(0, io.SeekStart); err != nil { + return nil, err + } + + if !isValidType { + log.WithContextFields(ctx, log.Fields{ + "filename": filename, + "imageType": imageType, + }).Info("invalid content type, not running exiftool") + + return tmpfile, nil + } + + log.WithContextFields(ctx, log.Fields{ + "filename": filename, + }).Info("running exiftool to remove any metadata") + + cleaner, err := exif.NewCleaner(ctx, tmpfile) + if err != nil { + return nil, err + } + + return cleaner, nil +} + +func isTIFF(r io.Reader) bool { + _, err := tiff.DecodeConfig(r) + if err == nil { + return true + } + + if _, unsupported := err.(tiff.UnsupportedError); unsupported { + return true + } + + return false +} + +func isJPEG(r io.Reader) bool { + // Only the first 512 bytes are used to sniff the content type. + buf, err := io.ReadAll(io.LimitReader(r, 512)) + if err != nil { + return false + } + + return http.DetectContentType(buf) == "image/jpeg" +} diff --git a/workhorse/internal/upload/exif/exif_test.go b/workhorse/internal/upload/exif/exif_test.go index ee5883d9e08..75ecfc51f08 100644 --- a/workhorse/internal/upload/exif/exif_test.go +++ b/workhorse/internal/upload/exif/exif_test.go @@ -3,7 +3,6 @@ package exif import ( "context" "io" - "io/ioutil" "os" "strings" "testing" @@ -75,7 +74,7 @@ func TestNewCleanerWithValidFile(t *testing.T) { cleaner, err := NewCleaner(ctx, input) require.NoError(t, err, "Expected no error when creating cleaner command") - size, err := io.Copy(ioutil.Discard, cleaner) + size, err := io.Copy(io.Discard, cleaner) require.NoError(t, err, "Expected no error when reading output") sizeAfterStrip := int64(25399) @@ -89,7 +88,7 @@ func TestNewCleanerWithInvalidFile(t *testing.T) { cleaner, err := NewCleaner(ctx, strings.NewReader("invalid image")) require.NoError(t, err, "Expected no error when creating cleaner command") - size, err := io.Copy(ioutil.Discard, cleaner) + size, err := io.Copy(io.Discard, cleaner) require.Error(t, err, "Expected error when reading output") require.Equal(t, int64(0), size, "Size of invalid image should be 0") } @@ -103,7 +102,7 @@ func TestNewCleanerReadingAfterEOF(t *testing.T) { cleaner, err := NewCleaner(ctx, input) require.NoError(t, err, "Expected no error when creating cleaner command") - _, err = io.Copy(ioutil.Discard, cleaner) + _, err = io.Copy(io.Discard, cleaner) require.NoError(t, err, "Expected no error when reading output") buf := make([]byte, 1) diff --git a/workhorse/internal/upload/multipart_uploader.go b/workhorse/internal/upload/multipart_uploader.go index 34675d2aa14..2456a2c8626 100644 --- a/workhorse/internal/upload/multipart_uploader.go +++ b/workhorse/internal/upload/multipart_uploader.go @@ -1,11 +1,9 @@ package upload import ( - "fmt" "net/http" "gitlab.com/gitlab-org/gitlab/workhorse/internal/api" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" ) // Multipart is a request middleware. If the request has a MIME multipart @@ -17,12 +15,27 @@ func Multipart(rails PreAuthorizer, h http.Handler, p Preparer) http.Handler { return rails.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) { s := &SavedFileTracker{Request: r} - opts, err := p.Prepare(a) - if err != nil { - helper.Fail500(w, r, fmt.Errorf("Multipart: error preparing file storage options")) - return + interceptMultipartFiles(w, r, h, s, &eagerAuthorizer{a}, p) + }, "/authorize") +} + +// SkipRailsPreAuthMultipart behaves like Multipart except it does not +// pre-authorize with Rails. It is intended for use on catch-all routes +// where we cannot pre-authorize both because we don't know which Rails +// endpoint to call, and because eagerly pre-authorizing would add too +// much overhead. +func SkipRailsPreAuthMultipart(tempPath string, myAPI *api.API, h http.Handler, p Preparer) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + s := &SavedFileTracker{Request: r} + + // We use testAuthorizer as a temporary measure. When + // https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/742 is done, we + // should only be using apiAuthorizer. + fa := &testAuthorizer{ + test: &apiAuthorizer{myAPI}, + actual: &eagerAuthorizer{&api.Response{TempPath: tempPath}}, } - interceptMultipartFiles(w, r, h, a, s, opts) - }, "/authorize") + interceptMultipartFiles(w, r, h, s, fa, p) + }) } diff --git a/workhorse/internal/upload/rewrite.go b/workhorse/internal/upload/rewrite.go index ff5190226af..d03445923fa 100644 --- a/workhorse/internal/upload/rewrite.go +++ b/workhorse/internal/upload/rewrite.go @@ -5,23 +5,19 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "mime/multipart" "net/http" "net/textproto" - "os" "path/filepath" "strings" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "gitlab.com/gitlab-org/labkit/log" - "golang.org/x/image/tiff" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/log" "gitlab.com/gitlab-org/gitlab/workhorse/internal/api" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/lsif_transformer/parser" "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination" "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/exif" ) @@ -62,13 +58,14 @@ var ( ) type rewriter struct { - writer *multipart.Writer - preauth *api.Response + writer *multipart.Writer + fileAuthorizer + Preparer filter MultipartFormProcessor finalizedFields map[string]bool } -func rewriteFormFilesFromMultipart(r *http.Request, writer *multipart.Writer, preauth *api.Response, filter MultipartFormProcessor, opts *destination.UploadOpts) error { +func rewriteFormFilesFromMultipart(r *http.Request, writer *multipart.Writer, filter MultipartFormProcessor, fa fileAuthorizer, preparer Preparer) error { // Create multipart reader reader, err := r.MultipartReader() if err != nil { @@ -83,7 +80,8 @@ func rewriteFormFilesFromMultipart(r *http.Request, writer *multipart.Writer, pr rew := &rewriter{ writer: writer, - preauth: preauth, + fileAuthorizer: fa, + Preparer: preparer, filter: filter, finalizedFields: make(map[string]bool), } @@ -108,7 +106,7 @@ func rewriteFormFilesFromMultipart(r *http.Request, writer *multipart.Writer, pr } if filename != "" { - err = rew.handleFilePart(r.Context(), name, p, opts) + err = rew.handleFilePart(r, name, p) } else { err = rew.copyPart(r.Context(), name, p) } @@ -128,7 +126,7 @@ func parseAndNormalizeContentDisposition(header textproto.MIMEHeader) (string, s return params["name"], params["filename"] } -func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipart.Part, opts *destination.UploadOpts) error { +func (rew *rewriter) handleFilePart(r *http.Request, name string, p *multipart.Part) error { if rew.filter.Count() >= maxFilesAllowed { return ErrTooManyFilesUploaded } @@ -141,30 +139,23 @@ func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipa return fmt.Errorf("illegal filename: %q", filename) } - opts.TempFilePrefix = filename - - var inputReader io.ReadCloser - var err error - - imageType := exif.FileTypeFromSuffix(filename) - switch { - case imageType != exif.TypeUnknown: - inputReader, err = handleExifUpload(ctx, p, filename, imageType) - if err != nil { - return err - } - case rew.preauth.ProcessLsif: - inputReader, err = handleLsifUpload(ctx, p, opts.LocalTempPath, filename, rew.preauth) - if err != nil { - return err - } - default: - inputReader = ioutil.NopCloser(p) + apiResponse, err := rew.AuthorizeFile(r) + if err != nil { + return err + } + opts, err := rew.Prepare(apiResponse) + if err != nil { + return err } + ctx := r.Context() + inputReader, err := rew.filter.TransformContents(ctx, filename, p) + if err != nil { + return err + } defer inputReader.Close() - fh, err := destination.Upload(ctx, inputReader, -1, opts) + fh, err := destination.Upload(ctx, inputReader, -1, filename, opts) if err != nil { switch err { case destination.ErrEntityTooLarge, exif.ErrRemovingExif: @@ -189,105 +180,63 @@ func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipa return rew.filter.ProcessFile(ctx, name, fh, rew.writer) } -func handleExifUpload(ctx context.Context, r io.Reader, filename string, imageType exif.FileType) (io.ReadCloser, error) { - tmpfile, err := ioutil.TempFile("", "exifremove") - if err != nil { - return nil, err - } - go func() { - <-ctx.Done() - tmpfile.Close() - }() - if err := os.Remove(tmpfile.Name()); err != nil { - return nil, err - } - - _, err = io.Copy(tmpfile, r) +func (rew *rewriter) copyPart(ctx context.Context, name string, p *multipart.Part) error { + np, err := rew.writer.CreatePart(p.Header) if err != nil { - return nil, err - } - - if _, err := tmpfile.Seek(0, io.SeekStart); err != nil { - return nil, err - } - - isValidType := false - switch imageType { - case exif.TypeJPEG: - isValidType = isJPEG(tmpfile) - case exif.TypeTIFF: - isValidType = isTIFF(tmpfile) - } - - if _, err := tmpfile.Seek(0, io.SeekStart); err != nil { - return nil, err + return fmt.Errorf("create multipart field: %v", err) } - if !isValidType { - log.WithContextFields(ctx, log.Fields{ - "filename": filename, - "imageType": imageType, - }).Print("invalid content type, not running exiftool") - - return tmpfile, nil + if _, err := io.Copy(np, p); err != nil { + return fmt.Errorf("duplicate multipart field: %v", err) } - log.WithContextFields(ctx, log.Fields{ - "filename": filename, - }).Print("running exiftool to remove any metadata") - - cleaner, err := exif.NewCleaner(ctx, tmpfile) - if err != nil { - return nil, err + if err := rew.filter.ProcessField(ctx, name, rew.writer); err != nil { + return fmt.Errorf("process multipart field: %v", err) } - return cleaner, nil + return nil } -func isTIFF(r io.Reader) bool { - _, err := tiff.DecodeConfig(r) - if err == nil { - return true - } +type fileAuthorizer interface { + AuthorizeFile(*http.Request) (*api.Response, error) +} - if _, unsupported := err.(tiff.UnsupportedError); unsupported { - return true - } +type eagerAuthorizer struct{ response *api.Response } - return false +func (ea *eagerAuthorizer) AuthorizeFile(r *http.Request) (*api.Response, error) { + return ea.response, nil } -func isJPEG(r io.Reader) bool { - // Only the first 512 bytes are used to sniff the content type. - buf, err := ioutil.ReadAll(io.LimitReader(r, 512)) - if err != nil { - return false - } +var _ fileAuthorizer = &eagerAuthorizer{} - return http.DetectContentType(buf) == "image/jpeg" +type apiAuthorizer struct { + api *api.API } -func handleLsifUpload(ctx context.Context, reader io.Reader, tempPath, filename string, preauth *api.Response) (io.ReadCloser, error) { - parserConfig := parser.Config{ - TempPath: tempPath, - } - - return parser.NewParser(ctx, reader, parserConfig) +func (aa *apiAuthorizer) AuthorizeFile(r *http.Request) (*api.Response, error) { + return aa.api.PreAuthorizeFixedPath( + r, + "POST", + "/api/v4/internal/workhorse/authorize_upload", + ) } -func (rew *rewriter) copyPart(ctx context.Context, name string, p *multipart.Part) error { - np, err := rew.writer.CreatePart(p.Header) - if err != nil { - return fmt.Errorf("create multipart field: %v", err) - } +var _ fileAuthorizer = &apiAuthorizer{} - if _, err := io.Copy(np, p); err != nil { - return fmt.Errorf("duplicate multipart field: %v", err) - } +type testAuthorizer struct { + test fileAuthorizer + actual fileAuthorizer +} - if err := rew.filter.ProcessField(ctx, name, rew.writer); err != nil { - return fmt.Errorf("process multipart field: %v", err) +func (ta *testAuthorizer) AuthorizeFile(r *http.Request) (*api.Response, error) { + logger := log.WithRequest(r) + if response, err := ta.test.AuthorizeFile(r); err != nil { + logger.WithError(err).Error("test api preauthorize request failed") + } else { + logger.WithFields(log.Fields{ + "temp_path": response.TempPath, + }).Info("test api preauthorize request") } - return nil + return ta.actual.AuthorizeFile(r) } diff --git a/workhorse/internal/upload/saved_file_tracker.go b/workhorse/internal/upload/saved_file_tracker.go index b70a303a4a4..1fad5343647 100644 --- a/workhorse/internal/upload/saved_file_tracker.go +++ b/workhorse/internal/upload/saved_file_tracker.go @@ -3,11 +3,13 @@ package upload import ( "context" "fmt" + "io" "mime/multipart" "net/http" "gitlab.com/gitlab-org/gitlab/workhorse/internal/secret" "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/exif" ) type SavedFileTracker struct { @@ -44,7 +46,7 @@ func (s *SavedFileTracker) Finalize(_ context.Context) error { return nil } - claims := MultipartClaims{RewrittenFields: s.rewrittenFields, StandardClaims: secret.DefaultClaims} + claims := MultipartClaims{RewrittenFields: s.rewrittenFields, RegisteredClaims: secret.DefaultClaims} tokenString, err := secret.JWTTokenString(claims) if err != nil { return fmt.Errorf("savedFileTracker.Finalize: %v", err) @@ -54,6 +56,12 @@ func (s *SavedFileTracker) Finalize(_ context.Context) error { return nil } -func (s *SavedFileTracker) Name() string { - return "accelerate" +func (s *SavedFileTracker) Name() string { return "accelerate" } + +func (*SavedFileTracker) TransformContents(ctx context.Context, filename string, r io.Reader) (io.ReadCloser, error) { + if imageType := exif.FileTypeFromSuffix(filename); imageType != exif.TypeUnknown { + return handleExifUpload(ctx, r, filename, imageType) + } + + return io.NopCloser(r), nil } diff --git a/workhorse/internal/upload/skip_rails_authorizer.go b/workhorse/internal/upload/skip_rails_authorizer.go deleted file mode 100644 index e74048fb6e3..00000000000 --- a/workhorse/internal/upload/skip_rails_authorizer.go +++ /dev/null @@ -1,22 +0,0 @@ -package upload - -import ( - "net/http" - - "gitlab.com/gitlab-org/gitlab/workhorse/internal/api" -) - -// SkipRailsAuthorizer implements a fake PreAuthorizer that does not call -// the gitlab-rails API. It must be fast because it gets called on each -// request proxied to Rails. -type SkipRailsAuthorizer struct { - // TempPath is a directory where workhorse can store files that can later - // be accessed by gitlab-rails. - TempPath string -} - -func (l *SkipRailsAuthorizer) PreAuthorizeHandler(next api.HandleFunc, _ string) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - next(w, r, &api.Response{TempPath: l.TempPath}) - }) -} diff --git a/workhorse/internal/upload/uploads.go b/workhorse/internal/upload/uploads.go index 8272a3d920d..61b419901a7 100644 --- a/workhorse/internal/upload/uploads.go +++ b/workhorse/internal/upload/uploads.go @@ -4,7 +4,7 @@ import ( "bytes" "context" "fmt" - "io/ioutil" + "io" "mime/multipart" "net/http" @@ -25,7 +25,7 @@ type PreAuthorizer interface { type MultipartClaims struct { RewrittenFields map[string]string `json:"rewritten_fields"` - jwt.StandardClaims + jwt.RegisteredClaims } // MultipartFormProcessor abstracts away implementation differences @@ -36,17 +36,18 @@ type MultipartFormProcessor interface { Finalize(ctx context.Context) error Name() string Count() int + TransformContents(ctx context.Context, filename string, r io.Reader) (io.ReadCloser, error) } // interceptMultipartFiles is the core of the implementation of // Multipart. -func interceptMultipartFiles(w http.ResponseWriter, r *http.Request, h http.Handler, preauth *api.Response, filter MultipartFormProcessor, opts *destination.UploadOpts) { +func interceptMultipartFiles(w http.ResponseWriter, r *http.Request, h http.Handler, filter MultipartFormProcessor, fa fileAuthorizer, p Preparer) { var body bytes.Buffer writer := multipart.NewWriter(&body) defer writer.Close() // Rewrite multipart form data - err := rewriteFormFilesFromMultipart(r, writer, preauth, filter, opts) + err := rewriteFormFilesFromMultipart(r, writer, filter, fa, p) if err != nil { switch err { case ErrInjectedClientParam: @@ -71,7 +72,7 @@ func interceptMultipartFiles(w http.ResponseWriter, r *http.Request, h http.Hand writer.Close() // Hijack the request - r.Body = ioutil.NopCloser(&body) + r.Body = io.NopCloser(&body) r.ContentLength = int64(body.Len()) r.Header.Set("Content-Type", writer.FormDataContentType()) diff --git a/workhorse/internal/upload/uploads_test.go b/workhorse/internal/upload/uploads_test.go index a9c8834d4be..ffe9fec302e 100644 --- a/workhorse/internal/upload/uploads_test.go +++ b/workhorse/internal/upload/uploads_test.go @@ -6,12 +6,12 @@ import ( "context" "fmt" "io" - "io/ioutil" "mime/multipart" "net/http" "net/http/httptest" "net/textproto" "os" + "path" "regexp" "strconv" "strings" @@ -54,7 +54,7 @@ func TestUploadHandlerForwardingRawData(t *testing.T) { ts := testhelper.TestServerWithHandler(regexp.MustCompile(`/url/path\z`), func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "PATCH", r.Method, "method") - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) require.NoError(t, err) require.Equal(t, "REQUEST", string(body), "request body") @@ -66,19 +66,14 @@ func TestUploadHandlerForwardingRawData(t *testing.T) { httpRequest, err := http.NewRequest("PATCH", ts.URL+"/url/path", bytes.NewBufferString("REQUEST")) require.NoError(t, err) - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) - + tempPath := t.TempDir() response := httptest.NewRecorder() handler := newProxy(ts.URL) - apiResponse := &api.Response{TempPath: tempPath} + fa := &eagerAuthorizer{&api.Response{TempPath: tempPath}} preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - interceptMultipartFiles(response, httpRequest, handler, apiResponse, nil, opts) + interceptMultipartFiles(response, httpRequest, handler, nil, fa, preparer) require.Equal(t, 202, response.Code) require.Equal(t, "RESPONSE", response.Body.String(), "response body") @@ -86,10 +81,7 @@ func TestUploadHandlerForwardingRawData(t *testing.T) { func TestUploadHandlerRewritingMultiPartData(t *testing.T) { var filePath string - - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) + tempPath := t.TempDir() ts := testhelper.TestServerWithHandler(regexp.MustCompile(`/url/path\z`), func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "PUT", r.Method, "method") @@ -137,19 +129,17 @@ func TestUploadHandlerRewritingMultiPartData(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) httpRequest = httpRequest.WithContext(ctx) - httpRequest.Body = ioutil.NopCloser(&buffer) + httpRequest.Body = io.NopCloser(&buffer) httpRequest.ContentLength = int64(buffer.Len()) httpRequest.Header.Set("Content-Type", writer.FormDataContentType()) response := httptest.NewRecorder() handler := newProxy(ts.URL) - apiResponse := &api.Response{TempPath: tempPath} + fa := &eagerAuthorizer{&api.Response{TempPath: tempPath}} preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - interceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts) + interceptMultipartFiles(response, httpRequest, handler, &testFormProcessor{}, fa, preparer) require.Equal(t, 202, response.Code) cancel() // this will trigger an async cleanup @@ -159,10 +149,6 @@ func TestUploadHandlerRewritingMultiPartData(t *testing.T) { func TestUploadHandlerDetectingInjectedMultiPartData(t *testing.T) { var filePath string - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) - tests := []struct { name string field string @@ -213,12 +199,8 @@ func TestUploadHandlerDetectingInjectedMultiPartData(t *testing.T) { response := httptest.NewRecorder() handler := newProxy(ts.URL) - apiResponse := &api.Response{TempPath: tempPath} - preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - interceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts) + testInterceptMultipartFiles(t, response, httpRequest, handler, &testFormProcessor{}) require.Equal(t, test.response, response.Code) cancel() // this will trigger an async cleanup @@ -228,10 +210,6 @@ func TestUploadHandlerDetectingInjectedMultiPartData(t *testing.T) { } func TestUploadProcessingField(t *testing.T) { - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) - var buffer bytes.Buffer writer := multipart.NewWriter(&buffer) @@ -243,12 +221,8 @@ func TestUploadProcessingField(t *testing.T) { httpRequest.Header.Set("Content-Type", writer.FormDataContentType()) response := httptest.NewRecorder() - apiResponse := &api.Response{TempPath: tempPath} - preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts) + testInterceptMultipartFiles(t, response, httpRequest, nilHandler, &testFormProcessor{}) require.Equal(t, 500, response.Code) } @@ -256,15 +230,11 @@ func TestUploadProcessingField(t *testing.T) { func TestUploadingMultipleFiles(t *testing.T) { testhelper.ConfigureSecret() - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) - var buffer bytes.Buffer writer := multipart.NewWriter(&buffer) for i := 0; i < 11; i++ { - _, err = writer.CreateFormFile(fmt.Sprintf("file %v", i), "my.file") + _, err := writer.CreateFormFile(fmt.Sprintf("file %v", i), "my.file") require.NoError(t, err) } require.NoError(t, writer.Close()) @@ -274,23 +244,18 @@ func TestUploadingMultipleFiles(t *testing.T) { httpRequest.Header.Set("Content-Type", writer.FormDataContentType()) response := httptest.NewRecorder() - apiResponse := &api.Response{TempPath: tempPath} - preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts) + testInterceptMultipartFiles(t, response, httpRequest, nilHandler, &testFormProcessor{}) require.Equal(t, 400, response.Code) require.Equal(t, "upload request contains more than 10 files\n", response.Body.String()) } func TestUploadProcessingFile(t *testing.T) { - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) + testhelper.ConfigureSecret() + tempPath := t.TempDir() - _, testServer := test.StartObjectStore() + objectStore, testServer := test.StartObjectStore() defer testServer.Close() storeUrl := testServer.URL + test.ObjectPath @@ -298,21 +263,24 @@ func TestUploadProcessingFile(t *testing.T) { tests := []struct { name string preauth *api.Response + content func(t *testing.T) []byte }{ { name: "FileStore Upload", preauth: &api.Response{TempPath: tempPath}, + content: func(t *testing.T) []byte { + entries, err := os.ReadDir(tempPath) + require.NoError(t, err) + require.Len(t, entries, 1) + content, err := os.ReadFile(path.Join(tempPath, entries[0].Name())) + require.NoError(t, err) + return content + }, }, { name: "ObjectStore Upload", - preauth: &api.Response{RemoteObject: api.RemoteObject{StoreURL: storeUrl}}, - }, - { - name: "ObjectStore and FileStore Upload", - preauth: &api.Response{ - TempPath: tempPath, - RemoteObject: api.RemoteObject{StoreURL: storeUrl}, - }, + preauth: &api.Response{RemoteObject: api.RemoteObject{StoreURL: storeUrl, ID: "123"}}, + content: func(*testing.T) []byte { return objectStore.GetObject(test.ObjectPath) }, }, } @@ -330,26 +298,20 @@ func TestUploadProcessingFile(t *testing.T) { httpRequest.Header.Set("Content-Type", writer.FormDataContentType()) response := httptest.NewRecorder() - apiResponse := &api.Response{TempPath: tempPath} + fa := &eagerAuthorizer{test.preauth} preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts) + interceptMultipartFiles(response, httpRequest, nilHandler, &testFormProcessor{}, fa, preparer) require.Equal(t, 200, response.Code) + require.Equal(t, "test", string(test.content(t))) }) } - } func TestInvalidFileNames(t *testing.T) { testhelper.ConfigureSecret() - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) - for _, testCase := range []struct { filename string code int @@ -376,24 +338,14 @@ func TestInvalidFileNames(t *testing.T) { httpRequest.Header.Set("Content-Type", writer.FormDataContentType()) response := httptest.NewRecorder() - apiResponse := &api.Response{TempPath: tempPath} - preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - - interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &SavedFileTracker{Request: httpRequest}, opts) + testInterceptMultipartFiles(t, response, httpRequest, nilHandler, &SavedFileTracker{Request: httpRequest}) require.Equal(t, testCase.code, response.Code) - require.Equal(t, testCase.expectedPrefix, opts.TempFilePrefix) } } func TestContentDispositionRewrite(t *testing.T) { testhelper.ConfigureSecret() - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) - tests := []struct { desc string header string @@ -442,12 +394,7 @@ func TestContentDispositionRewrite(t *testing.T) { }) response := httptest.NewRecorder() - apiResponse := &api.Response{TempPath: tempPath} - preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - - interceptMultipartFiles(response, httpRequest, customHandler, apiResponse, &SavedFileTracker{Request: httpRequest}, opts) + testInterceptMultipartFiles(t, response, httpRequest, customHandler, &SavedFileTracker{Request: httpRequest}) upstreamRequest, err := http.ReadRequest(bufio.NewReader(&upstreamRequestBuffer)) require.NoError(t, err) @@ -471,7 +418,7 @@ func TestContentDispositionRewrite(t *testing.T) { } func TestUploadHandlerRemovingExif(t *testing.T) { - content, err := ioutil.ReadFile("exif/testdata/sample_exif.jpg") + content, err := os.ReadFile("exif/testdata/sample_exif.jpg") require.NoError(t, err) runUploadTest(t, content, "sample_exif.jpg", 200, func(w http.ResponseWriter, r *http.Request) { @@ -489,7 +436,7 @@ func TestUploadHandlerRemovingExif(t *testing.T) { } func TestUploadHandlerRemovingExifTiff(t *testing.T) { - content, err := ioutil.ReadFile("exif/testdata/sample_exif.tiff") + content, err := os.ReadFile("exif/testdata/sample_exif.tiff") require.NoError(t, err) runUploadTest(t, content, "sample_exif.tiff", 200, func(w http.ResponseWriter, r *http.Request) { @@ -507,14 +454,14 @@ func TestUploadHandlerRemovingExifTiff(t *testing.T) { } func TestUploadHandlerRemovingExifInvalidContentType(t *testing.T) { - content, err := ioutil.ReadFile("exif/testdata/sample_exif_invalid.jpg") + content, err := os.ReadFile("exif/testdata/sample_exif_invalid.jpg") require.NoError(t, err) runUploadTest(t, content, "sample_exif_invalid.jpg", 200, func(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(100000) require.NoError(t, err) - output, err := ioutil.ReadFile(r.FormValue("file.path")) + output, err := os.ReadFile(r.FormValue("file.path")) require.NoError(t, err) require.Equal(t, content, output, "Expected the file to be same as before") @@ -524,7 +471,7 @@ func TestUploadHandlerRemovingExifInvalidContentType(t *testing.T) { } func TestUploadHandlerRemovingExifCorruptedFile(t *testing.T) { - content, err := ioutil.ReadFile("exif/testdata/sample_exif_corrupted.jpg") + content, err := os.ReadFile("exif/testdata/sample_exif_corrupted.jpg") require.NoError(t, err) runUploadTest(t, content, "sample_exif_corrupted.jpg", 422, func(w http.ResponseWriter, r *http.Request) { @@ -534,10 +481,6 @@ func TestUploadHandlerRemovingExifCorruptedFile(t *testing.T) { } func runUploadTest(t *testing.T, image []byte, filename string, httpCode int, tsHandler func(http.ResponseWriter, *http.Request)) { - tempPath, err := ioutil.TempDir("", "uploads") - require.NoError(t, err) - defer os.RemoveAll(tempPath) - var buffer bytes.Buffer writer := multipart.NewWriter(&buffer) @@ -565,12 +508,8 @@ func runUploadTest(t *testing.T, image []byte, filename string, httpCode int, ts response := httptest.NewRecorder() handler := newProxy(ts.URL) - apiResponse := &api.Response{TempPath: tempPath} - preparer := &DefaultPreparer{} - opts, err := preparer.Prepare(apiResponse) - require.NoError(t, err) - interceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts) + testInterceptMultipartFiles(t, response, httpRequest, handler, &testFormProcessor{}) require.Equal(t, httpCode, response.Code) } @@ -587,3 +526,12 @@ func waitUntilDeleted(t *testing.T, path string) { }, 10*time.Second, 10*time.Millisecond) require.True(t, os.IsNotExist(err), "expected the file to be deleted") } + +func testInterceptMultipartFiles(t *testing.T, w http.ResponseWriter, r *http.Request, h http.Handler, filter MultipartFormProcessor) { + t.Helper() + + fa := &eagerAuthorizer{&api.Response{TempPath: t.TempDir()}} + preparer := &DefaultPreparer{} + + interceptMultipartFiles(w, r, h, filter, fa, preparer) +} diff --git a/workhorse/internal/upstream/handlers_test.go b/workhorse/internal/upstream/handlers_test.go index 10c7479f5c5..03ca80ddcb9 100644 --- a/workhorse/internal/upstream/handlers_test.go +++ b/workhorse/internal/upstream/handlers_test.go @@ -4,7 +4,7 @@ import ( "bytes" "compress/gzip" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" @@ -20,7 +20,7 @@ func TestGzipEncoding(t *testing.T) { fmt.Fprint(w, "test") w.Close() - body := ioutil.NopCloser(&b) + body := io.NopCloser(&b) req, err := http.NewRequest("POST", "http://address/test", body) require.NoError(t, err) @@ -38,7 +38,7 @@ func TestNoEncoding(t *testing.T) { resp := httptest.NewRecorder() var b bytes.Buffer - body := ioutil.NopCloser(&b) + body := io.NopCloser(&b) req, err := http.NewRequest("POST", "http://address/test", body) require.NoError(t, err) diff --git a/workhorse/internal/upstream/roundtripper/roundtripper_test.go b/workhorse/internal/upstream/roundtripper/roundtripper_test.go index eed71cc5bae..d3cec80d49b 100644 --- a/workhorse/internal/upstream/roundtripper/roundtripper_test.go +++ b/workhorse/internal/upstream/roundtripper/roundtripper_test.go @@ -4,7 +4,7 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "net/url" @@ -86,7 +86,7 @@ func testNewBackendRoundTripper(t *testing.T, ts *httptest.Server, tlsClientConf require.NoError(t, err, "perform roundtrip") defer response.Body.Close() - body, err := ioutil.ReadAll(response.Body) + body, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, expectedResponseBody, string(body)) diff --git a/workhorse/internal/upstream/routes.go b/workhorse/internal/upstream/routes.go index dd106053f8b..95c9b99b833 100644 --- a/workhorse/internal/upstream/routes.go +++ b/workhorse/internal/upstream/routes.go @@ -223,7 +223,7 @@ func configureRoutes(u *upstream) { mimeMultipartUploader := upload.Multipart(api, signingProxy, preparer) uploadPath := path.Join(u.DocumentRoot, "uploads/tmp") - tempfileMultipartProxy := upload.Multipart(&upload.SkipRailsAuthorizer{TempPath: uploadPath}, proxy, preparer) + tempfileMultipartProxy := upload.SkipRailsPreAuthMultipart(uploadPath, api, proxy, preparer) ciAPIProxyQueue := queueing.QueueRequests("ci_api_job_requests", tempfileMultipartProxy, u.APILimit, u.APIQueueLimit, u.APIQueueTimeout) ciAPILongPolling := builds.RegisterHandler(ciAPIProxyQueue, redis.WatchKey, u.APICILongPollingDuration) diff --git a/workhorse/internal/upstream/upstream_test.go b/workhorse/internal/upstream/upstream_test.go index 8f054f5ccef..f931c1b31b3 100644 --- a/workhorse/internal/upstream/upstream_test.go +++ b/workhorse/internal/upstream/upstream_test.go @@ -3,7 +3,6 @@ package upstream import ( "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -287,7 +286,7 @@ func runTestCases(t *testing.T, ws *httptest.Server, testCases []testCase) { require.NoError(t, err) defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, 200, resp.StatusCode, "response code") diff --git a/workhorse/internal/utils/svg/README.md b/workhorse/internal/utils/svg/README.md index e5531f47473..4057316927c 100644 --- a/workhorse/internal/utils/svg/README.md +++ b/workhorse/internal/utils/svg/README.md @@ -15,13 +15,13 @@ package main import ( "fmt" - "io/ioutil" + "os" svg "github.com/h2non/go-is-svg" ) func main() { - buf, err := ioutil.ReadFile("_example/example.svg") + buf, err := os.ReadFile("_example/example.svg") if err != nil { fmt.Printf("Error: %s\n", err) return diff --git a/workhorse/internal/zipartifacts/metadata_test.go b/workhorse/internal/zipartifacts/metadata_test.go index 353ed4376f6..e4799ba4a59 100644 --- a/workhorse/internal/zipartifacts/metadata_test.go +++ b/workhorse/internal/zipartifacts/metadata_test.go @@ -6,7 +6,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "os" "testing" @@ -41,7 +40,7 @@ func validateMetadata(r io.Reader) error { return err } - meta, err := ioutil.ReadAll(gz) + meta, err := io.ReadAll(gz) if err != nil { return err } @@ -59,7 +58,7 @@ func validateMetadata(r io.Reader) error { func TestGenerateZipMetadataFromFile(t *testing.T) { var metaBuffer bytes.Buffer - f, err := ioutil.TempFile("", "workhorse-metadata.zip-") + f, err := os.CreateTemp("", "workhorse-metadata.zip-") if f != nil { defer os.Remove(f.Name()) } @@ -84,7 +83,7 @@ func TestGenerateZipMetadataFromFile(t *testing.T) { } func TestErrNotAZip(t *testing.T) { - f, err := ioutil.TempFile("", "workhorse-metadata.zip-") + f, err := os.CreateTemp("", "workhorse-metadata.zip-") if f != nil { defer os.Remove(f.Name()) } diff --git a/workhorse/logging.go b/workhorse/logging.go index 69718e6e834..e2e603b15e8 100644 --- a/workhorse/logging.go +++ b/workhorse/logging.go @@ -3,7 +3,6 @@ package main import ( "fmt" "io" - "io/ioutil" goLog "log" "os" @@ -28,7 +27,7 @@ func startLogging(file string, format string) (io.Closer, error) { switch format { case noneLogType: - return logkit.Initialize(logkit.WithWriter(ioutil.Discard)) + return logkit.Initialize(logkit.WithWriter(io.Discard)) case jsonLogFormat: return logkit.Initialize( logkit.WithOutputName(file), @@ -53,7 +52,7 @@ func startLogging(file string, format string) (io.Closer, error) { // In text format, we use a separate logger for access logs func getAccessLogger(file string, format string) (*log.Logger, io.Closer, error) { if format != "text" { - return log.StandardLogger(), ioutil.NopCloser(nil), nil + return log.StandardLogger(), io.NopCloser(nil), nil } if file == "" { diff --git a/workhorse/main.go b/workhorse/main.go index 55c29b8abf5..91008e16961 100644 --- a/workhorse/main.go +++ b/workhorse/main.go @@ -4,7 +4,6 @@ import ( "context" "flag" "fmt" - "io/ioutil" "net" "net/http" _ "net/http/pprof" @@ -137,7 +136,7 @@ func buildConfig(arg0 string, args []string) (*bootConfig, *config.Config, error tomlData := "" if *configFile != "" { - buf, err := ioutil.ReadFile(*configFile) + buf, err := os.ReadFile(*configFile) if err != nil { return nil, nil, fmt.Errorf("configFile: %v", err) } @@ -149,6 +148,14 @@ func buildConfig(arg0 string, args []string) (*bootConfig, *config.Config, error return nil, nil, fmt.Errorf("configFile: %v", err) } + cfg.MetricsListener = cfgFromFile.MetricsListener + if boot.prometheusListenAddr != "" { + if cfg.MetricsListener != nil { + return nil, nil, fmt.Errorf("configFile: both prometheusListenAddr and metrics_listener can't be specified") + } + cfg.MetricsListener = &config.ListenerConfig{Network: "tcp", Addr: boot.prometheusListenAddr} + } + cfg.Redis = cfgFromFile.Redis cfg.ObjectStorageCredentials = cfgFromFile.ObjectStorageCredentials cfg.ImageResizerConfig = cfgFromFile.ImageResizerConfig @@ -196,11 +203,10 @@ func run(boot bootConfig, cfg config.Config) error { } monitoringOpts := []monitoring.Option{monitoring.WithBuildInformation(Version, BuildTime)} - - if boot.prometheusListenAddr != "" { - l, err := net.Listen("tcp", boot.prometheusListenAddr) + if cfg.MetricsListener != nil { + l, err := newListener("metrics", *cfg.MetricsListener) if err != nil { - return fmt.Errorf("prometheusListenAddr: %v", err) + return err } monitoringOpts = append(monitoringOpts, monitoring.WithListener(l)) } diff --git a/workhorse/main_test.go b/workhorse/main_test.go index 59090cc1232..b6a09efa8db 100644 --- a/workhorse/main_test.go +++ b/workhorse/main_test.go @@ -8,7 +8,6 @@ import ( "fmt" "image/png" "io" - "io/ioutil" "net/http" "net/http/httptest" "net/url" @@ -307,7 +306,7 @@ func TestGzipAssets(t *testing.T) { resp, err := http.DefaultTransport.RoundTrip(req) require.NoError(t, err, desc) defer resp.Body.Close() - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) require.NoError(t, err, desc) require.Equal(t, 200, resp.StatusCode, "%s: status code", desc) @@ -366,7 +365,7 @@ func TestAltDocumentAssets(t *testing.T) { resp, err := http.DefaultTransport.RoundTrip(req) require.NoError(t, err) defer resp.Body.Close() - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) require.NoError(t, err) if tc.content != "" { @@ -412,7 +411,7 @@ func doSendDataRequest(path string, command, literalJSON string) (*http.Response } defer resp.Body.Close() - bodyData, err := ioutil.ReadAll(resp.Body) + bodyData, err := io.ReadAll(resp.Body) if err != nil { return resp, nil, err } @@ -574,7 +573,7 @@ func TestAPIFalsePositivesAreProxied(t *testing.T) { require.NoError(t, err, "%s %q", tc.method, tc.path) defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) require.NoError(t, err, "%s %q: reading body", tc.method, tc.path) require.Equal(t, 200, resp.StatusCode, "%s %q: status code", tc.method, tc.path) @@ -833,7 +832,7 @@ func httpGet(t *testing.T, url string, headers map[string]string) (*http.Respons require.NoError(t, err) defer resp.Body.Close() - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) require.NoError(t, err) return resp, string(b) diff --git a/workhorse/proxy_test.go b/workhorse/proxy_test.go index 02148c07522..6dd1354e618 100644 --- a/workhorse/proxy_test.go +++ b/workhorse/proxy_test.go @@ -3,7 +3,7 @@ package main import ( "bytes" "fmt" - "io/ioutil" + "io" "net" "net/http" "net/http/httptest" @@ -51,7 +51,7 @@ func TestProxyRequest(t *testing.T) { "expect Gitlab-Workhorse-Proxy-Start to start with 1", ) - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) require.NoError(t, err, "read body") require.Equal(t, "REQUEST", string(body), "body contents") diff --git a/workhorse/sendfile_test.go b/workhorse/sendfile_test.go index 0a01e410d39..f2b6da4eebd 100644 --- a/workhorse/sendfile_test.go +++ b/workhorse/sendfile_test.go @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "mime" "net/http" "os" @@ -53,14 +53,14 @@ func allowedXSendfileDownload(t *testing.T, contentFilename string, filePath str require.NoError(t, os.MkdirAll(cacheDir, 0755)) contentBytes := []byte("content") - require.NoError(t, ioutil.WriteFile(contentPath, contentBytes, 0644)) + require.NoError(t, os.WriteFile(contentPath, contentBytes, 0644)) resp, err := http.Get(fmt.Sprintf("%s/%s", ws.URL, filePath)) require.NoError(t, err) requireAttachmentName(t, resp, contentFilename) - actual, err := ioutil.ReadAll(resp.Body) + actual, err := io.ReadAll(resp.Body) require.NoError(t, err) require.NoError(t, resp.Body.Close()) @@ -89,7 +89,7 @@ func deniedXSendfileDownload(t *testing.T, contentFilename string, filePath stri requireAttachmentName(t, resp, contentFilename) - actual, err := ioutil.ReadAll(resp.Body) + actual, err := io.ReadAll(resp.Body) require.NoError(t, err, "read body") require.NoError(t, resp.Body.Close()) diff --git a/workhorse/upload_test.go b/workhorse/upload_test.go index 180598ab260..dedda4ea655 100644 --- a/workhorse/upload_test.go +++ b/workhorse/upload_test.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "mime/multipart" "net/http" "net/http/httptest" @@ -68,7 +67,7 @@ func expectSignedRequest(t *testing.T, r *http.Request) { func uploadTestServer(t *testing.T, authorizeTests func(r *http.Request), extraTests func(r *http.Request)) *httptest.Server { return testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, r *http.Request) { - if strings.HasSuffix(r.URL.Path, "/authorize") { + if strings.HasSuffix(r.URL.Path, "/authorize") || r.URL.Path == "/api/v4/internal/workhorse/authorize_upload" { expectSignedRequest(t, r) w.Header().Set("Content-Type", api.ResponseContentType) @@ -154,6 +153,10 @@ func TestAcceleratedUpload(t *testing.T) { t.Run(tt.resource, func(t *testing.T) { ts := uploadTestServer(t, func(r *http.Request) { + if r.URL.Path == "/api/v4/internal/workhorse/authorize_upload" { + // Nothing to validate: this is a hard coded URL + return + } resource := strings.TrimRight(tt.resource, "/") // Validate %2F characters haven't been unescaped require.Equal(t, resource+"/authorize", r.URL.String()) @@ -270,24 +273,23 @@ func TestUnacceleratedUploads(t *testing.T) { func TestBlockingRewrittenFieldsHeader(t *testing.T) { canary := "untrusted header passed by user" + multiPartBody, multiPartContentType, err := multipartBodyWithFile() + require.NoError(t, err) + testCases := []struct { desc string contentType string body io.Reader present bool }{ - {"multipart with file", "", nil, true}, // placeholder + {"multipart with file", multiPartContentType, multiPartBody, true}, {"no multipart", "text/plain", nil, false}, } - var err error - testCases[0].body, testCases[0].contentType, err = multipartBodyWithFile() - require.NoError(t, err) - for _, tc := range testCases { ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, r *http.Request) { key := upload.RewrittenFieldsHeader - if tc.present { + if tc.present && r.URL.Path != "/api/v4/internal/workhorse/authorize_upload" { require.Contains(t, r.Header, key) } else { require.NotContains(t, r.Header, key) @@ -342,7 +344,7 @@ func TestLfsUpload(t *testing.T) { require.Equal(t, oid, r.Form.Get("file.sha256"), "Invalid SHA256 populated") require.Equal(t, strconv.Itoa(len(reqBody)), r.Form.Get("file.size"), "Invalid size populated") - tempfile, err := ioutil.ReadFile(r.Form.Get("file.path")) + tempfile, err := os.ReadFile(r.Form.Get("file.path")) require.NoError(t, err) require.Equal(t, reqBody, string(tempfile), "Temporary file has the wrong body") @@ -366,7 +368,7 @@ func TestLfsUpload(t *testing.T) { require.NoError(t, err) defer resp.Body.Close() - rspData, err := ioutil.ReadAll(resp.Body) + rspData, err := io.ReadAll(resp.Body) require.NoError(t, err) // Expect the (eventual) response to be proxied through, untouched @@ -428,7 +430,7 @@ func TestLfsUploadRouting(t *testing.T) { require.NoError(t, err) defer resp.Body.Close() - rspData, err := ioutil.ReadAll(resp.Body) + rspData, err := io.ReadAll(resp.Body) require.NoError(t, err) if tc.match { @@ -467,7 +469,7 @@ func packageUploadTestServer(t *testing.T, method string, resource string, reqBo require.Equal(t, len, r.Form.Get("file.size"), "Invalid size populated") tmpFilePath := r.Form.Get("file.path") - fileData, err := ioutil.ReadFile(tmpFilePath) + fileData, err := os.ReadFile(tmpFilePath) defer os.Remove(tmpFilePath) require.NoError(t, err) @@ -496,7 +498,7 @@ func testPackageFileUpload(t *testing.T, method string, resource string) { resp, err := http.DefaultClient.Do(req) require.NoError(t, err) - respData, err := ioutil.ReadAll(resp.Body) + respData, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, rspBody, string(respData), "Temporary file has the wrong body") defer resp.Body.Close() |