# HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1634065486 -7200 # Tue Oct 12 21:04:46 2021 +0200 # Branch heptapod # Node ID 165749700fcf91aa0aab87370426464519421c81 # Parent 81a3afe35a6726ba827e5151d0191d18e734168a HEPTAPOD_NO_GIT: carrying over from internal API response As with Workhorse and direct subprocess calls, we'll need this flag, whose effect on py-heptapod is to prevent Git export entirely in the native case. diff --git a/internal/command/hg/hg.go b/internal/command/hg/hg.go --- a/internal/command/hg/hg.go +++ b/internal/command/hg/hg.go @@ -80,6 +80,7 @@ "HEPTAPOD_REPOSITORY_USAGE=" + strings.Split(response.Repo, "-")[0], // FormatBool output is "true" or "false", understood by hg config "HEPTAPOD_HG_NATIVE=" + strconv.FormatBool(response.HgNative), + "HEPTAPOD_NO_GIT=" + strconv.FormatBool(response.NoGit), }...) if c.Config.Mercurial.ModulePolicy != "" { env = append(env, "HGMODULEPOLICY=" + c.Config.Mercurial.ModulePolicy) diff --git a/internal/command/hg/hg_test.go b/internal/command/hg/hg_test.go --- a/internal/command/hg/hg_test.go +++ b/internal/command/hg/hg_test.go @@ -72,7 +72,9 @@ func TestExecuteSuccessfully(t *testing.T) { type testcase struct { native_input *bool + no_git_input *bool native_expected string + no_git_expected string module_policy string } @@ -81,14 +83,17 @@ yes := true; testcases := []testcase{ - {native_input: nil, native_expected: "false", module_policy: "c"}, - {native_input: &no, native_expected: "false", module_policy: ""}, - {native_input: &yes, native_expected: "true"}, + {native_input: nil, native_expected: "false", no_git_expected: "false", module_policy: "c"}, + {native_input: &no, native_expected: "false", no_git_expected: "false", module_policy: ""}, + {native_input: &yes, native_expected: "true", no_git_expected: "false"}, + {native_input: nil, no_git_input: &yes, native_expected: "false", no_git_expected: "true", module_policy: "c"}, + {native_input: &no, no_git_input: &yes, native_expected: "false", no_git_expected: "true", module_policy: ""}, + {native_input: &yes, native_expected: "true", no_git_input: &yes, no_git_expected: "true"}, } for _, tc := range testcases { - requests := requesthandlers.BuildHgApiSuccessHandlers(t, tc.native_input) + requests := requesthandlers.BuildHgApiSuccessHandlers(t, tc.native_input, tc.no_git_input) url := testserver.StartHttpServer(t, requests) output := &bytes.Buffer{} @@ -128,6 +133,7 @@ require.Equal(t, "awesome-proj", fake.Env["HEPTAPOD_PROJECT_PATH"]) require.Equal(t, "my/group", fake.Env["HEPTAPOD_PROJECT_NAMESPACE_FULL_PATH"]) require.Equal(t, tc.native_expected, fake.Env["HEPTAPOD_HG_NATIVE"]) + require.Equal(t, tc.no_git_expected, fake.Env["HEPTAPOD_NO_GIT"]) require.Equal(t, "/usr/share/shipped.hgrc:/etc/main.hgrc", fake.Env["HGRCPATH"]) require.Equal(t, tc.module_policy, fake.Env["HGMODULEPOLICY"]) } @@ -135,7 +141,7 @@ func TestIgnoreHarmfulClientArgs(t *testing.T) { - requests := requesthandlers.BuildHgApiSuccessHandlers(t, nil) + requests := requesthandlers.BuildHgApiSuccessHandlers(t, nil, nil) url := testserver.StartHttpServer(t, requests) output := &bytes.Buffer{} diff --git a/internal/gitlabnet/accessverifier/hg_client.go b/internal/gitlabnet/accessverifier/hg_client.go --- a/internal/gitlabnet/accessverifier/hg_client.go +++ b/internal/gitlabnet/accessverifier/hg_client.go @@ -33,6 +33,7 @@ Email string `json:"gl_email"` ProjectId int `json:"project_id"` HgNative bool `json:"hg_native"` + NoGit bool `json:"no_git"` StatusCode int } diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -50,7 +50,7 @@ return requests } -func BuildHgApiSuccessHandlers(t *testing.T, hg_native *bool) []testserver.TestRequestHandler { +func BuildHgApiSuccessHandlers(t *testing.T, hg_native *bool, no_git *bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/hg_access", @@ -68,6 +68,9 @@ if (hg_native != nil) { body["hg_native"] = *hg_native } + if (no_git != nil) { + body["no_git"] = *no_git + } w.WriteHeader(http.StatusOK) require.NoError(t, json.NewEncoder(w).Encode(body)) }, # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1635200949 -7200 # Tue Oct 26 00:29:09 2021 +0200 # Branch heptapod # Node ID 0eee7fea773f012168ff4499c06a94f2df12ffc7 # Parent 165749700fcf91aa0aab87370426464519421c81 # Parent 23b11deb9b862507063f1da21be251b61a7d4fb4 Merged heptapod-stable branch into heptapod Carries only CI rules changes diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -31,5 +31,6 @@ 3b2b3737c7a656cf2383fff51d57f51573e9b981 heptapod-13.16.0 4def2dd0132fde7ae4fd57ea21d402860dcd3612 heptapod-13.17.0 ed9dd657a0ab833fd60fe809385f2b73947d0819 heptapod-13.18.0 +3cfed32ac2038975b533352ff0f4839aa2a0a319 heptapod-13.18.1 aefbb5e3eac5411fc526a88d3df1762ecbdc2e76 heptapod-13.19.0 b84ce63181d5c0d07585be867dbe957eb6d35348 heptapod-13.19.1 diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -6,9 +6,11 @@ # For merge requests, create a pipeline. - if: '$CI_MERGE_REQUEST_IID' # For main development branches, create a pipeline (this includes on schedules, pushes, merges, etc.). - - if: '"$CI_COMMIT_HG_BRANCH" =~ "/^heptapod-.*/" && "$CI_COMMIT_HG_TOPIC" == ""' + - if: '"$CI_COMMIT_HG_BRANCH" =~ /^heptapod-/ && "$CI_COMMIT_HG_TOPIC" == ""' # For tags, create a pipeline. - if: '$CI_COMMIT_TAG' + # Always create a pipeline if manually requested + - if: '$CI_PIPELINE_SOURCE == "web"' default: image: golang:1.14 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1635201049 -7200 # Tue Oct 26 00:30:49 2021 +0200 # Branch heptapod # Node ID f593b81abfe52ca2083440f3f470dce3d13079da # Parent 0eee7fea773f012168ff4499c06a94f2df12ffc7 Updated version files for release diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,6 +9,11 @@ The corresponding tag is heptapod-x.y.z +## 13.19.2 + +- Added support for the new `NO_GIT` flag, telling Mercurial not to + use hg-git + ## 13.19.1 - No actual changes diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.19.1 +13.19.2 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1635201056 -7200 # Tue Oct 26 00:30:56 2021 +0200 # Branch heptapod # Node ID 837e1b491f17f9d8f8e2c0e5bb5519de76b6c4fb # Parent f593b81abfe52ca2083440f3f470dce3d13079da Added tag heptapod-13.19.2 for changeset f593b81abfe5 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -34,3 +34,4 @@ 3cfed32ac2038975b533352ff0f4839aa2a0a319 heptapod-13.18.1 aefbb5e3eac5411fc526a88d3df1762ecbdc2e76 heptapod-13.19.0 b84ce63181d5c0d07585be867dbe957eb6d35348 heptapod-13.19.1 +f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 # HG changeset patch # User Brad Sevy <bsevy@gitlab.com> # Date 1623066789 0 # Mon Jun 07 11:53:09 2021 +0000 # Node ID ca0dc0a8719c2f677f66f206650511349779dfee # Parent f0156728df1a322c23379d1e9ebf3fdc952df64a "Limits" to "Limit" on line 10 to align tenses diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ When you access the GitLab server over SSH then GitLab Shell will: -1. Limits you to predefined git commands (git push, git pull). +1. Limit you to predefined git commands (git push, git pull). 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1623113054 0 # Tue Jun 08 00:44:14 2021 +0000 # Node ID 7719f6152eb70048f2b92a6fb50e45bc5769eba4 # Parent f0156728df1a322c23379d1e9ebf3fdc952df64a # Parent ca0dc0a8719c2f677f66f206650511349779dfee Merge branch 'brad-tense-correction' into 'main' "Limits" to "Limit" on line 10 to align tenses See merge request gitlab-org/gitlab-shell!483 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ When you access the GitLab server over SSH then GitLab Shell will: -1. Limits you to predefined git commands (git push, git pull). +1. Limit you to predefined git commands (git push, git pull). 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server # HG changeset patch # User Gary Holtz <gholtz@gitlab.com> # Date 1624042629 18000 # Fri Jun 18 13:57:09 2021 -0500 # Node ID 334265484289351f0118bffe439b252224a27caa # Parent 7719f6152eb70048f2b92a6fb50e45bc5769eba4 Adding a UTC converter and test diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -10,9 +10,21 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) +type UTCFormatter struct { + log.Formatter +} + +func (u UTCFormatter) Format(e *log.Entry) ([]byte, error) { + e.Time = e.Time.UTC() + + return u.Formatter.Format(e) +} + func configureLogFormat(cfg *config.Config) { if cfg.LogFormat == "json" { - log.SetFormatter(&log.JSONFormatter{}) + log.SetFormatter(UTCFormatter{&log.JSONFormatter{}}) + } else { + log.SetFormatter(UTCFormatter{&log.TextFormatter{}}) } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -3,6 +3,7 @@ import ( "io/ioutil" "os" + "regexp" "strings" "testing" @@ -44,3 +45,27 @@ Configure(&config) log.Info("this is a test") } + +func TestLogInUTC(t *testing.T) { + tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + require.NoError(t, err) + defer tmpFile.Close() + defer os.Remove(tmpFile.Name()) + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + } + + Configure(&config) + log.Info("this is a test") + + data, err := ioutil.ReadFile(tmpFile.Name()) + require.NoError(t, err) + + utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` + r, e := regexp.MatchString(utc, string(data)) + + require.NoError(t, e) + require.True(t, r) +} # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1624274902 0 # Mon Jun 21 11:28:22 2021 +0000 # Node ID e217294e7c0ea89fe37160a49b0d3ced586063ca # Parent 7719f6152eb70048f2b92a6fb50e45bc5769eba4 # Parent 334265484289351f0118bffe439b252224a27caa Merge branch '140-standardize-logging-timestamp-format' into 'main' Standardize logging timestamp format Closes #140 See merge request gitlab-org/gitlab-shell!485 diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -10,9 +10,21 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) +type UTCFormatter struct { + log.Formatter +} + +func (u UTCFormatter) Format(e *log.Entry) ([]byte, error) { + e.Time = e.Time.UTC() + + return u.Formatter.Format(e) +} + func configureLogFormat(cfg *config.Config) { if cfg.LogFormat == "json" { - log.SetFormatter(&log.JSONFormatter{}) + log.SetFormatter(UTCFormatter{&log.JSONFormatter{}}) + } else { + log.SetFormatter(UTCFormatter{&log.TextFormatter{}}) } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -3,6 +3,7 @@ import ( "io/ioutil" "os" + "regexp" "strings" "testing" @@ -44,3 +45,27 @@ Configure(&config) log.Info("this is a test") } + +func TestLogInUTC(t *testing.T) { + tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + require.NoError(t, err) + defer tmpFile.Close() + defer os.Remove(tmpFile.Name()) + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + } + + Configure(&config) + log.Info("this is a test") + + data, err := ioutil.ReadFile(tmpFile.Name()) + require.NoError(t, err) + + utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` + r, e := regexp.MatchString(utc, string(data)) + + require.NoError(t, e) + require.True(t, r) +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1624439362 -10800 # Wed Jun 23 12:09:22 2021 +0300 # Node ID e093b917055514501be4def3f666a4dc73c84937 # Parent e217294e7c0ea89fe37160a49b0d3ced586063ca Create PROCESS.md page with Security release process diff --git a/PROCESS.md b/PROCESS.md new file mode 100644 --- /dev/null +++ b/PROCESS.md @@ -0,0 +1,44 @@ +## Releasing a new version + +GitLab Shell is versioned by git tags, and the version used by the Rails +application is stored in +[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). + +For each version, there is a raw version and a tag version: + +- The **raw version** is the version number. For instance, `15.2.8`. +- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. + +To release a new version of GitLab Shell and have that version available to the +Rails application: + +1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the + **tag version** and the [`VERSION`](VERSION) file with the **raw version**. +2. Ask a maintainer to review and merge the merge request. If you're already a + maintainer, second maintainer review is not required. +3. Add a new git tag with the **tag version**. +4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw + version**. (Note: this can be done as a separate MR to that, or in and MR + that will make use of the latest GitLab Shell changes.) + +## Security releases + +GitLab Shell is included in the packages we create for GitLab, and each version of GitLab specifies the version of GitLab Shell it uses in the `GITLAB_SHELL_VERSION` file, so security fixes in GitLab Shell are tightly coupled to the [GitLab security release](https://about.gitlab.com/handbook/engineering/workflow/#security-issues) workflow. + +For a security fix in GitLab Shell, two sets of merge requests are required: + +* The fix itself, in the `gitlab-org/security/gitlab-shell` repository and its backports to the previous versions of GitLab Shell +* Merge requests to change the versions of GitLab Shell included in the GitLab security release, in the `gitlab-org/security/gitlab` repository + +The first step could be to create a merge request with a fix targeting `main` in `gitlab-org/security/gitlab-shell`. When the merge request is approved by maintainers, backports targeting previous 3 versions of GitLab Shell must be created. The stable branches for those versions may not exist, feel free to ask a maintainer to create ones. The stable branches must be created out of the GitLab Shell tags/version used by the 3 previous GitLab releases. In order to find out the GitLab Shell version that is used on a particular GitLab stable release, the following steps may be helpful: + +```shell +git fetch security 13-9-stable-ee +git show refs/remotes/security/13-9-stable-ee:GITLAB_SHELL_VERSION +``` + +These steps display the version that is used by `13.9` version of GitLab. + +Close to the GitLab security release, a maintainer should merge the fix and backports and cut all the necessary GitLab Shell versions. This allows bumping the `GITLAB_SHELL_VERSION` for `gitlab-org/security/gitlab`. The GitLab merge request will be handled by the general GitLab security release process. + +Once the security release is done, a GitLab Shell maintainer is responsible for syncing tags and `main` to the `gitlab-org/gitlab-shell` repository. diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -78,28 +78,9 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. -## Releasing a new version - -GitLab Shell is versioned by git tags, and the version used by the Rails -application is stored in -[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). - -For each version, there is a raw version and a tag version: - -- The **raw version** is the version number. For instance, `15.2.8`. -- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. +## Releasing -To release a new version of GitLab Shell and have that version available to the -Rails application: - -1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the - **tag version** and the [`VERSION`](VERSION) file with the **raw version**. -2. Ask a maintainer to review and merge the merge request. If you're already a - maintainer, second maintainer review is not required. -3. Add a new git tag with the **tag version**. -4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw - version**. (Note: this can be done as a separate MR to that, or in and MR - that will make use of the latest GitLab Shell changes.) +See [PROCESS.md](./PROCESS.md) ## Contributing # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1624960917 0 # Tue Jun 29 10:01:57 2021 +0000 # Node ID 1520d1b058c03d38688d8eacd2c92966634f78aa # Parent e217294e7c0ea89fe37160a49b0d3ced586063ca # Parent e093b917055514501be4def3f666a4dc73c84937 Merge branch 'id-create-process-page' into 'main' Create PROCESS.md page with Security release process See merge request gitlab-org/gitlab-shell!488 diff --git a/PROCESS.md b/PROCESS.md new file mode 100644 --- /dev/null +++ b/PROCESS.md @@ -0,0 +1,44 @@ +## Releasing a new version + +GitLab Shell is versioned by git tags, and the version used by the Rails +application is stored in +[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). + +For each version, there is a raw version and a tag version: + +- The **raw version** is the version number. For instance, `15.2.8`. +- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. + +To release a new version of GitLab Shell and have that version available to the +Rails application: + +1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the + **tag version** and the [`VERSION`](VERSION) file with the **raw version**. +2. Ask a maintainer to review and merge the merge request. If you're already a + maintainer, second maintainer review is not required. +3. Add a new git tag with the **tag version**. +4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw + version**. (Note: this can be done as a separate MR to that, or in and MR + that will make use of the latest GitLab Shell changes.) + +## Security releases + +GitLab Shell is included in the packages we create for GitLab, and each version of GitLab specifies the version of GitLab Shell it uses in the `GITLAB_SHELL_VERSION` file, so security fixes in GitLab Shell are tightly coupled to the [GitLab security release](https://about.gitlab.com/handbook/engineering/workflow/#security-issues) workflow. + +For a security fix in GitLab Shell, two sets of merge requests are required: + +* The fix itself, in the `gitlab-org/security/gitlab-shell` repository and its backports to the previous versions of GitLab Shell +* Merge requests to change the versions of GitLab Shell included in the GitLab security release, in the `gitlab-org/security/gitlab` repository + +The first step could be to create a merge request with a fix targeting `main` in `gitlab-org/security/gitlab-shell`. When the merge request is approved by maintainers, backports targeting previous 3 versions of GitLab Shell must be created. The stable branches for those versions may not exist, feel free to ask a maintainer to create ones. The stable branches must be created out of the GitLab Shell tags/version used by the 3 previous GitLab releases. In order to find out the GitLab Shell version that is used on a particular GitLab stable release, the following steps may be helpful: + +```shell +git fetch security 13-9-stable-ee +git show refs/remotes/security/13-9-stable-ee:GITLAB_SHELL_VERSION +``` + +These steps display the version that is used by `13.9` version of GitLab. + +Close to the GitLab security release, a maintainer should merge the fix and backports and cut all the necessary GitLab Shell versions. This allows bumping the `GITLAB_SHELL_VERSION` for `gitlab-org/security/gitlab`. The GitLab merge request will be handled by the general GitLab security release process. + +Once the security release is done, a GitLab Shell maintainer is responsible for syncing tags and `main` to the `gitlab-org/gitlab-shell` repository. diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -78,28 +78,9 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. -## Releasing a new version - -GitLab Shell is versioned by git tags, and the version used by the Rails -application is stored in -[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). - -For each version, there is a raw version and a tag version: - -- The **raw version** is the version number. For instance, `15.2.8`. -- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. +## Releasing -To release a new version of GitLab Shell and have that version available to the -Rails application: - -1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the - **tag version** and the [`VERSION`](VERSION) file with the **raw version**. -2. Ask a maintainer to review and merge the merge request. If you're already a - maintainer, second maintainer review is not required. -3. Add a new git tag with the **tag version**. -4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw - version**. (Note: this can be done as a separate MR to that, or in and MR - that will make use of the latest GitLab Shell changes.) +See [PROCESS.md](./PROCESS.md) ## Contributing # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1624979605 -3600 # Tue Jun 29 16:13:25 2021 +0100 # Node ID 74ea2712640f2116b2c498ec137f155e186bb74c # Parent 1520d1b058c03d38688d8eacd2c92966634f78aa Fix a failing spec When the shell environment includes SSH_CONNECTION, one spec fails as the way we're stubbing the environment to the subprocess doesn't wipe out the pre-existing variable. This commit changes how we do it so the spec passes even in this environment. diff --git a/spec/gitlab_shell_discover_spec.rb b/spec/gitlab_shell_discover_spec.rb --- a/spec/gitlab_shell_discover_spec.rb +++ b/spec/gitlab_shell_discover_spec.rb @@ -108,7 +108,7 @@ end it 'outputs "Only SSH allowed"' do - _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {}) + _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {'SSH_CONNECTION' => ''}) expect(stderr).to eq("Only SSH allowed\n") expect(status).not_to be_success # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1625017871 0 # Wed Jun 30 01:51:11 2021 +0000 # Node ID 5c7ba8814ad7107e3b658abf36bea6df13ff95d7 # Parent 1520d1b058c03d38688d8eacd2c92966634f78aa # Parent 74ea2712640f2116b2c498ec137f155e186bb74c Merge branch 'fix-failing-spec' into 'main' Fix a failing spec See merge request gitlab-org/gitlab-shell!489 diff --git a/spec/gitlab_shell_discover_spec.rb b/spec/gitlab_shell_discover_spec.rb --- a/spec/gitlab_shell_discover_spec.rb +++ b/spec/gitlab_shell_discover_spec.rb @@ -108,7 +108,7 @@ end it 'outputs "Only SSH allowed"' do - _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {}) + _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {'SSH_CONNECTION' => ''}) expect(stderr).to eq("Only SSH allowed\n") expect(status).not_to be_success # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1625142408 -3600 # Thu Jul 01 13:26:48 2021 +0100 # Node ID 9c412e078524c8bd52e8df66692ecd65cf891d9a # Parent 1520d1b058c03d38688d8eacd2c92966634f78aa Add a make install command Changelog: added diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _install build compile check clean +.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$0="v"$0' VERSION 2>/dev/null || echo unknown) @@ -6,6 +6,8 @@ BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +PREFIX ?= /usr/local + validate: verify test verify: verify_golang @@ -30,9 +32,9 @@ coverage_golang: [ -f cover.out ] && go tool cover -func cover.out -setup: _install bin/gitlab-shell +setup: _script_install bin/gitlab-shell -_install: +_script_install: bin/install build: bin/gitlab-shell @@ -45,3 +47,12 @@ clean: rm -f bin/check bin/gitlab-shell bin/gitlab-shell-authorized-keys-check bin/gitlab-shell-authorized-principals-check bin/gitlab-sshd + +install: compile + mkdir -p $(DESTDIR)$(PREFIX)/bin/ + install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd + diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -34,16 +34,36 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Setup - - make setup - ## Check Checks if GitLab API access and redis via internal API can be reached: make check +## Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + + make compile + +## Install + +Builds the `gitlab-shell` binaries and installs them onto the filesystem. The +default location is `/usr/local`, but can be controlled by use of the `PREFIX` +and `DESTDIR` environment variables. + + make install + +## Setup + +This command is intended for use when installing GitLab from source on a single +machine. In addition to compiling the gitlab-shell binaries, it ensures that +various paths on the filesystem exist with the correct permissions. Do not run +it unless instructed to by your installation method documentation. + + make setup + + ## Testing Run tests: # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1625144842 0 # Thu Jul 01 13:07:22 2021 +0000 # Node ID d247e327a7980d24cc3ad1b344e51eb936955044 # Parent 5c7ba8814ad7107e3b658abf36bea6df13ff95d7 # Parent 9c412e078524c8bd52e8df66692ecd65cf891d9a Merge branch '475-make-install' into 'main' Add a make install command Closes #475 See merge request gitlab-org/gitlab-shell!490 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _install build compile check clean +.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$0="v"$0' VERSION 2>/dev/null || echo unknown) @@ -6,6 +6,8 @@ BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +PREFIX ?= /usr/local + validate: verify test verify: verify_golang @@ -30,9 +32,9 @@ coverage_golang: [ -f cover.out ] && go tool cover -func cover.out -setup: _install bin/gitlab-shell +setup: _script_install bin/gitlab-shell -_install: +_script_install: bin/install build: bin/gitlab-shell @@ -45,3 +47,12 @@ clean: rm -f bin/check bin/gitlab-shell bin/gitlab-shell-authorized-keys-check bin/gitlab-shell-authorized-principals-check bin/gitlab-sshd + +install: compile + mkdir -p $(DESTDIR)$(PREFIX)/bin/ + install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd + diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -34,16 +34,36 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Setup - - make setup - ## Check Checks if GitLab API access and redis via internal API can be reached: make check +## Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + + make compile + +## Install + +Builds the `gitlab-shell` binaries and installs them onto the filesystem. The +default location is `/usr/local`, but can be controlled by use of the `PREFIX` +and `DESTDIR` environment variables. + + make install + +## Setup + +This command is intended for use when installing GitLab from source on a single +machine. In addition to compiling the gitlab-shell binaries, it ensures that +various paths on the filesystem exist with the correct permissions. Do not run +it unless instructed to by your installation method documentation. + + make setup + + ## Testing Run tests: # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1625142471 -3600 # Thu Jul 01 13:27:51 2021 +0100 # Node ID f1429b64347f88576e0c36b54e297252b7e5b8dc # Parent 1520d1b058c03d38688d8eacd2c92966634f78aa Remove bin/authorized_keys We committed to removing this script in the 13.x release cycle, and it was announced then, but we never actually got around to it. Its functionality is completely replicated, in a safer manner, by the bin/gitlab-shell-authorized-keys script. Changelog: removed diff --git a/bin/authorized_keys b/bin/authorized_keys deleted file mode 100755 --- a/bin/authorized_keys +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Legacy script used for AuthorizedKeysCommand when configured without username. -# Executes gitlab-shell-authorized-keys-check with "git" as expected and actual -# username and with the passed key. -# -# TODO: Remove this in https://gitlab.com/gitlab-org/gitlab-shell/issues/209. - -$(dirname $0)/gitlab-shell-authorized-keys-check git git $1 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1625467858 0 # Mon Jul 05 06:50:58 2021 +0000 # Node ID 0a2a210a4b1d0e5f335a6c35ac3ae3d9356d4399 # Parent d247e327a7980d24cc3ad1b344e51eb936955044 # Parent f1429b64347f88576e0c36b54e297252b7e5b8dc Merge branch 'remove-bin-authorized-keys' into 'main' Remove bin/authorized_keys See merge request gitlab-org/gitlab-shell!491 diff --git a/bin/authorized_keys b/bin/authorized_keys deleted file mode 100755 --- a/bin/authorized_keys +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Legacy script used for AuthorizedKeysCommand when configured without username. -# Executes gitlab-shell-authorized-keys-check with "git" as expected and actual -# username and with the passed key. -# -# TODO: Remove this in https://gitlab.com/gitlab-org/gitlab-shell/issues/209. - -$(dirname $0)/gitlab-shell-authorized-keys-check git git $1 # HG changeset patch # User Valery Sizov <valery@gitlab.com> # Date 1624394952 -10800 # Tue Jun 22 23:49:12 2021 +0300 # Node ID 3e48e1b476145da95553f19ff8ddb8c0fcb7a3ca # Parent 5c7ba8814ad7107e3b658abf36bea6df13ff95d7 Fix the Geo SSH push proxy hanging Geo SSH proxy push currently impossible when the only action that happens is branch removal. This fix works in a way that it waits for flush packet from git and then checks pkt lines to determine is pack data is expected. The thing is that git doesnt send pack data when only branch removal happens. Explanation is in https://gitlab.com/gitlab-org/gitlab/-/issues/330494 diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -112,10 +112,32 @@ } func (c *Command) readFromStdin() ([]byte, error) { - output := new(bytes.Buffer) - _, err := io.Copy(output, c.ReadWriter.In) + var output []byte + var needsPackData bool + + scanner := pktline.NewScanner(c.ReadWriter.In) + for scanner.Scan() { + line := scanner.Bytes() + output = append(output, line...) + + if pktline.IsFlush(line) { + break + } - return output.Bytes(), err + if !needsPackData && !pktline.IsRefRemoval(line) { + needsPackData = true + } + } + + if needsPackData { + packData := new(bytes.Buffer) + _, err := io.Copy(packData, c.ReadWriter.In) + + output = append(output, packData.Bytes()...) + return output, err + } else { + return output, nil + } } func (c *Command) readFromStdinNoEOF() []byte { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -46,7 +46,7 @@ require.NoError(t, json.Unmarshal(b, &request)) require.Equal(t, request.Data.UserId, who) - require.Equal(t, "input", string(request.Output)) + require.Equal(t, "0009input", string(request.Output)) err = json.NewEncoder(w).Encode(Response{Result: []byte("output")}) require.NoError(t, err) @@ -58,7 +58,7 @@ outBuf := &bytes.Buffer{} errBuf := &bytes.Buffer{} - input := bytes.NewBufferString("input") + input := bytes.NewBufferString("0009input") response := &accessverifier.Response{ Who: who, diff --git a/internal/pktline/pktline.go b/internal/pktline/pktline.go --- a/internal/pktline/pktline.go +++ b/internal/pktline/pktline.go @@ -8,6 +8,7 @@ "bytes" "fmt" "io" + "regexp" "strconv" ) @@ -16,6 +17,8 @@ pktDelim = "0001" ) +var branchRemovalPktRegexp = regexp.MustCompile(`\A[a-f0-9]{4}[a-f0-9]{40} 0{40} `) + // NewScanner returns a bufio.Scanner that splits on Git pktline boundaries func NewScanner(r io.Reader) *bufio.Scanner { scanner := bufio.NewScanner(r) @@ -24,7 +27,16 @@ return scanner } -// IsDone detects the special flush packet '0009done\n' +func IsRefRemoval(pkt []byte) bool { + return branchRemovalPktRegexp.Match(pkt) +} + +// IsFlush detects the special flush packet '0000' +func IsFlush(pkt []byte) bool { + return bytes.Equal(pkt, []byte("0000")) +} + +// IsDone detects the special done packet '0009done\n' func IsDone(pkt []byte) bool { return bytes.Equal(pkt, PktDone()) } diff --git a/internal/pktline/pktline_test.go b/internal/pktline/pktline_test.go --- a/internal/pktline/pktline_test.go +++ b/internal/pktline/pktline_test.go @@ -68,6 +68,40 @@ } } +func TestIsRefRemoval(t *testing.T) { + testCases := []struct { + in string + isRemoval bool + }{ + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f0000000000000000000000000000000000000000 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 0000000000000000000000000000000000000000 refs/heads/debug", isRemoval: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.isRemoval, IsRefRemoval([]byte(tc.in))) + }) + } +} + +func TestIsFlush(t *testing.T) { + testCases := []struct { + in string + flush bool + }{ + {in: "0008abcd", flush: false}, + {in: "invalid packet", flush: false}, + {in: "0000", flush: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.flush, IsFlush([]byte(tc.in))) + }) + } +} + func TestIsDone(t *testing.T) { testCases := []struct { in string diff --git a/spec/gitlab_shell_custom_git_receive_pack_spec.rb b/spec/gitlab_shell_custom_git_receive_pack_spec.rb --- a/spec/gitlab_shell_custom_git_receive_pack_spec.rb +++ b/spec/gitlab_shell_custom_git_receive_pack_spec.rb @@ -74,11 +74,11 @@ expect(stderr.gets).to eq("remote: message\n") expect(stderr.gets).to eq(remote_blank_line) - stdin.puts("input") + stdin.puts("0009input") stdin.close expect(stdout.gets(6)).to eq("custom") - expect(stdout.flush.read).to eq("input\n") + expect(stdout.flush.read).to eq("0009input") end end # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1625629452 0 # Wed Jul 07 03:44:12 2021 +0000 # Node ID 394e15a73ea3a0a65d6ab36967159b3a17b05f34 # Parent 0a2a210a4b1d0e5f335a6c35ac3ae3d9356d4399 # Parent 3e48e1b476145da95553f19ff8ddb8c0fcb7a3ca Merge branch '330494-geo-ssh-push-proxy-hanging-bug' into 'main' Fix the Geo SSH push proxy hanging See merge request gitlab-org/gitlab-shell!487 diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -112,10 +112,32 @@ } func (c *Command) readFromStdin() ([]byte, error) { - output := new(bytes.Buffer) - _, err := io.Copy(output, c.ReadWriter.In) + var output []byte + var needsPackData bool + + scanner := pktline.NewScanner(c.ReadWriter.In) + for scanner.Scan() { + line := scanner.Bytes() + output = append(output, line...) + + if pktline.IsFlush(line) { + break + } - return output.Bytes(), err + if !needsPackData && !pktline.IsRefRemoval(line) { + needsPackData = true + } + } + + if needsPackData { + packData := new(bytes.Buffer) + _, err := io.Copy(packData, c.ReadWriter.In) + + output = append(output, packData.Bytes()...) + return output, err + } else { + return output, nil + } } func (c *Command) readFromStdinNoEOF() []byte { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -46,7 +46,7 @@ require.NoError(t, json.Unmarshal(b, &request)) require.Equal(t, request.Data.UserId, who) - require.Equal(t, "input", string(request.Output)) + require.Equal(t, "0009input", string(request.Output)) err = json.NewEncoder(w).Encode(Response{Result: []byte("output")}) require.NoError(t, err) @@ -58,7 +58,7 @@ outBuf := &bytes.Buffer{} errBuf := &bytes.Buffer{} - input := bytes.NewBufferString("input") + input := bytes.NewBufferString("0009input") response := &accessverifier.Response{ Who: who, diff --git a/internal/pktline/pktline.go b/internal/pktline/pktline.go --- a/internal/pktline/pktline.go +++ b/internal/pktline/pktline.go @@ -8,6 +8,7 @@ "bytes" "fmt" "io" + "regexp" "strconv" ) @@ -16,6 +17,8 @@ pktDelim = "0001" ) +var branchRemovalPktRegexp = regexp.MustCompile(`\A[a-f0-9]{4}[a-f0-9]{40} 0{40} `) + // NewScanner returns a bufio.Scanner that splits on Git pktline boundaries func NewScanner(r io.Reader) *bufio.Scanner { scanner := bufio.NewScanner(r) @@ -24,7 +27,16 @@ return scanner } -// IsDone detects the special flush packet '0009done\n' +func IsRefRemoval(pkt []byte) bool { + return branchRemovalPktRegexp.Match(pkt) +} + +// IsFlush detects the special flush packet '0000' +func IsFlush(pkt []byte) bool { + return bytes.Equal(pkt, []byte("0000")) +} + +// IsDone detects the special done packet '0009done\n' func IsDone(pkt []byte) bool { return bytes.Equal(pkt, PktDone()) } diff --git a/internal/pktline/pktline_test.go b/internal/pktline/pktline_test.go --- a/internal/pktline/pktline_test.go +++ b/internal/pktline/pktline_test.go @@ -68,6 +68,40 @@ } } +func TestIsRefRemoval(t *testing.T) { + testCases := []struct { + in string + isRemoval bool + }{ + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f0000000000000000000000000000000000000000 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 0000000000000000000000000000000000000000 refs/heads/debug", isRemoval: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.isRemoval, IsRefRemoval([]byte(tc.in))) + }) + } +} + +func TestIsFlush(t *testing.T) { + testCases := []struct { + in string + flush bool + }{ + {in: "0008abcd", flush: false}, + {in: "invalid packet", flush: false}, + {in: "0000", flush: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.flush, IsFlush([]byte(tc.in))) + }) + } +} + func TestIsDone(t *testing.T) { testCases := []struct { in string diff --git a/spec/gitlab_shell_custom_git_receive_pack_spec.rb b/spec/gitlab_shell_custom_git_receive_pack_spec.rb --- a/spec/gitlab_shell_custom_git_receive_pack_spec.rb +++ b/spec/gitlab_shell_custom_git_receive_pack_spec.rb @@ -74,11 +74,11 @@ expect(stderr.gets).to eq("remote: message\n") expect(stderr.gets).to eq(remote_blank_line) - stdin.puts("input") + stdin.puts("0009input") stdin.close expect(stdout.gets(6)).to eq("custom") - expect(stdout.flush.read).to eq("input\n") + expect(stdout.flush.read).to eq("0009input") end end # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1625639268 -36000 # Wed Jul 07 16:27:48 2021 +1000 # Node ID 6bc5c90d8eedac11a02cc801fc5284a2ec66b517 # Parent 394e15a73ea3a0a65d6ab36967159b3a17b05f34 Release v13.20.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.20.0 + +- Remove bin/authorized_keys !491 +- Add a make install command !490 +- Create PROCESS.md page with Security release process !488 +- Fix the Geo SSH push proxy hanging !487 +- Standardize logging timestamp format !485 + v13.19.0 - Don't finish the opentracing span early !466 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.19.0 +13.20.0 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1625642161 0 # Wed Jul 07 07:16:01 2021 +0000 # Node ID 523d59dd8f0d249ff283b987905896256991e8de # Parent 394e15a73ea3a0a65d6ab36967159b3a17b05f34 # Parent 6bc5c90d8eedac11a02cc801fc5284a2ec66b517 Merge branch 'ashmckenzie/gitlab-shell-13-20-0-release' into 'main' Release v13.20.0 See merge request gitlab-org/gitlab-shell!492 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.20.0 + +- Remove bin/authorized_keys !491 +- Add a make install command !490 +- Create PROCESS.md page with Security release process !488 +- Fix the Geo SSH push proxy hanging !487 +- Standardize logging timestamp format !485 + v13.19.0 - Don't finish the opentracing span early !466 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.19.0 +13.20.0 # HG changeset patch # User listout <listout@protonmail.com> # Date 1621870174 -19800 # Mon May 24 20:59:34 2021 +0530 # Node ID 568a2c87a290540d15402667b719f539b8023945 # Parent 111f852ad4b8171ba753a814b714499e3e92ee2b changed the format of log file to json from text diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -57,8 +57,8 @@ // The defaults to apply before parsing the config file(s). var ( DefaultConfig = Config{ - LogFile: "gitlab-shell.log", - LogFormat: "text", + LogFile: "gitlab-shell.json", + LogFormat: "json", Server: DefaultServerConfig, User: "git", } # HG changeset patch # User listout <listout@protonmail.com> # Date 1621870336 -19800 # Mon May 24 21:02:16 2021 +0530 # Node ID 8b2544a201455cafa554eee1143dcca987f6c4d4 # Parent 568a2c87a290540d15402667b719f539b8023945 default log format changed to json, making it reflect in example config diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -44,14 +44,14 @@ # secret: "supersecret" # Log file. -# Default is gitlab-shell.log in the root directory. -# log_file: "/home/git/gitlab-shell/gitlab-shell.log" +# Default is gitlab-shell.json in the root directory. +# log_file: "/home/git/gitlab-shell/gitlab-shell.json" # Log level. INFO by default log_level: INFO -# Log format. 'text' by default -# log_format: json +# Log format. 'json' by default +# log_format: text # Audit usernames. # Set to true to see real usernames in the logs instead of key ids, which is easier to follow, but @@ -73,7 +73,7 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # SSH host key files. + # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key # HG changeset patch # User listout <listout@protonmail.com> # Date 1622026628 -19800 # Wed May 26 16:27:08 2021 +0530 # Node ID 91951053a07282d1920ea481ea1c7f6ff8653e2d # Parent 8b2544a201455cafa554eee1143dcca987f6c4d4 changed filename extension to .log as json can operate on .log file diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -45,7 +45,7 @@ # Log file. # Default is gitlab-shell.json in the root directory. -# log_file: "/home/git/gitlab-shell/gitlab-shell.json" +# log_file: "/home/git/gitlab-shell/gitlab-shell.log" # Log level. INFO by default log_level: INFO diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -57,7 +57,7 @@ // The defaults to apply before parsing the config file(s). var ( DefaultConfig = Config{ - LogFile: "gitlab-shell.json", + LogFile: "gitlab-shell.log", LogFormat: "json", Server: DefaultServerConfig, User: "git", # HG changeset patch # User listout <listout@protonmail.com> # Date 1622027080 -19800 # Wed May 26 16:34:40 2021 +0530 # Node ID ab7d8d4a4ba471a0d97f5990a9311239779feb7f # Parent 91951053a07282d1920ea481ea1c7f6ff8653e2d log_format changed from 'text' to 'json' Edited log_format description comment, if for 'text' if a user need 'text' logging diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -44,14 +44,14 @@ # secret: "supersecret" # Log file. -# Default is gitlab-shell.json in the root directory. +# Default is gitlab-shell.log in the root directory. # log_file: "/home/git/gitlab-shell/gitlab-shell.log" # Log level. INFO by default log_level: INFO -# Log format. 'json' by default -# log_format: text +# Log format. 'json' by default, can be changed to 'text' if needed +# log_format: json # Audit usernames. # Set to true to see real usernames in the logs instead of key ids, which is easier to follow, but # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1626158579 0 # Tue Jul 13 06:42:59 2021 +0000 # Node ID d17152cf742059ad42a24cbaa6bdb29659a6d5bf # Parent 523d59dd8f0d249ff283b987905896256991e8de # Parent ab7d8d4a4ba471a0d97f5990a9311239779feb7f Merge branch 'change_log_format' into 'main' Change default logging format to JSON See merge request gitlab-org/gitlab-shell!476 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -50,7 +50,7 @@ # Log level. INFO by default log_level: INFO -# Log format. 'text' by default +# Log format. 'json' by default, can be changed to 'text' if needed # log_format: json # Audit usernames. @@ -73,7 +73,7 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # SSH host key files. + # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -60,7 +60,7 @@ var ( DefaultConfig = Config{ LogFile: "gitlab-shell.log", - LogFormat: "text", + LogFormat: "json", Server: DefaultServerConfig, User: "git", } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1626273816 -10800 # Wed Jul 14 17:43:36 2021 +0300 # Node ID dddfbff7e5ff07b712a1c9a21dde1e64bbdf6a09 # Parent 0a2a210a4b1d0e5f335a6c35ac3ae3d9356d4399 Refactor testhelper.PrepareTestRootDir using t.Cleanup diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -18,9 +18,7 @@ ) func TestClients(t *testing.T) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) testCases := []struct { desc string diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -98,9 +98,7 @@ } func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) *GitlabNetClient { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ { diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -95,9 +95,7 @@ t.Helper() return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) t.Logf("gitlab-api-mock: received request: %s %s", r.Method, r.RequestURI) w.Header().Set("Content-Type", "application/json") diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -163,9 +163,7 @@ } func setup(t *testing.T, allowedPayload string) *Client { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -7,10 +7,12 @@ "path" "runtime" "time" + "testing" "github.com/otiai10/copy" "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/require" ) var ( @@ -31,42 +33,21 @@ } } -func PrepareTestRootDir() (func(), error) { - if err := os.MkdirAll(TestRoot, 0700); err != nil { - return nil, err - } +func PrepareTestRootDir(t *testing.T) { + t.Helper() - var oldWd string - cleanup := func() { - if oldWd != "" { - err := os.Chdir(oldWd) - if err != nil { - panic(err) - } - } + require.NoError(t, os.MkdirAll(TestRoot, 0700)) - if err := os.RemoveAll(TestRoot); err != nil { - panic(err) - } - } + t.Cleanup(func() { os.RemoveAll(TestRoot) }) - if err := copyTestData(); err != nil { - cleanup() - return nil, err - } + require.NoError(t, copyTestData()) oldWd, err := os.Getwd() - if err != nil { - cleanup() - return nil, err - } + require.NoError(t, err) - if err := os.Chdir(TestRoot); err != nil { - cleanup() - return nil, err - } + t.Cleanup(func() { os.Chdir(oldWd) }) - return cleanup, nil + require.NoError(t, os.Chdir(TestRoot)) } func copyTestData() error { # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1626274506 0 # Wed Jul 14 14:55:06 2021 +0000 # Node ID c0c264775367004fa947479834f9b2a15c7f755f # Parent d17152cf742059ad42a24cbaa6bdb29659a6d5bf # Parent dddfbff7e5ff07b712a1c9a21dde1e64bbdf6a09 Merge branch 'id-refactor-test-helper' into 'main' Refactor testhelper.PrepareTestRootDir using t.Cleanup See merge request gitlab-org/gitlab-shell!493 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -18,9 +18,7 @@ ) func TestClients(t *testing.T) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) testCases := []struct { desc string diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -98,9 +98,7 @@ } func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) *GitlabNetClient { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ { diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -95,9 +95,7 @@ t.Helper() return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) t.Logf("gitlab-api-mock: received request: %s %s", r.Method, r.RequestURI) w.Header().Set("Content-Type", "application/json") diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -163,9 +163,7 @@ } func setup(t *testing.T, allowedPayload string) *Client { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -7,10 +7,12 @@ "path" "runtime" "time" + "testing" "github.com/otiai10/copy" "github.com/sirupsen/logrus" "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/require" ) var ( @@ -31,42 +33,21 @@ } } -func PrepareTestRootDir() (func(), error) { - if err := os.MkdirAll(TestRoot, 0700); err != nil { - return nil, err - } +func PrepareTestRootDir(t *testing.T) { + t.Helper() - var oldWd string - cleanup := func() { - if oldWd != "" { - err := os.Chdir(oldWd) - if err != nil { - panic(err) - } - } + require.NoError(t, os.MkdirAll(TestRoot, 0700)) - if err := os.RemoveAll(TestRoot); err != nil { - panic(err) - } - } + t.Cleanup(func() { os.RemoveAll(TestRoot) }) - if err := copyTestData(); err != nil { - cleanup() - return nil, err - } + require.NoError(t, copyTestData()) oldWd, err := os.Getwd() - if err != nil { - cleanup() - return nil, err - } + require.NoError(t, err) - if err := os.Chdir(TestRoot); err != nil { - cleanup() - return nil, err - } + t.Cleanup(func() { os.Chdir(oldWd) }) - return cleanup, nil + require.NoError(t, os.Chdir(TestRoot)) } func copyTestData() error { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1625830901 -10800 # Fri Jul 09 14:41:41 2021 +0300 # Node ID 6678b2b63861742378ad71ccc68eea953c08ca18 # Parent c0c264775367004fa947479834f9b2a15c7f755f Shutdown sshd gracefully When interruption signal is sent, we are closing ssh listener to prevent it from accepting new connections Then after configured grace period, we cancel the context to cancel all ongoing operations diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -3,6 +3,10 @@ import ( "flag" "os" + "os/signal" + "context" + "syscall" + "time" log "github.com/sirupsen/logrus" @@ -63,6 +67,8 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + server := sshd.Server{Config: cfg} + // Startup monitoring endpoint. if cfg.Server.WebListen != "" { go func() { @@ -75,7 +81,27 @@ }() } - if err := sshd.Run(ctx, cfg); err != nil { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + done := make(chan os.Signal, 1) + signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) + + go func() { + sig := <-done + signal.Reset(syscall.SIGINT, syscall.SIGTERM) + + log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Infof("Shutdown initiated") + + server.Shutdown() + + <-time.After(cfg.Server.GracePeriod()) + + cancel() + + }() + + if err := server.ListenAndServe(ctx); err != nil { log.Fatalf("Failed to start GitLab built-in sshd: %v", err) } } diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -8,6 +8,7 @@ "path" "path/filepath" "sync" + "time" "gitlab.com/gitlab-org/labkit/tracing" yaml "gopkg.in/yaml.v2" @@ -25,6 +26,7 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` } @@ -69,6 +71,7 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -77,6 +80,10 @@ } ) +func (sc *ServerConfig) GracePeriod() time.Duration { + return time.Duration(sc.GracePeriodSeconds) * time.Second +} + func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { os.Setenv("SSL_CERT_DIR", c.SslCertDir) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -9,6 +9,7 @@ "net" "strconv" "time" + "sync" log "github.com/sirupsen/logrus" @@ -20,28 +21,87 @@ "gitlab.com/gitlab-org/labkit/correlation" ) -func Run(ctx context.Context, cfg *config.Config) error { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) - if err != nil { - return fmt.Errorf("failed to initialize GitLab client: %w", err) +type Server struct { + Config *config.Config + + onShutdown bool + wg sync.WaitGroup + listener net.Listener +} + +func (s *Server) ListenAndServe(ctx context.Context) error { + if err := s.listen(); err != nil { + return err + } + defer s.listener.Close() + + return s.serve(ctx) +} + +func (s *Server) Shutdown() error { + if s.listener == nil { + return nil } - sshListener, err := net.Listen("tcp", cfg.Server.Listen) + s.onShutdown = true + + return s.listener.Close() +} + +func (s *Server) listen() error { + sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) } - if cfg.Server.ProxyProtocol { + + if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{Listener: sshListener} log.Info("Proxy protocol is enabled") } - defer sshListener.Close() log.Infof("Listening on %v", sshListener.Addr().String()) + s.listener = sshListener + + return nil +} + +func (s *Server) serve(ctx context.Context) error { + sshCfg, err := s.initConfig(ctx) + if err != nil { + return err + } + + for { + nconn, err := s.listener.Accept() + if err != nil { + if s.onShutdown { + break + } + + log.Warnf("Failed to accept connection: %v\n", err) + continue + } + + s.wg.Add(1) + go s.handleConn(ctx, sshCfg, nconn) + } + + s.wg.Wait() + + return nil +} + +func (s *Server) initConfig(ctx context.Context) (*ssh.ServerConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(s.Config) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + sshCfg := &ssh.ServerConfig{ PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != cfg.User { + if conn.User() != s.Config.User { return nil, errors.New("unknown user") } if key.Type() == ssh.KeyAlgoDSA { @@ -64,7 +124,7 @@ } var loadedHostKeys uint - for _, filename := range cfg.Server.HostKeyFiles { + for _, filename := range s.Config.Server.HostKeyFiles { keyRaw, err := ioutil.ReadFile(filename) if err != nil { log.Warnf("Failed to read host key %v: %v", filename, err) @@ -79,23 +139,17 @@ sshCfg.AddHostKey(key) } if loadedHostKeys == 0 { - return fmt.Errorf("No host keys could be loaded, aborting") + return nil, fmt.Errorf("No host keys could be loaded, aborting") } - for { - nconn, err := sshListener.Accept() - if err != nil { - log.Warnf("Failed to accept connection: %v\n", err) - continue - } - - go handleConn(ctx, cfg, sshCfg, nconn) - } + return sshCfg, nil } -func handleConn(ctx context.Context, cfg *config.Config, sshCfg *ssh.ServerConfig, nconn net.Conn) { + +func (s *Server) handleConn(ctx context.Context, sshCfg *ssh.ServerConfig, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() + defer s.wg.Done() defer nconn.Close() // Prevent a panic in a single connection from taking out the whole server @@ -116,10 +170,10 @@ go ssh.DiscardRequests(reqs) - conn := newConnection(cfg.Server.ConcurrentSessionsLimit, remoteAddr) + conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { session := &session{ - cfg: cfg, + cfg: s.Config, channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/sshd_test.go @@ -0,0 +1,49 @@ +package sshd + +import ( + "testing" + "context" + "path" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +const serverUrl = "127.0.0.1:50000" + +func TestShutdown(t *testing.T) { + s := setupServer(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + done := make(chan bool, 1) + go func() { + require.NoError(t, s.serve(ctx)) + done <- true + }() + + require.NoError(t, s.Shutdown()) + + require.True(t, <-done, "the accepting loop must be interrupted") +} + +func setupServer(t *testing.T) *Server { + testhelper.PrepareTestRootDir(t) + + url := testserver.StartSocketHttpServer(t, []testserver.TestRequestHandler{}) + srvCfg := config.ServerConfig{ + Listen: serverUrl, + HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + } + + cfg := &config.Config{RootDir: "/tmp", GitlabUrl: url, Server: srvCfg} + + s := &Server{Config: cfg} + require.NoError(t, s.listen()) + + return s +} # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1626353088 0 # Thu Jul 15 12:44:48 2021 +0000 # Node ID a40d5d811efa26be2600db894127d84e008eee0e # Parent c0c264775367004fa947479834f9b2a15c7f755f # Parent 6678b2b63861742378ad71ccc68eea953c08ca18 Merge branch 'id-cancelable-sshd' into 'main' Shutdown sshd gracefully See merge request gitlab-org/gitlab-shell!484 diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -3,6 +3,10 @@ import ( "flag" "os" + "os/signal" + "context" + "syscall" + "time" log "github.com/sirupsen/logrus" @@ -63,6 +67,8 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + server := sshd.Server{Config: cfg} + // Startup monitoring endpoint. if cfg.Server.WebListen != "" { go func() { @@ -75,7 +81,27 @@ }() } - if err := sshd.Run(ctx, cfg); err != nil { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + done := make(chan os.Signal, 1) + signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) + + go func() { + sig := <-done + signal.Reset(syscall.SIGINT, syscall.SIGTERM) + + log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Infof("Shutdown initiated") + + server.Shutdown() + + <-time.After(cfg.Server.GracePeriod()) + + cancel() + + }() + + if err := server.ListenAndServe(ctx); err != nil { log.Fatalf("Failed to start GitLab built-in sshd: %v", err) } } diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -8,6 +8,7 @@ "path" "path/filepath" "sync" + "time" "gitlab.com/gitlab-org/labkit/tracing" yaml "gopkg.in/yaml.v2" @@ -25,6 +26,7 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` } @@ -69,6 +71,7 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -77,6 +80,10 @@ } ) +func (sc *ServerConfig) GracePeriod() time.Duration { + return time.Duration(sc.GracePeriodSeconds) * time.Second +} + func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { os.Setenv("SSL_CERT_DIR", c.SslCertDir) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -9,6 +9,7 @@ "net" "strconv" "time" + "sync" log "github.com/sirupsen/logrus" @@ -20,28 +21,87 @@ "gitlab.com/gitlab-org/labkit/correlation" ) -func Run(ctx context.Context, cfg *config.Config) error { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) - if err != nil { - return fmt.Errorf("failed to initialize GitLab client: %w", err) +type Server struct { + Config *config.Config + + onShutdown bool + wg sync.WaitGroup + listener net.Listener +} + +func (s *Server) ListenAndServe(ctx context.Context) error { + if err := s.listen(); err != nil { + return err + } + defer s.listener.Close() + + return s.serve(ctx) +} + +func (s *Server) Shutdown() error { + if s.listener == nil { + return nil } - sshListener, err := net.Listen("tcp", cfg.Server.Listen) + s.onShutdown = true + + return s.listener.Close() +} + +func (s *Server) listen() error { + sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) } - if cfg.Server.ProxyProtocol { + + if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{Listener: sshListener} log.Info("Proxy protocol is enabled") } - defer sshListener.Close() log.Infof("Listening on %v", sshListener.Addr().String()) + s.listener = sshListener + + return nil +} + +func (s *Server) serve(ctx context.Context) error { + sshCfg, err := s.initConfig(ctx) + if err != nil { + return err + } + + for { + nconn, err := s.listener.Accept() + if err != nil { + if s.onShutdown { + break + } + + log.Warnf("Failed to accept connection: %v\n", err) + continue + } + + s.wg.Add(1) + go s.handleConn(ctx, sshCfg, nconn) + } + + s.wg.Wait() + + return nil +} + +func (s *Server) initConfig(ctx context.Context) (*ssh.ServerConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(s.Config) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + sshCfg := &ssh.ServerConfig{ PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != cfg.User { + if conn.User() != s.Config.User { return nil, errors.New("unknown user") } if key.Type() == ssh.KeyAlgoDSA { @@ -64,7 +124,7 @@ } var loadedHostKeys uint - for _, filename := range cfg.Server.HostKeyFiles { + for _, filename := range s.Config.Server.HostKeyFiles { keyRaw, err := ioutil.ReadFile(filename) if err != nil { log.Warnf("Failed to read host key %v: %v", filename, err) @@ -79,23 +139,17 @@ sshCfg.AddHostKey(key) } if loadedHostKeys == 0 { - return fmt.Errorf("No host keys could be loaded, aborting") + return nil, fmt.Errorf("No host keys could be loaded, aborting") } - for { - nconn, err := sshListener.Accept() - if err != nil { - log.Warnf("Failed to accept connection: %v\n", err) - continue - } - - go handleConn(ctx, cfg, sshCfg, nconn) - } + return sshCfg, nil } -func handleConn(ctx context.Context, cfg *config.Config, sshCfg *ssh.ServerConfig, nconn net.Conn) { + +func (s *Server) handleConn(ctx context.Context, sshCfg *ssh.ServerConfig, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() + defer s.wg.Done() defer nconn.Close() // Prevent a panic in a single connection from taking out the whole server @@ -116,10 +170,10 @@ go ssh.DiscardRequests(reqs) - conn := newConnection(cfg.Server.ConcurrentSessionsLimit, remoteAddr) + conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { session := &session{ - cfg: cfg, + cfg: s.Config, channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/sshd_test.go @@ -0,0 +1,49 @@ +package sshd + +import ( + "testing" + "context" + "path" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +const serverUrl = "127.0.0.1:50000" + +func TestShutdown(t *testing.T) { + s := setupServer(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + done := make(chan bool, 1) + go func() { + require.NoError(t, s.serve(ctx)) + done <- true + }() + + require.NoError(t, s.Shutdown()) + + require.True(t, <-done, "the accepting loop must be interrupted") +} + +func setupServer(t *testing.T) *Server { + testhelper.PrepareTestRootDir(t) + + url := testserver.StartSocketHttpServer(t, []testserver.TestRequestHandler{}) + srvCfg := config.ServerConfig{ + Listen: serverUrl, + HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + } + + cfg := &config.Config{RootDir: "/tmp", GitlabUrl: url, Server: srvCfg} + + s := &Server{Config: cfg} + require.NoError(t, s.listen()) + + return s +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1626349267 -10800 # Thu Jul 15 14:41:07 2021 +0300 # Node ID c9a651a976232ad89780083dcaf03b1e249692bf # Parent a40d5d811efa26be2600db894127d84e008eee0e Provide liveness and readiness probes They are going to be used to determine whether a server is alive and ready to accept traffic diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -76,6 +76,7 @@ monitoring.Start( monitoring.WithListenerAddress(cfg.Server.WebListen), monitoring.WithBuildInformation(Version, BuildTime), + monitoring.WithServeMux(server.MonitoringServeMux()), ), ) }() diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -26,7 +26,9 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` } @@ -72,6 +74,8 @@ WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, GracePeriodSeconds: 10, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,6 +10,7 @@ "strconv" "time" "sync" + "net/http" log "github.com/sirupsen/logrus" @@ -21,10 +22,20 @@ "gitlab.com/gitlab-org/labkit/correlation" ) +type status int + +const( + StatusStarting status = iota + StatusReady + StatusOnShutdown + StatusClosed +) + type Server struct { Config *config.Config - onShutdown bool + status status + statusMu sync.Mutex wg sync.WaitGroup listener net.Listener } @@ -43,11 +54,29 @@ return nil } - s.onShutdown = true + s.changeStatus(StatusOnShutdown) return s.listener.Close() } +func (s *Server) MonitoringServeMux() *http.ServeMux { + mux := http.NewServeMux() + + mux.HandleFunc(s.Config.Server.ReadinessProbe, func(w http.ResponseWriter, r *http.Request) { + if s.getStatus() == StatusReady { + w.WriteHeader(http.StatusOK) + } else { + w.WriteHeader(http.StatusServiceUnavailable) + } + }) + + mux.HandleFunc(s.Config.Server.LivenessProbe, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + + return mux +} + func (s *Server) listen() error { sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { @@ -73,10 +102,12 @@ return err } + s.changeStatus(StatusReady) + for { nconn, err := s.listener.Accept() if err != nil { - if s.onShutdown { + if s.getStatus() == StatusOnShutdown { break } @@ -90,9 +121,24 @@ s.wg.Wait() + s.changeStatus(StatusClosed) + return nil } +func (s *Server) changeStatus(st status) { + s.statusMu.Lock() + s.status = st + s.statusMu.Unlock() +} + +func (s *Server) getStatus() status { + s.statusMu.Lock() + defer s.statusMu.Unlock() + + return s.status +} + func (s *Server) initConfig(ctx context.Context) (*ssh.ServerConfig, error) { authorizedKeysClient, err := authorizedkeys.NewClient(s.Config) if err != nil { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -4,6 +4,8 @@ "testing" "context" "path" + "net/http/httptest" + "time" "github.com/stretchr/testify/require" @@ -17,18 +19,55 @@ func TestShutdown(t *testing.T) { s := setupServer(t) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() - done := make(chan bool, 1) - go func() { - require.NoError(t, s.serve(ctx)) - done <- true - }() + verifyStatus(t, s, StatusReady) + + s.wg.Add(1) require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusOnShutdown) - require.True(t, <-done, "the accepting loop must be interrupted") + s.wg.Done() + + verifyStatus(t, s, StatusClosed) +} + +func TestReadinessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + + require.Equal(t, StatusStarting, s.getStatus()) + + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/start", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) + + s.changeStatus(StatusReady) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) + + s.changeStatus(StatusOnShutdown) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) +} + +func TestLivenessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/health", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) } func setupServer(t *testing.T) *Server { @@ -42,8 +81,18 @@ cfg := &config.Config{RootDir: "/tmp", GitlabUrl: url, Server: srvCfg} - s := &Server{Config: cfg} - require.NoError(t, s.listen()) + return &Server{Config: cfg} +} - return s +func verifyStatus(t *testing.T, s *Server, st status) { + for i := 5; i < 500; i+=50 { + if s.getStatus() == st { + break + } + + // Sleep incrementally ~2s in total + time.Sleep(time.Duration(i) * time.Millisecond) + } + + require.Equal(t, s.getStatus(), st) } # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1626701357 0 # Mon Jul 19 13:29:17 2021 +0000 # Node ID 257a87a032b82d016afbcd37d34e19cd1524bab1 # Parent a40d5d811efa26be2600db894127d84e008eee0e # Parent c9a651a976232ad89780083dcaf03b1e249692bf Merge branch 'id-kubernetes-probes' into 'main' Provide liveness and readiness probes See merge request gitlab-org/gitlab-shell!494 diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -76,6 +76,7 @@ monitoring.Start( monitoring.WithListenerAddress(cfg.Server.WebListen), monitoring.WithBuildInformation(Version, BuildTime), + monitoring.WithServeMux(server.MonitoringServeMux()), ), ) }() diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -26,7 +26,9 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` } @@ -72,6 +74,8 @@ WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, GracePeriodSeconds: 10, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,6 +10,7 @@ "strconv" "time" "sync" + "net/http" log "github.com/sirupsen/logrus" @@ -21,10 +22,20 @@ "gitlab.com/gitlab-org/labkit/correlation" ) +type status int + +const( + StatusStarting status = iota + StatusReady + StatusOnShutdown + StatusClosed +) + type Server struct { Config *config.Config - onShutdown bool + status status + statusMu sync.Mutex wg sync.WaitGroup listener net.Listener } @@ -43,11 +54,29 @@ return nil } - s.onShutdown = true + s.changeStatus(StatusOnShutdown) return s.listener.Close() } +func (s *Server) MonitoringServeMux() *http.ServeMux { + mux := http.NewServeMux() + + mux.HandleFunc(s.Config.Server.ReadinessProbe, func(w http.ResponseWriter, r *http.Request) { + if s.getStatus() == StatusReady { + w.WriteHeader(http.StatusOK) + } else { + w.WriteHeader(http.StatusServiceUnavailable) + } + }) + + mux.HandleFunc(s.Config.Server.LivenessProbe, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + + return mux +} + func (s *Server) listen() error { sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { @@ -73,10 +102,12 @@ return err } + s.changeStatus(StatusReady) + for { nconn, err := s.listener.Accept() if err != nil { - if s.onShutdown { + if s.getStatus() == StatusOnShutdown { break } @@ -90,9 +121,24 @@ s.wg.Wait() + s.changeStatus(StatusClosed) + return nil } +func (s *Server) changeStatus(st status) { + s.statusMu.Lock() + s.status = st + s.statusMu.Unlock() +} + +func (s *Server) getStatus() status { + s.statusMu.Lock() + defer s.statusMu.Unlock() + + return s.status +} + func (s *Server) initConfig(ctx context.Context) (*ssh.ServerConfig, error) { authorizedKeysClient, err := authorizedkeys.NewClient(s.Config) if err != nil { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -4,6 +4,8 @@ "testing" "context" "path" + "net/http/httptest" + "time" "github.com/stretchr/testify/require" @@ -17,18 +19,55 @@ func TestShutdown(t *testing.T) { s := setupServer(t) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() - done := make(chan bool, 1) - go func() { - require.NoError(t, s.serve(ctx)) - done <- true - }() + verifyStatus(t, s, StatusReady) + + s.wg.Add(1) require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusOnShutdown) - require.True(t, <-done, "the accepting loop must be interrupted") + s.wg.Done() + + verifyStatus(t, s, StatusClosed) +} + +func TestReadinessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + + require.Equal(t, StatusStarting, s.getStatus()) + + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/start", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) + + s.changeStatus(StatusReady) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) + + s.changeStatus(StatusOnShutdown) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) +} + +func TestLivenessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/health", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) } func setupServer(t *testing.T) *Server { @@ -42,8 +81,18 @@ cfg := &config.Config{RootDir: "/tmp", GitlabUrl: url, Server: srvCfg} - s := &Server{Config: cfg} - require.NoError(t, s.listen()) + return &Server{Config: cfg} +} - return s +func verifyStatus(t *testing.T, s *Server, st status) { + for i := 5; i < 500; i+=50 { + if s.getStatus() == st { + break + } + + // Sleep incrementally ~2s in total + time.Sleep(time.Duration(i) * time.Millisecond) + } + + require.Equal(t, s.getStatus(), st) } # HG changeset patch # User Igor <iwiedler@gitlab.com> # Date 1626793946 0 # Tue Jul 20 15:12:26 2021 +0000 # Node ID c30b94f8fc7a2289775e8ea552be684138ba4ec8 # Parent 257a87a032b82d016afbcd37d34e19cd1524bab1 Add tracing instrumentation to http client diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -14,6 +14,7 @@ log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/tracing" ) const ( @@ -85,7 +86,7 @@ } c := &http.Client{ - Transport: correlation.NewInstrumentedRoundTripper(transport), + Transport: correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(transport)), Timeout: readTimeout(readTimeoutSeconds), } # HG changeset patch # User Igor Wiedler <iwiedler@gitlab.com> # Date 1626798262 -7200 # Tue Jul 20 18:24:22 2021 +0200 # Node ID 496c683df4ed7cca478a635a5c65628201a996eb # Parent c30b94f8fc7a2289775e8ea552be684138ba4ec8 remove tracing.NewRoundTripper from internal/Config, now that NewHTTPClient already includes it diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -10,7 +10,6 @@ "sync" "time" - "gitlab.com/gitlab-org/labkit/tracing" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -73,9 +72,9 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ReadinessProbe: "/start", - LivenessProbe: "/health", + GracePeriodSeconds: 10, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -96,7 +95,7 @@ func (c *Config) HttpClient() *client.HttpClient { c.httpClientOnce.Do(func() { - client := client.NewHTTPClient( + c.httpClient = client.NewHTTPClient( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, @@ -104,11 +103,6 @@ c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, ) - - tr := client.Transport - client.Transport = tracing.NewRoundTripper(tr) - - c.httpClient = client }) return c.httpClient # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1626798669 0 # Tue Jul 20 16:31:09 2021 +0000 # Node ID 66984f720ad0593eed17c66ac852cff1a03dae76 # Parent 257a87a032b82d016afbcd37d34e19cd1524bab1 # Parent 496c683df4ed7cca478a635a5c65628201a996eb Merge branch 'igorwwwwwwwwwwwwwwwwwwww-main-patch-84756' into 'main' Add tracing instrumentation to http client See merge request gitlab-org/gitlab-shell!495 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -14,6 +14,7 @@ log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/tracing" ) const ( @@ -85,7 +86,7 @@ } c := &http.Client{ - Transport: correlation.NewInstrumentedRoundTripper(transport), + Transport: correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(transport)), Timeout: readTimeout(readTimeoutSeconds), } diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -10,7 +10,6 @@ "sync" "time" - "gitlab.com/gitlab-org/labkit/tracing" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -73,9 +72,9 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ReadinessProbe: "/start", - LivenessProbe: "/health", + GracePeriodSeconds: 10, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -96,7 +95,7 @@ func (c *Config) HttpClient() *client.HttpClient { c.httpClientOnce.Do(func() { - client := client.NewHTTPClient( + c.httpClient = client.NewHTTPClient( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, @@ -104,11 +103,6 @@ c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, ) - - tr := client.Transport - client.Transport = tracing.NewRoundTripper(tr) - - c.httpClient = client }) return c.httpClient # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1626855840 -10800 # Wed Jul 21 11:24:00 2021 +0300 # Node ID 485cf435129a7f60571720785cf4944ac4aa3d6c # Parent 66984f720ad0593eed17c66ac852cff1a03dae76 Prometheus metrics for HTTP requests A RoundTripper for tracking the duration of an http request is introduced diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -10,9 +10,11 @@ "sync" "time" + "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) const ( @@ -95,7 +97,7 @@ func (c *Config) HttpClient() *client.HttpClient { c.httpClientOnce.Do(func() { - c.httpClient = client.NewHTTPClient( + client := client.NewHTTPClient( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, @@ -103,6 +105,12 @@ c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, ) + + tr := client.Transport + client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) + + + c.httpClient = client }) return c.httpClient diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -5,8 +5,10 @@ "testing" "github.com/stretchr/testify/require" + "github.com/prometheus/client_golang/prometheus" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" ) func TestConfigApplyGlobalState(t *testing.T) { @@ -22,3 +24,27 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } + +func TestHttpClient(t *testing.T) { + url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) + + config := &Config{GitlabUrl: url} + client := config.HttpClient() + + _, err := client.Get("http://host.com/path") + require.NoError(t, err) + + ms, err := prometheus.DefaultGatherer.Gather() + require.NoError(t, err) + + lastMetric := ms[0] + require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") + + labels := lastMetric.GetMetric()[0].Label + + require.Equal(t, "code", labels[0].GetName()) + require.Equal(t, "404", labels[0].GetValue()) + + require.Equal(t, "method", labels[1].GetName()) + require.Equal(t, "get", labels[1].GetValue()) +} diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go new file mode 100644 --- /dev/null +++ b/internal/metrics/metrics.go @@ -0,0 +1,63 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +const ( + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" +) + +var ( + SshdConnectionDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "connection_duration_seconds", + Help: "A histogram of latencies for connections to gitlab-shell sshd.", + Buckets: []float64{ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ + }, + }, + ) + + SshdHitMaxSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "concurrent_limited_sessions_total", + Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", + }, + ) + + HttpRequestDuration = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: "request_seconds", + Help: "A histogram of latencies for gitlab-shell http requests", + Buckets: []float64{ + 0.01, /* 10ms */ + 0.05, /* 50ms */ + 0.1, /* 100ms */ + 0.25, /* 250ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ + 10.0, /* 10s */ + }, + }, + []string{"code", "method"}, + ) +) diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -4,47 +4,11 @@ "context" "time" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" -) -const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" -) - -var ( - sshdConnectionDuration = promauto.NewHistogram( - prometheus.HistogramOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", - Help: "A histogram of latencies for connections to gitlab-shell sshd.", - Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ - }, - }, - ) - - sshdHitMaxSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", - Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", - }, - ) + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) type connection struct { @@ -64,7 +28,7 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - defer sshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { if newChannel.ChannelType() != "session" { @@ -73,7 +37,7 @@ } if !c.concurrentSessions.TryAcquire(1) { newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") - sshdHitMaxSessions.Inc() + metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1626871593 0 # Wed Jul 21 12:46:33 2021 +0000 # Node ID 23032cdc93aadbbdd6ded07c42637c58cfac13d2 # Parent 66984f720ad0593eed17c66ac852cff1a03dae76 # Parent 485cf435129a7f60571720785cf4944ac4aa3d6c Merge branch 'id-prometheus-metrics-for-http' into 'main' Prometheus metrics for HTTP requests See merge request gitlab-org/gitlab-shell!496 diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -10,9 +10,11 @@ "sync" "time" + "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) const ( @@ -95,7 +97,7 @@ func (c *Config) HttpClient() *client.HttpClient { c.httpClientOnce.Do(func() { - c.httpClient = client.NewHTTPClient( + client := client.NewHTTPClient( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, @@ -103,6 +105,12 @@ c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, ) + + tr := client.Transport + client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) + + + c.httpClient = client }) return c.httpClient diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -5,8 +5,10 @@ "testing" "github.com/stretchr/testify/require" + "github.com/prometheus/client_golang/prometheus" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" ) func TestConfigApplyGlobalState(t *testing.T) { @@ -22,3 +24,27 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } + +func TestHttpClient(t *testing.T) { + url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) + + config := &Config{GitlabUrl: url} + client := config.HttpClient() + + _, err := client.Get("http://host.com/path") + require.NoError(t, err) + + ms, err := prometheus.DefaultGatherer.Gather() + require.NoError(t, err) + + lastMetric := ms[0] + require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") + + labels := lastMetric.GetMetric()[0].Label + + require.Equal(t, "code", labels[0].GetName()) + require.Equal(t, "404", labels[0].GetValue()) + + require.Equal(t, "method", labels[1].GetName()) + require.Equal(t, "get", labels[1].GetValue()) +} diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go new file mode 100644 --- /dev/null +++ b/internal/metrics/metrics.go @@ -0,0 +1,63 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +const ( + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" +) + +var ( + SshdConnectionDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "connection_duration_seconds", + Help: "A histogram of latencies for connections to gitlab-shell sshd.", + Buckets: []float64{ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ + }, + }, + ) + + SshdHitMaxSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "concurrent_limited_sessions_total", + Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", + }, + ) + + HttpRequestDuration = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: "request_seconds", + Help: "A histogram of latencies for gitlab-shell http requests", + Buckets: []float64{ + 0.01, /* 10ms */ + 0.05, /* 50ms */ + 0.1, /* 100ms */ + 0.25, /* 250ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ + 10.0, /* 10s */ + }, + }, + []string{"code", "method"}, + ) +) diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -4,47 +4,11 @@ "context" "time" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" -) -const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" -) - -var ( - sshdConnectionDuration = promauto.NewHistogram( - prometheus.HistogramOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", - Help: "A histogram of latencies for connections to gitlab-shell sshd.", - Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ - }, - }, - ) - - sshdHitMaxSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", - Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", - }, - ) + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) type connection struct { @@ -64,7 +28,7 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - defer sshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { if newChannel.ChannelType() != "session" { @@ -73,7 +37,7 @@ } if !c.concurrentSessions.TryAcquire(1) { newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") - sshdHitMaxSessions.Inc() + metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1626874353 -3600 # Wed Jul 21 14:32:33 2021 +0100 # Node ID 293e15251974026e8214c688c3d5c114691cdf86 # Parent 23032cdc93aadbbdd6ded07c42637c58cfac13d2 Unit tests for internal/sshd/connection.go diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "testing" "github.com/stretchr/testify/require" @@ -9,22 +10,31 @@ ) type rejectCall struct { - reason ssh.RejectionReason + reason ssh.RejectionReason message string } type fakeNewChannel struct { channelType string extraData []byte + acceptErr error + + acceptCh chan struct{} rejectCh chan rejectCall } func (f *fakeNewChannel) Accept() (ssh.Channel, <-chan *ssh.Request, error) { - return nil, nil, nil + if f.acceptCh != nil { + f.acceptCh <- struct{}{} + } + + return nil, nil, f.acceptErr } func (f *fakeNewChannel) Reject(reason ssh.RejectionReason, message string) error { - f.rejectCh <- rejectCall{reason: reason, message: message} + if f.rejectCh != nil { + f.rejectCh <- rejectCall{reason: reason, message: message} + } return nil } @@ -63,7 +73,9 @@ } func TestUnknownChannelType(t *testing.T) { - rejectCh := make(chan rejectCall, 1) + rejectCh := make(chan rejectCall) + defer close(rejectCh) + newChannel := &fakeNewChannel{channelType: "unknown session", rejectCh: rejectCh} conn, chans := setup(1, newChannel) @@ -72,8 +84,64 @@ }() rejectionData := <-rejectCh - close(rejectCh) expectedRejection := rejectCall{reason: ssh.UnknownChannelType, message: "unknown channel type"} require.Equal(t, expectedRejection, rejectionData) } + +func TestTooManySessions(t *testing.T) { + rejectCh := make(chan rejectCall) + defer close(rejectCh) + + newChannel := &fakeNewChannel{channelType: "session", rejectCh: rejectCh} + conn, chans := setup(1, newChannel) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + <-ctx.Done() // Keep the accepted channel open until the end of the test + }) + }() + + chans <- newChannel + require.Equal(t, <-rejectCh, rejectCall{reason: ssh.ResourceShortage, message: "too many concurrent sessions"}) +} + +func TestAcceptSessionSucceeds(t *testing.T) { + newChannel := &fakeNewChannel{channelType: "session"} + conn, chans := setup(1, newChannel) + + channelHandled := false + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + close(chans) + }) + + require.True(t, channelHandled) +} + +func TestAcceptSessionFails(t *testing.T) { + acceptCh := make(chan struct{}) + defer close(acceptCh) + + acceptErr := errors.New("some failure") + newChannel := &fakeNewChannel{channelType: "session", acceptCh: acceptCh, acceptErr: acceptErr} + conn, chans := setup(1, newChannel) + + channelHandled := false + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + }) + }() + + require.Equal(t, <-acceptCh, struct{}{}) + + // Waits until the number of sessions is back to 0, since we can only have 1 + conn.concurrentSessions.Acquire(context.Background(), 1) + defer conn.concurrentSessions.Release(1) + + require.False(t, channelHandled) +} # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1626948958 0 # Thu Jul 22 10:15:58 2021 +0000 # Node ID 687e8fd1fae0939addf3d3297a25b2903e33c669 # Parent 23032cdc93aadbbdd6ded07c42637c58cfac13d2 # Parent 293e15251974026e8214c688c3d5c114691cdf86 Merge branch '521-test-connection-dot-go' into 'main' Unit tests for internal/sshd/connection.go Closes #521 See merge request gitlab-org/gitlab-shell!497 diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "testing" "github.com/stretchr/testify/require" @@ -9,22 +10,31 @@ ) type rejectCall struct { - reason ssh.RejectionReason + reason ssh.RejectionReason message string } type fakeNewChannel struct { channelType string extraData []byte + acceptErr error + + acceptCh chan struct{} rejectCh chan rejectCall } func (f *fakeNewChannel) Accept() (ssh.Channel, <-chan *ssh.Request, error) { - return nil, nil, nil + if f.acceptCh != nil { + f.acceptCh <- struct{}{} + } + + return nil, nil, f.acceptErr } func (f *fakeNewChannel) Reject(reason ssh.RejectionReason, message string) error { - f.rejectCh <- rejectCall{reason: reason, message: message} + if f.rejectCh != nil { + f.rejectCh <- rejectCall{reason: reason, message: message} + } return nil } @@ -63,7 +73,9 @@ } func TestUnknownChannelType(t *testing.T) { - rejectCh := make(chan rejectCall, 1) + rejectCh := make(chan rejectCall) + defer close(rejectCh) + newChannel := &fakeNewChannel{channelType: "unknown session", rejectCh: rejectCh} conn, chans := setup(1, newChannel) @@ -72,8 +84,64 @@ }() rejectionData := <-rejectCh - close(rejectCh) expectedRejection := rejectCall{reason: ssh.UnknownChannelType, message: "unknown channel type"} require.Equal(t, expectedRejection, rejectionData) } + +func TestTooManySessions(t *testing.T) { + rejectCh := make(chan rejectCall) + defer close(rejectCh) + + newChannel := &fakeNewChannel{channelType: "session", rejectCh: rejectCh} + conn, chans := setup(1, newChannel) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + <-ctx.Done() // Keep the accepted channel open until the end of the test + }) + }() + + chans <- newChannel + require.Equal(t, <-rejectCh, rejectCall{reason: ssh.ResourceShortage, message: "too many concurrent sessions"}) +} + +func TestAcceptSessionSucceeds(t *testing.T) { + newChannel := &fakeNewChannel{channelType: "session"} + conn, chans := setup(1, newChannel) + + channelHandled := false + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + close(chans) + }) + + require.True(t, channelHandled) +} + +func TestAcceptSessionFails(t *testing.T) { + acceptCh := make(chan struct{}) + defer close(acceptCh) + + acceptErr := errors.New("some failure") + newChannel := &fakeNewChannel{channelType: "session", acceptCh: acceptCh, acceptErr: acceptErr} + conn, chans := setup(1, newChannel) + + channelHandled := false + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + }) + }() + + require.Equal(t, <-acceptCh, struct{}{}) + + // Waits until the number of sessions is back to 0, since we can only have 1 + conn.concurrentSessions.Acquire(context.Background(), 1) + defer conn.concurrentSessions.Release(1) + + require.False(t, channelHandled) +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1626965938 -10800 # Thu Jul 22 17:58:58 2021 +0300 # Node ID c44839d4d44f0dabe53dba9cc7db0b4c12426f2e # Parent 23032cdc93aadbbdd6ded07c42637c58cfac13d2 Switch to labkit/log for logging functionality diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,9 +11,7 @@ "strings" "time" - "gitlab.com/gitlab-org/labkit/correlation" - - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -71,12 +69,12 @@ return path } -func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, string, error) { +func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { jsonData, err := json.Marshal(data) if err != nil { - return nil, "", err + return nil, err } jsonReader = bytes.NewReader(jsonData) @@ -84,12 +82,10 @@ request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) if err != nil { - return nil, "", err + return nil, err } - correlationID := correlation.ExtractFromContext(ctx) - - return request, correlationID, nil + return request, nil } func parseError(resp *http.Response) error { @@ -116,7 +112,7 @@ } func (c *GitlabNetClient) DoRequest(ctx context.Context, method, path string, data interface{}) (*http.Response, error) { - request, correlationID, err := newRequest(ctx, method, c.httpClient.Host, path, data) + request, err := newRequest(ctx, method, c.httpClient.Host, path, data) if err != nil { return nil, err } @@ -136,12 +132,11 @@ start := time.Now() response, err := c.httpClient.Do(request) fields := log.Fields{ - "correlation_id": correlationID, "method": method, "url": request.URL.String(), "duration_ms": time.Since(start) / time.Millisecond, } - logger := log.WithFields(fields) + logger := log.WithContextFields(ctx, fields) if err != nil { logger.WithError(err).Error("Internal API unreachable") diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -12,9 +12,9 @@ "strings" "time" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" + "gitlab.com/gitlab-org/labkit/log" ) const ( diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -229,7 +229,7 @@ t.Cleanup(func() { pw.Close() }) scanner := bufio.NewScanner(pr) - extractor := regexp.MustCompile(`msg="Listening on ([0-9a-f\[\]\.:]+)"`) + extractor := regexp.MustCompile(`tcp_address="([0-9a-f\[\]\.:]+)"`) ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, sshdPath, "-config-dir", dir) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -8,13 +8,13 @@ "syscall" "time" - log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/labkit/monitoring" + "gitlab.com/gitlab-org/labkit/log" ) var ( @@ -49,15 +49,16 @@ var err error cfg, err = config.NewFromDir(*configDir) if err != nil { - log.Fatalf("failed to load configuration from specified directory: %v", err) + log.WithError(err).Fatal("failed to load configuration from specified directory") } } overrideConfigFromEnvironment(cfg) if err := cfg.IsSane(); err != nil { if *configDir == "" { - log.Warn("note: no config-dir provided, using only environment variables") + log.WithError(err).Fatal("no config-dir provided, using only environment variables") + } else { + log.WithError(err).Fatal("configuration error") } - log.Fatalf("configuration error: %v", err) } cfg.ApplyGlobalState() @@ -72,13 +73,13 @@ // Startup monitoring endpoint. if cfg.Server.WebListen != "" { go func() { - log.Fatal( - monitoring.Start( - monitoring.WithListenerAddress(cfg.Server.WebListen), - monitoring.WithBuildInformation(Version, BuildTime), - monitoring.WithServeMux(server.MonitoringServeMux()), - ), + err := monitoring.Start( + monitoring.WithListenerAddress(cfg.Server.WebListen), + monitoring.WithBuildInformation(Version, BuildTime), + monitoring.WithServeMux(server.MonitoringServeMux()), ) + + log.WithError(err).Fatal("monitoring service raised an error") }() } @@ -92,7 +93,7 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Infof("Shutdown initiated") + log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() @@ -103,6 +104,6 @@ }() if err := server.ListenAndServe(ctx); err != nil { - log.Fatalf("Failed to start GitLab built-in sshd: %v", err) + log.WithError(err).Fatal("Failed to start GitLab built-in sshd") } } diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -10,12 +10,13 @@ "io" "net/http" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + + "gitlab.com/gitlab-org/labkit/log" ) type Request struct { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -8,19 +8,20 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" ) // GitalyHandlerFunc implementations are responsible for making @@ -75,7 +76,6 @@ func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { fields := log.Fields{ "command": gc.ServiceName, - "correlation_id": correlation.ExtractFromContext(ctx), "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, "user_id": response.UserId, @@ -86,7 +86,7 @@ "gl_key_id": response.KeyId, } - log.WithFields(fields).Info("executing git command") + log.WithContextFields(ctx, fields).Info("executing git command") } func withOutgoingMetadata(ctx context.Context, features map[string]string) context.Context { @@ -108,9 +108,9 @@ serviceName := correlation.ExtractClientNameFromContext(ctx) if serviceName == "" { - log.Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + serviceName = "gitlab-shell-unknown" - serviceName = "gitlab-shell-unknown" + log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -4,11 +4,12 @@ "context" "time" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + + "gitlab.com/gitlab-org/labkit/log" ) type connection struct { @@ -42,7 +43,7 @@ } channel, requests, err := newChannel.Accept() if err != nil { - log.Infof("Could not accept channel: %v", err) + log.WithError(err).Info("could not accept channel") c.concurrentSessions.Release(1) continue } @@ -53,7 +54,7 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling session from %s: recovered: %#+v", c.remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) } }() diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,13 +12,13 @@ "sync" "net/http" - log "github.com/sirupsen/logrus" - "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/correlation" ) @@ -89,7 +89,7 @@ log.Info("Proxy protocol is enabled") } - log.Infof("Listening on %v", sshListener.Addr().String()) + log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") s.listener = sshListener @@ -111,7 +111,7 @@ break } - log.Warnf("Failed to accept connection: %v\n", err) + log.WithError(err).Warn("Failed to accept connection") continue } @@ -173,12 +173,12 @@ for _, filename := range s.Config.Server.HostKeyFiles { keyRaw, err := ioutil.ReadFile(filename) if err != nil { - log.Warnf("Failed to read host key %v: %v", filename, err) + log.WithError(err).Warnf("Failed to read host key %v", filename) continue } key, err := ssh.ParsePrivateKey(keyRaw) if err != nil { - log.Warnf("Failed to parse host key %v: %v", filename, err) + log.WithError(err).Warnf("Failed to parse host key %v", filename) continue } loadedHostKeys++ @@ -201,7 +201,7 @@ // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling connection from %s: recovered: %#+v", remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) } }() @@ -210,7 +210,7 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, sshCfg) if err != nil { - log.Infof("Failed to initialize SSH connection: %v", err) + log.WithError(err).Info("Failed to initialize SSH connection") return } # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1627014829 0 # Fri Jul 23 04:33:49 2021 +0000 # Node ID 74469468b5ac973a2bc32ab92753eb218e6ad779 # Parent 687e8fd1fae0939addf3d3297a25b2903e33c669 # Parent c44839d4d44f0dabe53dba9cc7db0b4c12426f2e Merge branch 'id-switch-logging-to-labkit' into 'main' Switch to labkit/log for logging functionality See merge request gitlab-org/gitlab-shell!498 diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,9 +11,7 @@ "strings" "time" - "gitlab.com/gitlab-org/labkit/correlation" - - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -71,12 +69,12 @@ return path } -func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, string, error) { +func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { jsonData, err := json.Marshal(data) if err != nil { - return nil, "", err + return nil, err } jsonReader = bytes.NewReader(jsonData) @@ -84,12 +82,10 @@ request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) if err != nil { - return nil, "", err + return nil, err } - correlationID := correlation.ExtractFromContext(ctx) - - return request, correlationID, nil + return request, nil } func parseError(resp *http.Response) error { @@ -116,7 +112,7 @@ } func (c *GitlabNetClient) DoRequest(ctx context.Context, method, path string, data interface{}) (*http.Response, error) { - request, correlationID, err := newRequest(ctx, method, c.httpClient.Host, path, data) + request, err := newRequest(ctx, method, c.httpClient.Host, path, data) if err != nil { return nil, err } @@ -136,12 +132,11 @@ start := time.Now() response, err := c.httpClient.Do(request) fields := log.Fields{ - "correlation_id": correlationID, "method": method, "url": request.URL.String(), "duration_ms": time.Since(start) / time.Millisecond, } - logger := log.WithFields(fields) + logger := log.WithContextFields(ctx, fields) if err != nil { logger.WithError(err).Error("Internal API unreachable") diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -12,9 +12,9 @@ "strings" "time" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" + "gitlab.com/gitlab-org/labkit/log" ) const ( diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -229,7 +229,7 @@ t.Cleanup(func() { pw.Close() }) scanner := bufio.NewScanner(pr) - extractor := regexp.MustCompile(`msg="Listening on ([0-9a-f\[\]\.:]+)"`) + extractor := regexp.MustCompile(`tcp_address="([0-9a-f\[\]\.:]+)"`) ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, sshdPath, "-config-dir", dir) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -8,13 +8,13 @@ "syscall" "time" - log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/labkit/monitoring" + "gitlab.com/gitlab-org/labkit/log" ) var ( @@ -49,15 +49,16 @@ var err error cfg, err = config.NewFromDir(*configDir) if err != nil { - log.Fatalf("failed to load configuration from specified directory: %v", err) + log.WithError(err).Fatal("failed to load configuration from specified directory") } } overrideConfigFromEnvironment(cfg) if err := cfg.IsSane(); err != nil { if *configDir == "" { - log.Warn("note: no config-dir provided, using only environment variables") + log.WithError(err).Fatal("no config-dir provided, using only environment variables") + } else { + log.WithError(err).Fatal("configuration error") } - log.Fatalf("configuration error: %v", err) } cfg.ApplyGlobalState() @@ -72,13 +73,13 @@ // Startup monitoring endpoint. if cfg.Server.WebListen != "" { go func() { - log.Fatal( - monitoring.Start( - monitoring.WithListenerAddress(cfg.Server.WebListen), - monitoring.WithBuildInformation(Version, BuildTime), - monitoring.WithServeMux(server.MonitoringServeMux()), - ), + err := monitoring.Start( + monitoring.WithListenerAddress(cfg.Server.WebListen), + monitoring.WithBuildInformation(Version, BuildTime), + monitoring.WithServeMux(server.MonitoringServeMux()), ) + + log.WithError(err).Fatal("monitoring service raised an error") }() } @@ -92,7 +93,7 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Infof("Shutdown initiated") + log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() @@ -103,6 +104,6 @@ }() if err := server.ListenAndServe(ctx); err != nil { - log.Fatalf("Failed to start GitLab built-in sshd: %v", err) + log.WithError(err).Fatal("Failed to start GitLab built-in sshd") } } diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -10,12 +10,13 @@ "io" "net/http" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + + "gitlab.com/gitlab-org/labkit/log" ) type Request struct { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -8,19 +8,20 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" ) // GitalyHandlerFunc implementations are responsible for making @@ -75,7 +76,6 @@ func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { fields := log.Fields{ "command": gc.ServiceName, - "correlation_id": correlation.ExtractFromContext(ctx), "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, "user_id": response.UserId, @@ -86,7 +86,7 @@ "gl_key_id": response.KeyId, } - log.WithFields(fields).Info("executing git command") + log.WithContextFields(ctx, fields).Info("executing git command") } func withOutgoingMetadata(ctx context.Context, features map[string]string) context.Context { @@ -108,9 +108,9 @@ serviceName := correlation.ExtractClientNameFromContext(ctx) if serviceName == "" { - log.Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + serviceName = "gitlab-shell-unknown" - serviceName = "gitlab-shell-unknown" + log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -4,11 +4,12 @@ "context" "time" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + + "gitlab.com/gitlab-org/labkit/log" ) type connection struct { @@ -42,7 +43,7 @@ } channel, requests, err := newChannel.Accept() if err != nil { - log.Infof("Could not accept channel: %v", err) + log.WithError(err).Info("could not accept channel") c.concurrentSessions.Release(1) continue } @@ -53,7 +54,7 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling session from %s: recovered: %#+v", c.remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) } }() diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,13 +12,13 @@ "sync" "net/http" - log "github.com/sirupsen/logrus" - "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/correlation" ) @@ -89,7 +89,7 @@ log.Info("Proxy protocol is enabled") } - log.Infof("Listening on %v", sshListener.Addr().String()) + log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") s.listener = sshListener @@ -111,7 +111,7 @@ break } - log.Warnf("Failed to accept connection: %v\n", err) + log.WithError(err).Warn("Failed to accept connection") continue } @@ -173,12 +173,12 @@ for _, filename := range s.Config.Server.HostKeyFiles { keyRaw, err := ioutil.ReadFile(filename) if err != nil { - log.Warnf("Failed to read host key %v: %v", filename, err) + log.WithError(err).Warnf("Failed to read host key %v", filename) continue } key, err := ssh.ParsePrivateKey(keyRaw) if err != nil { - log.Warnf("Failed to parse host key %v: %v", filename, err) + log.WithError(err).Warnf("Failed to parse host key %v", filename) continue } loadedHostKeys++ @@ -201,7 +201,7 @@ // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling connection from %s: recovered: %#+v", remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) } }() @@ -210,7 +210,7 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, sshCfg) if err != nil { - log.Infof("Failed to initialize SSH connection: %v", err) + log.WithError(err).Info("Failed to initialize SSH connection") return } # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1627341670 25200 # Mon Jul 26 16:21:10 2021 -0700 # Node ID 4aa911586a1bdb878f30a4f2da1a80ea9f3f5934 # Parent 74469468b5ac973a2bc32ab92753eb218e6ad779 Make gofmt check fail if there are any matching files gofmt doesn't return an exit code 1 if there are matching files: https://github.com/golang/go/issues/24230 To fix this, use the same trick we use in Workhorse to parse output. Also add a `make fmt` step to format all the code properly. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -13,7 +13,10 @@ verify: verify_golang verify_golang: - gofmt -s -l $(GO_SOURCES) + gofmt -s -l $(GO_SOURCES) | awk '{ print } END { if (NR > 0) { print "Please run make fmt"; exit 1 } }' + +fmt: + gofmt -w -s $(GO_SOURCES) test: test_ruby test_golang # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1627341754 25200 # Mon Jul 26 16:22:34 2021 -0700 # Node ID 445b4494c1da824e2d9c9488845c1fad1b42353f # Parent 4aa911586a1bdb878f30a4f2da1a80ea9f3f5934 Fix formatting via make fmt diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -132,9 +132,9 @@ start := time.Now() response, err := c.httpClient.Do(request) fields := log.Fields{ - "method": method, - "url": request.URL.String(), - "duration_ms": time.Since(start) / time.Millisecond, + "method": method, + "url": request.URL.String(), + "duration_ms": time.Since(start) / time.Millisecond, } logger := log.WithContextFields(ctx, fields) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -13,8 +13,8 @@ "time" "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/tracing" - "gitlab.com/gitlab-org/labkit/log" ) const ( diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -1,10 +1,10 @@ package main import ( + "context" "flag" "os" "os/signal" - "context" "syscall" "time" @@ -13,8 +13,8 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/logger" "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" - "gitlab.com/gitlab-org/labkit/log" ) var ( diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -109,7 +109,6 @@ tr := client.Transport client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) - c.httpClient = client }) diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -4,11 +4,11 @@ "os" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" - "github.com/prometheus/client_golang/prometheus" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" ) func TestConfigApplyGlobalState(t *testing.T) { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -18,10 +18,10 @@ gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" - "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/labkit/log" ) // GitalyHandlerFunc implementations are responsible for making diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -7,10 +7,10 @@ "fmt" "io/ioutil" "net" + "net/http" "strconv" + "sync" "time" - "sync" - "net/http" "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" @@ -18,13 +18,13 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/labkit/correlation" ) type status int -const( +const ( StatusStarting status = iota StatusReady StatusOnShutdown @@ -34,9 +34,9 @@ type Server struct { Config *config.Config - status status + status status statusMu sync.Mutex - wg sync.WaitGroup + wg sync.WaitGroup listener net.Listener } @@ -71,7 +71,7 @@ }) mux.HandleFunc(s.Config.Server.LivenessProbe, func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) + w.WriteHeader(http.StatusOK) }) return mux @@ -191,7 +191,6 @@ return sshCfg, nil } - func (s *Server) handleConn(ctx context.Context, sshCfg *ssh.ServerConfig, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -1,10 +1,10 @@ package sshd import ( + "context" + "net/http/httptest" + "path" "testing" - "context" - "path" - "net/http/httptest" "time" "github.com/stretchr/testify/require" @@ -75,7 +75,7 @@ url := testserver.StartSocketHttpServer(t, []testserver.TestRequestHandler{}) srvCfg := config.ServerConfig{ - Listen: serverUrl, + Listen: serverUrl, HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, } @@ -85,7 +85,7 @@ } func verifyStatus(t *testing.T, s *Server, st status) { - for i := 5; i < 500; i+=50 { + for i := 5; i < 500; i += 50 { if s.getStatus() == st { break } diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -6,8 +6,8 @@ "os" "path" "runtime" + "testing" "time" - "testing" "github.com/otiai10/copy" "github.com/sirupsen/logrus" # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1627378502 0 # Tue Jul 27 09:35:02 2021 +0000 # Node ID da2664071061f9e28db0aa6287b3d1409d730d68 # Parent 74469468b5ac973a2bc32ab92753eb218e6ad779 # Parent 445b4494c1da824e2d9c9488845c1fad1b42353f Merge branch 'sh-fix-gofmt' into 'main' Make gofmt check fail if there are any matching files See merge request gitlab-org/gitlab-shell!500 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -13,7 +13,10 @@ verify: verify_golang verify_golang: - gofmt -s -l $(GO_SOURCES) + gofmt -s -l $(GO_SOURCES) | awk '{ print } END { if (NR > 0) { print "Please run make fmt"; exit 1 } }' + +fmt: + gofmt -w -s $(GO_SOURCES) test: test_ruby test_golang diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -132,9 +132,9 @@ start := time.Now() response, err := c.httpClient.Do(request) fields := log.Fields{ - "method": method, - "url": request.URL.String(), - "duration_ms": time.Since(start) / time.Millisecond, + "method": method, + "url": request.URL.String(), + "duration_ms": time.Since(start) / time.Millisecond, } logger := log.WithContextFields(ctx, fields) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -13,8 +13,8 @@ "time" "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/tracing" - "gitlab.com/gitlab-org/labkit/log" ) const ( diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -1,10 +1,10 @@ package main import ( + "context" "flag" "os" "os/signal" - "context" "syscall" "time" @@ -13,8 +13,8 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/logger" "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" - "gitlab.com/gitlab-org/labkit/log" ) var ( diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -109,7 +109,6 @@ tr := client.Transport client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) - c.httpClient = client }) diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -4,11 +4,11 @@ "os" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" - "github.com/prometheus/client_golang/prometheus" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" ) func TestConfigApplyGlobalState(t *testing.T) { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -18,10 +18,10 @@ gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" - "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/labkit/log" ) // GitalyHandlerFunc implementations are responsible for making diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -7,10 +7,10 @@ "fmt" "io/ioutil" "net" + "net/http" "strconv" + "sync" "time" - "sync" - "net/http" "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" @@ -18,13 +18,13 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/labkit/correlation" ) type status int -const( +const ( StatusStarting status = iota StatusReady StatusOnShutdown @@ -34,9 +34,9 @@ type Server struct { Config *config.Config - status status + status status statusMu sync.Mutex - wg sync.WaitGroup + wg sync.WaitGroup listener net.Listener } @@ -71,7 +71,7 @@ }) mux.HandleFunc(s.Config.Server.LivenessProbe, func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) + w.WriteHeader(http.StatusOK) }) return mux @@ -191,7 +191,6 @@ return sshCfg, nil } - func (s *Server) handleConn(ctx context.Context, sshCfg *ssh.ServerConfig, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -1,10 +1,10 @@ package sshd import ( + "context" + "net/http/httptest" + "path" "testing" - "context" - "path" - "net/http/httptest" "time" "github.com/stretchr/testify/require" @@ -75,7 +75,7 @@ url := testserver.StartSocketHttpServer(t, []testserver.TestRequestHandler{}) srvCfg := config.ServerConfig{ - Listen: serverUrl, + Listen: serverUrl, HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, } @@ -85,7 +85,7 @@ } func verifyStatus(t *testing.T, s *Server, st status) { - for i := 5; i < 500; i+=50 { + for i := 5; i < 500; i += 50 { if s.getStatus() == st { break } diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -6,8 +6,8 @@ "os" "path" "runtime" + "testing" "time" - "testing" "github.com/otiai10/copy" "github.com/sirupsen/logrus" # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1627339379 25200 # Mon Jul 26 15:42:59 2021 -0700 # Node ID 0db8e97c4aa95ca224d2dbaae7a03917ed886c32 # Parent 74469468b5ac973a2bc32ab92753eb218e6ad779 Update go-proxyproto to v0.6.0 From https://github.com/pires/go-proxyproto/releases: Prevent potentially malicious client(s) from opening connections and not send the proxy protocol header, which could lead to DoS as the server would hold those socket descriptors open indefinitely, eventually running out of resources. The solution is to set a read deadline when waiting for the PROXY protocol header: https://github.com/pires/go-proxyproto/pull/74 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.5.0 + github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -505,8 +505,8 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pires/go-proxyproto v0.5.0 h1:A4Jv4ZCaV3AFJeGh5mGwkz4iuWUYMlQ7IoO/GTuSuLo= -github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= +github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1627340061 25200 # Mon Jul 26 15:54:21 2021 -0700 # Node ID 972fa21631f9058c9a028e65be82e07e385b4770 # Parent 0db8e97c4aa95ca224d2dbaae7a03917ed886c32 Set a 90-second timeout on proxy headers diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -7,10 +7,10 @@ "fmt" "io/ioutil" "net" + "net/http" "strconv" + "sync" "time" - "sync" - "net/http" "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" @@ -18,25 +18,26 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/labkit/correlation" ) type status int -const( +const ( StatusStarting status = iota StatusReady StatusOnShutdown StatusClosed + ProxyHeaderTimeout = 90 * time.Second ) type Server struct { Config *config.Config - status status + status status statusMu sync.Mutex - wg sync.WaitGroup + wg sync.WaitGroup listener net.Listener } @@ -71,7 +72,7 @@ }) mux.HandleFunc(s.Config.Server.LivenessProbe, func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) + w.WriteHeader(http.StatusOK) }) return mux @@ -84,7 +85,10 @@ } if s.Config.Server.ProxyProtocol { - sshListener = &proxyproto.Listener{Listener: sshListener} + sshListener = &proxyproto.Listener{ + Listener: sshListener, + ReadHeaderTimeout: ProxyHeaderTimeout, + } log.Info("Proxy protocol is enabled") } @@ -191,7 +195,6 @@ return sshCfg, nil } - func (s *Server) handleConn(ctx context.Context, sshCfg *ssh.ServerConfig, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1627378654 0 # Tue Jul 27 09:37:34 2021 +0000 # Node ID 4949e081af6690bc614873249604d13058084701 # Parent da2664071061f9e28db0aa6287b3d1409d730d68 # Parent 972fa21631f9058c9a028e65be82e07e385b4770 Merge branch 'sh-update-go-proxyproto' into 'main' Update go-proxyproto to v0.6.0 See merge request gitlab-org/gitlab-shell!499 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.5.0 + github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -505,8 +505,8 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pires/go-proxyproto v0.5.0 h1:A4Jv4ZCaV3AFJeGh5mGwkz4iuWUYMlQ7IoO/GTuSuLo= -github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= +github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -29,6 +29,7 @@ StatusReady StatusOnShutdown StatusClosed + ProxyHeaderTimeout = 90 * time.Second ) type Server struct { @@ -84,7 +85,10 @@ } if s.Config.Server.ProxyProtocol { - sshListener = &proxyproto.Listener{Listener: sshListener} + sshListener = &proxyproto.Listener{ + Listener: sshListener, + ReadHeaderTimeout: ProxyHeaderTimeout, + } log.Info("Proxy protocol is enabled") } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1627386765 -10800 # Tue Jul 27 14:52:45 2021 +0300 # Node ID a126ea2cb7555f1cf1e7bb5d53fee1486fe2ae2d # Parent 4949e081af6690bc614873249604d13058084701 Sshd: Log same correlation_id on auth keys diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -68,7 +68,10 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() - server := sshd.Server{Config: cfg} + server, err := sshd.NewServer(cfg) + if err != nil { + log.WithError(err).Fatal("Failed to start GitLab built-in sshd") + } // Startup monitoring endpoint. if cfg.Server.WebListen != "" { @@ -104,6 +107,6 @@ }() if err := server.ListenAndServe(ctx); err != nil { - log.WithError(err).Fatal("Failed to start GitLab built-in sshd") + log.WithError(err).Fatal("GitLab built-in sshd failed to listen for new connections") } } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -35,10 +35,40 @@ type Server struct { Config *config.Config - status status - statusMu sync.Mutex - wg sync.WaitGroup - listener net.Listener + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func NewServer(cfg *config.Config) (*Server, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := ioutil.ReadFile(filename) + if err != nil { + log.WithError(err).Warnf("Failed to read host key %v", filename) + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).Warnf("Failed to parse host key %v", filename) + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") + } + + return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil } func (s *Server) ListenAndServe(ctx context.Context) error { @@ -47,7 +77,9 @@ } defer s.listener.Close() - return s.serve(ctx) + s.serve(ctx) + + return nil } func (s *Server) Shutdown() error { @@ -100,12 +132,7 @@ return nil } -func (s *Server) serve(ctx context.Context) error { - sshCfg, err := s.initConfig(ctx) - if err != nil { - return err - } - +func (s *Server) serve(ctx context.Context) { s.changeStatus(StatusReady) for { @@ -120,14 +147,12 @@ } s.wg.Add(1) - go s.handleConn(ctx, sshCfg, nconn) + go s.handleConn(ctx, nconn) } s.wg.Wait() s.changeStatus(StatusClosed) - - return nil } func (s *Server) changeStatus(st status) { @@ -143,12 +168,7 @@ return s.status } -func (s *Server) initConfig(ctx context.Context) (*ssh.ServerConfig, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(s.Config) - if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) - } - +func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { sshCfg := &ssh.ServerConfig{ PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if conn.User() != s.Config.User { @@ -159,7 +179,7 @@ } ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - res, err := authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) if err != nil { return nil, err } @@ -173,29 +193,14 @@ }, } - var loadedHostKeys uint - for _, filename := range s.Config.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) - if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) - continue - } - loadedHostKeys++ + for _, key := range s.hostKeys { sshCfg.AddHostKey(key) } - if loadedHostKeys == 0 { - return nil, fmt.Errorf("No host keys could be loaded, aborting") - } - return sshCfg, nil + return sshCfg } -func (s *Server) handleConn(ctx context.Context, sshCfg *ssh.ServerConfig, nconn net.Conn) { +func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() @@ -211,7 +216,7 @@ ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() - sconn, chans, reqs, err := ssh.NewServerConn(nconn, sshCfg) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) if err != nil { log.WithError(err).Info("Failed to initialize SSH connection") return diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -2,37 +2,71 @@ import ( "context" + "fmt" + "io/ioutil" + "net/http" "net/http/httptest" "path" "testing" "time" "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) -const serverUrl = "127.0.0.1:50000" +const ( + serverUrl = "127.0.0.1:50000" + user = "git" +) -func TestShutdown(t *testing.T) { +var ( + correlationId = "" +) + +func TestListenAndServe(t *testing.T) { s := setupServer(t) - go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() - - verifyStatus(t, s, StatusReady) - - s.wg.Add(1) + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() require.NoError(t, s.Shutdown()) verifyStatus(t, s, StatusOnShutdown) - s.wg.Done() + holdSession(t, client) + + _, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.Equal(t, err.Error(), "dial tcp 127.0.0.1:50000: connect: connection refused") + + client.Close() verifyStatus(t, s, StatusClosed) } +func TestCorrelationId(t *testing.T) { + setupServer(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + previousCorrelationId := correlationId + + client, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + require.NotEqual(t, previousCorrelationId, correlationId) +} + func TestReadinessProbe(t *testing.T) { s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} @@ -71,17 +105,75 @@ } func setupServer(t *testing.T) *Server { + t.Helper() + + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/authorized_keys", + Handler: func(w http.ResponseWriter, r *http.Request) { + correlationId = r.Header.Get("X-Request-Id") + + require.NotEmpty(t, correlationId) + + fmt.Fprint(w, `{"id": 1000, "key": "key"}`) + }, + }, { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + + fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) + }, + }, + } + testhelper.PrepareTestRootDir(t) - url := testserver.StartSocketHttpServer(t, []testserver.TestRequestHandler{}) + url := testserver.StartSocketHttpServer(t, requests) srvCfg := config.ServerConfig{ - Listen: serverUrl, - HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + Listen: serverUrl, + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, } - cfg := &config.Config{RootDir: "/tmp", GitlabUrl: url, Server: srvCfg} + s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + require.NoError(t, err) + + go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + t.Cleanup(func() { s.Shutdown() }) + + verifyStatus(t, s, StatusReady) + + return s +} + +func clientConfig(t *testing.T) *ssh.ClientConfig { + keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + require.NoError(t, err) - return &Server{Config: cfg} + key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + require.NoError(t, err) + signer, err := ssh.ParsePrivateKey(key) + require.NoError(t, err) + + return &ssh.ClientConfig{ + User: user, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.FixedHostKey(pKey), + } +} + +func holdSession(t *testing.T, c *ssh.Client) { + session, err := c.NewSession() + require.NoError(t, err) + defer session.Close() + + output, err := session.Output("discover") + require.NoError(t, err) + require.Equal(t, "Welcome to GitLab, @test-user!\n", string(output)) } func verifyStatus(t *testing.T, s *Server, st status) { @@ -94,5 +186,5 @@ time.Sleep(time.Duration(i) * time.Millisecond) } - require.Equal(t, s.getStatus(), st) + require.Equal(t, st, s.getStatus()) } diff --git a/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1627400514 0 # Tue Jul 27 15:41:54 2021 +0000 # Node ID 84b7234ba7d9caf04353ea64f82b77e8c6dfc14a # Parent 4949e081af6690bc614873249604d13058084701 # Parent a126ea2cb7555f1cf1e7bb5d53fee1486fe2ae2d Merge branch 'id-ctx-for-auth-check' into 'main' Log same correlation_id on auth keys check of ssh connections See merge request gitlab-org/gitlab-shell!501 diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -68,7 +68,10 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() - server := sshd.Server{Config: cfg} + server, err := sshd.NewServer(cfg) + if err != nil { + log.WithError(err).Fatal("Failed to start GitLab built-in sshd") + } // Startup monitoring endpoint. if cfg.Server.WebListen != "" { @@ -104,6 +107,6 @@ }() if err := server.ListenAndServe(ctx); err != nil { - log.WithError(err).Fatal("Failed to start GitLab built-in sshd") + log.WithError(err).Fatal("GitLab built-in sshd failed to listen for new connections") } } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -35,10 +35,40 @@ type Server struct { Config *config.Config - status status - statusMu sync.Mutex - wg sync.WaitGroup - listener net.Listener + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func NewServer(cfg *config.Config) (*Server, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := ioutil.ReadFile(filename) + if err != nil { + log.WithError(err).Warnf("Failed to read host key %v", filename) + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).Warnf("Failed to parse host key %v", filename) + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") + } + + return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil } func (s *Server) ListenAndServe(ctx context.Context) error { @@ -47,7 +77,9 @@ } defer s.listener.Close() - return s.serve(ctx) + s.serve(ctx) + + return nil } func (s *Server) Shutdown() error { @@ -100,12 +132,7 @@ return nil } -func (s *Server) serve(ctx context.Context) error { - sshCfg, err := s.initConfig(ctx) - if err != nil { - return err - } - +func (s *Server) serve(ctx context.Context) { s.changeStatus(StatusReady) for { @@ -120,14 +147,12 @@ } s.wg.Add(1) - go s.handleConn(ctx, sshCfg, nconn) + go s.handleConn(ctx, nconn) } s.wg.Wait() s.changeStatus(StatusClosed) - - return nil } func (s *Server) changeStatus(st status) { @@ -143,12 +168,7 @@ return s.status } -func (s *Server) initConfig(ctx context.Context) (*ssh.ServerConfig, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(s.Config) - if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) - } - +func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { sshCfg := &ssh.ServerConfig{ PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if conn.User() != s.Config.User { @@ -159,7 +179,7 @@ } ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - res, err := authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) if err != nil { return nil, err } @@ -173,29 +193,14 @@ }, } - var loadedHostKeys uint - for _, filename := range s.Config.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) - if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) - continue - } - loadedHostKeys++ + for _, key := range s.hostKeys { sshCfg.AddHostKey(key) } - if loadedHostKeys == 0 { - return nil, fmt.Errorf("No host keys could be loaded, aborting") - } - return sshCfg, nil + return sshCfg } -func (s *Server) handleConn(ctx context.Context, sshCfg *ssh.ServerConfig, nconn net.Conn) { +func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() @@ -211,7 +216,7 @@ ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() - sconn, chans, reqs, err := ssh.NewServerConn(nconn, sshCfg) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) if err != nil { log.WithError(err).Info("Failed to initialize SSH connection") return diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -2,37 +2,71 @@ import ( "context" + "fmt" + "io/ioutil" + "net/http" "net/http/httptest" "path" "testing" "time" "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) -const serverUrl = "127.0.0.1:50000" +const ( + serverUrl = "127.0.0.1:50000" + user = "git" +) -func TestShutdown(t *testing.T) { +var ( + correlationId = "" +) + +func TestListenAndServe(t *testing.T) { s := setupServer(t) - go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() - - verifyStatus(t, s, StatusReady) - - s.wg.Add(1) + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() require.NoError(t, s.Shutdown()) verifyStatus(t, s, StatusOnShutdown) - s.wg.Done() + holdSession(t, client) + + _, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.Equal(t, err.Error(), "dial tcp 127.0.0.1:50000: connect: connection refused") + + client.Close() verifyStatus(t, s, StatusClosed) } +func TestCorrelationId(t *testing.T) { + setupServer(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + previousCorrelationId := correlationId + + client, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + require.NotEqual(t, previousCorrelationId, correlationId) +} + func TestReadinessProbe(t *testing.T) { s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} @@ -71,17 +105,75 @@ } func setupServer(t *testing.T) *Server { + t.Helper() + + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/authorized_keys", + Handler: func(w http.ResponseWriter, r *http.Request) { + correlationId = r.Header.Get("X-Request-Id") + + require.NotEmpty(t, correlationId) + + fmt.Fprint(w, `{"id": 1000, "key": "key"}`) + }, + }, { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + + fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) + }, + }, + } + testhelper.PrepareTestRootDir(t) - url := testserver.StartSocketHttpServer(t, []testserver.TestRequestHandler{}) + url := testserver.StartSocketHttpServer(t, requests) srvCfg := config.ServerConfig{ - Listen: serverUrl, - HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + Listen: serverUrl, + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, } - cfg := &config.Config{RootDir: "/tmp", GitlabUrl: url, Server: srvCfg} + s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + require.NoError(t, err) + + go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + t.Cleanup(func() { s.Shutdown() }) + + verifyStatus(t, s, StatusReady) + + return s +} + +func clientConfig(t *testing.T) *ssh.ClientConfig { + keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + require.NoError(t, err) - return &Server{Config: cfg} + key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + require.NoError(t, err) + signer, err := ssh.ParsePrivateKey(key) + require.NoError(t, err) + + return &ssh.ClientConfig{ + User: user, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.FixedHostKey(pKey), + } +} + +func holdSession(t *testing.T, c *ssh.Client) { + session, err := c.NewSession() + require.NoError(t, err) + defer session.Close() + + output, err := session.Output("discover") + require.NoError(t, err) + require.Equal(t, "Welcome to GitLab, @test-user!\n", string(output)) } func verifyStatus(t *testing.T, s *Server, st status) { @@ -94,5 +186,5 @@ time.Sleep(time.Duration(i) * time.Millisecond) } - require.Equal(t, s.getStatus(), st) + require.Equal(t, st, s.getStatus()) } diff --git a/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1627657747 -3600 # Fri Jul 30 16:09:07 2021 +0100 # Node ID d8a447645e047a33945a38b0fa64a8fe53cba5ff # Parent 84b7234ba7d9caf04353ea64f82b77e8c6dfc14a Remove some unreliable tests Logrus buffers its output internally, which makes these tests fail intermittently. They're also not a good example to follow generally. We now have acceptance tests that exercise this functionality so I'm pretty relaxed about losing the expectations. However, we can test them by inspecting the server-received metadata too, so there's no loss of coverage here. The move from logrus to labkit for logging also makes these tests hard to justify keeping. diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -11,8 +11,8 @@ "strings" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -76,7 +76,6 @@ func testSuccessfulGet(t *testing.T, client *GitlabNetClient) { t.Run("Successful get", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) require.NotNil(t, response) @@ -86,22 +85,11 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testSuccessfulPost(t *testing.T, client *GitlabNetClient) { t.Run("Successful Post", func(t *testing.T) { - hook := testhelper.SetupLogger() data := map[string]string{"key": "value"} response, err := client.Post(context.Background(), "/post_endpoint", data) @@ -113,50 +101,20 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testMissing(t *testing.T, client *GitlabNetClient) { t.Run("Missing error for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/missing") require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Missing error for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Post(context.Background(), "/missing", map[string]string{}) require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) } @@ -176,37 +134,15 @@ func testBrokenRequest(t *testing.T, client *GitlabNetClient) { t.Run("Broken request for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Get(context.Background(), "/broken") require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Broken request for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Post(context.Background(), "/broken", map[string]string{}) require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) } diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -14,12 +13,11 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -43,10 +41,15 @@ env := sshenv.Env{ IsSSHConnection: true, - OriginalCommand: "git-receive-pack group/repo", + OriginalCommand: "git-receive-pack " + repo, RemoteAddr: "127.0.0.1", } - args := &commandargs.Shell{CommandType: commandargs.ReceivePack, SshArgs: []string{"git-receive-pack", repo}, Env: env} + + args := &commandargs.Shell{ + CommandType: commandargs.ReceivePack, + SshArgs: []string{"git-receive-pack", repo}, + Env: env, + } if tc.username != "" { args.GitlabUsername = tc.username @@ -60,7 +63,6 @@ ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -73,15 +75,20 @@ require.Equal(t, "ReceivePack: key-123 "+repo, output.String()) } - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-receive-pack") - require.Contains(t, entries[1].Message, "remote_ip=127.0.0.1") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-receive-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } } diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,12 +12,12 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) -func TestUploadPack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) +func TestUploadArchive(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-archive " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadArchive, + SshArgs: []string{"git-upload-archive", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadArchive, SshArgs: []string{"git-upload-archive", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -44,13 +55,19 @@ require.Equal(t, "UploadArchive: "+repo, output.String()) - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-archive") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-archive", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -4,7 +4,6 @@ "bytes" "context" "testing" - "time" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,7 +12,7 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadPack, SshArgs: []string{"git-upload-pack", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -43,25 +54,20 @@ require.NoError(t, err) require.Equal(t, "UploadPack: "+repo, output.String()) - require.Eventually(t, func() bool { - entries := hook.AllEntries() - - require.Equal(t, 2, len(entries)) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-pack") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") - return true - }, time.Second, time.Millisecond) for k, v := range map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", } { actual := testServer.ReceivedMD[k] require.Len(t, actual, 1) require.Equal(t, v, actual[0]) } require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -7,11 +7,8 @@ "path" "runtime" "testing" - "time" "github.com/otiai10/copy" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" ) @@ -75,25 +72,3 @@ err := os.Setenv(key, value) return func() { os.Setenv(key, oldValue) }, err } - -func SetupLogger() *test.Hook { - logger, hook := test.NewNullLogger() - logrus.SetOutput(logger.Writer()) - - return hook -} - -// logrus fires a Goroutine to write the output log, but there's no way to -// flush all outstanding hooks to fire. We just wait up to a second -// for an event to appear. -func WaitForLogEvent(hook *test.Hook) bool { - for i := 0; i < 10; i++ { - if entry := hook.LastEntry(); entry != nil { - return true - } - - time.Sleep(100 * time.Millisecond) - } - - return false -} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1627881433 0 # Mon Aug 02 05:17:13 2021 +0000 # Node ID 13bc78f1f276a64b306d4d26ea67239804c8b634 # Parent 84b7234ba7d9caf04353ea64f82b77e8c6dfc14a # Parent d8a447645e047a33945a38b0fa64a8fe53cba5ff Merge branch '477-remove-logrus-tests' into 'main' Remove some unreliable tests Closes #477 See merge request gitlab-org/gitlab-shell!503 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -11,8 +11,8 @@ "strings" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -76,7 +76,6 @@ func testSuccessfulGet(t *testing.T, client *GitlabNetClient) { t.Run("Successful get", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) require.NotNil(t, response) @@ -86,22 +85,11 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testSuccessfulPost(t *testing.T, client *GitlabNetClient) { t.Run("Successful Post", func(t *testing.T) { - hook := testhelper.SetupLogger() data := map[string]string{"key": "value"} response, err := client.Post(context.Background(), "/post_endpoint", data) @@ -113,50 +101,20 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testMissing(t *testing.T, client *GitlabNetClient) { t.Run("Missing error for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/missing") require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Missing error for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Post(context.Background(), "/missing", map[string]string{}) require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) } @@ -176,37 +134,15 @@ func testBrokenRequest(t *testing.T, client *GitlabNetClient) { t.Run("Broken request for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Get(context.Background(), "/broken") require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Broken request for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Post(context.Background(), "/broken", map[string]string{}) require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) } diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -14,12 +13,11 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -43,10 +41,15 @@ env := sshenv.Env{ IsSSHConnection: true, - OriginalCommand: "git-receive-pack group/repo", + OriginalCommand: "git-receive-pack " + repo, RemoteAddr: "127.0.0.1", } - args := &commandargs.Shell{CommandType: commandargs.ReceivePack, SshArgs: []string{"git-receive-pack", repo}, Env: env} + + args := &commandargs.Shell{ + CommandType: commandargs.ReceivePack, + SshArgs: []string{"git-receive-pack", repo}, + Env: env, + } if tc.username != "" { args.GitlabUsername = tc.username @@ -60,7 +63,6 @@ ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -73,15 +75,20 @@ require.Equal(t, "ReceivePack: key-123 "+repo, output.String()) } - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-receive-pack") - require.Contains(t, entries[1].Message, "remote_ip=127.0.0.1") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-receive-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } } diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,12 +12,12 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) -func TestUploadPack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) +func TestUploadArchive(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-archive " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadArchive, + SshArgs: []string{"git-upload-archive", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadArchive, SshArgs: []string{"git-upload-archive", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -44,13 +55,19 @@ require.Equal(t, "UploadArchive: "+repo, output.String()) - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-archive") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-archive", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -4,7 +4,6 @@ "bytes" "context" "testing" - "time" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,7 +12,7 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadPack, SshArgs: []string{"git-upload-pack", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -43,25 +54,20 @@ require.NoError(t, err) require.Equal(t, "UploadPack: "+repo, output.String()) - require.Eventually(t, func() bool { - entries := hook.AllEntries() - - require.Equal(t, 2, len(entries)) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-pack") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") - return true - }, time.Second, time.Millisecond) for k, v := range map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", } { actual := testServer.ReceivedMD[k] require.Len(t, actual, 1) require.Equal(t, v, actual[0]) } require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -7,11 +7,8 @@ "path" "runtime" "testing" - "time" "github.com/otiai10/copy" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" ) @@ -75,25 +72,3 @@ err := os.Setenv(key, value) return func() { os.Setenv(key, oldValue) }, err } - -func SetupLogger() *test.Hook { - logger, hook := test.NewNullLogger() - logrus.SetOutput(logger.Writer()) - - return hook -} - -// logrus fires a Goroutine to write the output log, but there's no way to -// flush all outstanding hooks to fire. We just wait up to a second -// for an event to appear. -func WaitForLogEvent(hook *test.Hook) bool { - for i := 0; i < 10; i++ { - if entry := hook.LastEntry(); entry != nil { - return true - } - - time.Sleep(100 * time.Millisecond) - } - - return false -} # HG changeset patch # User Robert May <rmay@gitlab.com> # Date 1624893480 -3600 # Mon Jun 28 16:18:00 2021 +0100 # Node ID d7381c5162dcba14ef705a9d2d292b9073ebe6e3 # Parent e217294e7c0ea89fe37160a49b0d3ced586063ca Modify regex to prevent partial matches diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go --- a/internal/command/commandargs/command_args_test.go +++ b/internal/command/commandargs/command_args_test.go @@ -23,14 +23,19 @@ env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, arguments: []string{}, expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, - { + }, { desc: "It finds the key id in any passed arguments", executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, arguments: []string{"hello", "key-123"}, expectedArgs: &Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, }, { + desc: "It finds the key id only if the argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-key-123"}, + expectedArgs: &Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, { desc: "It finds the username in any passed arguments", executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -20,8 +20,8 @@ ) var ( - whoKeyRegex = regexp.MustCompile(`\bkey-(?P<keyid>\d+)\b`) - whoUsernameRegex = regexp.MustCompile(`\busername-(?P<username>\S+)\b`) + whoKeyRegex = regexp.MustCompile(`\Akey-(?P<keyid>\d+)\z`) + whoUsernameRegex = regexp.MustCompile(`\Ausername-(?P<username>\S+)\z`) ) type Shell struct { # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1628044275 0 # Wed Aug 04 02:31:15 2021 +0000 # Node ID bf50f08857a03c5cd33abcd3e739c71d978306b8 # Parent 13bc78f1f276a64b306d4d26ea67239804c8b634 # Parent d7381c5162dcba14ef705a9d2d292b9073ebe6e3 Merge branch 'security-300265' into 'main' Modify regex to prevent partial matches See merge request gitlab-org/security/gitlab-shell!6 diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go --- a/internal/command/commandargs/command_args_test.go +++ b/internal/command/commandargs/command_args_test.go @@ -23,14 +23,19 @@ env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, arguments: []string{}, expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, - { + }, { desc: "It finds the key id in any passed arguments", executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, arguments: []string{"hello", "key-123"}, expectedArgs: &Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, }, { + desc: "It finds the key id only if the argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-key-123"}, + expectedArgs: &Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, { desc: "It finds the username in any passed arguments", executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -20,8 +20,8 @@ ) var ( - whoKeyRegex = regexp.MustCompile(`\bkey-(?P<keyid>\d+)\b`) - whoUsernameRegex = regexp.MustCompile(`\busername-(?P<username>\S+)\b`) + whoKeyRegex = regexp.MustCompile(`\Akey-(?P<keyid>\d+)\z`) + whoUsernameRegex = regexp.MustCompile(`\Ausername-(?P<username>\S+)\z`) ) type Shell struct { # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1627999633 -3600 # Tue Aug 03 15:07:13 2021 +0100 # Node ID 3851cebeb009f19cf6792a5e48d8d898a71229c5 # Parent 13bc78f1f276a64b306d4d26ea67239804c8b634 Switch to labkit for logging system setup - We start supporting the "color" format for logs. - We now respond to SIGHUP by reopening the log file. - We now respect the log format when no log filename is specified. Output to syslog in the event of logging system setup is preserved in OpenSSH mode. Changelog: added diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -31,7 +31,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -46,7 +46,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() env := sshenv.NewFromEnv() cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -229,7 +229,7 @@ t.Cleanup(func() { pw.Close() }) scanner := bufio.NewScanner(pr) - extractor := regexp.MustCompile(`tcp_address="([0-9a-f\[\]\.:]+)"`) + extractor := regexp.MustCompile(`"tcp_address":"([0-9a-f\[\]\.:]+)"`) ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, sshdPath, "-config-dir", dir) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -63,7 +63,8 @@ cfg.ApplyGlobalState() - logger.ConfigureStandalone(cfg) + logCloser := logger.ConfigureStandalone(cfg) + defer logCloser.Close() ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,10 +10,9 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 - github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 - gitlab.com/gitlab-org/labkit v1.4.1 + gitlab.com/gitlab-org/labkit v1.7.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.37.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -16,6 +16,7 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= @@ -38,6 +39,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +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= 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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -81,6 +84,8 @@ github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= +github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -91,6 +96,8 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -214,6 +221,8 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -274,6 +283,7 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= @@ -343,6 +353,10 @@ 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= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -645,8 +659,8 @@ gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= -gitlab.com/gitlab-org/labkit v1.4.1 h1:mh4g+c/esQSWCVQJ197aftrIbXlhXCtiLC8RgSvyCx0= -gitlab.com/gitlab-org/labkit v1.4.1/go.mod h1:x5JO5uvdX4t6e/TZXLXZnFL5AcKz2uLLd3uKXZcuO4k= +gitlab.com/gitlab-org/labkit v1.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= +gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= 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.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -657,6 +671,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -771,6 +786,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= @@ -783,6 +799,7 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -937,6 +954,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -969,6 +987,7 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= @@ -1020,6 +1039,8 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -2,37 +2,54 @@ import ( "fmt" + "io" "io/ioutil" "log/syslog" "os" + "time" - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) -type UTCFormatter struct { - log.Formatter +func logFmt(inFmt string) string { + // Hide the "combined" format, since that makes no sense in gitlab-shell. + // The default is JSON when unspecified. + if inFmt == "" || inFmt == "combined" { + return "json" + } + + return inFmt } -func (u UTCFormatter) Format(e *log.Entry) ([]byte, error) { - e.Time = e.Time.UTC() +func logFile(inFile string) string { + if inFile == "" { + return "stderr" + } - return u.Formatter.Format(e) + return inFile } -func configureLogFormat(cfg *config.Config) { - if cfg.LogFormat == "json" { - log.SetFormatter(UTCFormatter{&log.JSONFormatter{}}) - } else { - log.SetFormatter(UTCFormatter{&log.TextFormatter{}}) +func buildOpts(cfg *config.Config) []log.LoggerOption { + return []log.LoggerOption{ + log.WithFormatter(logFmt(cfg.LogFormat)), + log.WithOutputName(logFile(cfg.LogFile)), + log.WithTimezone(time.UTC), } } // Configure configures the logging singleton for operation inside a remote TTY (like SSH). In this // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. -func Configure(cfg *config.Config) { - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) +func Configure(cfg *config.Config) io.Closer { + var closer io.Closer = ioutil.NopCloser(nil) + err := fmt.Errorf("No logfile specified") + + if cfg.LogFile != "" { + closer, err = log.Initialize(buildOpts(cfg)...) + } + if err != nil { progName, _ := os.Executable() syslogLogger, syslogLoggerErr := syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0) @@ -44,29 +61,35 @@ fmt.Fprintf(os.Stderr, msg) } - // Discard logs since a log file was specified but couldn't be opened - log.SetOutput(ioutil.Discard) + cfg.LogFile = "/dev/null" + closer, err = log.Initialize(buildOpts(cfg)...) + if err != nil { + log.WithError(err).Warn("Unable to configure logging to /dev/null, leaving unconfigured") + } } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } // ConfigureStandalone configures the logging singleton for standalone operation. In this mode an -// empty LogFile is treated as logging to standard output and standard output is used as a fallback +// empty LogFile is treated as logging to stderr, and standard output is used as a fallback // when LogFile could not be opened for writing. -func ConfigureStandalone(cfg *config.Config) { - if cfg.LogFile == "" { - return +func ConfigureStandalone(cfg *config.Config) io.Closer { + closer, err1 := log.Initialize(buildOpts(cfg)...) + if err1 != nil { + var err2 error + + cfg.LogFile = "stdout" + closer, err2 = log.Initialize(buildOpts(cfg)...) + + // Output this after the logger has been configured! + log.WithError(err1).WithField("log_file", cfg.LogFile).Warn("Unable to configure logging, falling back to STDOUT") + + // LabKit v1.7.0 doesn't have any conditions where logging to "stdout" will fail + if err2 != nil { + log.WithError(err2).Warn("Unable to configure logging to STDOUT, leaving unconfigured") + } } - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) - if err != nil { - log.Printf("Unable to configure logging, falling back to stdout: %v", err) - return - } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -7,8 +7,9 @@ "strings" "testing" - log "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) @@ -22,7 +23,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") tmpFile.Close() @@ -42,7 +45,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") } @@ -57,7 +62,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") data, err := ioutil.ReadFile(tmpFile.Name()) # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1628066623 0 # Wed Aug 04 08:43:43 2021 +0000 # Node ID 6ea629933069190232b9adb008f60e84d889904f # Parent bf50f08857a03c5cd33abcd3e739c71d978306b8 # Parent 3851cebeb009f19cf6792a5e48d8d898a71229c5 Merge branch '499-use-labkit-logging-initialize' into 'main' Switch to labkit for logging system setup Closes #271 See merge request gitlab-org/gitlab-shell!504 diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -31,7 +31,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -46,7 +46,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() env := sshenv.NewFromEnv() cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -229,7 +229,7 @@ t.Cleanup(func() { pw.Close() }) scanner := bufio.NewScanner(pr) - extractor := regexp.MustCompile(`tcp_address="([0-9a-f\[\]\.:]+)"`) + extractor := regexp.MustCompile(`"tcp_address":"([0-9a-f\[\]\.:]+)"`) ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, sshdPath, "-config-dir", dir) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -63,7 +63,8 @@ cfg.ApplyGlobalState() - logger.ConfigureStandalone(cfg) + logCloser := logger.ConfigureStandalone(cfg) + defer logCloser.Close() ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,10 +10,9 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 - github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 - gitlab.com/gitlab-org/labkit v1.4.1 + gitlab.com/gitlab-org/labkit v1.7.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.37.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -16,6 +16,7 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= @@ -38,6 +39,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +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= 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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -81,6 +84,8 @@ github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= +github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -91,6 +96,8 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -214,6 +221,8 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -274,6 +283,7 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= @@ -343,6 +353,10 @@ 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= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -645,8 +659,8 @@ gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= -gitlab.com/gitlab-org/labkit v1.4.1 h1:mh4g+c/esQSWCVQJ197aftrIbXlhXCtiLC8RgSvyCx0= -gitlab.com/gitlab-org/labkit v1.4.1/go.mod h1:x5JO5uvdX4t6e/TZXLXZnFL5AcKz2uLLd3uKXZcuO4k= +gitlab.com/gitlab-org/labkit v1.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= +gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= 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.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -657,6 +671,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -771,6 +786,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= @@ -783,6 +799,7 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -937,6 +954,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -969,6 +987,7 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= @@ -1020,6 +1039,8 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -2,37 +2,54 @@ import ( "fmt" + "io" "io/ioutil" "log/syslog" "os" + "time" - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) -type UTCFormatter struct { - log.Formatter +func logFmt(inFmt string) string { + // Hide the "combined" format, since that makes no sense in gitlab-shell. + // The default is JSON when unspecified. + if inFmt == "" || inFmt == "combined" { + return "json" + } + + return inFmt } -func (u UTCFormatter) Format(e *log.Entry) ([]byte, error) { - e.Time = e.Time.UTC() +func logFile(inFile string) string { + if inFile == "" { + return "stderr" + } - return u.Formatter.Format(e) + return inFile } -func configureLogFormat(cfg *config.Config) { - if cfg.LogFormat == "json" { - log.SetFormatter(UTCFormatter{&log.JSONFormatter{}}) - } else { - log.SetFormatter(UTCFormatter{&log.TextFormatter{}}) +func buildOpts(cfg *config.Config) []log.LoggerOption { + return []log.LoggerOption{ + log.WithFormatter(logFmt(cfg.LogFormat)), + log.WithOutputName(logFile(cfg.LogFile)), + log.WithTimezone(time.UTC), } } // Configure configures the logging singleton for operation inside a remote TTY (like SSH). In this // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. -func Configure(cfg *config.Config) { - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) +func Configure(cfg *config.Config) io.Closer { + var closer io.Closer = ioutil.NopCloser(nil) + err := fmt.Errorf("No logfile specified") + + if cfg.LogFile != "" { + closer, err = log.Initialize(buildOpts(cfg)...) + } + if err != nil { progName, _ := os.Executable() syslogLogger, syslogLoggerErr := syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0) @@ -44,29 +61,35 @@ fmt.Fprintf(os.Stderr, msg) } - // Discard logs since a log file was specified but couldn't be opened - log.SetOutput(ioutil.Discard) + cfg.LogFile = "/dev/null" + closer, err = log.Initialize(buildOpts(cfg)...) + if err != nil { + log.WithError(err).Warn("Unable to configure logging to /dev/null, leaving unconfigured") + } } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } // ConfigureStandalone configures the logging singleton for standalone operation. In this mode an -// empty LogFile is treated as logging to standard output and standard output is used as a fallback +// empty LogFile is treated as logging to stderr, and standard output is used as a fallback // when LogFile could not be opened for writing. -func ConfigureStandalone(cfg *config.Config) { - if cfg.LogFile == "" { - return +func ConfigureStandalone(cfg *config.Config) io.Closer { + closer, err1 := log.Initialize(buildOpts(cfg)...) + if err1 != nil { + var err2 error + + cfg.LogFile = "stdout" + closer, err2 = log.Initialize(buildOpts(cfg)...) + + // Output this after the logger has been configured! + log.WithError(err1).WithField("log_file", cfg.LogFile).Warn("Unable to configure logging, falling back to STDOUT") + + // LabKit v1.7.0 doesn't have any conditions where logging to "stdout" will fail + if err2 != nil { + log.WithError(err2).Warn("Unable to configure logging to STDOUT, leaving unconfigured") + } } - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) - if err != nil { - log.Printf("Unable to configure logging, falling back to stdout: %v", err) - return - } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -7,8 +7,9 @@ "strings" "testing" - log "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) @@ -22,7 +23,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") tmpFile.Close() @@ -42,7 +45,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") } @@ -57,7 +62,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") data, err := ioutil.ReadFile(tmpFile.Name()) # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1628701200 0 # Wed Aug 11 17:00:00 2021 +0000 # Node ID 8dbc9ecf1d7b9d31c961acf9df5060f9ef71ffd3 # Parent 6ea629933069190232b9adb008f60e84d889904f build: bump go to 1.15 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.13 +go 1.15 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -219,7 +219,6 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1628701283 0 # Wed Aug 11 17:01:23 2021 +0000 # Node ID 4d1c9a805e96f0cf67572ce3b9aa97cfaf5854ed # Parent 8dbc9ecf1d7b9d31c961acf9df5060f9ef71ffd3 test: remove go 1.14 test job diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,13 +52,6 @@ script: - make verify test -go:1.14: - extends: .test - image: golang:1.14 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.15: extends: .test image: golang:1.15 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1628737339 0 # Thu Aug 12 03:02:19 2021 +0000 # Node ID e60f605d38985002cfe0bc98354e6ada8c4c5013 # Parent 6ea629933069190232b9adb008f60e84d889904f # Parent 4d1c9a805e96f0cf67572ce3b9aa97cfaf5854ed Merge branch 'bump/go1.15' into 'main' build: bump go to 1.15 See merge request gitlab-org/gitlab-shell!505 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,13 +52,6 @@ script: - make verify test -go:1.14: - extends: .test - image: golang:1.14 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.15: extends: .test image: golang:1.15 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.13 +go 1.15 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -219,7 +219,6 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1628703619 0 # Wed Aug 11 17:40:19 2021 +0000 # Node ID 8500146e19b08043dd21f4bbc8173d3f1fe50bc6 # Parent 6ea629933069190232b9adb008f60e84d889904f refactor: update usage of NewHTTPClient to NewHTTPClientWithOpts diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -59,7 +59,8 @@ secret := "sssh, it's a secret" - httpClient := NewHTTPClient(url, tc.relativeURLRoot, tc.caFile, "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient("", "", secret, httpClient) require.NoError(t, err) diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,8 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client := NewHTTPClient("http://localhost:3000", "", "", "", false, expectedSeconds) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + require.NoError(t, err) require.NotNil(t, client) require.Equal(t, time.Duration(expectedSeconds)*time.Second, client.Client.Timeout) @@ -122,7 +123,8 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient := NewHTTPClient(url, "", "", "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -15,6 +15,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -97,14 +98,18 @@ func (c *Config) HttpClient() *client.HttpClient { c.httpClientOnce.Do(func() { - client := client.NewHTTPClient( + client, err := client.NewHTTPClientWithOpts( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, + nil, ) + if err != nil { + log.WithError(err).Fatal("new http client with opts") + } tr := client.Transport client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1628862681 0 # Fri Aug 13 13:51:21 2021 +0000 # Node ID 18156564c912d06693c21ccc74b01866a7ea862d # Parent 8500146e19b08043dd21f4bbc8173d3f1fe50bc6 refactor: change httpclient to return an error diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -15,7 +15,6 @@ "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -59,6 +58,7 @@ Server ServerConfig `yaml:"sshd"` httpClient *client.HttpClient + httpClientErr error httpClientOnce sync.Once } @@ -96,7 +96,7 @@ } } -func (c *Config) HttpClient() *client.HttpClient { +func (c *Config) HttpClient() (*client.HttpClient, error) { c.httpClientOnce.Do(func() { client, err := client.NewHTTPClientWithOpts( c.GitlabUrl, @@ -108,7 +108,8 @@ nil, ) if err != nil { - log.WithError(err).Fatal("new http client with opts") + c.httpClientErr = err + return } tr := client.Transport @@ -117,7 +118,7 @@ c.httpClient = client }) - return c.httpClient + return c.httpClient, c.httpClientErr } // NewFromDirExternal returns a new config from a given root dir. It also applies defaults appropriate for diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -29,9 +29,10 @@ url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) config := &Config{GitlabUrl: url} - client := config.HttpClient() + client, err := config.HttpClient() + require.NoError(t, err) - _, err := client.Get("http://host.com/path") + _, err = client.Get("http://host.com/path") require.NoError(t, err) ms, err := prometheus.DefaultGatherer.Gather() diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -15,7 +15,10 @@ ) func GetClient(config *config.Config) (*client.GitlabNetClient, error) { - httpClient := config.HttpClient() + httpClient, err := config.HttpClient() + if err != nil { + return nil, err + } if httpClient == nil { return nil, fmt.Errorf("Unsupported protocol") # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1628866202 0 # Fri Aug 13 14:50:02 2021 +0000 # Node ID edce299c5e1051efa54e516561c6ea0b59ea09e5 # Parent e60f605d38985002cfe0bc98354e6ada8c4c5013 # Parent 18156564c912d06693c21ccc74b01866a7ea862d Merge branch 'update/newclientopts' into 'main' refactor: update usage of NewHTTPClient to NewHTTPClientWithOpts Closes #484 See merge request gitlab-org/gitlab-shell!507 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -59,7 +59,8 @@ secret := "sssh, it's a secret" - httpClient := NewHTTPClient(url, tc.relativeURLRoot, tc.caFile, "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient("", "", secret, httpClient) require.NoError(t, err) diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,8 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client := NewHTTPClient("http://localhost:3000", "", "", "", false, expectedSeconds) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + require.NoError(t, err) require.NotNil(t, client) require.Equal(t, time.Duration(expectedSeconds)*time.Second, client.Client.Timeout) @@ -122,7 +123,8 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient := NewHTTPClient(url, "", "", "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -58,6 +58,7 @@ Server ServerConfig `yaml:"sshd"` httpClient *client.HttpClient + httpClientErr error httpClientOnce sync.Once } @@ -95,16 +96,21 @@ } } -func (c *Config) HttpClient() *client.HttpClient { +func (c *Config) HttpClient() (*client.HttpClient, error) { c.httpClientOnce.Do(func() { - client := client.NewHTTPClient( + client, err := client.NewHTTPClientWithOpts( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, + nil, ) + if err != nil { + c.httpClientErr = err + return + } tr := client.Transport client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) @@ -112,7 +118,7 @@ c.httpClient = client }) - return c.httpClient + return c.httpClient, c.httpClientErr } // NewFromDirExternal returns a new config from a given root dir. It also applies defaults appropriate for diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -29,9 +29,10 @@ url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) config := &Config{GitlabUrl: url} - client := config.HttpClient() + client, err := config.HttpClient() + require.NoError(t, err) - _, err := client.Get("http://host.com/path") + _, err = client.Get("http://host.com/path") require.NoError(t, err) ms, err := prometheus.DefaultGatherer.Gather() diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -15,7 +15,10 @@ ) func GetClient(config *config.Config) (*client.GitlabNetClient, error) { - httpClient := config.HttpClient() + httpClient, err := config.HttpClient() + if err != nil { + return nil, err + } if httpClient == nil { return nil, fmt.Errorf("Unsupported protocol") # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1628708524 0 # Wed Aug 11 19:02:04 2021 +0000 # Node ID 2b4161c1cc984d75c75714c1c9e4ea08d5574731 # Parent 6ea629933069190232b9adb008f60e84d889904f fix: validate client cert paths exist on disk before proceeding diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -5,9 +5,11 @@ "crypto/tls" "crypto/x509" "errors" + "fmt" "io/ioutil" "net" "net/http" + "os" "path/filepath" "strings" "time" @@ -25,6 +27,10 @@ defaultReadTimeoutSeconds = 300 ) +var ( + ErrCafileNotFound = errors.New("cafile not found") +) + type HttpClient struct { *http.Client Host string @@ -60,15 +66,6 @@ // NewHTTPClientWithOpts builds an HTTP client using the provided options func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { - hcc := &httpClientCfg{ - caFile: caFile, - caPath: caPath, - } - - for _, opt := range opts { - opt(hcc) - } - var transport *http.Transport var host string var err error @@ -77,6 +74,19 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { + hcc := &httpClientCfg{ + caFile: caFile, + caPath: caPath, + } + + for _, opt := range opts { + opt(hcc) + } + + if _, err := os.Stat(caFile); err != nil { + return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) + } + transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) if err != nil { return nil, err diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -28,10 +28,7 @@ { desc: "Valid CaPath", caPath: path.Join(testhelper.TestRoot, "certs/valid"), - }, - { - desc: "Self signed cert option enabled", - selfSigned: true, + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Invalid cert with self signed cert option enabled", @@ -51,7 +48,8 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) @@ -68,13 +66,15 @@ func TestFailedRequests(t *testing.T) { testCases := []struct { - desc string - caFile string - caPath string + desc string + caFile string + caPath string + expectedError string }{ { - desc: "Invalid CaFile", - caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + desc: "Invalid CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + expectedError: "Internal API unreachable", }, { desc: "Invalid CaPath", @@ -87,17 +87,21 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + if tc.caFile == "" { + require.Error(t, err) + require.ErrorIs(t, err, ErrCafileNotFound) + } else { + _, err = client.Get(context.Background(), "/hello") + require.Error(t, err) - _, err := client.Get(context.Background(), "/hello") - require.Error(t, err) - - require.Equal(t, err.Error(), "Internal API unreachable") + require.Equal(t, err.Error(), tc.expectedError) + } }) } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) *GitlabNetClient { +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ @@ -119,10 +123,11 @@ } httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) - require.NoError(t, err) + if err != nil { + return nil, err + } client, err := NewGitlabNetClient("", "", "", httpClient) - require.NoError(t, err) - return client + return client, err } # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1628708688 0 # Wed Aug 11 19:04:48 2021 +0000 # Node ID 3a36fa325bb40b48473f63e9a753efdc1c984ac0 # Parent 2b4161c1cc984d75c75714c1c9e4ea08d5574731 fix: make sure ErrCafileNotFound is returned only when the file doesn't exist diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -84,7 +84,10 @@ } if _, err := os.Stat(caFile); err != nil { - return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) + if os.IsNotExist(err) { + return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) + } + return nil, err } transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1629221837 0 # Tue Aug 17 17:37:17 2021 +0000 # Node ID 8fcbb1e258a9106764517736fc9582f52a6d80c7 # Parent 3a36fa325bb40b48473f63e9a753efdc1c984ac0 test: move os.stat check before the hcc creation diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -74,6 +74,13 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { + if _, err := os.Stat(caFile); err != nil { + if os.IsNotExist(err) { + return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) + } + return nil, err + } + hcc := &httpClientCfg{ caFile: caFile, caPath: caPath, @@ -83,13 +90,6 @@ opt(hcc) } - if _, err := os.Stat(caFile); err != nil { - if os.IsNotExist(err) { - return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) - } - return nil, err - } - transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) if err != nil { return nil, err # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1629250631 0 # Wed Aug 18 01:37:11 2021 +0000 # Node ID 8053a4a7b429fd4ce407f623882b2021729518d1 # Parent edce299c5e1051efa54e516561c6ea0b59ea09e5 # Parent 8fcbb1e258a9106764517736fc9582f52a6d80c7 Merge branch 'verify/cafile' into 'main' fix: validate client cert paths exist on disk before proceeding Closes #486 See merge request gitlab-org/gitlab-shell!508 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -5,9 +5,11 @@ "crypto/tls" "crypto/x509" "errors" + "fmt" "io/ioutil" "net" "net/http" + "os" "path/filepath" "strings" "time" @@ -25,6 +27,10 @@ defaultReadTimeoutSeconds = 300 ) +var ( + ErrCafileNotFound = errors.New("cafile not found") +) + type HttpClient struct { *http.Client Host string @@ -60,15 +66,6 @@ // NewHTTPClientWithOpts builds an HTTP client using the provided options func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { - hcc := &httpClientCfg{ - caFile: caFile, - caPath: caPath, - } - - for _, opt := range opts { - opt(hcc) - } - var transport *http.Transport var host string var err error @@ -77,6 +74,22 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { + if _, err := os.Stat(caFile); err != nil { + if os.IsNotExist(err) { + return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) + } + return nil, err + } + + hcc := &httpClientCfg{ + caFile: caFile, + caPath: caPath, + } + + for _, opt := range opts { + opt(hcc) + } + transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) if err != nil { return nil, err diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -28,10 +28,7 @@ { desc: "Valid CaPath", caPath: path.Join(testhelper.TestRoot, "certs/valid"), - }, - { - desc: "Self signed cert option enabled", - selfSigned: true, + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Invalid cert with self signed cert option enabled", @@ -51,7 +48,8 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) @@ -68,13 +66,15 @@ func TestFailedRequests(t *testing.T) { testCases := []struct { - desc string - caFile string - caPath string + desc string + caFile string + caPath string + expectedError string }{ { - desc: "Invalid CaFile", - caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + desc: "Invalid CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + expectedError: "Internal API unreachable", }, { desc: "Invalid CaPath", @@ -87,17 +87,21 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + if tc.caFile == "" { + require.Error(t, err) + require.ErrorIs(t, err, ErrCafileNotFound) + } else { + _, err = client.Get(context.Background(), "/hello") + require.Error(t, err) - _, err := client.Get(context.Background(), "/hello") - require.Error(t, err) - - require.Equal(t, err.Error(), "Internal API unreachable") + require.Equal(t, err.Error(), tc.expectedError) + } }) } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) *GitlabNetClient { +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ @@ -119,10 +123,11 @@ } httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) - require.NoError(t, err) + if err != nil { + return nil, err + } client, err := NewGitlabNetClient("", "", "", httpClient) - require.NoError(t, err) - return client + return client, err } # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1629337890 0 # Thu Aug 19 01:51:30 2021 +0000 # Node ID 79145e25a794bb927b527cdc467734c9c5072c6e # Parent 8053a4a7b429fd4ce407f623882b2021729518d1 ci: start integrating go 1.17 into the CI pipelines diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -66,9 +66,16 @@ - make coverage coverage: '/\d+.\d+%/' +go:1.17: + extends: .test + image: golang:1.17 + after_script: + - make coverage + coverage: '/\d+.\d+%/' + race: extends: .test - image: golang:1.16 + image: golang:1.17 script: - make test_golang_race # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1629341362 0 # Thu Aug 19 02:49:22 2021 +0000 # Node ID c44eb8f53c8a45ecaf0f6a750ad793f56c248926 # Parent 8053a4a7b429fd4ce407f623882b2021729518d1 # Parent 79145e25a794bb927b527cdc467734c9c5072c6e Merge branch 'test/go-1.17' into 'main' ci: start integrating go 1.17 into the CI pipelines See merge request gitlab-org/gitlab-shell!510 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -66,9 +66,16 @@ - make coverage coverage: '/\d+.\d+%/' +go:1.17: + extends: .test + image: golang:1.17 + after_script: + - make coverage + coverage: '/\d+.\d+%/' + race: extends: .test - image: golang:1.16 + image: golang:1.17 script: - make test_golang_race # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1629337974 0 # Thu Aug 19 01:52:54 2021 +0000 # Node ID 7164a9b6bb008b61362352124e85969d76d8d405 # Parent 8053a4a7b429fd4ce407f623882b2021729518d1 build: bump go version to 1.16 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.15 +go 1.16 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -162,7 +162,6 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 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 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 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= @@ -180,7 +179,6 @@ github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -268,10 +266,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 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= @@ -498,7 +494,6 @@ github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= @@ -516,7 +511,6 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= @@ -713,7 +707,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -962,9 +955,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1629338024 0 # Thu Aug 19 01:53:44 2021 +0000 # Node ID d6626bbcf01234bb3c5625bd1f9fe14de80f4f08 # Parent 7164a9b6bb008b61362352124e85969d76d8d405 ci: remove go 1.15 test job diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,13 +52,6 @@ script: - make verify test -go:1.15: - extends: .test - image: golang:1.15 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.16: extends: .test image: golang:1.16 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1629368304 0 # Thu Aug 19 10:18:24 2021 +0000 # Node ID 6415f1b04fa7998f0c06b2a12b06d45eb15651ad # Parent c44eb8f53c8a45ecaf0f6a750ad793f56c248926 # Parent d6626bbcf01234bb3c5625bd1f9fe14de80f4f08 Merge branch 'bump/go-1.16' into 'main' build: bump go version to 1.16 See merge request gitlab-org/gitlab-shell!509 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,13 +52,6 @@ script: - make verify test -go:1.15: - extends: .test - image: golang:1.15 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.16: extends: .test image: golang:1.16 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.15 +go 1.16 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -162,7 +162,6 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 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 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 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= @@ -180,7 +179,6 @@ github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -268,10 +266,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 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= @@ -498,7 +494,6 @@ github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= @@ -516,7 +511,6 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= @@ -713,7 +707,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -962,9 +955,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1629905872 -3600 # Wed Aug 25 16:37:52 2021 +0100 # Node ID ae635775668d803f836b4227e42b500037db32e4 # Parent 6415f1b04fa7998f0c06b2a12b06d45eb15651ad Add missing CHANGELOG entries diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,10 @@ - Fix the Geo SSH push proxy hanging !487 - Standardize logging timestamp format !485 +v13.19.1 + +- Modify regex to prevent partial matches + v13.19.0 - Don't finish the opentracing span early !466 @@ -13,6 +17,10 @@ - Stop changing directory to the filesystem root !470 - Fix opentracing setup for gitlab-sshd !473 +v13.18.1 + +- Modify regex to prevent partial matches + v13.18.0 - Fix thread-safety issues in gitlab-shell !463 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1629905884 -3600 # Wed Aug 25 16:38:04 2021 +0100 # Node ID f8a1d5432aebce2dc98f5e17722235818e47d9b3 # Parent ae635775668d803f836b4227e42b500037db32e4 Version 3.21.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +v13.21.0 + +- Change default logging format to JSON !476 +- Shutdown sshd gracefully !484 +- Provide liveness and readiness probes !494 +- Add tracing instrumentation to http client !495 +- Log same correlation_id on auth keys check of ssh connections !501 +- fix: validate client cert paths exist on disk before proceeding !508 +- Modify regex to prevent partial matches + v13.20.0 - Remove bin/authorized_keys !491 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.20.0 +13.21.0 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1629906785 0 # Wed Aug 25 15:53:05 2021 +0000 # Node ID 854da4efdb45866ea0259ffcd156c46f5f8b238b # Parent 6415f1b04fa7998f0c06b2a12b06d45eb15651ad # Parent f8a1d5432aebce2dc98f5e17722235818e47d9b3 Merge branch 'release-13-21' into 'main' Release v13.21.0 See merge request gitlab-org/gitlab-shell!512 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +v13.21.0 + +- Change default logging format to JSON !476 +- Shutdown sshd gracefully !484 +- Provide liveness and readiness probes !494 +- Add tracing instrumentation to http client !495 +- Log same correlation_id on auth keys check of ssh connections !501 +- fix: validate client cert paths exist on disk before proceeding !508 +- Modify regex to prevent partial matches + v13.20.0 - Remove bin/authorized_keys !491 @@ -6,6 +16,10 @@ - Fix the Geo SSH push proxy hanging !487 - Standardize logging timestamp format !485 +v13.19.1 + +- Modify regex to prevent partial matches + v13.19.0 - Don't finish the opentracing span early !466 @@ -13,6 +27,10 @@ - Stop changing directory to the filesystem root !470 - Fix opentracing setup for gitlab-sshd !473 +v13.18.1 + +- Modify regex to prevent partial matches + v13.18.0 - Fix thread-safety issues in gitlab-shell !463 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.20.0 +13.21.0 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632383296 0 # Thu Sep 23 07:48:16 2021 +0000 # Node ID da6ed6ed7edcb351d82790a413d3edab8e991c10 # Parent 854da4efdb45866ea0259ffcd156c46f5f8b238b Merge branch 'sh-fix-issue-529' into 'main' Only validate SSL cert file exists if a value is supplied See merge request gitlab-org/gitlab-shell!527 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -55,6 +55,22 @@ } } +func validateCaFile(filename string) error { + if filename == "" { + return nil + } + + if _, err := os.Stat(filename); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("cannot find cafile '%s': %w", filename, ErrCafileNotFound) + } + + return err + } + + return nil +} + // Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) @@ -74,10 +90,8 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { - if _, err := os.Stat(caFile); err != nil { - if os.IsNotExist(err) { - return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) - } + err = validateCaFile(caFile) + if err != nil { return nil, err } diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -66,10 +66,11 @@ func TestFailedRequests(t *testing.T) { testCases := []struct { - desc string - caFile string - caPath string - expectedError string + desc string + caFile string + caPath string + expectedCaFileNotFound bool + expectedError string }{ { desc: "Invalid CaFile", @@ -77,18 +78,25 @@ expectedError: "Internal API unreachable", }, { - desc: "Invalid CaPath", - caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + desc: "Missing CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/missing.crt"), + expectedCaFileNotFound: true, }, { - desc: "Empty config", + desc: "Invalid CaPath", + caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + expectedError: "Internal API unreachable", + }, + { + desc: "Empty config", + expectedError: "Internal API unreachable", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) - if tc.caFile == "" { + if tc.expectedCaFileNotFound { require.Error(t, err) require.ErrorIs(t, err, ErrCafileNotFound) } else { # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1632384319 25200 # Thu Sep 23 01:05:19 2021 -0700 # Node ID a32928a56da5398ddec1d2b2f2df48e07863e2fe # Parent da6ed6ed7edcb351d82790a413d3edab8e991c10 Release v13.21.1 This brings in https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/527 to fix SSL certs not working when HTTPS is used for the internal API. diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.21.1 + +- Only validate SSL cert file exists if a value is supplied !527 + v13.21.0 - Change default logging format to JSON !476 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.21.0 +13.21.1 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632385264 0 # Thu Sep 23 08:21:04 2021 +0000 # Node ID 5b532c297ecf2e1ee5819a6ab61bbee647a6c904 # Parent da6ed6ed7edcb351d82790a413d3edab8e991c10 # Parent a32928a56da5398ddec1d2b2f2df48e07863e2fe Merge branch 'sh-release-13-21-1' into '13-21-stable' Release v13.21.1 See merge request gitlab-org/gitlab-shell!529 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.21.1 + +- Only validate SSL cert file exists if a value is supplied !527 + v13.21.0 - Change default logging format to JSON !476 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.21.0 +13.21.1 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1636629399 -3600 # Thu Nov 11 12:16:39 2021 +0100 # Branch heptapod-stable # Node ID 29ff795406b8b544ad4be6b1dcbc3f119b955a36 # Parent 23b11deb9b862507063f1da21be251b61a7d4fb4 # Parent 837e1b491f17f9d8f8e2c0e5bb5519de76b6c4fb heptapod#574: making Heptapod 0.26 the new stable diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -34,3 +34,4 @@ 3cfed32ac2038975b533352ff0f4839aa2a0a319 heptapod-13.18.1 aefbb5e3eac5411fc526a88d3df1762ecbdc2e76 heptapod-13.19.0 b84ce63181d5c0d07585be867dbe957eb6d35348 heptapod-13.19.1 +f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,6 +9,11 @@ The corresponding tag is heptapod-x.y.z +## 13.19.2 + +- Added support for the new `NO_GIT` flag, telling Mercurial not to + use hg-git + ## 13.19.1 - No actual changes diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.19.1 +13.19.2 diff --git a/internal/command/hg/hg.go b/internal/command/hg/hg.go --- a/internal/command/hg/hg.go +++ b/internal/command/hg/hg.go @@ -80,6 +80,7 @@ "HEPTAPOD_REPOSITORY_USAGE=" + strings.Split(response.Repo, "-")[0], // FormatBool output is "true" or "false", understood by hg config "HEPTAPOD_HG_NATIVE=" + strconv.FormatBool(response.HgNative), + "HEPTAPOD_NO_GIT=" + strconv.FormatBool(response.NoGit), }...) if c.Config.Mercurial.ModulePolicy != "" { env = append(env, "HGMODULEPOLICY=" + c.Config.Mercurial.ModulePolicy) diff --git a/internal/command/hg/hg_test.go b/internal/command/hg/hg_test.go --- a/internal/command/hg/hg_test.go +++ b/internal/command/hg/hg_test.go @@ -72,7 +72,9 @@ func TestExecuteSuccessfully(t *testing.T) { type testcase struct { native_input *bool + no_git_input *bool native_expected string + no_git_expected string module_policy string } @@ -81,14 +83,17 @@ yes := true; testcases := []testcase{ - {native_input: nil, native_expected: "false", module_policy: "c"}, - {native_input: &no, native_expected: "false", module_policy: ""}, - {native_input: &yes, native_expected: "true"}, + {native_input: nil, native_expected: "false", no_git_expected: "false", module_policy: "c"}, + {native_input: &no, native_expected: "false", no_git_expected: "false", module_policy: ""}, + {native_input: &yes, native_expected: "true", no_git_expected: "false"}, + {native_input: nil, no_git_input: &yes, native_expected: "false", no_git_expected: "true", module_policy: "c"}, + {native_input: &no, no_git_input: &yes, native_expected: "false", no_git_expected: "true", module_policy: ""}, + {native_input: &yes, native_expected: "true", no_git_input: &yes, no_git_expected: "true"}, } for _, tc := range testcases { - requests := requesthandlers.BuildHgApiSuccessHandlers(t, tc.native_input) + requests := requesthandlers.BuildHgApiSuccessHandlers(t, tc.native_input, tc.no_git_input) url := testserver.StartHttpServer(t, requests) output := &bytes.Buffer{} @@ -128,6 +133,7 @@ require.Equal(t, "awesome-proj", fake.Env["HEPTAPOD_PROJECT_PATH"]) require.Equal(t, "my/group", fake.Env["HEPTAPOD_PROJECT_NAMESPACE_FULL_PATH"]) require.Equal(t, tc.native_expected, fake.Env["HEPTAPOD_HG_NATIVE"]) + require.Equal(t, tc.no_git_expected, fake.Env["HEPTAPOD_NO_GIT"]) require.Equal(t, "/usr/share/shipped.hgrc:/etc/main.hgrc", fake.Env["HGRCPATH"]) require.Equal(t, tc.module_policy, fake.Env["HGMODULEPOLICY"]) } @@ -135,7 +141,7 @@ func TestIgnoreHarmfulClientArgs(t *testing.T) { - requests := requesthandlers.BuildHgApiSuccessHandlers(t, nil) + requests := requesthandlers.BuildHgApiSuccessHandlers(t, nil, nil) url := testserver.StartHttpServer(t, requests) output := &bytes.Buffer{} diff --git a/internal/gitlabnet/accessverifier/hg_client.go b/internal/gitlabnet/accessverifier/hg_client.go --- a/internal/gitlabnet/accessverifier/hg_client.go +++ b/internal/gitlabnet/accessverifier/hg_client.go @@ -33,6 +33,7 @@ Email string `json:"gl_email"` ProjectId int `json:"project_id"` HgNative bool `json:"hg_native"` + NoGit bool `json:"no_git"` StatusCode int } diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -50,7 +50,7 @@ return requests } -func BuildHgApiSuccessHandlers(t *testing.T, hg_native *bool) []testserver.TestRequestHandler { +func BuildHgApiSuccessHandlers(t *testing.T, hg_native *bool, no_git *bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/hg_access", @@ -68,6 +68,9 @@ if (hg_native != nil) { body["hg_native"] = *hg_native } + if (no_git != nil) { + body["no_git"] = *no_git + } w.WriteHeader(http.StatusOK) require.NoError(t, json.NewEncoder(w).Encode(body)) }, # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1636323814 -3600 # Sun Nov 07 23:23:34 2021 +0100 # Branch heptapod # Node ID f23dd26963eecab3f2dc56638921336cc5e88db2 # Parent 837e1b491f17f9d8f8e2c0e5bb5519de76b6c4fb # Parent 5b532c297ecf2e1ee5819a6ab61bbee647a6c904 Merged upstream v13.21.1 Just had to adapt the setup for hg_client_test.go because of a test helper API change and rerun `make fmt` (new rule, it seems). diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,20 +52,6 @@ script: - make verify test -go:1.14: - extends: .test - image: golang:1.14 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.15: - extends: .test - image: golang:1.15 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.16: extends: .test image: golang:1.16 @@ -73,9 +59,16 @@ - make coverage coverage: '/\d+.\d+%/' +go:1.17: + extends: .test + image: golang:1.17 + after_script: + - make coverage + coverage: '/\d+.\d+%/' + race: extends: .test - image: golang:1.16 + image: golang:1.17 script: - make test_golang_race diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,25 @@ +v13.21.1 + +- Only validate SSL cert file exists if a value is supplied !527 + +v13.21.0 + +- Change default logging format to JSON !476 +- Shutdown sshd gracefully !484 +- Provide liveness and readiness probes !494 +- Add tracing instrumentation to http client !495 +- Log same correlation_id on auth keys check of ssh connections !501 +- fix: validate client cert paths exist on disk before proceeding !508 +- Modify regex to prevent partial matches + +v13.20.0 + +- Remove bin/authorized_keys !491 +- Add a make install command !490 +- Create PROCESS.md page with Security release process !488 +- Fix the Geo SSH push proxy hanging !487 +- Standardize logging timestamp format !485 + v13.19.1 - Modify regex to prevent partial matches diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,6 +9,10 @@ The corresponding tag is heptapod-x.y.z +## 13.21.0 + +- Jump to upstream GitLab Shell v13.21.1 (GitLab 14.4 series) + ## 13.19.2 - Added support for the new `NO_GIT` flag, telling Mercurial not to diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.19.2 +13.21.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _install build compile check clean +.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) @@ -6,12 +6,17 @@ BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +PREFIX ?= /usr/local + validate: verify test verify: verify_golang verify_golang: - gofmt -s -l $(GO_SOURCES) + gofmt -s -l $(GO_SOURCES) | awk '{ print } END { if (NR > 0) { print "Please run make fmt"; exit 1 } }' + +fmt: + gofmt -w -s $(GO_SOURCES) test: test_ruby test_golang @@ -30,9 +35,9 @@ coverage_golang: [ -f cover.out ] && go tool cover -func cover.out -setup: _install bin/gitlab-shell +setup: _script_install bin/gitlab-shell -_install: +_script_install: bin/install build: bin/gitlab-shell @@ -45,3 +50,12 @@ clean: rm -f bin/check bin/gitlab-shell bin/gitlab-shell-authorized-keys-check bin/gitlab-shell-authorized-principals-check bin/gitlab-sshd + +install: compile + mkdir -p $(DESTDIR)$(PREFIX)/bin/ + install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd + diff --git a/PROCESS.md b/PROCESS.md new file mode 100644 --- /dev/null +++ b/PROCESS.md @@ -0,0 +1,44 @@ +## Releasing a new version + +GitLab Shell is versioned by git tags, and the version used by the Rails +application is stored in +[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). + +For each version, there is a raw version and a tag version: + +- The **raw version** is the version number. For instance, `15.2.8`. +- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. + +To release a new version of GitLab Shell and have that version available to the +Rails application: + +1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the + **tag version** and the [`VERSION`](VERSION) file with the **raw version**. +2. Ask a maintainer to review and merge the merge request. If you're already a + maintainer, second maintainer review is not required. +3. Add a new git tag with the **tag version**. +4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw + version**. (Note: this can be done as a separate MR to that, or in and MR + that will make use of the latest GitLab Shell changes.) + +## Security releases + +GitLab Shell is included in the packages we create for GitLab, and each version of GitLab specifies the version of GitLab Shell it uses in the `GITLAB_SHELL_VERSION` file, so security fixes in GitLab Shell are tightly coupled to the [GitLab security release](https://about.gitlab.com/handbook/engineering/workflow/#security-issues) workflow. + +For a security fix in GitLab Shell, two sets of merge requests are required: + +* The fix itself, in the `gitlab-org/security/gitlab-shell` repository and its backports to the previous versions of GitLab Shell +* Merge requests to change the versions of GitLab Shell included in the GitLab security release, in the `gitlab-org/security/gitlab` repository + +The first step could be to create a merge request with a fix targeting `main` in `gitlab-org/security/gitlab-shell`. When the merge request is approved by maintainers, backports targeting previous 3 versions of GitLab Shell must be created. The stable branches for those versions may not exist, feel free to ask a maintainer to create ones. The stable branches must be created out of the GitLab Shell tags/version used by the 3 previous GitLab releases. In order to find out the GitLab Shell version that is used on a particular GitLab stable release, the following steps may be helpful: + +```shell +git fetch security 13-9-stable-ee +git show refs/remotes/security/13-9-stable-ee:GITLAB_SHELL_VERSION +``` + +These steps display the version that is used by `13.9` version of GitLab. + +Close to the GitLab security release, a maintainer should merge the fix and backports and cut all the necessary GitLab Shell versions. This allows bumping the `GITLAB_SHELL_VERSION` for `gitlab-org/security/gitlab`. The GitLab merge request will be handled by the general GitLab security release process. + +Once the security release is done, a GitLab Shell maintainer is responsible for syncing tags and `main` to the `gitlab-org/gitlab-shell` repository. diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ When you access the GitLab server over SSH then GitLab Shell will: -1. Limits you to predefined git commands (git push, git pull). +1. Limit you to predefined git commands (git push, git pull). 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server @@ -38,16 +38,36 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Setup - - make setup - ## Check Checks if GitLab API access and redis via internal API can be reached: make check +## Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + + make compile + +## Install + +Builds the `gitlab-shell` binaries and installs them onto the filesystem. The +default location is `/usr/local`, but can be controlled by use of the `PREFIX` +and `DESTDIR` environment variables. + + make install + +## Setup + +This command is intended for use when installing GitLab from source on a single +machine. In addition to compiling the gitlab-shell binaries, it ensures that +various paths on the filesystem exist with the correct permissions. Do not run +it unless instructed to by your installation method documentation. + + make setup + + ## Testing Run tests: @@ -82,28 +102,9 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. -## Releasing a new version - -GitLab Shell is versioned by git tags, and the version used by the Rails -application is stored in -[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). - -For each version, there is a raw version and a tag version: - -- The **raw version** is the version number. For instance, `15.2.8`. -- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. +## Releasing -To release a new version of GitLab Shell and have that version available to the -Rails application: - -1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the - **tag version** and the [`VERSION`](VERSION) file with the **raw version**. -2. Ask a maintainer to review and merge the merge request. If you're already a - maintainer, second maintainer review is not required. -3. Add a new git tag with the **tag version**. -4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw - version**. (Note: this can be done as a separate MR to that, or in and MR - that will make use of the latest GitLab Shell changes.) +See [PROCESS.md](./PROCESS.md) ## Contributing diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.19.1 +13.21.1 diff --git a/bin/authorized_keys b/bin/authorized_keys deleted file mode 100755 --- a/bin/authorized_keys +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Legacy script used for AuthorizedKeysCommand when configured without username. -# Executes gitlab-shell-authorized-keys-check with "git" as expected and actual -# username and with the passed key. -# -# TODO: Remove this in https://gitlab.com/gitlab-org/gitlab-shell/issues/209. - -$(dirname $0)/gitlab-shell-authorized-keys-check git git $1 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -11,16 +11,14 @@ "strings" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) func TestClients(t *testing.T) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) testCases := []struct { desc string @@ -61,7 +59,8 @@ secret := "sssh, it's a secret" - httpClient := NewHTTPClient(url, tc.relativeURLRoot, tc.caFile, "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient("", "", secret, httpClient) require.NoError(t, err) @@ -78,7 +77,6 @@ func testSuccessfulGet(t *testing.T, client *GitlabNetClient) { t.Run("Successful get", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) require.NotNil(t, response) @@ -88,22 +86,11 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testSuccessfulPost(t *testing.T, client *GitlabNetClient) { t.Run("Successful Post", func(t *testing.T) { - hook := testhelper.SetupLogger() data := map[string]string{"key": "value"} response, err := client.Post(context.Background(), "/post_endpoint", data) @@ -115,50 +102,20 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testMissing(t *testing.T, client *GitlabNetClient) { t.Run("Missing error for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/missing") require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Missing error for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Post(context.Background(), "/missing", map[string]string{}) require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) } @@ -178,37 +135,15 @@ func testBrokenRequest(t *testing.T, client *GitlabNetClient) { t.Run("Broken request for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Get(context.Background(), "/broken") require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Broken request for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Post(context.Background(), "/broken", map[string]string{}) require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) } diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,9 +11,7 @@ "strings" "time" - "gitlab.com/gitlab-org/labkit/correlation" - - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -71,12 +69,12 @@ return path } -func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, string, error) { +func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { jsonData, err := json.Marshal(data) if err != nil { - return nil, "", err + return nil, err } jsonReader = bytes.NewReader(jsonData) @@ -84,12 +82,10 @@ request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) if err != nil { - return nil, "", err + return nil, err } - correlationID := correlation.ExtractFromContext(ctx) - - return request, correlationID, nil + return request, nil } func parseError(resp *http.Response) error { @@ -116,7 +112,7 @@ } func (c *GitlabNetClient) DoRequest(ctx context.Context, method, path string, data interface{}) (*http.Response, error) { - request, correlationID, err := newRequest(ctx, method, c.httpClient.Host, path, data) + request, err := newRequest(ctx, method, c.httpClient.Host, path, data) if err != nil { return nil, err } @@ -136,12 +132,11 @@ start := time.Now() response, err := c.httpClient.Do(request) fields := log.Fields{ - "correlation_id": correlationID, - "method": method, - "url": request.URL.String(), - "duration_ms": time.Since(start) / time.Millisecond, + "method": method, + "url": request.URL.String(), + "duration_ms": time.Since(start) / time.Millisecond, } - logger := log.WithFields(fields) + logger := log.WithContextFields(ctx, fields) if err != nil { logger.WithError(err).Error("Internal API unreachable") diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -5,15 +5,18 @@ "crypto/tls" "crypto/x509" "errors" + "fmt" "io/ioutil" "net" "net/http" + "os" "path/filepath" "strings" "time" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/labkit/tracing" ) const ( @@ -24,6 +27,10 @@ defaultReadTimeoutSeconds = 300 ) +var ( + ErrCafileNotFound = errors.New("cafile not found") +) + type HttpClient struct { *http.Client Host string @@ -48,6 +55,22 @@ } } +func validateCaFile(filename string) error { + if filename == "" { + return nil + } + + if _, err := os.Stat(filename); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("cannot find cafile '%s': %w", filename, ErrCafileNotFound) + } + + return err + } + + return nil +} + // Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) @@ -59,15 +82,6 @@ // NewHTTPClientWithOpts builds an HTTP client using the provided options func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { - hcc := &httpClientCfg{ - caFile: caFile, - caPath: caPath, - } - - for _, opt := range opts { - opt(hcc) - } - var transport *http.Transport var host string var err error @@ -76,6 +90,20 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { + err = validateCaFile(caFile) + if err != nil { + return nil, err + } + + hcc := &httpClientCfg{ + caFile: caFile, + caPath: caPath, + } + + for _, opt := range opts { + opt(hcc) + } + transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) if err != nil { return nil, err @@ -85,7 +113,7 @@ } c := &http.Client{ - Transport: correlation.NewInstrumentedRoundTripper(transport), + Transport: correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(transport)), Timeout: readTimeout(readTimeoutSeconds), } diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,8 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client := NewHTTPClient("http://localhost:3000", "", "", "", false, expectedSeconds) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + require.NoError(t, err) require.NotNil(t, client) require.Equal(t, time.Duration(expectedSeconds)*time.Second, client.Client.Timeout) @@ -122,7 +123,8 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient := NewHTTPClient(url, "", "", "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) require.NoError(t, err) diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -28,10 +28,7 @@ { desc: "Valid CaPath", caPath: path.Join(testhelper.TestRoot, "certs/valid"), - }, - { - desc: "Self signed cert option enabled", - selfSigned: true, + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Invalid cert with self signed cert option enabled", @@ -51,7 +48,8 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) @@ -68,39 +66,51 @@ func TestFailedRequests(t *testing.T) { testCases := []struct { - desc string - caFile string - caPath string + desc string + caFile string + caPath string + expectedCaFileNotFound bool + expectedError string }{ { - desc: "Invalid CaFile", - caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + desc: "Invalid CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + expectedError: "Internal API unreachable", }, { - desc: "Invalid CaPath", - caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + desc: "Missing CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/missing.crt"), + expectedCaFileNotFound: true, }, { - desc: "Empty config", + desc: "Invalid CaPath", + caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + expectedError: "Internal API unreachable", + }, + { + desc: "Empty config", + expectedError: "Internal API unreachable", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + if tc.expectedCaFileNotFound { + require.Error(t, err) + require.ErrorIs(t, err, ErrCafileNotFound) + } else { + _, err = client.Get(context.Background(), "/hello") + require.Error(t, err) - _, err := client.Get(context.Background(), "/hello") - require.Error(t, err) - - require.Equal(t, err.Error(), "Internal API unreachable") + require.Equal(t, err.Error(), tc.expectedError) + } }) } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) *GitlabNetClient { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { + testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ { @@ -121,10 +131,11 @@ } httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) - require.NoError(t, err) + if err != nil { + return nil, err + } client, err := NewGitlabNetClient("", "", "", httpClient) - require.NoError(t, err) - return client + return client, err } diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -31,7 +31,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -46,7 +46,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() env := sshenv.NewFromEnv() cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -95,9 +95,7 @@ t.Helper() return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) t.Logf("gitlab-api-mock: received request: %s %s", r.Method, r.RequestURI) w.Header().Set("Content-Type", "application/json") @@ -231,7 +229,7 @@ t.Cleanup(func() { pw.Close() }) scanner := bufio.NewScanner(pr) - extractor := regexp.MustCompile(`msg="Listening on ([0-9a-f\[\]\.:]+)"`) + extractor := regexp.MustCompile(`"tcp_address":"([0-9a-f\[\]\.:]+)"`) ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, sshdPath, "-config-dir", dir) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -1,15 +1,19 @@ package main import ( + "context" "flag" "os" - - log "github.com/sirupsen/logrus" + "os/signal" + "syscall" + "time" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" ) @@ -45,37 +49,65 @@ var err error cfg, err = config.NewFromDir(*configDir) if err != nil { - log.Fatalf("failed to load configuration from specified directory: %v", err) + log.WithError(err).Fatal("failed to load configuration from specified directory") } } overrideConfigFromEnvironment(cfg) if err := cfg.IsSane(); err != nil { if *configDir == "" { - log.Warn("note: no config-dir provided, using only environment variables") + log.WithError(err).Fatal("no config-dir provided, using only environment variables") + } else { + log.WithError(err).Fatal("configuration error") } - log.Fatalf("configuration error: %v", err) } cfg.ApplyGlobalState() - logger.ConfigureStandalone(cfg) + logCloser := logger.ConfigureStandalone(cfg) + defer logCloser.Close() ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + server, err := sshd.NewServer(cfg) + if err != nil { + log.WithError(err).Fatal("Failed to start GitLab built-in sshd") + } + // Startup monitoring endpoint. if cfg.Server.WebListen != "" { go func() { - log.Fatal( - monitoring.Start( - monitoring.WithListenerAddress(cfg.Server.WebListen), - monitoring.WithBuildInformation(Version, BuildTime), - ), + err := monitoring.Start( + monitoring.WithListenerAddress(cfg.Server.WebListen), + monitoring.WithBuildInformation(Version, BuildTime), + monitoring.WithServeMux(server.MonitoringServeMux()), ) + + log.WithError(err).Fatal("monitoring service raised an error") }() } - if err := sshd.Run(ctx, cfg); err != nil { - log.Fatalf("Failed to start GitLab built-in sshd: %v", err) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + done := make(chan os.Signal, 1) + signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) + + go func() { + sig := <-done + signal.Reset(syscall.SIGINT, syscall.SIGTERM) + + log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + + server.Shutdown() + + <-time.After(cfg.Server.GracePeriod()) + + cancel() + + }() + + if err := server.ListenAndServe(ctx); err != nil { + log.WithError(err).Fatal("GitLab built-in sshd failed to listen for new connections") } } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -66,7 +66,7 @@ # Log level. INFO by default log_level: INFO -# Log format. 'text' by default +# Log format. 'json' by default, can be changed to 'text' if needed # log_format: json # Audit usernames. @@ -89,7 +89,7 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # SSH host key files. + # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.13 +go 1.16 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 @@ -8,12 +8,11 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.5.0 + github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 - github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 - gitlab.com/gitlab-org/labkit v1.4.1 + gitlab.com/gitlab-org/labkit v1.7.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.37.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -16,6 +16,7 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= @@ -38,6 +39,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +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= 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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -81,6 +84,8 @@ github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= +github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -91,6 +96,8 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -155,7 +162,6 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 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 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 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= @@ -173,7 +179,6 @@ github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -212,8 +217,9 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -260,10 +266,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 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= @@ -274,6 +278,7 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= @@ -343,6 +348,10 @@ 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= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -485,7 +494,6 @@ github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= @@ -503,10 +511,9 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pires/go-proxyproto v0.5.0 h1:A4Jv4ZCaV3AFJeGh5mGwkz4iuWUYMlQ7IoO/GTuSuLo= -github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= +github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= @@ -645,8 +652,8 @@ gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= -gitlab.com/gitlab-org/labkit v1.4.1 h1:mh4g+c/esQSWCVQJ197aftrIbXlhXCtiLC8RgSvyCx0= -gitlab.com/gitlab-org/labkit v1.4.1/go.mod h1:x5JO5uvdX4t6e/TZXLXZnFL5AcKz2uLLd3uKXZcuO4k= +gitlab.com/gitlab-org/labkit v1.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= +gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= 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.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -657,6 +664,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -699,7 +707,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -771,6 +778,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= @@ -783,6 +791,7 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -937,6 +946,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -945,9 +955,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= @@ -969,6 +977,7 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= @@ -1020,6 +1029,8 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= diff --git a/internal/command/hg/hg.go b/internal/command/hg/hg.go --- a/internal/command/hg/hg.go +++ b/internal/command/hg/hg.go @@ -83,7 +83,7 @@ "HEPTAPOD_NO_GIT=" + strconv.FormatBool(response.NoGit), }...) if c.Config.Mercurial.ModulePolicy != "" { - env = append(env, "HGMODULEPOLICY=" + c.Config.Mercurial.ModulePolicy) + env = append(env, "HGMODULEPOLICY="+c.Config.Mercurial.ModulePolicy) } hg_exe := c.Config.Mercurial.BinPath() diff --git a/internal/command/hg/hg_test.go b/internal/command/hg/hg_test.go --- a/internal/command/hg/hg_test.go +++ b/internal/command/hg/hg_test.go @@ -79,8 +79,8 @@ } // cannot directly take a reference to false and true - no := false; - yes := true; + no := false + yes := true testcases := []testcase{ {native_input: nil, native_expected: "false", no_git_expected: "false", module_policy: "c"}, @@ -103,7 +103,7 @@ GitlabUrl: url, Mercurial: config.MercurialConfig{ OptionalBinPath: "hg5.4-py3", - ModulePolicy: tc.module_policy, + ModulePolicy: tc.module_policy, Hgrc: []string{"/usr/share/shipped.hgrc", "/etc/main.hgrc"}}, }, Args: &commandargs.Shell{GitlabKeyId: "key-12", SshArgs: []string{"hg", "-R", "my/group/awesome-proj", "serve", "--stdio"}}, diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -14,12 +13,11 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -43,10 +41,15 @@ env := sshenv.Env{ IsSSHConnection: true, - OriginalCommand: "git-receive-pack group/repo", + OriginalCommand: "git-receive-pack " + repo, RemoteAddr: "127.0.0.1", } - args := &commandargs.Shell{CommandType: commandargs.ReceivePack, SshArgs: []string{"git-receive-pack", repo}, Env: env} + + args := &commandargs.Shell{ + CommandType: commandargs.ReceivePack, + SshArgs: []string{"git-receive-pack", repo}, + Env: env, + } if tc.username != "" { args.GitlabUsername = tc.username @@ -60,7 +63,6 @@ ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -73,15 +75,20 @@ require.Equal(t, "ReceivePack: key-123 "+repo, output.String()) } - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-receive-pack") - require.Contains(t, entries[1].Message, "remote_ip=127.0.0.1") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-receive-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } } diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -10,12 +10,13 @@ "io" "net/http" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + + "gitlab.com/gitlab-org/labkit/log" ) type Request struct { @@ -112,10 +113,32 @@ } func (c *Command) readFromStdin() ([]byte, error) { - output := new(bytes.Buffer) - _, err := io.Copy(output, c.ReadWriter.In) + var output []byte + var needsPackData bool + + scanner := pktline.NewScanner(c.ReadWriter.In) + for scanner.Scan() { + line := scanner.Bytes() + output = append(output, line...) + + if pktline.IsFlush(line) { + break + } - return output.Bytes(), err + if !needsPackData && !pktline.IsRefRemoval(line) { + needsPackData = true + } + } + + if needsPackData { + packData := new(bytes.Buffer) + _, err := io.Copy(packData, c.ReadWriter.In) + + output = append(output, packData.Bytes()...) + return output, err + } else { + return output, nil + } } func (c *Command) readFromStdinNoEOF() []byte { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -46,7 +46,7 @@ require.NoError(t, json.Unmarshal(b, &request)) require.Equal(t, request.Data.UserId, who) - require.Equal(t, "input", string(request.Output)) + require.Equal(t, "0009input", string(request.Output)) err = json.NewEncoder(w).Encode(Response{Result: []byte("output")}) require.NoError(t, err) @@ -58,7 +58,7 @@ outBuf := &bytes.Buffer{} errBuf := &bytes.Buffer{} - input := bytes.NewBufferString("input") + input := bytes.NewBufferString("0009input") response := &accessverifier.Response{ Who: who, diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,12 +12,12 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) -func TestUploadPack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) +func TestUploadArchive(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-archive " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadArchive, + SshArgs: []string{"git-upload-archive", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadArchive, SshArgs: []string{"git-upload-archive", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -44,13 +55,19 @@ require.Equal(t, "UploadArchive: "+repo, output.String()) - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-archive") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-archive", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -4,7 +4,6 @@ "bytes" "context" "testing" - "time" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,7 +12,7 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadPack, SshArgs: []string{"git-upload-pack", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -43,25 +54,20 @@ require.NoError(t, err) require.Equal(t, "UploadPack: "+repo, output.String()) - require.Eventually(t, func() bool { - entries := hook.AllEntries() - - require.Equal(t, 2, len(entries)) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-pack") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") - return true - }, time.Second, time.Millisecond) for k, v := range map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", } { actual := testServer.ReceivedMD[k] require.Len(t, actual, 1) require.Equal(t, v, actual[0]) } require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -9,11 +9,13 @@ "path/filepath" "strings" "sync" + "time" - "gitlab.com/gitlab-org/labkit/tracing" + "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) const ( @@ -22,8 +24,8 @@ ) var ( - defaultHgBinPath string = "hg" - defaultHgrcPath string = "/opt/gitlab/etc/docker.hgrc:/etc/gitlab/heptapod.hgrc" + defaultHgBinPath string = "hg" + defaultHgrcPath string = "/opt/gitlab/etc/docker.hgrc:/etc/gitlab/heptapod.hgrc" ) type ServerConfig struct { @@ -31,6 +33,9 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` } @@ -76,10 +81,11 @@ Secret string `yaml:"secret"` SslCertDir string `yaml:"ssl_cert_dir"` HttpSettings HttpSettingsConfig `yaml:"http_settings"` - Mercurial MercurialConfig `yaml:"mercurial"` + Mercurial MercurialConfig `yaml:"mercurial"` Server ServerConfig `yaml:"sshd"` httpClient *client.HttpClient + httpClientErr error httpClientOnce sync.Once } @@ -87,7 +93,7 @@ var ( DefaultConfig = Config{ LogFile: "gitlab-shell.log", - LogFormat: "text", + LogFormat: "json", Server: DefaultServerConfig, User: "git", } @@ -96,6 +102,9 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -104,30 +113,39 @@ } ) +func (sc *ServerConfig) GracePeriod() time.Duration { + return time.Duration(sc.GracePeriodSeconds) * time.Second +} + func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { os.Setenv("SSL_CERT_DIR", c.SslCertDir) } } -func (c *Config) HttpClient() *client.HttpClient { +func (c *Config) HttpClient() (*client.HttpClient, error) { c.httpClientOnce.Do(func() { - client := client.NewHTTPClient( + client, err := client.NewHTTPClientWithOpts( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, + nil, ) + if err != nil { + c.httpClientErr = err + return + } tr := client.Transport - client.Transport = tracing.NewRoundTripper(tr) + client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) c.httpClient = client }) - return c.httpClient + return c.httpClient, c.httpClientErr } // NewFromDirExternal returns a new config from a given root dir. It also applies defaults appropriate for diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -4,8 +4,10 @@ "os" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -22,3 +24,28 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } + +func TestHttpClient(t *testing.T) { + url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) + + config := &Config{GitlabUrl: url} + client, err := config.HttpClient() + require.NoError(t, err) + + _, err = client.Get("http://host.com/path") + require.NoError(t, err) + + ms, err := prometheus.DefaultGatherer.Gather() + require.NoError(t, err) + + lastMetric := ms[0] + require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") + + labels := lastMetric.GetMetric()[0].Label + + require.Equal(t, "code", labels[0].GetName()) + require.Equal(t, "404", labels[0].GetValue()) + + require.Equal(t, "method", labels[1].GetName()) + require.Equal(t, "get", labels[1].GetValue()) +} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -163,9 +163,7 @@ } func setup(t *testing.T, allowedPayload string) *Client { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) diff --git a/internal/gitlabnet/accessverifier/hg_client_test.go b/internal/gitlabnet/accessverifier/hg_client_test.go --- a/internal/gitlabnet/accessverifier/hg_client_test.go +++ b/internal/gitlabnet/accessverifier/hg_client_test.go @@ -111,9 +111,7 @@ } func hgSetup(t *testing.T) *HgClient { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/hg_allowed.json")) require.NoError(t, err) diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -15,7 +15,10 @@ ) func GetClient(config *config.Config) (*client.GitlabNetClient, error) { - httpClient := config.HttpClient() + httpClient, err := config.HttpClient() + if err != nil { + return nil, err + } if httpClient == nil { return nil, fmt.Errorf("Unsupported protocol") diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -8,18 +8,19 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" ) @@ -75,7 +76,6 @@ func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { fields := log.Fields{ "command": gc.ServiceName, - "correlation_id": correlation.ExtractFromContext(ctx), "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, "user_id": response.UserId, @@ -86,7 +86,7 @@ "gl_key_id": response.KeyId, } - log.WithFields(fields).Info("executing git command") + log.WithContextFields(ctx, fields).Info("executing git command") } func withOutgoingMetadata(ctx context.Context, features map[string]string) context.Context { @@ -108,9 +108,9 @@ serviceName := correlation.ExtractClientNameFromContext(ctx) if serviceName == "" { - log.Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + serviceName = "gitlab-shell-unknown" - serviceName = "gitlab-shell-unknown" + log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -2,25 +2,54 @@ import ( "fmt" + "io" "io/ioutil" "log/syslog" "os" + "time" - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) -func configureLogFormat(cfg *config.Config) { - if cfg.LogFormat == "json" { - log.SetFormatter(&log.JSONFormatter{}) +func logFmt(inFmt string) string { + // Hide the "combined" format, since that makes no sense in gitlab-shell. + // The default is JSON when unspecified. + if inFmt == "" || inFmt == "combined" { + return "json" + } + + return inFmt +} + +func logFile(inFile string) string { + if inFile == "" { + return "stderr" + } + + return inFile +} + +func buildOpts(cfg *config.Config) []log.LoggerOption { + return []log.LoggerOption{ + log.WithFormatter(logFmt(cfg.LogFormat)), + log.WithOutputName(logFile(cfg.LogFile)), + log.WithTimezone(time.UTC), } } // Configure configures the logging singleton for operation inside a remote TTY (like SSH). In this // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. -func Configure(cfg *config.Config) { - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) +func Configure(cfg *config.Config) io.Closer { + var closer io.Closer = ioutil.NopCloser(nil) + err := fmt.Errorf("No logfile specified") + + if cfg.LogFile != "" { + closer, err = log.Initialize(buildOpts(cfg)...) + } + if err != nil { progName, _ := os.Executable() syslogLogger, syslogLoggerErr := syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0) @@ -32,29 +61,35 @@ fmt.Fprintf(os.Stderr, msg) } - // Discard logs since a log file was specified but couldn't be opened - log.SetOutput(ioutil.Discard) + cfg.LogFile = "/dev/null" + closer, err = log.Initialize(buildOpts(cfg)...) + if err != nil { + log.WithError(err).Warn("Unable to configure logging to /dev/null, leaving unconfigured") + } } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } // ConfigureStandalone configures the logging singleton for standalone operation. In this mode an -// empty LogFile is treated as logging to standard output and standard output is used as a fallback +// empty LogFile is treated as logging to stderr, and standard output is used as a fallback // when LogFile could not be opened for writing. -func ConfigureStandalone(cfg *config.Config) { - if cfg.LogFile == "" { - return +func ConfigureStandalone(cfg *config.Config) io.Closer { + closer, err1 := log.Initialize(buildOpts(cfg)...) + if err1 != nil { + var err2 error + + cfg.LogFile = "stdout" + closer, err2 = log.Initialize(buildOpts(cfg)...) + + // Output this after the logger has been configured! + log.WithError(err1).WithField("log_file", cfg.LogFile).Warn("Unable to configure logging, falling back to STDOUT") + + // LabKit v1.7.0 doesn't have any conditions where logging to "stdout" will fail + if err2 != nil { + log.WithError(err2).Warn("Unable to configure logging to STDOUT, leaving unconfigured") + } } - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) - if err != nil { - log.Printf("Unable to configure logging, falling back to stdout: %v", err) - return - } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -3,11 +3,13 @@ import ( "io/ioutil" "os" + "regexp" "strings" "testing" - log "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) @@ -21,7 +23,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") tmpFile.Close() @@ -41,6 +45,34 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") } + +func TestLogInUTC(t *testing.T) { + tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + require.NoError(t, err) + defer tmpFile.Close() + defer os.Remove(tmpFile.Name()) + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + } + + closer := Configure(&config) + defer closer.Close() + + log.Info("this is a test") + + data, err := ioutil.ReadFile(tmpFile.Name()) + require.NoError(t, err) + + utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` + r, e := regexp.MatchString(utc, string(data)) + + require.NoError(t, e) + require.True(t, r) +} diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go new file mode 100644 --- /dev/null +++ b/internal/metrics/metrics.go @@ -0,0 +1,63 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +const ( + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" +) + +var ( + SshdConnectionDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "connection_duration_seconds", + Help: "A histogram of latencies for connections to gitlab-shell sshd.", + Buckets: []float64{ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ + }, + }, + ) + + SshdHitMaxSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "concurrent_limited_sessions_total", + Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", + }, + ) + + HttpRequestDuration = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: "request_seconds", + Help: "A histogram of latencies for gitlab-shell http requests", + Buckets: []float64{ + 0.01, /* 10ms */ + 0.05, /* 50ms */ + 0.1, /* 100ms */ + 0.25, /* 250ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ + 10.0, /* 10s */ + }, + }, + []string{"code", "method"}, + ) +) diff --git a/internal/pktline/pktline.go b/internal/pktline/pktline.go --- a/internal/pktline/pktline.go +++ b/internal/pktline/pktline.go @@ -8,6 +8,7 @@ "bytes" "fmt" "io" + "regexp" "strconv" ) @@ -16,6 +17,8 @@ pktDelim = "0001" ) +var branchRemovalPktRegexp = regexp.MustCompile(`\A[a-f0-9]{4}[a-f0-9]{40} 0{40} `) + // NewScanner returns a bufio.Scanner that splits on Git pktline boundaries func NewScanner(r io.Reader) *bufio.Scanner { scanner := bufio.NewScanner(r) @@ -24,7 +27,16 @@ return scanner } -// IsDone detects the special flush packet '0009done\n' +func IsRefRemoval(pkt []byte) bool { + return branchRemovalPktRegexp.Match(pkt) +} + +// IsFlush detects the special flush packet '0000' +func IsFlush(pkt []byte) bool { + return bytes.Equal(pkt, []byte("0000")) +} + +// IsDone detects the special done packet '0009done\n' func IsDone(pkt []byte) bool { return bytes.Equal(pkt, PktDone()) } diff --git a/internal/pktline/pktline_test.go b/internal/pktline/pktline_test.go --- a/internal/pktline/pktline_test.go +++ b/internal/pktline/pktline_test.go @@ -68,6 +68,40 @@ } } +func TestIsRefRemoval(t *testing.T) { + testCases := []struct { + in string + isRemoval bool + }{ + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f0000000000000000000000000000000000000000 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 0000000000000000000000000000000000000000 refs/heads/debug", isRemoval: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.isRemoval, IsRefRemoval([]byte(tc.in))) + }) + } +} + +func TestIsFlush(t *testing.T) { + testCases := []struct { + in string + flush bool + }{ + {in: "0008abcd", flush: false}, + {in: "invalid packet", flush: false}, + {in: "0000", flush: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.flush, IsFlush([]byte(tc.in))) + }) + } +} + func TestIsDone(t *testing.T) { testCases := []struct { in string diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -4,47 +4,12 @@ "context" "time" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" -) - -const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" -) -var ( - sshdConnectionDuration = promauto.NewHistogram( - prometheus.HistogramOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", - Help: "A histogram of latencies for connections to gitlab-shell sshd.", - Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ - }, - }, - ) + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - sshdHitMaxSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", - Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", - }, - ) + "gitlab.com/gitlab-org/labkit/log" ) type connection struct { @@ -64,7 +29,7 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - defer sshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { if newChannel.ChannelType() != "session" { @@ -73,12 +38,12 @@ } if !c.concurrentSessions.TryAcquire(1) { newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") - sshdHitMaxSessions.Inc() + metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - log.Infof("Could not accept channel: %v", err) + log.WithError(err).Info("could not accept channel") c.concurrentSessions.Release(1) continue } @@ -89,7 +54,7 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling session from %s: recovered: %#+v", c.remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) } }() diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "testing" "github.com/stretchr/testify/require" @@ -9,22 +10,31 @@ ) type rejectCall struct { - reason ssh.RejectionReason + reason ssh.RejectionReason message string } type fakeNewChannel struct { channelType string extraData []byte + acceptErr error + + acceptCh chan struct{} rejectCh chan rejectCall } func (f *fakeNewChannel) Accept() (ssh.Channel, <-chan *ssh.Request, error) { - return nil, nil, nil + if f.acceptCh != nil { + f.acceptCh <- struct{}{} + } + + return nil, nil, f.acceptErr } func (f *fakeNewChannel) Reject(reason ssh.RejectionReason, message string) error { - f.rejectCh <- rejectCall{reason: reason, message: message} + if f.rejectCh != nil { + f.rejectCh <- rejectCall{reason: reason, message: message} + } return nil } @@ -63,7 +73,9 @@ } func TestUnknownChannelType(t *testing.T) { - rejectCh := make(chan rejectCall, 1) + rejectCh := make(chan rejectCall) + defer close(rejectCh) + newChannel := &fakeNewChannel{channelType: "unknown session", rejectCh: rejectCh} conn, chans := setup(1, newChannel) @@ -72,8 +84,64 @@ }() rejectionData := <-rejectCh - close(rejectCh) expectedRejection := rejectCall{reason: ssh.UnknownChannelType, message: "unknown channel type"} require.Equal(t, expectedRejection, rejectionData) } + +func TestTooManySessions(t *testing.T) { + rejectCh := make(chan rejectCall) + defer close(rejectCh) + + newChannel := &fakeNewChannel{channelType: "session", rejectCh: rejectCh} + conn, chans := setup(1, newChannel) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + <-ctx.Done() // Keep the accepted channel open until the end of the test + }) + }() + + chans <- newChannel + require.Equal(t, <-rejectCh, rejectCall{reason: ssh.ResourceShortage, message: "too many concurrent sessions"}) +} + +func TestAcceptSessionSucceeds(t *testing.T) { + newChannel := &fakeNewChannel{channelType: "session"} + conn, chans := setup(1, newChannel) + + channelHandled := false + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + close(chans) + }) + + require.True(t, channelHandled) +} + +func TestAcceptSessionFails(t *testing.T) { + acceptCh := make(chan struct{}) + defer close(acceptCh) + + acceptErr := errors.New("some failure") + newChannel := &fakeNewChannel{channelType: "session", acceptCh: acceptCh, acceptErr: acceptErr} + conn, chans := setup(1, newChannel) + + channelHandled := false + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + }) + }() + + require.Equal(t, <-acceptCh, struct{}{}) + + // Waits until the number of sessions is back to 0, since we can only have 1 + conn.concurrentSessions.Acquire(context.Background(), 1) + defer conn.concurrentSessions.Release(1) + + require.False(t, channelHandled) +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -7,41 +7,171 @@ "fmt" "io/ioutil" "net" + "net/http" "strconv" + "sync" "time" - log "github.com/sirupsen/logrus" - "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" +) + +type status int + +const ( + StatusStarting status = iota + StatusReady + StatusOnShutdown + StatusClosed + ProxyHeaderTimeout = 90 * time.Second ) -func Run(ctx context.Context, cfg *config.Config) error { +type Server struct { + Config *config.Config + + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func NewServer(cfg *config.Config) (*Server, error) { authorizedKeysClient, err := authorizedkeys.NewClient(cfg) if err != nil { - return fmt.Errorf("failed to initialize GitLab client: %w", err) + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := ioutil.ReadFile(filename) + if err != nil { + log.WithError(err).Warnf("Failed to read host key %v", filename) + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).Warnf("Failed to parse host key %v", filename) + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") } - sshListener, err := net.Listen("tcp", cfg.Server.Listen) + return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil +} + +func (s *Server) ListenAndServe(ctx context.Context) error { + if err := s.listen(); err != nil { + return err + } + defer s.listener.Close() + + s.serve(ctx) + + return nil +} + +func (s *Server) Shutdown() error { + if s.listener == nil { + return nil + } + + s.changeStatus(StatusOnShutdown) + + return s.listener.Close() +} + +func (s *Server) MonitoringServeMux() *http.ServeMux { + mux := http.NewServeMux() + + mux.HandleFunc(s.Config.Server.ReadinessProbe, func(w http.ResponseWriter, r *http.Request) { + if s.getStatus() == StatusReady { + w.WriteHeader(http.StatusOK) + } else { + w.WriteHeader(http.StatusServiceUnavailable) + } + }) + + mux.HandleFunc(s.Config.Server.LivenessProbe, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + + return mux +} + +func (s *Server) listen() error { + sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) } - if cfg.Server.ProxyProtocol { - sshListener = &proxyproto.Listener{Listener: sshListener} + + if s.Config.Server.ProxyProtocol { + sshListener = &proxyproto.Listener{ + Listener: sshListener, + ReadHeaderTimeout: ProxyHeaderTimeout, + } log.Info("Proxy protocol is enabled") } - defer sshListener.Close() + + log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") + + s.listener = sshListener + + return nil +} + +func (s *Server) serve(ctx context.Context) { + s.changeStatus(StatusReady) + + for { + nconn, err := s.listener.Accept() + if err != nil { + if s.getStatus() == StatusOnShutdown { + break + } + + log.WithError(err).Warn("Failed to accept connection") + continue + } - log.Infof("Listening on %v", sshListener.Addr().String()) + s.wg.Add(1) + go s.handleConn(ctx, nconn) + } + + s.wg.Wait() + + s.changeStatus(StatusClosed) +} +func (s *Server) changeStatus(st status) { + s.statusMu.Lock() + s.status = st + s.statusMu.Unlock() +} + +func (s *Server) getStatus() status { + s.statusMu.Lock() + defer s.statusMu.Unlock() + + return s.status +} + +func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { sshCfg := &ssh.ServerConfig{ PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != cfg.User { + if conn.User() != s.Config.User { return nil, errors.New("unknown user") } if key.Type() == ssh.KeyAlgoDSA { @@ -49,7 +179,7 @@ } ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - res, err := authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) if err != nil { return nil, err } @@ -63,63 +193,41 @@ }, } - var loadedHostKeys uint - for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) - if err != nil { - log.Warnf("Failed to read host key %v: %v", filename, err) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.Warnf("Failed to parse host key %v: %v", filename, err) - continue - } - loadedHostKeys++ + for _, key := range s.hostKeys { sshCfg.AddHostKey(key) } - if loadedHostKeys == 0 { - return fmt.Errorf("No host keys could be loaded, aborting") - } - for { - nconn, err := sshListener.Accept() - if err != nil { - log.Warnf("Failed to accept connection: %v\n", err) - continue - } - - go handleConn(ctx, cfg, sshCfg, nconn) - } + return sshCfg } -func handleConn(ctx context.Context, cfg *config.Config, sshCfg *ssh.ServerConfig, nconn net.Conn) { +func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() + defer s.wg.Done() defer nconn.Close() // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling connection from %s: recovered: %#+v", remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) } }() ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() - sconn, chans, reqs, err := ssh.NewServerConn(nconn, sshCfg) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) if err != nil { - log.Infof("Failed to initialize SSH connection: %v", err) + log.WithError(err).Info("Failed to initialize SSH connection") return } go ssh.DiscardRequests(reqs) - conn := newConnection(cfg.Server.ConcurrentSessionsLimit, remoteAddr) + conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { session := &session{ - cfg: cfg, + cfg: s.Config, channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/sshd_test.go @@ -0,0 +1,190 @@ +package sshd + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "path" + "testing" + "time" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +const ( + serverUrl = "127.0.0.1:50000" + user = "git" +) + +var ( + correlationId = "" +) + +func TestListenAndServe(t *testing.T) { + s := setupServer(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusOnShutdown) + + holdSession(t, client) + + _, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.Equal(t, err.Error(), "dial tcp 127.0.0.1:50000: connect: connection refused") + + client.Close() + + verifyStatus(t, s, StatusClosed) +} + +func TestCorrelationId(t *testing.T) { + setupServer(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + previousCorrelationId := correlationId + + client, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + require.NotEqual(t, previousCorrelationId, correlationId) +} + +func TestReadinessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + + require.Equal(t, StatusStarting, s.getStatus()) + + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/start", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) + + s.changeStatus(StatusReady) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) + + s.changeStatus(StatusOnShutdown) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) +} + +func TestLivenessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/health", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) +} + +func setupServer(t *testing.T) *Server { + t.Helper() + + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/authorized_keys", + Handler: func(w http.ResponseWriter, r *http.Request) { + correlationId = r.Header.Get("X-Request-Id") + + require.NotEmpty(t, correlationId) + + fmt.Fprint(w, `{"id": 1000, "key": "key"}`) + }, + }, { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + + fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) + }, + }, + } + + testhelper.PrepareTestRootDir(t) + + url := testserver.StartSocketHttpServer(t, requests) + srvCfg := config.ServerConfig{ + Listen: serverUrl, + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + } + + s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + require.NoError(t, err) + + go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + t.Cleanup(func() { s.Shutdown() }) + + verifyStatus(t, s, StatusReady) + + return s +} + +func clientConfig(t *testing.T) *ssh.ClientConfig { + keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + require.NoError(t, err) + + key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + require.NoError(t, err) + signer, err := ssh.ParsePrivateKey(key) + require.NoError(t, err) + + return &ssh.ClientConfig{ + User: user, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.FixedHostKey(pKey), + } +} + +func holdSession(t *testing.T, c *ssh.Client) { + session, err := c.NewSession() + require.NoError(t, err) + defer session.Close() + + output, err := session.Output("discover") + require.NoError(t, err) + require.Equal(t, "Welcome to GitLab, @test-user!\n", string(output)) +} + +func verifyStatus(t *testing.T, s *Server, st status) { + for i := 5; i < 500; i += 50 { + if s.getStatus() == st { + break + } + + // Sleep incrementally ~2s in total + time.Sleep(time.Duration(i) * time.Millisecond) + } + + require.Equal(t, st, s.getStatus()) +} diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -65,10 +65,10 @@ "gl_email": "testgr@heptapod.test", "gl_id": 17, } - if (hg_native != nil) { + if hg_native != nil { body["hg_native"] = *hg_native } - if (no_git != nil) { + if no_git != nil { body["no_git"] = *no_git } w.WriteHeader(http.StatusOK) diff --git a/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -6,11 +6,10 @@ "os" "path" "runtime" - "time" + "testing" "github.com/otiai10/copy" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/require" ) var ( @@ -31,42 +30,21 @@ } } -func PrepareTestRootDir() (func(), error) { - if err := os.MkdirAll(TestRoot, 0700); err != nil { - return nil, err - } +func PrepareTestRootDir(t *testing.T) { + t.Helper() - var oldWd string - cleanup := func() { - if oldWd != "" { - err := os.Chdir(oldWd) - if err != nil { - panic(err) - } - } + require.NoError(t, os.MkdirAll(TestRoot, 0700)) - if err := os.RemoveAll(TestRoot); err != nil { - panic(err) - } - } + t.Cleanup(func() { os.RemoveAll(TestRoot) }) - if err := copyTestData(); err != nil { - cleanup() - return nil, err - } + require.NoError(t, copyTestData()) oldWd, err := os.Getwd() - if err != nil { - cleanup() - return nil, err - } + require.NoError(t, err) - if err := os.Chdir(TestRoot); err != nil { - cleanup() - return nil, err - } + t.Cleanup(func() { os.Chdir(oldWd) }) - return cleanup, nil + require.NoError(t, os.Chdir(TestRoot)) } func copyTestData() error { @@ -94,25 +72,3 @@ err := os.Setenv(key, value) return func() { os.Setenv(key, oldValue) }, err } - -func SetupLogger() *test.Hook { - logger, hook := test.NewNullLogger() - logrus.SetOutput(logger.Writer()) - - return hook -} - -// logrus fires a Goroutine to write the output log, but there's no way to -// flush all outstanding hooks to fire. We just wait up to a second -// for an event to appear. -func WaitForLogEvent(hook *test.Hook) bool { - for i := 0; i < 10; i++ { - if entry := hook.LastEntry(); entry != nil { - return true - } - - time.Sleep(100 * time.Millisecond) - } - - return false -} diff --git a/spec/gitlab_shell_custom_git_receive_pack_spec.rb b/spec/gitlab_shell_custom_git_receive_pack_spec.rb --- a/spec/gitlab_shell_custom_git_receive_pack_spec.rb +++ b/spec/gitlab_shell_custom_git_receive_pack_spec.rb @@ -74,11 +74,11 @@ expect(stderr.gets).to eq("remote: message\n") expect(stderr.gets).to eq(remote_blank_line) - stdin.puts("input") + stdin.puts("0009input") stdin.close expect(stdout.gets(6)).to eq("custom") - expect(stdout.flush.read).to eq("input\n") + expect(stdout.flush.read).to eq("0009input") end end diff --git a/spec/gitlab_shell_discover_spec.rb b/spec/gitlab_shell_discover_spec.rb --- a/spec/gitlab_shell_discover_spec.rb +++ b/spec/gitlab_shell_discover_spec.rb @@ -108,7 +108,7 @@ end it 'outputs "Only SSH allowed"' do - _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {}) + _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {'SSH_CONNECTION' => ''}) expect(stderr).to eq("Only SSH allowed\n") expect(status).not_to be_success # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1636757512 -3600 # Fri Nov 12 23:51:52 2021 +0100 # Branch heptapod # Node ID b15301c706769652286af112a4437dc8cdfac86e # Parent f23dd26963eecab3f2dc56638921336cc5e88db2 Heptapod CI: apply changes in pipeline as in upstream Golang < 1.16 is not supported any more ; 1.17 appears in the build. diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -38,20 +38,6 @@ script: - make verify test -go:1.14: - extends: .test - image: golang:1.14 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.15: - extends: .test - image: golang:1.15 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.16: extends: .test image: golang:1.16 @@ -59,8 +45,15 @@ - make coverage coverage: '/\d+.\d+%/' +go:1.17: + extends: .test + image: golang:1.17 + after_script: + - make coverage + coverage: '/\d+.\d+%/' + race: extends: .test - image: golang:1.16 + image: golang:1.17 script: - make test_golang_race # HG changeset patch # User Georges Racinet on mutations.racinet.fr <georges@racinet.fr> # Date 1636989848 -3600 # Mon Nov 15 16:24:08 2021 +0100 # Branch heptapod # Node ID 9e659daeffdf3b711ef6aaba6cf4c737bb9f632c # Parent b15301c706769652286af112a4437dc8cdfac86e Added tag heptapod-13.21.0 for changeset b15301c70676 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -35,3 +35,4 @@ aefbb5e3eac5411fc526a88d3df1762ecbdc2e76 heptapod-13.19.0 b84ce63181d5c0d07585be867dbe957eb6d35348 heptapod-13.19.1 f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 +b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1637927653 -3600 # Fri Nov 26 12:54:13 2021 +0100 # Branch heptapod-stable # Node ID 7a9511f85a6a3aca688269a37504d371068a2961 # Parent 29ff795406b8b544ad4be6b1dcbc3f119b955a36 # Parent 9e659daeffdf3b711ef6aaba6cf4c737bb9f632c heptapod#582: making Heptapod 0.27 the stable series diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,20 +52,6 @@ script: - make verify test -go:1.14: - extends: .test - image: golang:1.14 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.15: - extends: .test - image: golang:1.15 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.16: extends: .test image: golang:1.16 @@ -73,9 +59,16 @@ - make coverage coverage: '/\d+.\d+%/' +go:1.17: + extends: .test + image: golang:1.17 + after_script: + - make coverage + coverage: '/\d+.\d+%/' + race: extends: .test - image: golang:1.16 + image: golang:1.17 script: - make test_golang_race diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -35,3 +35,4 @@ aefbb5e3eac5411fc526a88d3df1762ecbdc2e76 heptapod-13.19.0 b84ce63181d5c0d07585be867dbe957eb6d35348 heptapod-13.19.1 f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 +b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,25 @@ +v13.21.1 + +- Only validate SSL cert file exists if a value is supplied !527 + +v13.21.0 + +- Change default logging format to JSON !476 +- Shutdown sshd gracefully !484 +- Provide liveness and readiness probes !494 +- Add tracing instrumentation to http client !495 +- Log same correlation_id on auth keys check of ssh connections !501 +- fix: validate client cert paths exist on disk before proceeding !508 +- Modify regex to prevent partial matches + +v13.20.0 + +- Remove bin/authorized_keys !491 +- Add a make install command !490 +- Create PROCESS.md page with Security release process !488 +- Fix the Geo SSH push proxy hanging !487 +- Standardize logging timestamp format !485 + v13.19.1 - Modify regex to prevent partial matches diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,6 +9,10 @@ The corresponding tag is heptapod-x.y.z +## 13.21.0 + +- Jump to upstream GitLab Shell v13.21.1 (GitLab 14.4 series) + ## 13.19.2 - Added support for the new `NO_GIT` flag, telling Mercurial not to diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.19.2 +13.21.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _install build compile check clean +.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) @@ -6,12 +6,17 @@ BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +PREFIX ?= /usr/local + validate: verify test verify: verify_golang verify_golang: - gofmt -s -l $(GO_SOURCES) + gofmt -s -l $(GO_SOURCES) | awk '{ print } END { if (NR > 0) { print "Please run make fmt"; exit 1 } }' + +fmt: + gofmt -w -s $(GO_SOURCES) test: test_ruby test_golang @@ -30,9 +35,9 @@ coverage_golang: [ -f cover.out ] && go tool cover -func cover.out -setup: _install bin/gitlab-shell +setup: _script_install bin/gitlab-shell -_install: +_script_install: bin/install build: bin/gitlab-shell @@ -45,3 +50,12 @@ clean: rm -f bin/check bin/gitlab-shell bin/gitlab-shell-authorized-keys-check bin/gitlab-shell-authorized-principals-check bin/gitlab-sshd + +install: compile + mkdir -p $(DESTDIR)$(PREFIX)/bin/ + install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd + diff --git a/PROCESS.md b/PROCESS.md new file mode 100644 --- /dev/null +++ b/PROCESS.md @@ -0,0 +1,44 @@ +## Releasing a new version + +GitLab Shell is versioned by git tags, and the version used by the Rails +application is stored in +[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). + +For each version, there is a raw version and a tag version: + +- The **raw version** is the version number. For instance, `15.2.8`. +- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. + +To release a new version of GitLab Shell and have that version available to the +Rails application: + +1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the + **tag version** and the [`VERSION`](VERSION) file with the **raw version**. +2. Ask a maintainer to review and merge the merge request. If you're already a + maintainer, second maintainer review is not required. +3. Add a new git tag with the **tag version**. +4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw + version**. (Note: this can be done as a separate MR to that, or in and MR + that will make use of the latest GitLab Shell changes.) + +## Security releases + +GitLab Shell is included in the packages we create for GitLab, and each version of GitLab specifies the version of GitLab Shell it uses in the `GITLAB_SHELL_VERSION` file, so security fixes in GitLab Shell are tightly coupled to the [GitLab security release](https://about.gitlab.com/handbook/engineering/workflow/#security-issues) workflow. + +For a security fix in GitLab Shell, two sets of merge requests are required: + +* The fix itself, in the `gitlab-org/security/gitlab-shell` repository and its backports to the previous versions of GitLab Shell +* Merge requests to change the versions of GitLab Shell included in the GitLab security release, in the `gitlab-org/security/gitlab` repository + +The first step could be to create a merge request with a fix targeting `main` in `gitlab-org/security/gitlab-shell`. When the merge request is approved by maintainers, backports targeting previous 3 versions of GitLab Shell must be created. The stable branches for those versions may not exist, feel free to ask a maintainer to create ones. The stable branches must be created out of the GitLab Shell tags/version used by the 3 previous GitLab releases. In order to find out the GitLab Shell version that is used on a particular GitLab stable release, the following steps may be helpful: + +```shell +git fetch security 13-9-stable-ee +git show refs/remotes/security/13-9-stable-ee:GITLAB_SHELL_VERSION +``` + +These steps display the version that is used by `13.9` version of GitLab. + +Close to the GitLab security release, a maintainer should merge the fix and backports and cut all the necessary GitLab Shell versions. This allows bumping the `GITLAB_SHELL_VERSION` for `gitlab-org/security/gitlab`. The GitLab merge request will be handled by the general GitLab security release process. + +Once the security release is done, a GitLab Shell maintainer is responsible for syncing tags and `main` to the `gitlab-org/gitlab-shell` repository. diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ When you access the GitLab server over SSH then GitLab Shell will: -1. Limits you to predefined git commands (git push, git pull). +1. Limit you to predefined git commands (git push, git pull). 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server @@ -38,16 +38,36 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Setup - - make setup - ## Check Checks if GitLab API access and redis via internal API can be reached: make check +## Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + + make compile + +## Install + +Builds the `gitlab-shell` binaries and installs them onto the filesystem. The +default location is `/usr/local`, but can be controlled by use of the `PREFIX` +and `DESTDIR` environment variables. + + make install + +## Setup + +This command is intended for use when installing GitLab from source on a single +machine. In addition to compiling the gitlab-shell binaries, it ensures that +various paths on the filesystem exist with the correct permissions. Do not run +it unless instructed to by your installation method documentation. + + make setup + + ## Testing Run tests: @@ -82,28 +102,9 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. -## Releasing a new version - -GitLab Shell is versioned by git tags, and the version used by the Rails -application is stored in -[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION). - -For each version, there is a raw version and a tag version: - -- The **raw version** is the version number. For instance, `15.2.8`. -- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`. +## Releasing -To release a new version of GitLab Shell and have that version available to the -Rails application: - -1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the - **tag version** and the [`VERSION`](VERSION) file with the **raw version**. -2. Ask a maintainer to review and merge the merge request. If you're already a - maintainer, second maintainer review is not required. -3. Add a new git tag with the **tag version**. -4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw - version**. (Note: this can be done as a separate MR to that, or in and MR - that will make use of the latest GitLab Shell changes.) +See [PROCESS.md](./PROCESS.md) ## Contributing diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.19.1 +13.21.1 diff --git a/bin/authorized_keys b/bin/authorized_keys deleted file mode 100755 --- a/bin/authorized_keys +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Legacy script used for AuthorizedKeysCommand when configured without username. -# Executes gitlab-shell-authorized-keys-check with "git" as expected and actual -# username and with the passed key. -# -# TODO: Remove this in https://gitlab.com/gitlab-org/gitlab-shell/issues/209. - -$(dirname $0)/gitlab-shell-authorized-keys-check git git $1 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -11,16 +11,14 @@ "strings" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) func TestClients(t *testing.T) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) testCases := []struct { desc string @@ -61,7 +59,8 @@ secret := "sssh, it's a secret" - httpClient := NewHTTPClient(url, tc.relativeURLRoot, tc.caFile, "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient("", "", secret, httpClient) require.NoError(t, err) @@ -78,7 +77,6 @@ func testSuccessfulGet(t *testing.T, client *GitlabNetClient) { t.Run("Successful get", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) require.NotNil(t, response) @@ -88,22 +86,11 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testSuccessfulPost(t *testing.T, client *GitlabNetClient) { t.Run("Successful Post", func(t *testing.T) { - hook := testhelper.SetupLogger() data := map[string]string{"key": "value"} response, err := client.Post(context.Background(), "/post_endpoint", data) @@ -115,50 +102,20 @@ responseBody, err := ioutil.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=200") - require.Contains(t, entries[0].Message, "content_length_bytes=") - require.Contains(t, entries[0].Message, "Finished HTTP request") - require.Contains(t, entries[0].Message, "correlation_id=") }) } func testMissing(t *testing.T, client *GitlabNetClient) { t.Run("Missing error for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Get(context.Background(), "/missing") require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Missing error for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() response, err := client.Post(context.Background(), "/missing", map[string]string{}) require.EqualError(t, err, "Internal API error (404)") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.Contains(t, entries[0].Message, "status=404") - require.Contains(t, entries[0].Message, "Internal API error") - require.Contains(t, entries[0].Message, "correlation_id=") }) } @@ -178,37 +135,15 @@ func testBrokenRequest(t *testing.T, client *GitlabNetClient) { t.Run("Broken request for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Get(context.Background(), "/broken") require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=GET") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) t.Run("Broken request for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Post(context.Background(), "/broken", map[string]string{}) require.EqualError(t, err, "Internal API unreachable") require.Nil(t, response) - - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 1, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[0].Level) - require.Contains(t, entries[0].Message, "method=POST") - require.NotContains(t, entries[0].Message, "status=") - require.Contains(t, entries[0].Message, "Internal API unreachable") - require.Contains(t, entries[0].Message, "correlation_id=") }) } diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,9 +11,7 @@ "strings" "time" - "gitlab.com/gitlab-org/labkit/correlation" - - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -71,12 +69,12 @@ return path } -func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, string, error) { +func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { jsonData, err := json.Marshal(data) if err != nil { - return nil, "", err + return nil, err } jsonReader = bytes.NewReader(jsonData) @@ -84,12 +82,10 @@ request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) if err != nil { - return nil, "", err + return nil, err } - correlationID := correlation.ExtractFromContext(ctx) - - return request, correlationID, nil + return request, nil } func parseError(resp *http.Response) error { @@ -116,7 +112,7 @@ } func (c *GitlabNetClient) DoRequest(ctx context.Context, method, path string, data interface{}) (*http.Response, error) { - request, correlationID, err := newRequest(ctx, method, c.httpClient.Host, path, data) + request, err := newRequest(ctx, method, c.httpClient.Host, path, data) if err != nil { return nil, err } @@ -136,12 +132,11 @@ start := time.Now() response, err := c.httpClient.Do(request) fields := log.Fields{ - "correlation_id": correlationID, - "method": method, - "url": request.URL.String(), - "duration_ms": time.Since(start) / time.Millisecond, + "method": method, + "url": request.URL.String(), + "duration_ms": time.Since(start) / time.Millisecond, } - logger := log.WithFields(fields) + logger := log.WithContextFields(ctx, fields) if err != nil { logger.WithError(err).Error("Internal API unreachable") diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -5,15 +5,18 @@ "crypto/tls" "crypto/x509" "errors" + "fmt" "io/ioutil" "net" "net/http" + "os" "path/filepath" "strings" "time" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/labkit/tracing" ) const ( @@ -24,6 +27,10 @@ defaultReadTimeoutSeconds = 300 ) +var ( + ErrCafileNotFound = errors.New("cafile not found") +) + type HttpClient struct { *http.Client Host string @@ -48,6 +55,22 @@ } } +func validateCaFile(filename string) error { + if filename == "" { + return nil + } + + if _, err := os.Stat(filename); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("cannot find cafile '%s': %w", filename, ErrCafileNotFound) + } + + return err + } + + return nil +} + // Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) @@ -59,15 +82,6 @@ // NewHTTPClientWithOpts builds an HTTP client using the provided options func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { - hcc := &httpClientCfg{ - caFile: caFile, - caPath: caPath, - } - - for _, opt := range opts { - opt(hcc) - } - var transport *http.Transport var host string var err error @@ -76,6 +90,20 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { + err = validateCaFile(caFile) + if err != nil { + return nil, err + } + + hcc := &httpClientCfg{ + caFile: caFile, + caPath: caPath, + } + + for _, opt := range opts { + opt(hcc) + } + transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) if err != nil { return nil, err @@ -85,7 +113,7 @@ } c := &http.Client{ - Transport: correlation.NewInstrumentedRoundTripper(transport), + Transport: correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(transport)), Timeout: readTimeout(readTimeoutSeconds), } diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,8 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client := NewHTTPClient("http://localhost:3000", "", "", "", false, expectedSeconds) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + require.NoError(t, err) require.NotNil(t, client) require.Equal(t, time.Duration(expectedSeconds)*time.Second, client.Client.Timeout) @@ -122,7 +123,8 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient := NewHTTPClient(url, "", "", "", false, 1) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) require.NoError(t, err) diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -28,10 +28,7 @@ { desc: "Valid CaPath", caPath: path.Join(testhelper.TestRoot, "certs/valid"), - }, - { - desc: "Self signed cert option enabled", - selfSigned: true, + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Invalid cert with self signed cert option enabled", @@ -51,7 +48,8 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") require.NoError(t, err) @@ -68,39 +66,51 @@ func TestFailedRequests(t *testing.T) { testCases := []struct { - desc string - caFile string - caPath string + desc string + caFile string + caPath string + expectedCaFileNotFound bool + expectedError string }{ { - desc: "Invalid CaFile", - caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + desc: "Invalid CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + expectedError: "Internal API unreachable", }, { - desc: "Invalid CaPath", - caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + desc: "Missing CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/missing.crt"), + expectedCaFileNotFound: true, }, { - desc: "Empty config", + desc: "Invalid CaPath", + caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + expectedError: "Internal API unreachable", + }, + { + desc: "Empty config", + expectedError: "Internal API unreachable", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + if tc.expectedCaFileNotFound { + require.Error(t, err) + require.ErrorIs(t, err, ErrCafileNotFound) + } else { + _, err = client.Get(context.Background(), "/hello") + require.Error(t, err) - _, err := client.Get(context.Background(), "/hello") - require.Error(t, err) - - require.Equal(t, err.Error(), "Internal API unreachable") + require.Equal(t, err.Error(), tc.expectedError) + } }) } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) *GitlabNetClient { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { + testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ { @@ -121,10 +131,11 @@ } httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) - require.NoError(t, err) + if err != nil { + return nil, err + } client, err := NewGitlabNetClient("", "", "", httpClient) - require.NoError(t, err) - return client + return client, err } diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -31,7 +31,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -32,7 +32,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -46,7 +46,8 @@ os.Exit(1) } - logger.Configure(config) + logCloser := logger.Configure(config) + defer logCloser.Close() env := sshenv.NewFromEnv() cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -95,9 +95,7 @@ t.Helper() return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) t.Logf("gitlab-api-mock: received request: %s %s", r.Method, r.RequestURI) w.Header().Set("Content-Type", "application/json") @@ -231,7 +229,7 @@ t.Cleanup(func() { pw.Close() }) scanner := bufio.NewScanner(pr) - extractor := regexp.MustCompile(`msg="Listening on ([0-9a-f\[\]\.:]+)"`) + extractor := regexp.MustCompile(`"tcp_address":"([0-9a-f\[\]\.:]+)"`) ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, sshdPath, "-config-dir", dir) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -1,15 +1,19 @@ package main import ( + "context" "flag" "os" - - log "github.com/sirupsen/logrus" + "os/signal" + "syscall" + "time" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + + "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" ) @@ -45,37 +49,65 @@ var err error cfg, err = config.NewFromDir(*configDir) if err != nil { - log.Fatalf("failed to load configuration from specified directory: %v", err) + log.WithError(err).Fatal("failed to load configuration from specified directory") } } overrideConfigFromEnvironment(cfg) if err := cfg.IsSane(); err != nil { if *configDir == "" { - log.Warn("note: no config-dir provided, using only environment variables") + log.WithError(err).Fatal("no config-dir provided, using only environment variables") + } else { + log.WithError(err).Fatal("configuration error") } - log.Fatalf("configuration error: %v", err) } cfg.ApplyGlobalState() - logger.ConfigureStandalone(cfg) + logCloser := logger.ConfigureStandalone(cfg) + defer logCloser.Close() ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + server, err := sshd.NewServer(cfg) + if err != nil { + log.WithError(err).Fatal("Failed to start GitLab built-in sshd") + } + // Startup monitoring endpoint. if cfg.Server.WebListen != "" { go func() { - log.Fatal( - monitoring.Start( - monitoring.WithListenerAddress(cfg.Server.WebListen), - monitoring.WithBuildInformation(Version, BuildTime), - ), + err := monitoring.Start( + monitoring.WithListenerAddress(cfg.Server.WebListen), + monitoring.WithBuildInformation(Version, BuildTime), + monitoring.WithServeMux(server.MonitoringServeMux()), ) + + log.WithError(err).Fatal("monitoring service raised an error") }() } - if err := sshd.Run(ctx, cfg); err != nil { - log.Fatalf("Failed to start GitLab built-in sshd: %v", err) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + done := make(chan os.Signal, 1) + signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) + + go func() { + sig := <-done + signal.Reset(syscall.SIGINT, syscall.SIGTERM) + + log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + + server.Shutdown() + + <-time.After(cfg.Server.GracePeriod()) + + cancel() + + }() + + if err := server.ListenAndServe(ctx); err != nil { + log.WithError(err).Fatal("GitLab built-in sshd failed to listen for new connections") } } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -66,7 +66,7 @@ # Log level. INFO by default log_level: INFO -# Log format. 'text' by default +# Log format. 'json' by default, can be changed to 'text' if needed # log_format: json # Audit usernames. @@ -89,7 +89,7 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # SSH host key files. + # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.13 +go 1.16 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 @@ -8,12 +8,11 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.5.0 + github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 - github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 - gitlab.com/gitlab-org/labkit v1.4.1 + gitlab.com/gitlab-org/labkit v1.7.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.37.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -16,6 +16,7 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= @@ -38,6 +39,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +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= 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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -81,6 +84,8 @@ github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= +github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -91,6 +96,8 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -155,7 +162,6 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 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 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 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= @@ -173,7 +179,6 @@ github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -212,8 +217,9 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -260,10 +266,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 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= @@ -274,6 +278,7 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= @@ -343,6 +348,10 @@ 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= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -485,7 +494,6 @@ github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= @@ -503,10 +511,9 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pires/go-proxyproto v0.5.0 h1:A4Jv4ZCaV3AFJeGh5mGwkz4iuWUYMlQ7IoO/GTuSuLo= -github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= +github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= @@ -645,8 +652,8 @@ gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= -gitlab.com/gitlab-org/labkit v1.4.1 h1:mh4g+c/esQSWCVQJ197aftrIbXlhXCtiLC8RgSvyCx0= -gitlab.com/gitlab-org/labkit v1.4.1/go.mod h1:x5JO5uvdX4t6e/TZXLXZnFL5AcKz2uLLd3uKXZcuO4k= +gitlab.com/gitlab-org/labkit v1.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= +gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= 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.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -657,6 +664,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -699,7 +707,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -771,6 +778,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= @@ -783,6 +791,7 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -937,6 +946,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -945,9 +955,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= @@ -969,6 +977,7 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= @@ -1020,6 +1029,8 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -38,20 +38,6 @@ script: - make verify test -go:1.14: - extends: .test - image: golang:1.14 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.15: - extends: .test - image: golang:1.15 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - go:1.16: extends: .test image: golang:1.16 @@ -59,8 +45,15 @@ - make coverage coverage: '/\d+.\d+%/' +go:1.17: + extends: .test + image: golang:1.17 + after_script: + - make coverage + coverage: '/\d+.\d+%/' + race: extends: .test - image: golang:1.16 + image: golang:1.17 script: - make test_golang_race diff --git a/internal/command/hg/hg.go b/internal/command/hg/hg.go --- a/internal/command/hg/hg.go +++ b/internal/command/hg/hg.go @@ -83,7 +83,7 @@ "HEPTAPOD_NO_GIT=" + strconv.FormatBool(response.NoGit), }...) if c.Config.Mercurial.ModulePolicy != "" { - env = append(env, "HGMODULEPOLICY=" + c.Config.Mercurial.ModulePolicy) + env = append(env, "HGMODULEPOLICY="+c.Config.Mercurial.ModulePolicy) } hg_exe := c.Config.Mercurial.BinPath() diff --git a/internal/command/hg/hg_test.go b/internal/command/hg/hg_test.go --- a/internal/command/hg/hg_test.go +++ b/internal/command/hg/hg_test.go @@ -79,8 +79,8 @@ } // cannot directly take a reference to false and true - no := false; - yes := true; + no := false + yes := true testcases := []testcase{ {native_input: nil, native_expected: "false", no_git_expected: "false", module_policy: "c"}, @@ -103,7 +103,7 @@ GitlabUrl: url, Mercurial: config.MercurialConfig{ OptionalBinPath: "hg5.4-py3", - ModulePolicy: tc.module_policy, + ModulePolicy: tc.module_policy, Hgrc: []string{"/usr/share/shipped.hgrc", "/etc/main.hgrc"}}, }, Args: &commandargs.Shell{GitlabKeyId: "key-12", SshArgs: []string{"hg", "-R", "my/group/awesome-proj", "serve", "--stdio"}}, diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -14,12 +13,11 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -43,10 +41,15 @@ env := sshenv.Env{ IsSSHConnection: true, - OriginalCommand: "git-receive-pack group/repo", + OriginalCommand: "git-receive-pack " + repo, RemoteAddr: "127.0.0.1", } - args := &commandargs.Shell{CommandType: commandargs.ReceivePack, SshArgs: []string{"git-receive-pack", repo}, Env: env} + + args := &commandargs.Shell{ + CommandType: commandargs.ReceivePack, + SshArgs: []string{"git-receive-pack", repo}, + Env: env, + } if tc.username != "" { args.GitlabUsername = tc.username @@ -60,7 +63,6 @@ ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -73,15 +75,20 @@ require.Equal(t, "ReceivePack: key-123 "+repo, output.String()) } - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-receive-pack") - require.Contains(t, entries[1].Message, "remote_ip=127.0.0.1") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-receive-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } } diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -10,12 +10,13 @@ "io" "net/http" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + + "gitlab.com/gitlab-org/labkit/log" ) type Request struct { @@ -112,10 +113,32 @@ } func (c *Command) readFromStdin() ([]byte, error) { - output := new(bytes.Buffer) - _, err := io.Copy(output, c.ReadWriter.In) + var output []byte + var needsPackData bool + + scanner := pktline.NewScanner(c.ReadWriter.In) + for scanner.Scan() { + line := scanner.Bytes() + output = append(output, line...) + + if pktline.IsFlush(line) { + break + } - return output.Bytes(), err + if !needsPackData && !pktline.IsRefRemoval(line) { + needsPackData = true + } + } + + if needsPackData { + packData := new(bytes.Buffer) + _, err := io.Copy(packData, c.ReadWriter.In) + + output = append(output, packData.Bytes()...) + return output, err + } else { + return output, nil + } } func (c *Command) readFromStdinNoEOF() []byte { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -46,7 +46,7 @@ require.NoError(t, json.Unmarshal(b, &request)) require.Equal(t, request.Data.UserId, who) - require.Equal(t, "input", string(request.Output)) + require.Equal(t, "0009input", string(request.Output)) err = json.NewEncoder(w).Encode(Response{Result: []byte("output")}) require.NoError(t, err) @@ -58,7 +58,7 @@ outBuf := &bytes.Buffer{} errBuf := &bytes.Buffer{} - input := bytes.NewBufferString("input") + input := bytes.NewBufferString("0009input") response := &accessverifier.Response{ Who: who, diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -5,7 +5,6 @@ "context" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,12 +12,12 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) -func TestUploadPack(t *testing.T) { - gitalyAddress, _ := testserver.StartGitalyServer(t) +func TestUploadArchive(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress) url := testserver.StartHttpServer(t, requests) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-archive " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadArchive, + SshArgs: []string{"git-upload-archive", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadArchive, SshArgs: []string{"git-upload-archive", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -44,13 +55,19 @@ require.Equal(t, "UploadArchive: "+repo, output.String()) - require.True(t, testhelper.WaitForLogEvent(hook)) - entries := hook.AllEntries() - require.Equal(t, 2, len(entries)) - require.Equal(t, logrus.InfoLevel, entries[1].Level) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-archive") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-archive", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -4,7 +4,6 @@ "bytes" "context" "testing" - "time" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" @@ -13,7 +12,7 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" ) @@ -29,13 +28,25 @@ userId := "1" repo := "group/repo" + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + cmd := &Command{ Config: &config.Config{GitlabUrl: url}, - Args: &commandargs.Shell{GitlabKeyId: userId, CommandType: commandargs.UploadPack, SshArgs: []string{"git-upload-pack", repo}}, + Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - hook := testhelper.SetupLogger() ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") @@ -43,25 +54,20 @@ require.NoError(t, err) require.Equal(t, "UploadPack: "+repo, output.String()) - require.Eventually(t, func() bool { - entries := hook.AllEntries() - - require.Equal(t, 2, len(entries)) - require.Contains(t, entries[1].Message, "executing git command") - require.Contains(t, entries[1].Message, "command=git-upload-pack") - require.Contains(t, entries[1].Message, "gl_key_type=key") - require.Contains(t, entries[1].Message, "gl_key_id=123") - require.Contains(t, entries[1].Message, "correlation_id=a-correlation-id") - return true - }, time.Second, time.Millisecond) for k, v := range map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", } { actual := testServer.ReceivedMD[k] require.Len(t, actual, 1) require.Equal(t, v, actual[0]) } require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -9,11 +9,13 @@ "path/filepath" "strings" "sync" + "time" - "gitlab.com/gitlab-org/labkit/tracing" + "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) const ( @@ -22,8 +24,8 @@ ) var ( - defaultHgBinPath string = "hg" - defaultHgrcPath string = "/opt/gitlab/etc/docker.hgrc:/etc/gitlab/heptapod.hgrc" + defaultHgBinPath string = "hg" + defaultHgrcPath string = "/opt/gitlab/etc/docker.hgrc:/etc/gitlab/heptapod.hgrc" ) type ServerConfig struct { @@ -31,6 +33,9 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` } @@ -76,10 +81,11 @@ Secret string `yaml:"secret"` SslCertDir string `yaml:"ssl_cert_dir"` HttpSettings HttpSettingsConfig `yaml:"http_settings"` - Mercurial MercurialConfig `yaml:"mercurial"` + Mercurial MercurialConfig `yaml:"mercurial"` Server ServerConfig `yaml:"sshd"` httpClient *client.HttpClient + httpClientErr error httpClientOnce sync.Once } @@ -87,7 +93,7 @@ var ( DefaultConfig = Config{ LogFile: "gitlab-shell.log", - LogFormat: "text", + LogFormat: "json", Server: DefaultServerConfig, User: "git", } @@ -96,6 +102,9 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -104,30 +113,39 @@ } ) +func (sc *ServerConfig) GracePeriod() time.Duration { + return time.Duration(sc.GracePeriodSeconds) * time.Second +} + func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { os.Setenv("SSL_CERT_DIR", c.SslCertDir) } } -func (c *Config) HttpClient() *client.HttpClient { +func (c *Config) HttpClient() (*client.HttpClient, error) { c.httpClientOnce.Do(func() { - client := client.NewHTTPClient( + client, err := client.NewHTTPClientWithOpts( c.GitlabUrl, c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, + nil, ) + if err != nil { + c.httpClientErr = err + return + } tr := client.Transport - client.Transport = tracing.NewRoundTripper(tr) + client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) c.httpClient = client }) - return c.httpClient + return c.httpClient, c.httpClientErr } // NewFromDirExternal returns a new config from a given root dir. It also applies defaults appropriate for diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -4,8 +4,10 @@ "os" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -22,3 +24,28 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } + +func TestHttpClient(t *testing.T) { + url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) + + config := &Config{GitlabUrl: url} + client, err := config.HttpClient() + require.NoError(t, err) + + _, err = client.Get("http://host.com/path") + require.NoError(t, err) + + ms, err := prometheus.DefaultGatherer.Gather() + require.NoError(t, err) + + lastMetric := ms[0] + require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") + + labels := lastMetric.GetMetric()[0].Label + + require.Equal(t, "code", labels[0].GetName()) + require.Equal(t, "404", labels[0].GetValue()) + + require.Equal(t, "method", labels[1].GetName()) + require.Equal(t, "get", labels[1].GetValue()) +} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -163,9 +163,7 @@ } func setup(t *testing.T, allowedPayload string) *Client { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) diff --git a/internal/gitlabnet/accessverifier/hg_client_test.go b/internal/gitlabnet/accessverifier/hg_client_test.go --- a/internal/gitlabnet/accessverifier/hg_client_test.go +++ b/internal/gitlabnet/accessverifier/hg_client_test.go @@ -111,9 +111,7 @@ } func hgSetup(t *testing.T) *HgClient { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() + testhelper.PrepareTestRootDir(t) body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/hg_allowed.json")) require.NoError(t, err) diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -15,7 +15,10 @@ ) func GetClient(config *config.Config) (*client.GitlabNetClient, error) { - httpClient := config.HttpClient() + httpClient, err := config.HttpClient() + if err != nil { + return nil, err + } if httpClient == nil { return nil, fmt.Errorf("Unsupported protocol") diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -8,18 +8,19 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" ) @@ -75,7 +76,6 @@ func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { fields := log.Fields{ "command": gc.ServiceName, - "correlation_id": correlation.ExtractFromContext(ctx), "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, "user_id": response.UserId, @@ -86,7 +86,7 @@ "gl_key_id": response.KeyId, } - log.WithFields(fields).Info("executing git command") + log.WithContextFields(ctx, fields).Info("executing git command") } func withOutgoingMetadata(ctx context.Context, features map[string]string) context.Context { @@ -108,9 +108,9 @@ serviceName := correlation.ExtractClientNameFromContext(ctx) if serviceName == "" { - log.Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + serviceName = "gitlab-shell-unknown" - serviceName = "gitlab-shell-unknown" + log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -2,25 +2,54 @@ import ( "fmt" + "io" "io/ioutil" "log/syslog" "os" + "time" - log "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) -func configureLogFormat(cfg *config.Config) { - if cfg.LogFormat == "json" { - log.SetFormatter(&log.JSONFormatter{}) +func logFmt(inFmt string) string { + // Hide the "combined" format, since that makes no sense in gitlab-shell. + // The default is JSON when unspecified. + if inFmt == "" || inFmt == "combined" { + return "json" + } + + return inFmt +} + +func logFile(inFile string) string { + if inFile == "" { + return "stderr" + } + + return inFile +} + +func buildOpts(cfg *config.Config) []log.LoggerOption { + return []log.LoggerOption{ + log.WithFormatter(logFmt(cfg.LogFormat)), + log.WithOutputName(logFile(cfg.LogFile)), + log.WithTimezone(time.UTC), } } // Configure configures the logging singleton for operation inside a remote TTY (like SSH). In this // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. -func Configure(cfg *config.Config) { - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) +func Configure(cfg *config.Config) io.Closer { + var closer io.Closer = ioutil.NopCloser(nil) + err := fmt.Errorf("No logfile specified") + + if cfg.LogFile != "" { + closer, err = log.Initialize(buildOpts(cfg)...) + } + if err != nil { progName, _ := os.Executable() syslogLogger, syslogLoggerErr := syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0) @@ -32,29 +61,35 @@ fmt.Fprintf(os.Stderr, msg) } - // Discard logs since a log file was specified but couldn't be opened - log.SetOutput(ioutil.Discard) + cfg.LogFile = "/dev/null" + closer, err = log.Initialize(buildOpts(cfg)...) + if err != nil { + log.WithError(err).Warn("Unable to configure logging to /dev/null, leaving unconfigured") + } } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } // ConfigureStandalone configures the logging singleton for standalone operation. In this mode an -// empty LogFile is treated as logging to standard output and standard output is used as a fallback +// empty LogFile is treated as logging to stderr, and standard output is used as a fallback // when LogFile could not be opened for writing. -func ConfigureStandalone(cfg *config.Config) { - if cfg.LogFile == "" { - return +func ConfigureStandalone(cfg *config.Config) io.Closer { + closer, err1 := log.Initialize(buildOpts(cfg)...) + if err1 != nil { + var err2 error + + cfg.LogFile = "stdout" + closer, err2 = log.Initialize(buildOpts(cfg)...) + + // Output this after the logger has been configured! + log.WithError(err1).WithField("log_file", cfg.LogFile).Warn("Unable to configure logging, falling back to STDOUT") + + // LabKit v1.7.0 doesn't have any conditions where logging to "stdout" will fail + if err2 != nil { + log.WithError(err2).Warn("Unable to configure logging to STDOUT, leaving unconfigured") + } } - logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) - if err != nil { - log.Printf("Unable to configure logging, falling back to stdout: %v", err) - return - } - log.SetOutput(logFile) - - configureLogFormat(cfg) + return closer } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -3,11 +3,13 @@ import ( "io/ioutil" "os" + "regexp" "strings" "testing" - log "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) @@ -21,7 +23,9 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") tmpFile.Close() @@ -41,6 +45,34 @@ LogFormat: "json", } - Configure(&config) + closer := Configure(&config) + defer closer.Close() + log.Info("this is a test") } + +func TestLogInUTC(t *testing.T) { + tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + require.NoError(t, err) + defer tmpFile.Close() + defer os.Remove(tmpFile.Name()) + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + } + + closer := Configure(&config) + defer closer.Close() + + log.Info("this is a test") + + data, err := ioutil.ReadFile(tmpFile.Name()) + require.NoError(t, err) + + utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` + r, e := regexp.MatchString(utc, string(data)) + + require.NoError(t, e) + require.True(t, r) +} diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go new file mode 100644 --- /dev/null +++ b/internal/metrics/metrics.go @@ -0,0 +1,63 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +const ( + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" +) + +var ( + SshdConnectionDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "connection_duration_seconds", + Help: "A histogram of latencies for connections to gitlab-shell sshd.", + Buckets: []float64{ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ + }, + }, + ) + + SshdHitMaxSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: "concurrent_limited_sessions_total", + Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", + }, + ) + + HttpRequestDuration = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: "request_seconds", + Help: "A histogram of latencies for gitlab-shell http requests", + Buckets: []float64{ + 0.01, /* 10ms */ + 0.05, /* 50ms */ + 0.1, /* 100ms */ + 0.25, /* 250ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ + 10.0, /* 10s */ + }, + }, + []string{"code", "method"}, + ) +) diff --git a/internal/pktline/pktline.go b/internal/pktline/pktline.go --- a/internal/pktline/pktline.go +++ b/internal/pktline/pktline.go @@ -8,6 +8,7 @@ "bytes" "fmt" "io" + "regexp" "strconv" ) @@ -16,6 +17,8 @@ pktDelim = "0001" ) +var branchRemovalPktRegexp = regexp.MustCompile(`\A[a-f0-9]{4}[a-f0-9]{40} 0{40} `) + // NewScanner returns a bufio.Scanner that splits on Git pktline boundaries func NewScanner(r io.Reader) *bufio.Scanner { scanner := bufio.NewScanner(r) @@ -24,7 +27,16 @@ return scanner } -// IsDone detects the special flush packet '0009done\n' +func IsRefRemoval(pkt []byte) bool { + return branchRemovalPktRegexp.Match(pkt) +} + +// IsFlush detects the special flush packet '0000' +func IsFlush(pkt []byte) bool { + return bytes.Equal(pkt, []byte("0000")) +} + +// IsDone detects the special done packet '0009done\n' func IsDone(pkt []byte) bool { return bytes.Equal(pkt, PktDone()) } diff --git a/internal/pktline/pktline_test.go b/internal/pktline/pktline_test.go --- a/internal/pktline/pktline_test.go +++ b/internal/pktline/pktline_test.go @@ -68,6 +68,40 @@ } } +func TestIsRefRemoval(t *testing.T) { + testCases := []struct { + in string + isRemoval bool + }{ + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f0000000000000000000000000000000000000000 7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug", isRemoval: false}, + {in: "003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 0000000000000000000000000000000000000000 refs/heads/debug", isRemoval: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.isRemoval, IsRefRemoval([]byte(tc.in))) + }) + } +} + +func TestIsFlush(t *testing.T) { + testCases := []struct { + in string + flush bool + }{ + {in: "0008abcd", flush: false}, + {in: "invalid packet", flush: false}, + {in: "0000", flush: true}, + } + + for _, tc := range testCases { + t.Run(tc.in, func(t *testing.T) { + require.Equal(t, tc.flush, IsFlush([]byte(tc.in))) + }) + } +} + func TestIsDone(t *testing.T) { testCases := []struct { in string diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -4,47 +4,12 @@ "context" "time" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" -) - -const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" -) -var ( - sshdConnectionDuration = promauto.NewHistogram( - prometheus.HistogramOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", - Help: "A histogram of latencies for connections to gitlab-shell sshd.", - Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ - }, - }, - ) + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - sshdHitMaxSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", - Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", - }, - ) + "gitlab.com/gitlab-org/labkit/log" ) type connection struct { @@ -64,7 +29,7 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - defer sshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { if newChannel.ChannelType() != "session" { @@ -73,12 +38,12 @@ } if !c.concurrentSessions.TryAcquire(1) { newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") - sshdHitMaxSessions.Inc() + metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - log.Infof("Could not accept channel: %v", err) + log.WithError(err).Info("could not accept channel") c.concurrentSessions.Release(1) continue } @@ -89,7 +54,7 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling session from %s: recovered: %#+v", c.remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) } }() diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "testing" "github.com/stretchr/testify/require" @@ -9,22 +10,31 @@ ) type rejectCall struct { - reason ssh.RejectionReason + reason ssh.RejectionReason message string } type fakeNewChannel struct { channelType string extraData []byte + acceptErr error + + acceptCh chan struct{} rejectCh chan rejectCall } func (f *fakeNewChannel) Accept() (ssh.Channel, <-chan *ssh.Request, error) { - return nil, nil, nil + if f.acceptCh != nil { + f.acceptCh <- struct{}{} + } + + return nil, nil, f.acceptErr } func (f *fakeNewChannel) Reject(reason ssh.RejectionReason, message string) error { - f.rejectCh <- rejectCall{reason: reason, message: message} + if f.rejectCh != nil { + f.rejectCh <- rejectCall{reason: reason, message: message} + } return nil } @@ -63,7 +73,9 @@ } func TestUnknownChannelType(t *testing.T) { - rejectCh := make(chan rejectCall, 1) + rejectCh := make(chan rejectCall) + defer close(rejectCh) + newChannel := &fakeNewChannel{channelType: "unknown session", rejectCh: rejectCh} conn, chans := setup(1, newChannel) @@ -72,8 +84,64 @@ }() rejectionData := <-rejectCh - close(rejectCh) expectedRejection := rejectCall{reason: ssh.UnknownChannelType, message: "unknown channel type"} require.Equal(t, expectedRejection, rejectionData) } + +func TestTooManySessions(t *testing.T) { + rejectCh := make(chan rejectCall) + defer close(rejectCh) + + newChannel := &fakeNewChannel{channelType: "session", rejectCh: rejectCh} + conn, chans := setup(1, newChannel) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + <-ctx.Done() // Keep the accepted channel open until the end of the test + }) + }() + + chans <- newChannel + require.Equal(t, <-rejectCh, rejectCall{reason: ssh.ResourceShortage, message: "too many concurrent sessions"}) +} + +func TestAcceptSessionSucceeds(t *testing.T) { + newChannel := &fakeNewChannel{channelType: "session"} + conn, chans := setup(1, newChannel) + + channelHandled := false + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + close(chans) + }) + + require.True(t, channelHandled) +} + +func TestAcceptSessionFails(t *testing.T) { + acceptCh := make(chan struct{}) + defer close(acceptCh) + + acceptErr := errors.New("some failure") + newChannel := &fakeNewChannel{channelType: "session", acceptCh: acceptCh, acceptErr: acceptErr} + conn, chans := setup(1, newChannel) + + channelHandled := false + go func() { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + channelHandled = true + }) + }() + + require.Equal(t, <-acceptCh, struct{}{}) + + // Waits until the number of sessions is back to 0, since we can only have 1 + conn.concurrentSessions.Acquire(context.Background(), 1) + defer conn.concurrentSessions.Release(1) + + require.False(t, channelHandled) +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -7,41 +7,171 @@ "fmt" "io/ioutil" "net" + "net/http" "strconv" + "sync" "time" - log "github.com/sirupsen/logrus" - "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/log" +) + +type status int + +const ( + StatusStarting status = iota + StatusReady + StatusOnShutdown + StatusClosed + ProxyHeaderTimeout = 90 * time.Second ) -func Run(ctx context.Context, cfg *config.Config) error { +type Server struct { + Config *config.Config + + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func NewServer(cfg *config.Config) (*Server, error) { authorizedKeysClient, err := authorizedkeys.NewClient(cfg) if err != nil { - return fmt.Errorf("failed to initialize GitLab client: %w", err) + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := ioutil.ReadFile(filename) + if err != nil { + log.WithError(err).Warnf("Failed to read host key %v", filename) + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).Warnf("Failed to parse host key %v", filename) + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") } - sshListener, err := net.Listen("tcp", cfg.Server.Listen) + return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil +} + +func (s *Server) ListenAndServe(ctx context.Context) error { + if err := s.listen(); err != nil { + return err + } + defer s.listener.Close() + + s.serve(ctx) + + return nil +} + +func (s *Server) Shutdown() error { + if s.listener == nil { + return nil + } + + s.changeStatus(StatusOnShutdown) + + return s.listener.Close() +} + +func (s *Server) MonitoringServeMux() *http.ServeMux { + mux := http.NewServeMux() + + mux.HandleFunc(s.Config.Server.ReadinessProbe, func(w http.ResponseWriter, r *http.Request) { + if s.getStatus() == StatusReady { + w.WriteHeader(http.StatusOK) + } else { + w.WriteHeader(http.StatusServiceUnavailable) + } + }) + + mux.HandleFunc(s.Config.Server.LivenessProbe, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + + return mux +} + +func (s *Server) listen() error { + sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) } - if cfg.Server.ProxyProtocol { - sshListener = &proxyproto.Listener{Listener: sshListener} + + if s.Config.Server.ProxyProtocol { + sshListener = &proxyproto.Listener{ + Listener: sshListener, + ReadHeaderTimeout: ProxyHeaderTimeout, + } log.Info("Proxy protocol is enabled") } - defer sshListener.Close() + + log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") + + s.listener = sshListener + + return nil +} + +func (s *Server) serve(ctx context.Context) { + s.changeStatus(StatusReady) + + for { + nconn, err := s.listener.Accept() + if err != nil { + if s.getStatus() == StatusOnShutdown { + break + } + + log.WithError(err).Warn("Failed to accept connection") + continue + } - log.Infof("Listening on %v", sshListener.Addr().String()) + s.wg.Add(1) + go s.handleConn(ctx, nconn) + } + + s.wg.Wait() + + s.changeStatus(StatusClosed) +} +func (s *Server) changeStatus(st status) { + s.statusMu.Lock() + s.status = st + s.statusMu.Unlock() +} + +func (s *Server) getStatus() status { + s.statusMu.Lock() + defer s.statusMu.Unlock() + + return s.status +} + +func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { sshCfg := &ssh.ServerConfig{ PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != cfg.User { + if conn.User() != s.Config.User { return nil, errors.New("unknown user") } if key.Type() == ssh.KeyAlgoDSA { @@ -49,7 +179,7 @@ } ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - res, err := authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) if err != nil { return nil, err } @@ -63,63 +193,41 @@ }, } - var loadedHostKeys uint - for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) - if err != nil { - log.Warnf("Failed to read host key %v: %v", filename, err) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.Warnf("Failed to parse host key %v: %v", filename, err) - continue - } - loadedHostKeys++ + for _, key := range s.hostKeys { sshCfg.AddHostKey(key) } - if loadedHostKeys == 0 { - return fmt.Errorf("No host keys could be loaded, aborting") - } - for { - nconn, err := sshListener.Accept() - if err != nil { - log.Warnf("Failed to accept connection: %v\n", err) - continue - } - - go handleConn(ctx, cfg, sshCfg, nconn) - } + return sshCfg } -func handleConn(ctx context.Context, cfg *config.Config, sshCfg *ssh.ServerConfig, nconn net.Conn) { +func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() + defer s.wg.Done() defer nconn.Close() // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.Warnf("panic handling connection from %s: recovered: %#+v", remoteAddr, err) + log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) } }() ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() - sconn, chans, reqs, err := ssh.NewServerConn(nconn, sshCfg) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) if err != nil { - log.Infof("Failed to initialize SSH connection: %v", err) + log.WithError(err).Info("Failed to initialize SSH connection") return } go ssh.DiscardRequests(reqs) - conn := newConnection(cfg.Server.ConcurrentSessionsLimit, remoteAddr) + conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { session := &session{ - cfg: cfg, + cfg: s.Config, channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/sshd_test.go @@ -0,0 +1,190 @@ +package sshd + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "path" + "testing" + "time" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +const ( + serverUrl = "127.0.0.1:50000" + user = "git" +) + +var ( + correlationId = "" +) + +func TestListenAndServe(t *testing.T) { + s := setupServer(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusOnShutdown) + + holdSession(t, client) + + _, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.Equal(t, err.Error(), "dial tcp 127.0.0.1:50000: connect: connection refused") + + client.Close() + + verifyStatus(t, s, StatusClosed) +} + +func TestCorrelationId(t *testing.T) { + setupServer(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + previousCorrelationId := correlationId + + client, err = ssh.Dial("tcp", serverUrl, clientConfig(t)) + require.NoError(t, err) + defer client.Close() + + holdSession(t, client) + + require.NotEqual(t, previousCorrelationId, correlationId) +} + +func TestReadinessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + + require.Equal(t, StatusStarting, s.getStatus()) + + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/start", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) + + s.changeStatus(StatusReady) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) + + s.changeStatus(StatusOnShutdown) + + r = httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 503, r.Result().StatusCode) +} + +func TestLivenessProbe(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.DefaultServerConfig}} + mux := s.MonitoringServeMux() + + req := httptest.NewRequest("GET", "/health", nil) + + r := httptest.NewRecorder() + mux.ServeHTTP(r, req) + require.Equal(t, 200, r.Result().StatusCode) +} + +func setupServer(t *testing.T) *Server { + t.Helper() + + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/authorized_keys", + Handler: func(w http.ResponseWriter, r *http.Request) { + correlationId = r.Header.Get("X-Request-Id") + + require.NotEmpty(t, correlationId) + + fmt.Fprint(w, `{"id": 1000, "key": "key"}`) + }, + }, { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + + fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) + }, + }, + } + + testhelper.PrepareTestRootDir(t) + + url := testserver.StartSocketHttpServer(t, requests) + srvCfg := config.ServerConfig{ + Listen: serverUrl, + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + } + + s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + require.NoError(t, err) + + go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + t.Cleanup(func() { s.Shutdown() }) + + verifyStatus(t, s, StatusReady) + + return s +} + +func clientConfig(t *testing.T) *ssh.ClientConfig { + keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + require.NoError(t, err) + + key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + require.NoError(t, err) + signer, err := ssh.ParsePrivateKey(key) + require.NoError(t, err) + + return &ssh.ClientConfig{ + User: user, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.FixedHostKey(pKey), + } +} + +func holdSession(t *testing.T, c *ssh.Client) { + session, err := c.NewSession() + require.NoError(t, err) + defer session.Close() + + output, err := session.Output("discover") + require.NoError(t, err) + require.Equal(t, "Welcome to GitLab, @test-user!\n", string(output)) +} + +func verifyStatus(t *testing.T, s *Server, st status) { + for i := 5; i < 500; i += 50 { + if s.getStatus() == st { + break + } + + // Sleep incrementally ~2s in total + time.Sleep(time.Duration(i) * time.Millisecond) + } + + require.Equal(t, st, s.getStatus()) +} diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -65,10 +65,10 @@ "gl_email": "testgr@heptapod.test", "gl_id": 17, } - if (hg_native != nil) { + if hg_native != nil { body["hg_native"] = *hg_native } - if (no_git != nil) { + if no_git != nil { body["no_git"] = *no_git } w.WriteHeader(http.StatusOK) diff --git a/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server_authorized_key @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -6,11 +6,10 @@ "os" "path" "runtime" - "time" + "testing" "github.com/otiai10/copy" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/require" ) var ( @@ -31,42 +30,21 @@ } } -func PrepareTestRootDir() (func(), error) { - if err := os.MkdirAll(TestRoot, 0700); err != nil { - return nil, err - } +func PrepareTestRootDir(t *testing.T) { + t.Helper() - var oldWd string - cleanup := func() { - if oldWd != "" { - err := os.Chdir(oldWd) - if err != nil { - panic(err) - } - } + require.NoError(t, os.MkdirAll(TestRoot, 0700)) - if err := os.RemoveAll(TestRoot); err != nil { - panic(err) - } - } + t.Cleanup(func() { os.RemoveAll(TestRoot) }) - if err := copyTestData(); err != nil { - cleanup() - return nil, err - } + require.NoError(t, copyTestData()) oldWd, err := os.Getwd() - if err != nil { - cleanup() - return nil, err - } + require.NoError(t, err) - if err := os.Chdir(TestRoot); err != nil { - cleanup() - return nil, err - } + t.Cleanup(func() { os.Chdir(oldWd) }) - return cleanup, nil + require.NoError(t, os.Chdir(TestRoot)) } func copyTestData() error { @@ -94,25 +72,3 @@ err := os.Setenv(key, value) return func() { os.Setenv(key, oldValue) }, err } - -func SetupLogger() *test.Hook { - logger, hook := test.NewNullLogger() - logrus.SetOutput(logger.Writer()) - - return hook -} - -// logrus fires a Goroutine to write the output log, but there's no way to -// flush all outstanding hooks to fire. We just wait up to a second -// for an event to appear. -func WaitForLogEvent(hook *test.Hook) bool { - for i := 0; i < 10; i++ { - if entry := hook.LastEntry(); entry != nil { - return true - } - - time.Sleep(100 * time.Millisecond) - } - - return false -} diff --git a/spec/gitlab_shell_custom_git_receive_pack_spec.rb b/spec/gitlab_shell_custom_git_receive_pack_spec.rb --- a/spec/gitlab_shell_custom_git_receive_pack_spec.rb +++ b/spec/gitlab_shell_custom_git_receive_pack_spec.rb @@ -74,11 +74,11 @@ expect(stderr.gets).to eq("remote: message\n") expect(stderr.gets).to eq(remote_blank_line) - stdin.puts("input") + stdin.puts("0009input") stdin.close expect(stdout.gets(6)).to eq("custom") - expect(stdout.flush.read).to eq("input\n") + expect(stdout.flush.read).to eq("0009input") end end diff --git a/spec/gitlab_shell_discover_spec.rb b/spec/gitlab_shell_discover_spec.rb --- a/spec/gitlab_shell_discover_spec.rb +++ b/spec/gitlab_shell_discover_spec.rb @@ -108,7 +108,7 @@ end it 'outputs "Only SSH allowed"' do - _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {}) + _, stderr, status = run!(["-c/usr/share/webapps/gitlab-shell/bin/gitlab-shell", "username-someuser"], env: {'SSH_CONNECTION' => ''}) expect(stderr).to eq("Only SSH allowed\n") expect(status).not_to be_success # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1629388460 0 # Thu Aug 19 15:54:20 2021 +0000 # Node ID 3be8a3ee74158b77c49e7c2619076cf04c6b1a69 # Parent 6415f1b04fa7998f0c06b2a12b06d45eb15651ad refactor: move away from ioutil (deprecated) diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -5,7 +5,7 @@ "encoding/base64" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "path" "strings" @@ -83,7 +83,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) @@ -99,7 +99,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) }) @@ -155,7 +155,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -170,7 +170,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -194,7 +194,7 @@ Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, http.MethodPost, r.Method) - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -6,7 +6,6 @@ "crypto/x509" "errors" "fmt" - "io/ioutil" "net" "net/http" "os" @@ -139,7 +138,7 @@ } if hcc.caPath != "" { - fis, _ := ioutil.ReadDir(hcc.caPath) + fis, _ := os.ReadDir(hcc.caPath) for _, fi := range fis { if fi.IsDir() { continue @@ -171,7 +170,7 @@ } func addCertToPool(certPool *x509.CertPool, fileName string) { - cert, err := ioutil.ReadFile(fileName) + cert, err := os.ReadFile(fileName) if err == nil { certPool.AppendCertsFromPEM(cert) } diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -4,7 +4,7 @@ "context" "encoding/base64" "fmt" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -64,7 +64,7 @@ defer response.Body.Close() require.NotNil(t, response) - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) headerParts := strings.Split(string(responseBody), " ") diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -3,7 +3,7 @@ import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "path" "testing" @@ -57,7 +57,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,7 +1,6 @@ package testserver import ( - "io/ioutil" "net" "os" "path" @@ -61,7 +60,7 @@ func StartGitalyServer(t *testing.T) (string, *TestGitalyServer) { t.Helper() - tempDir, _ := ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ := os.MkdirTemp("", "gitlab-shell-test-api") gitalySocketPath := path.Join(tempDir, "gitaly.sock") t.Cleanup(func() { os.RemoveAll(tempDir) }) diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -3,7 +3,7 @@ import ( "crypto/tls" "crypto/x509" - "io/ioutil" + "io" "log" "net" "net/http" @@ -18,7 +18,7 @@ ) var ( - tempDir, _ = ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ = os.MkdirTemp("", "gitlab-shell-test-api") testSocket = path.Join(tempDir, "internal.sock") ) @@ -41,7 +41,7 @@ Handler: buildHandler(handlers), // We'll put this server through some nasty stuff we don't want // in our test output - ErrorLog: log.New(ioutil.Discard, "", 0), + ErrorLog: log.New(io.Discard, "", 0), } go server.Serve(socketListener) @@ -76,7 +76,7 @@ server.TLS.BuildNameToCertificate() if clientCAPath != "" { - caCert, err := ioutil.ReadFile(clientCAPath) + caCert, err := os.ReadFile(clientCAPath) require.NoError(t, err) caCertPool := x509.NewCertPool() diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -8,7 +8,6 @@ "encoding/pem" "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -112,7 +111,7 @@ case "/api/v4/internal/two_factor_otp_check": fmt.Fprint(w, `{"success": true}`) case "/api/v4/internal/allowed": - body, err := ioutil.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) + body, err := os.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) require.NoError(t, err) response := strings.Replace(string(body), "GITALY_REPOSITORY", testRepo, 1) @@ -198,7 +197,7 @@ func configureSSHD(t *testing.T, apiServer string) (string, ed25519.PublicKey) { t.Helper() - dir, err := ioutil.TempDir("", "gitlab-sshd-acceptance-test-") + dir, err := os.MkdirTemp("", "gitlab-sshd-acceptance-test-") require.NoError(t, err) t.Cleanup(func() { os.RemoveAll(dir) }) @@ -209,11 +208,11 @@ require.NoError(t, err) configFileData := genServerConfig(apiServer, hostKeyFile) - require.NoError(t, ioutil.WriteFile(configFile, configFileData, 0644)) + require.NoError(t, os.WriteFile(configFile, configFileData, 0644)) block := &pem.Block{Type: "OPENSSH PRIVATE KEY", Bytes: edkey.MarshalED25519PrivateKey(priv)} hostKeyData := pem.EncodeToMemory(block) - require.NoError(t, ioutil.WriteFile(hostKeyFile, hostKeyData, 0400)) + require.NoError(t, os.WriteFile(hostKeyFile, hostKeyData, 0400)) return dir, pub } @@ -326,7 +325,7 @@ _, err = fmt.Fprintln(stdin, "yes") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, ` Your two-factor authentication recovery codes are: @@ -365,7 +364,7 @@ _, err = fmt.Fprintln(stdin, "otp123") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, "OTP validation successful. Git operations are now allowed.\n", string(output)) } diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -70,7 +70,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) @@ -94,7 +94,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -26,7 +26,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *accessverifier.Request diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -23,7 +23,7 @@ { Path: "/geo/proxy/info_refs_receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -39,7 +39,7 @@ { Path: "/geo/proxy/receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -92,7 +92,7 @@ { Path: "/geo/proxy/info_refs_upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -108,7 +108,7 @@ { Path: "/geo/proxy/upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -22,7 +22,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -2,7 +2,6 @@ import ( "errors" - "io/ioutil" "net/url" "os" "path" @@ -147,7 +146,7 @@ *cfg = DefaultConfig cfg.RootDir = filepath.Dir(path) - configBytes, err := ioutil.ReadFile(path) + configBytes, err := os.ReadFile(path) if err != nil { return nil, err } @@ -191,7 +190,7 @@ cfg.SecretFilePath = path.Join(cfg.RootDir, cfg.SecretFilePath) } - secretFileContent, err := ioutil.ReadFile(cfg.SecretFilePath) + secretFileContent, err := os.ReadFile(cfg.SecretFilePath) if err != nil { return err } diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -3,8 +3,9 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" + "os" "path" "testing" @@ -165,14 +166,14 @@ func setup(t *testing.T, allowedPayload string) *Client { testhelper.PrepareTestRootDir(t) - body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) var bodyWithPayload []byte if allowedPayload != "" { allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = ioutil.ReadFile(allowedWithPayloadPath) + bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) require.NoError(t, err) } @@ -180,7 +181,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *Request diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -3,11 +3,12 @@ import ( "context" "encoding/json" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" - "io/ioutil" + "io" "net/http" "testing" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" @@ -20,7 +21,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -3,7 +3,6 @@ import ( "fmt" "io" - "io/ioutil" "log/syslog" "os" "time" @@ -43,7 +42,7 @@ // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. func Configure(cfg *config.Config) io.Closer { - var closer io.Closer = ioutil.NopCloser(nil) + var closer io.Closer = io.NopCloser(nil) err := fmt.Errorf("No logfile specified") if cfg.LogFile != "" { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -1,7 +1,6 @@ package logger import ( - "io/ioutil" "os" "regexp" "strings" @@ -14,7 +13,7 @@ ) func TestConfigure(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() @@ -30,13 +29,13 @@ tmpFile.Close() - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) require.True(t, strings.Contains(string(data), `msg":"this is a test"`)) } func TestConfigureWithPermissionError(t *testing.T) { - tmpPath, err := ioutil.TempDir(os.TempDir(), "logtest-") + tmpPath, err := os.MkdirTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer os.RemoveAll(tmpPath) @@ -52,7 +51,7 @@ } func TestLogInUTC(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() defer os.Remove(tmpFile.Name()) @@ -67,7 +66,7 @@ log.Info("this is a test") - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -5,9 +5,9 @@ "encoding/base64" "errors" "fmt" - "io/ioutil" "net" "net/http" + "os" "strconv" "sync" "time" @@ -51,7 +51,7 @@ var hostKeys []ssh.Signer for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) + keyRaw, err := os.ReadFile(filename) if err != nil { log.WithError(err).Warnf("Failed to read host key %v", filename) continue diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,9 +3,9 @@ import ( "context" "fmt" - "io/ioutil" "net/http" "net/http/httptest" + "os" "path" "testing" "time" @@ -148,11 +148,11 @@ } func clientConfig(t *testing.T) *ssh.ClientConfig { - keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + keyRaw, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) require.NoError(t, err) - key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + key, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) require.NoError(t, err) signer, err := ssh.ParsePrivateKey(key) require.NoError(t, err) diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -2,7 +2,6 @@ import ( "fmt" - "io/ioutil" "os" "path" "runtime" @@ -13,7 +12,7 @@ ) var ( - TestRoot, _ = ioutil.TempDir("", "test-gitlab-shell") + TestRoot, _ = os.MkdirTemp("", "test-gitlab-shell") ) func TempEnv(env map[string]string) func() { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631091173 0 # Wed Sep 08 08:52:53 2021 +0000 # Node ID 8e875d8f6c8521570db68de53e522902911ff494 # Parent 854da4efdb45866ea0259ffcd156c46f5f8b238b # Parent 3be8a3ee74158b77c49e7c2619076cf04c6b1a69 Merge branch 'remove/ioutil' into 'main' refactor: move away from ioutil (deprecated) See merge request gitlab-org/gitlab-shell!511 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -5,7 +5,7 @@ "encoding/base64" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "path" "strings" @@ -83,7 +83,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) @@ -99,7 +99,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) }) @@ -155,7 +155,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -170,7 +170,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -194,7 +194,7 @@ Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, http.MethodPost, r.Method) - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -6,7 +6,6 @@ "crypto/x509" "errors" "fmt" - "io/ioutil" "net" "net/http" "os" @@ -139,7 +138,7 @@ } if hcc.caPath != "" { - fis, _ := ioutil.ReadDir(hcc.caPath) + fis, _ := os.ReadDir(hcc.caPath) for _, fi := range fis { if fi.IsDir() { continue @@ -171,7 +170,7 @@ } func addCertToPool(certPool *x509.CertPool, fileName string) { - cert, err := ioutil.ReadFile(fileName) + cert, err := os.ReadFile(fileName) if err == nil { certPool.AppendCertsFromPEM(cert) } diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -4,7 +4,7 @@ "context" "encoding/base64" "fmt" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -64,7 +64,7 @@ defer response.Body.Close() require.NotNil(t, response) - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) headerParts := strings.Split(string(responseBody), " ") diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -3,7 +3,7 @@ import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "path" "testing" @@ -57,7 +57,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,7 +1,6 @@ package testserver import ( - "io/ioutil" "net" "os" "path" @@ -61,7 +60,7 @@ func StartGitalyServer(t *testing.T) (string, *TestGitalyServer) { t.Helper() - tempDir, _ := ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ := os.MkdirTemp("", "gitlab-shell-test-api") gitalySocketPath := path.Join(tempDir, "gitaly.sock") t.Cleanup(func() { os.RemoveAll(tempDir) }) diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -3,7 +3,7 @@ import ( "crypto/tls" "crypto/x509" - "io/ioutil" + "io" "log" "net" "net/http" @@ -18,7 +18,7 @@ ) var ( - tempDir, _ = ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ = os.MkdirTemp("", "gitlab-shell-test-api") testSocket = path.Join(tempDir, "internal.sock") ) @@ -41,7 +41,7 @@ Handler: buildHandler(handlers), // We'll put this server through some nasty stuff we don't want // in our test output - ErrorLog: log.New(ioutil.Discard, "", 0), + ErrorLog: log.New(io.Discard, "", 0), } go server.Serve(socketListener) @@ -76,7 +76,7 @@ server.TLS.BuildNameToCertificate() if clientCAPath != "" { - caCert, err := ioutil.ReadFile(clientCAPath) + caCert, err := os.ReadFile(clientCAPath) require.NoError(t, err) caCertPool := x509.NewCertPool() diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -8,7 +8,6 @@ "encoding/pem" "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -112,7 +111,7 @@ case "/api/v4/internal/two_factor_otp_check": fmt.Fprint(w, `{"success": true}`) case "/api/v4/internal/allowed": - body, err := ioutil.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) + body, err := os.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) require.NoError(t, err) response := strings.Replace(string(body), "GITALY_REPOSITORY", testRepo, 1) @@ -198,7 +197,7 @@ func configureSSHD(t *testing.T, apiServer string) (string, ed25519.PublicKey) { t.Helper() - dir, err := ioutil.TempDir("", "gitlab-sshd-acceptance-test-") + dir, err := os.MkdirTemp("", "gitlab-sshd-acceptance-test-") require.NoError(t, err) t.Cleanup(func() { os.RemoveAll(dir) }) @@ -209,11 +208,11 @@ require.NoError(t, err) configFileData := genServerConfig(apiServer, hostKeyFile) - require.NoError(t, ioutil.WriteFile(configFile, configFileData, 0644)) + require.NoError(t, os.WriteFile(configFile, configFileData, 0644)) block := &pem.Block{Type: "OPENSSH PRIVATE KEY", Bytes: edkey.MarshalED25519PrivateKey(priv)} hostKeyData := pem.EncodeToMemory(block) - require.NoError(t, ioutil.WriteFile(hostKeyFile, hostKeyData, 0400)) + require.NoError(t, os.WriteFile(hostKeyFile, hostKeyData, 0400)) return dir, pub } @@ -326,7 +325,7 @@ _, err = fmt.Fprintln(stdin, "yes") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, ` Your two-factor authentication recovery codes are: @@ -365,7 +364,7 @@ _, err = fmt.Fprintln(stdin, "otp123") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, "OTP validation successful. Git operations are now allowed.\n", string(output)) } diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -70,7 +70,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) @@ -94,7 +94,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -26,7 +26,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *accessverifier.Request diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -23,7 +23,7 @@ { Path: "/geo/proxy/info_refs_receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -39,7 +39,7 @@ { Path: "/geo/proxy/receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -92,7 +92,7 @@ { Path: "/geo/proxy/info_refs_upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -108,7 +108,7 @@ { Path: "/geo/proxy/upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -22,7 +22,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -2,7 +2,6 @@ import ( "errors" - "io/ioutil" "net/url" "os" "path" @@ -147,7 +146,7 @@ *cfg = DefaultConfig cfg.RootDir = filepath.Dir(path) - configBytes, err := ioutil.ReadFile(path) + configBytes, err := os.ReadFile(path) if err != nil { return nil, err } @@ -191,7 +190,7 @@ cfg.SecretFilePath = path.Join(cfg.RootDir, cfg.SecretFilePath) } - secretFileContent, err := ioutil.ReadFile(cfg.SecretFilePath) + secretFileContent, err := os.ReadFile(cfg.SecretFilePath) if err != nil { return err } diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -3,8 +3,9 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" + "os" "path" "testing" @@ -165,14 +166,14 @@ func setup(t *testing.T, allowedPayload string) *Client { testhelper.PrepareTestRootDir(t) - body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) var bodyWithPayload []byte if allowedPayload != "" { allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = ioutil.ReadFile(allowedWithPayloadPath) + bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) require.NoError(t, err) } @@ -180,7 +181,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *Request diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -3,11 +3,12 @@ import ( "context" "encoding/json" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" - "io/ioutil" + "io" "net/http" "testing" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" @@ -20,7 +21,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -3,7 +3,6 @@ import ( "fmt" "io" - "io/ioutil" "log/syslog" "os" "time" @@ -43,7 +42,7 @@ // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. func Configure(cfg *config.Config) io.Closer { - var closer io.Closer = ioutil.NopCloser(nil) + var closer io.Closer = io.NopCloser(nil) err := fmt.Errorf("No logfile specified") if cfg.LogFile != "" { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -1,7 +1,6 @@ package logger import ( - "io/ioutil" "os" "regexp" "strings" @@ -14,7 +13,7 @@ ) func TestConfigure(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() @@ -30,13 +29,13 @@ tmpFile.Close() - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) require.True(t, strings.Contains(string(data), `msg":"this is a test"`)) } func TestConfigureWithPermissionError(t *testing.T) { - tmpPath, err := ioutil.TempDir(os.TempDir(), "logtest-") + tmpPath, err := os.MkdirTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer os.RemoveAll(tmpPath) @@ -52,7 +51,7 @@ } func TestLogInUTC(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() defer os.Remove(tmpFile.Name()) @@ -67,7 +66,7 @@ log.Info("this is a test") - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -5,9 +5,9 @@ "encoding/base64" "errors" "fmt" - "io/ioutil" "net" "net/http" + "os" "strconv" "sync" "time" @@ -51,7 +51,7 @@ var hostKeys []ssh.Signer for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) + keyRaw, err := os.ReadFile(filename) if err != nil { log.WithError(err).Warnf("Failed to read host key %v", filename) continue diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,9 +3,9 @@ import ( "context" "fmt" - "io/ioutil" "net/http" "net/http/httptest" + "os" "path" "testing" "time" @@ -148,11 +148,11 @@ } func clientConfig(t *testing.T) *ssh.ClientConfig { - keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + keyRaw, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) require.NoError(t, err) - key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + key, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) require.NoError(t, err) signer, err := ssh.ParsePrivateKey(key) require.NoError(t, err) diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -2,7 +2,6 @@ import ( "fmt" - "io/ioutil" "os" "path" "runtime" @@ -13,7 +12,7 @@ ) var ( - TestRoot, _ = ioutil.TempDir("", "test-gitlab-shell") + TestRoot, _ = os.MkdirTemp("", "test-gitlab-shell") ) func TempEnv(env map[string]string) func() { # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1628702942 0 # Wed Aug 11 17:29:02 2021 +0000 # Node ID cdc409eddfe2feb8c498280977addb799ffd6ccc # Parent 6ea629933069190232b9adb008f60e84d889904f refactor: remove commandargs.GenericArgs diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -1,6 +1,8 @@ package commandargs import ( + "errors" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -13,7 +15,7 @@ } func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (CommandArgs, error) { - var args CommandArgs = &GenericArgs{Arguments: arguments} + var args CommandArgs switch e.Name { case executable.GitlabShell: @@ -22,6 +24,10 @@ args = &AuthorizedKeys{Arguments: arguments} case executable.AuthorizedPrincipalsCheck: args = &AuthorizedPrincipals{Arguments: arguments} + case executable.Healthcheck: + return args, nil + default: + return nil, errors.New("unknown executable") } if err := args.Parse(); err != nil { diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go --- a/internal/command/commandargs/command_args_test.go +++ b/internal/command/commandargs/command_args_test.go @@ -16,6 +16,7 @@ env sshenv.Env arguments []string expectedArgs CommandArgs + expectError bool }{ { desc: "It sets discover as the command when the command string was empty", @@ -100,10 +101,10 @@ arguments: []string{"key", "principal-1", "principal-2"}, expectedArgs: &AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, }, { - desc: "Unknown executable", - executable: &executable.Executable{Name: "unknown"}, - arguments: []string{}, - expectedArgs: &GenericArgs{Arguments: []string{}}, + desc: "Unknown executable", + executable: &executable.Executable{Name: "unknown"}, + arguments: []string{}, + expectError: true, }, } @@ -111,8 +112,12 @@ t.Run(tc.desc, func(t *testing.T) { result, err := Parse(tc.executable, tc.arguments, tc.env) - require.NoError(t, err) - require.Equal(t, tc.expectedArgs, result) + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } }) } } diff --git a/internal/command/commandargs/generic_args.go b/internal/command/commandargs/generic_args.go deleted file mode 100644 --- a/internal/command/commandargs/generic_args.go +++ /dev/null @@ -1,14 +0,0 @@ -package commandargs - -type GenericArgs struct { - Arguments []string -} - -func (b *GenericArgs) Parse() error { - // Do nothing - return nil -} - -func (b *GenericArgs) GetArguments() []string { - return b.Arguments -} # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1631090876 0 # Wed Sep 08 08:47:56 2021 +0000 # Node ID c1dab100d7cd2d71f31ada539338bf9f11a33a6e # Parent cdc409eddfe2feb8c498280977addb799ffd6ccc refactor: improve unknown executable error message diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -2,6 +2,7 @@ import ( "errors" + "fmt" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" @@ -27,7 +28,7 @@ case executable.Healthcheck: return args, nil default: - return nil, errors.New("unknown executable") + return nil, errors.New(fmt.Sprintf("unknown executable: %s", e.Name)) } if err := args.Parse(); err != nil { # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1631094884 0 # Wed Sep 08 09:54:44 2021 +0000 # Node ID b1dda74d86534db7944861f5a004347c3f974644 # Parent c1dab100d7cd2d71f31ada539338bf9f11a33a6e refactor: add acceptargs field to executable parse logic will only run if the executable accept args. healthcheck is the only one not accepting arguments. diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -19,7 +19,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.Healthcheck) + executable, err := executable.New(executable.Healthcheck, false) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -20,7 +20,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedKeysCheck) + executable, err := executable.New(executable.AuthorizedKeysCheck, true) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -20,7 +20,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedPrincipalsCheck) + executable, err := executable.New(executable.AuthorizedPrincipalsCheck, true) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -34,7 +34,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.GitlabShell) + executable, err := executable.New(executable.GitlabShell, true) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -29,9 +29,13 @@ } func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (Command, error) { - args, err := commandargs.Parse(e, arguments, env) - if err != nil { - return nil, err + var args commandargs.CommandArgs + if e.AcceptArgs { + var err error + args, err = commandargs.Parse(e, arguments, env) + if err != nil { + return nil, err + } } if cmd := buildCommand(e, args, config, readWriter); cmd != nil { diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -26,10 +26,10 @@ ) var ( - authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} - authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} - checkExec = &executable.Executable{Name: executable.Healthcheck} - gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} + authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck, AcceptArgs: true} + authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck, AcceptArgs: true} + checkExec = &executable.Executable{Name: executable.Healthcheck, AcceptArgs: false} + gitlabShellExec = &executable.Executable{Name: executable.GitlabShell, AcceptArgs: true} basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} advancedConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket", SslCertDir: "/tmp/certs"} diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -25,8 +25,6 @@ args = &AuthorizedKeys{Arguments: arguments} case executable.AuthorizedPrincipalsCheck: args = &AuthorizedPrincipals{Arguments: arguments} - case executable.Healthcheck: - return args, nil default: return nil, errors.New(fmt.Sprintf("unknown executable: %s", e.Name)) } diff --git a/internal/executable/executable.go b/internal/executable/executable.go --- a/internal/executable/executable.go +++ b/internal/executable/executable.go @@ -14,8 +14,9 @@ ) type Executable struct { - Name string - RootDir string + Name string + RootDir string + AcceptArgs bool } var ( @@ -23,7 +24,7 @@ osExecutable = os.Executable ) -func New(name string) (*Executable, error) { +func New(name string, acceptArgs bool) (*Executable, error) { path, err := osExecutable() if err != nil { return nil, err @@ -35,8 +36,9 @@ } executable := &Executable{ - Name: name, - RootDir: rootDir, + Name: name, + RootDir: rootDir, + AcceptArgs: acceptArgs, } return executable, nil diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -59,7 +59,7 @@ fake.Setup() defer fake.Cleanup() - result, err := New("gitlab-shell") + result, err := New("gitlab-shell", true) require.NoError(t, err) require.Equal(t, result.Name, "gitlab-shell") @@ -96,7 +96,7 @@ fake.Setup() defer fake.Cleanup() - _, err := New("gitlab-shell") + _, err := New("gitlab-shell", true) require.Error(t, err) }) # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631095566 0 # Wed Sep 08 10:06:06 2021 +0000 # Node ID 9d6099095d58735db722bcca90bc4782f7614ba5 # Parent 8e875d8f6c8521570db68de53e522902911ff494 # Parent b1dda74d86534db7944861f5a004347c3f974644 Merge branch 'remove/generic-args' into 'main' refactor: remove commandargs.GenericArgs Closes #212 See merge request gitlab-org/gitlab-shell!506 diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -19,7 +19,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.Healthcheck) + executable, err := executable.New(executable.Healthcheck, false) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -20,7 +20,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedKeysCheck) + executable, err := executable.New(executable.AuthorizedKeysCheck, true) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -20,7 +20,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedPrincipalsCheck) + executable, err := executable.New(executable.AuthorizedPrincipalsCheck, true) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -34,7 +34,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.GitlabShell) + executable, err := executable.New(executable.GitlabShell, true) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -29,9 +29,13 @@ } func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (Command, error) { - args, err := commandargs.Parse(e, arguments, env) - if err != nil { - return nil, err + var args commandargs.CommandArgs + if e.AcceptArgs { + var err error + args, err = commandargs.Parse(e, arguments, env) + if err != nil { + return nil, err + } } if cmd := buildCommand(e, args, config, readWriter); cmd != nil { diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -26,10 +26,10 @@ ) var ( - authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} - authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} - checkExec = &executable.Executable{Name: executable.Healthcheck} - gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} + authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck, AcceptArgs: true} + authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck, AcceptArgs: true} + checkExec = &executable.Executable{Name: executable.Healthcheck, AcceptArgs: false} + gitlabShellExec = &executable.Executable{Name: executable.GitlabShell, AcceptArgs: true} basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} advancedConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket", SslCertDir: "/tmp/certs"} diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -1,6 +1,9 @@ package commandargs import ( + "errors" + "fmt" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -13,7 +16,7 @@ } func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (CommandArgs, error) { - var args CommandArgs = &GenericArgs{Arguments: arguments} + var args CommandArgs switch e.Name { case executable.GitlabShell: @@ -22,6 +25,8 @@ args = &AuthorizedKeys{Arguments: arguments} case executable.AuthorizedPrincipalsCheck: args = &AuthorizedPrincipals{Arguments: arguments} + default: + return nil, errors.New(fmt.Sprintf("unknown executable: %s", e.Name)) } if err := args.Parse(); err != nil { diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go --- a/internal/command/commandargs/command_args_test.go +++ b/internal/command/commandargs/command_args_test.go @@ -16,6 +16,7 @@ env sshenv.Env arguments []string expectedArgs CommandArgs + expectError bool }{ { desc: "It sets discover as the command when the command string was empty", @@ -100,10 +101,10 @@ arguments: []string{"key", "principal-1", "principal-2"}, expectedArgs: &AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, }, { - desc: "Unknown executable", - executable: &executable.Executable{Name: "unknown"}, - arguments: []string{}, - expectedArgs: &GenericArgs{Arguments: []string{}}, + desc: "Unknown executable", + executable: &executable.Executable{Name: "unknown"}, + arguments: []string{}, + expectError: true, }, } @@ -111,8 +112,12 @@ t.Run(tc.desc, func(t *testing.T) { result, err := Parse(tc.executable, tc.arguments, tc.env) - require.NoError(t, err) - require.Equal(t, tc.expectedArgs, result) + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } }) } } diff --git a/internal/command/commandargs/generic_args.go b/internal/command/commandargs/generic_args.go deleted file mode 100644 --- a/internal/command/commandargs/generic_args.go +++ /dev/null @@ -1,14 +0,0 @@ -package commandargs - -type GenericArgs struct { - Arguments []string -} - -func (b *GenericArgs) Parse() error { - // Do nothing - return nil -} - -func (b *GenericArgs) GetArguments() []string { - return b.Arguments -} diff --git a/internal/executable/executable.go b/internal/executable/executable.go --- a/internal/executable/executable.go +++ b/internal/executable/executable.go @@ -14,8 +14,9 @@ ) type Executable struct { - Name string - RootDir string + Name string + RootDir string + AcceptArgs bool } var ( @@ -23,7 +24,7 @@ osExecutable = os.Executable ) -func New(name string) (*Executable, error) { +func New(name string, acceptArgs bool) (*Executable, error) { path, err := osExecutable() if err != nil { return nil, err @@ -35,8 +36,9 @@ } executable := &Executable{ - Name: name, - RootDir: rootDir, + Name: name, + RootDir: rootDir, + AcceptArgs: acceptArgs, } return executable, nil diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -59,7 +59,7 @@ fake.Setup() defer fake.Cleanup() - result, err := New("gitlab-shell") + result, err := New("gitlab-shell", true) require.NoError(t, err) require.Equal(t, result.Name, "gitlab-shell") @@ -96,7 +96,7 @@ fake.Setup() defer fake.Cleanup() - _, err := New("gitlab-shell") + _, err := New("gitlab-shell", true) require.Error(t, err) }) # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1631020085 0 # Tue Sep 07 13:08:05 2021 +0000 # Node ID 092da560442d8510301acabbfc6b1eb16fbc07f0 # Parent 854da4efdb45866ea0259ffcd156c46f5f8b238b build: move build task to the top of the Makefile diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ PREFIX ?= /usr/local +build: bin/gitlab-shell + validate: verify test verify: verify_golang @@ -40,7 +42,6 @@ _script_install: bin/install -build: bin/gitlab-shell compile: bin/gitlab-shell bin/gitlab-shell: $(GO_SOURCES) GOBIN="$(CURDIR)/bin" go install $(GOBUILD_FLAGS) ./cmd/... # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631176434 0 # Thu Sep 09 08:33:54 2021 +0000 # Node ID 2ba81bca2e86125681be34ca3395651d245b553c # Parent 9d6099095d58735db722bcca90bc4782f7614ba5 # Parent 092da560442d8510301acabbfc6b1eb16fbc07f0 Merge branch 'build/make' into 'main' build: move build task to the top of the Makefile See merge request gitlab-org/gitlab-shell!513 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ PREFIX ?= /usr/local +build: bin/gitlab-shell + validate: verify test verify: verify_golang @@ -40,7 +42,6 @@ _script_install: bin/install -build: bin/gitlab-shell compile: bin/gitlab-shell bin/gitlab-shell: $(GO_SOURCES) GOBIN="$(CURDIR)/bin" go install $(GOBUILD_FLAGS) ./cmd/... # HG changeset patch # User Evan Read <eread@gitlab.com> # Date 1631576374 -36000 # Tue Sep 14 09:39:34 2021 +1000 # Node ID 495d526457d639d0e82a9b50ed8145520e9fea42 # Parent 2ba81bca2e86125681be34ca3395651d245b553c Update Ruby version to 2.7.4 and add Go version 1.16.8 for tooling diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.2 +2.7.4 diff --git a/.tool-versions b/.tool-versions new file mode 100644 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +ruby 2.7.4 +go 1.16.8 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1631578269 0 # Tue Sep 14 00:11:09 2021 +0000 # Node ID c70a9087948342444e87b77b0fb4a749bec95b42 # Parent 2ba81bca2e86125681be34ca3395651d245b553c # Parent 495d526457d639d0e82a9b50ed8145520e9fea42 Merge branch 'eread/update-project-tool-versions' into 'main' Update Ruby version to 2.7.4 and add Go version 1.16.8 for tooling See merge request gitlab-org/gitlab-shell!517 diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.2 +2.7.4 diff --git a/.tool-versions b/.tool-versions new file mode 100644 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +ruby 2.7.4 +go 1.16.8 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631626218 -3600 # Tue Sep 14 14:30:18 2021 +0100 # Node ID eaec6774ef2e610eb3399b296d21cd7652b9b8ff # Parent c70a9087948342444e87b77b0fb4a749bec95b42 Fix a flaky test diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -32,7 +32,7 @@ client, err := config.HttpClient() require.NoError(t, err) - _, err = client.Get("http://host.com/path") + _, err = client.Get(url) require.NoError(t, err) ms, err := prometheus.DefaultGatherer.Gather() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631626707 0 # Tue Sep 14 13:38:27 2021 +0000 # Node ID a6e55095129693b9c697f000caa234685cdc2ba1 # Parent c70a9087948342444e87b77b0fb4a749bec95b42 # Parent eaec6774ef2e610eb3399b296d21cd7652b9b8ff Merge branch 'fix-bad-spec' into 'main' Fix a flaky test See merge request gitlab-org/gitlab-shell!519 diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -32,7 +32,7 @@ client, err := config.HttpClient() require.NoError(t, err) - _, err = client.Get("http://host.com/path") + _, err = client.Get(url) require.NoError(t, err) ms, err := prometheus.DefaultGatherer.Gather() # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1631112035 0 # Wed Sep 08 14:40:35 2021 +0000 # Node ID a99f16501b1facae51eb16a109177c695102bc96 # Parent 9d6099095d58735db722bcca90bc4782f7614ba5 refactor: rearchitect command and executable Go modules diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command.go @@ -0,0 +1,22 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + + +func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + if cmd := build(config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func build(config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &healthcheck.Command{Config: config, ReadWriter: readWriter} +} diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command_test.go @@ -0,0 +1,42 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Healthcheck command", + config: basicConfig, + expectedType: &healthcheck.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -19,7 +19,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.Healthcheck, false) + executable, err := executable.New(executable.Healthcheck) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -34,7 +34,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := checkCmd.New(config, readWriter) if err != nil { fmt.Fprintf(readWriter.ErrOut, "%v\n", err) os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -0,0 +1,39 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(e, arguments, env) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (*commandargs.AuthorizedKeys, error) { + args := &commandargs.AuthorizedKeys{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -0,0 +1,120 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedKeys command", + executable: authorizedKeysExec, + arguments: []string{"git", "git", "key"}, + config: basicConfig, + expectedType: &authorizedkeys.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.executable, tc.arguments, tc.env, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-keys command", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"git", "git", "key"}, + expectedArgs: &commandargs.AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := command.Parse(tc.executable, tc.arguments, tc.env) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With too many arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", "key", "something-else"}, + expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With missing username for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "", "key"}, + expectedError: "# No username provided", + }, + { + desc: "With missing key for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", ""}, + expectedError: "# No key provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := command.Parse(tc.executable, tc.arguments, tc.env) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,6 +4,7 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -20,7 +21,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedKeysCheck, true) + executable, err := executable.New(executable.AuthorizedKeysCheck) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -35,7 +36,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -0,0 +1,39 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(e, arguments, env) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (*commandargs.AuthorizedPrincipals, error) { + args := &commandargs.AuthorizedPrincipals{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -0,0 +1,114 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedPrincipals command", + executable: authorizedPrincipalsExec, + arguments: []string{"key", "principal"}, + config: basicConfig, + expectedType: &authorizedprincipals.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.executable, tc.arguments, tc.env, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-principals command", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal-1", "principal-2"}, + expectedArgs: &commandargs.AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", + }, + { + desc: "With missing key_id for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"", "principal"}, + expectedError: "# No key_id provided", + }, + { + desc: "With blank principal for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal", ""}, + expectedError: "# An invalid principal was provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,6 +4,7 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -20,7 +21,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedPrincipalsCheck, true) + executable, err := executable.New(executable.AuthorizedPrincipalsCheck) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -35,7 +36,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command.go @@ -0,0 +1,65 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(e, arguments, env) + if err != nil { + return nil, err + } + + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (*commandargs.Shell, error) { + args := &commandargs.Shell{Arguments: arguments, Env: env} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func Build(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + switch args.CommandType { + case commandargs.Discover: + return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorRecover: + return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorVerify: + return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.LfsAuthenticate: + return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.ReceivePack: + return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadPack: + return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadArchive: + return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.PersonalAccessToken: + return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} + } + + return nil +} diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command_test.go @@ -0,0 +1,281 @@ +package command_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Discover command", + executable: gitlabShellExec, + env: buildEnv(""), + config: basicConfig, + expectedType: &discover.Command{}, + }, + { + desc: "it returns a TwoFactorRecover command", + executable: gitlabShellExec, + env: buildEnv("2fa_recovery_codes"), + config: basicConfig, + expectedType: &twofactorrecover.Command{}, + }, + { + desc: "it returns a TwoFactorVerify command", + executable: gitlabShellExec, + env: buildEnv("2fa_verify"), + config: basicConfig, + expectedType: &twofactorverify.Command{}, + }, + { + desc: "it returns an LfsAuthenticate command", + executable: gitlabShellExec, + env: buildEnv("git-lfs-authenticate"), + config: basicConfig, + expectedType: &lfsauthenticate.Command{}, + }, + { + desc: "it returns a ReceivePack command", + executable: gitlabShellExec, + env: buildEnv("git-receive-pack"), + config: basicConfig, + expectedType: &receivepack.Command{}, + }, + { + desc: "it returns an UploadPack command", + executable: gitlabShellExec, + env: buildEnv("git-upload-pack"), + config: basicConfig, + expectedType: &uploadpack.Command{}, + }, + { + desc: "it returns an UploadArchive command", + executable: gitlabShellExec, + env: buildEnv("git-upload-archive"), + config: basicConfig, + expectedType: &uploadarchive.Command{}, + }, + { + desc: "it returns a PersonalAccessToken command", + executable: gitlabShellExec, + env: buildEnv("personal_access_token"), + config: basicConfig, + expectedType: &personalaccesstoken.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.executable, tc.arguments, tc.env, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestFailingNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + expectedError error + }{ + { + desc: "Parsing environment failed", + executable: gitlabShellExec, + expectedError: errors.New("Only SSH allowed"), + }, + { + desc: "Unknown command given", + executable: gitlabShellExec, + env: buildEnv("unknown"), + expectedError: disallowedcommand.Error, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.executable, []string{}, tc.env, basicConfig, nil) + require.Nil(t, command) + require.Equal(t, tc.expectedError, err) + }) + } +} + +func buildEnv(command string) sshenv.Env { + return sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: command, + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It sets discover as the command when the command string was empty", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: commandargs.Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It parses 2fa_recovery_codes command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: commandargs.TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, + }, + { + desc: "It parses git-receive-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, + }, + { + desc: "It parses git-receive-pack command and a project with single quotes", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, + }, + { + desc: `It parses "git receive-pack" command`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, + }, + { + desc: `It parses a command followed by control characters`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, + }, + { + desc: "It parses git-upload-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: commandargs.UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, + }, + { + desc: "It parses git-upload-archive command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: commandargs.UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, + }, + { + desc: "It parses git-lfs-authenticate command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: commandargs.LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "It fails if SSH connection is not set", + executable: &executable.Executable{Name: executable.GitlabShell}, + arguments: []string{}, + expectedError: "Only SSH allowed", + }, + { + desc: "It fails if SSH command is invalid", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, + arguments: []string{}, + expectedError: "Invalid SSH command", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -4,6 +4,7 @@ "fmt" "os" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -34,7 +35,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.GitlabShell, true) + executable, err := executable.New(executable.GitlabShell) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -50,7 +51,7 @@ defer logCloser.Close() env := sshenv.NewFromEnv() - cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) + cmd, err := shellCmd.New(executable, os.Args[1:], env, config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,23 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -28,23 +12,6 @@ Execute(ctx context.Context) error } -func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (Command, error) { - var args commandargs.CommandArgs - if e.AcceptArgs { - var err error - args, err = commandargs.Parse(e, arguments, env) - if err != nil { - return nil, err - } - } - - if cmd := buildCommand(e, args, config, readWriter); cmd != nil { - return cmd, nil - } - - return nil, disallowedcommand.Error -} - // Setup() initializes tracing from the configuration file and generates a // background context from which all other contexts in the process should derive // from, as it has a service name and initial correlation ID set. @@ -80,53 +47,3 @@ closer.Close() } } - -func buildCommand(e *executable.Executable, args commandargs.CommandArgs, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch e.Name { - case executable.GitlabShell: - return BuildShellCommand(args.(*commandargs.Shell), config, readWriter) - case executable.AuthorizedKeysCheck: - return buildAuthorizedKeysCommand(args.(*commandargs.AuthorizedKeys), config, readWriter) - case executable.AuthorizedPrincipalsCheck: - return buildAuthorizedPrincipalsCommand(args.(*commandargs.AuthorizedPrincipals), config, readWriter) - case executable.Healthcheck: - return buildHealthcheckCommand(config, readWriter) - } - - return nil -} - -func BuildShellCommand(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch args.CommandType { - case commandargs.Discover: - return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorRecover: - return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorVerify: - return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.LfsAuthenticate: - return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.ReceivePack: - return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadPack: - return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadArchive: - return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.PersonalAccessToken: - return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} - } - - return nil -} - -func buildAuthorizedKeysCommand(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildAuthorizedPrincipalsCommand(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildHealthcheckCommand(config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &healthcheck.Command{Config: config, ReadWriter: readWriter} -} diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -1,173 +1,15 @@ package command import ( - "errors" "os" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" ) -var ( - authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck, AcceptArgs: true} - authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck, AcceptArgs: true} - checkExec = &executable.Executable{Name: executable.Healthcheck, AcceptArgs: false} - gitlabShellExec = &executable.Executable{Name: executable.GitlabShell, AcceptArgs: true} - - basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} - advancedConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket", SslCertDir: "/tmp/certs"} -) - -func buildEnv(command string) sshenv.Env { - return sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: command, - } -} - -func TestNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - config *config.Config - expectedType interface{} - }{ - { - desc: "it returns a Discover command", - executable: gitlabShellExec, - env: buildEnv(""), - config: basicConfig, - expectedType: &discover.Command{}, - }, - { - desc: "it returns a TwoFactorRecover command", - executable: gitlabShellExec, - env: buildEnv("2fa_recovery_codes"), - config: basicConfig, - expectedType: &twofactorrecover.Command{}, - }, - { - desc: "it returns a TwoFactorVerify command", - executable: gitlabShellExec, - env: buildEnv("2fa_verify"), - config: basicConfig, - expectedType: &twofactorverify.Command{}, - }, - { - desc: "it returns an LfsAuthenticate command", - executable: gitlabShellExec, - env: buildEnv("git-lfs-authenticate"), - config: basicConfig, - expectedType: &lfsauthenticate.Command{}, - }, - { - desc: "it returns a ReceivePack command", - executable: gitlabShellExec, - env: buildEnv("git-receive-pack"), - config: basicConfig, - expectedType: &receivepack.Command{}, - }, - { - desc: "it returns an UploadPack command", - executable: gitlabShellExec, - env: buildEnv("git-upload-pack"), - config: basicConfig, - expectedType: &uploadpack.Command{}, - }, - { - desc: "it returns an UploadArchive command", - executable: gitlabShellExec, - env: buildEnv("git-upload-archive"), - config: basicConfig, - expectedType: &uploadarchive.Command{}, - }, - { - desc: "it returns a Healthcheck command", - executable: checkExec, - config: basicConfig, - expectedType: &healthcheck.Command{}, - }, - { - desc: "it returns a AuthorizedKeys command", - executable: authorizedKeysExec, - arguments: []string{"git", "git", "key"}, - config: basicConfig, - expectedType: &authorizedkeys.Command{}, - }, - { - desc: "it returns a AuthorizedPrincipals command", - executable: authorizedPrincipalsExec, - arguments: []string{"key", "principal"}, - config: basicConfig, - expectedType: &authorizedprincipals.Command{}, - }, - { - desc: "it returns a PersonalAccessToken command", - executable: gitlabShellExec, - env: buildEnv("personal_access_token"), - config: basicConfig, - expectedType: &personalaccesstoken.Command{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, tc.arguments, tc.env, tc.config, nil) - - require.NoError(t, err) - require.IsType(t, tc.expectedType, command) - }) - } -} - -func TestFailingNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - expectedError error - }{ - { - desc: "Parsing environment failed", - executable: gitlabShellExec, - expectedError: errors.New("Only SSH allowed"), - }, - { - desc: "Unknown command given", - executable: gitlabShellExec, - env: buildEnv("unknown"), - expectedError: disallowedcommand.Error, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, []string{}, tc.env, basicConfig, nil) - require.Nil(t, command) - require.Equal(t, tc.expectedError, err) - }) - } -} - func TestSetup(t *testing.T) { testCases := []struct { name string diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -1,37 +1,8 @@ package commandargs -import ( - "errors" - "fmt" - - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" -) - type CommandType string type CommandArgs interface { Parse() error GetArguments() []string } - -func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (CommandArgs, error) { - var args CommandArgs - - switch e.Name { - case executable.GitlabShell: - args = &Shell{Arguments: arguments, Env: env} - case executable.AuthorizedKeysCheck: - args = &AuthorizedKeys{Arguments: arguments} - case executable.AuthorizedPrincipalsCheck: - args = &AuthorizedPrincipals{Arguments: arguments} - default: - return nil, errors.New(fmt.Sprintf("unknown executable: %s", e.Name)) - } - - if err := args.Parse(); err != nil { - return nil, err - } - - return args, nil -} diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go deleted file mode 100644 --- a/internal/command/commandargs/command_args_test.go +++ /dev/null @@ -1,197 +0,0 @@ -package commandargs - -import ( - "testing" - - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - - "github.com/stretchr/testify/require" -) - -func TestParseSuccess(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedArgs CommandArgs - expectError bool - }{ - { - desc: "It sets discover as the command when the command string was empty", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id only if the argument is of <key-id> format", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the username in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-jane-doe"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It parses 2fa_recovery_codes command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, - }, { - desc: "It parses git-receive-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, - }, { - desc: "It parses git-receive-pack command and a project with single quotes", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, - }, { - desc: `It parses "git receive-pack" command`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, - }, { - desc: `It parses a command followed by control characters`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, - }, { - desc: "It parses git-upload-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, - }, { - desc: "It parses git-upload-archive command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, - }, { - desc: "It parses git-lfs-authenticate command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, - }, { - desc: "It parses authorized-keys command", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"git", "git", "key"}, - expectedArgs: &AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, - }, { - desc: "It parses authorized-principals command", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal-1", "principal-2"}, - expectedArgs: &AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, - }, { - desc: "Unknown executable", - executable: &executable.Executable{Name: "unknown"}, - arguments: []string{}, - expectError: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := Parse(tc.executable, tc.arguments, tc.env) - - if !tc.expectError { - require.NoError(t, err) - require.Equal(t, tc.expectedArgs, result) - } else { - require.Error(t, err) - } - }) - } -} - -func TestParseFailure(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedError string - }{ - { - desc: "It fails if SSH connection is not set", - executable: &executable.Executable{Name: executable.GitlabShell}, - arguments: []string{}, - expectedError: "Only SSH allowed", - }, - { - desc: "It fails if SSH command is invalid", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, - arguments: []string{}, - expectedError: "Invalid SSH command", - }, - { - desc: "With not enough arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With too many arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", "key", "something-else"}, - expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With missing username for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "", "key"}, - expectedError: "# No username provided", - }, - { - desc: "With missing key for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", ""}, - expectedError: "# No key provided", - }, - { - desc: "With not enough arguments for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", - }, - { - desc: "With missing key_id for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"", "principal"}, - expectedError: "# No key_id provided", - }, - { - desc: "With blank principal for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal", ""}, - expectedError: "# An invalid principal was provided", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - _, err := Parse(tc.executable, tc.arguments, tc.env) - - require.EqualError(t, err, tc.expectedError) - }) - } -} diff --git a/internal/executable/executable.go b/internal/executable/executable.go --- a/internal/executable/executable.go +++ b/internal/executable/executable.go @@ -16,7 +16,6 @@ type Executable struct { Name string RootDir string - AcceptArgs bool } var ( @@ -24,7 +23,7 @@ osExecutable = os.Executable ) -func New(name string, acceptArgs bool) (*Executable, error) { +func New(name string) (*Executable, error) { path, err := osExecutable() if err != nil { return nil, err @@ -38,7 +37,6 @@ executable := &Executable{ Name: name, RootDir: rootDir, - AcceptArgs: acceptArgs, } return executable, nil diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -59,7 +59,7 @@ fake.Setup() defer fake.Cleanup() - result, err := New("gitlab-shell", true) + result, err := New("gitlab-shell") require.NoError(t, err) require.Equal(t, result.Name, "gitlab-shell") @@ -96,7 +96,7 @@ fake.Setup() defer fake.Cleanup() - _, err := New("gitlab-shell", true) + _, err := New("gitlab-shell") require.Error(t, err) }) diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -6,7 +6,7 @@ "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -125,7 +125,7 @@ ErrOut: s.channel.Stderr(), } - cmd := command.BuildShellCommand(args, s.cfg, rw) + cmd := shellCmd.Build(args, s.cfg, rw) if cmd == nil { s.toStderr("Unknown command: %v\n", args.CommandType) return 128 # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1631113461 0 # Wed Sep 08 15:04:21 2021 +0000 # Node ID e48762224368d26c2fd014c5bd1bf27923987dba # Parent a99f16501b1facae51eb16a109177c695102bc96 refactor: cleanup func signature and remove unused args diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -7,12 +7,10 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { - args, err := Parse(e, arguments, env) +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) if err != nil { return nil, err } @@ -24,7 +22,7 @@ return nil, disallowedcommand.Error } -func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (*commandargs.AuthorizedKeys, error) { +func Parse(arguments []string) (*commandargs.AuthorizedKeys, error) { args := &commandargs.AuthorizedKeys{Arguments: arguments} if err := args.Parse(); err != nil { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -37,7 +37,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - command, err := command.New(tc.executable, tc.arguments, tc.env, tc.config, nil) + command, err := command.New(tc.arguments, tc.config, nil) require.NoError(t, err) require.IsType(t, tc.expectedType, command) @@ -64,7 +64,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - result, err := command.Parse(tc.executable, tc.arguments, tc.env) + result, err := command.Parse(tc.arguments) if !tc.expectError { require.NoError(t, err) @@ -112,7 +112,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - _, err := command.Parse(tc.executable, tc.arguments, tc.env) + _, err := command.Parse(tc.arguments) require.EqualError(t, err, tc.expectedError) }) diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -11,7 +11,6 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -36,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := cmd.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -7,12 +7,10 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { - args, err := Parse(e, arguments, env) +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) if err != nil { return nil, err } @@ -24,7 +22,7 @@ return nil, disallowedcommand.Error } -func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (*commandargs.AuthorizedPrincipals, error) { +func Parse(arguments []string) (*commandargs.AuthorizedPrincipals, error) { args := &commandargs.AuthorizedPrincipals{Arguments: arguments} if err := args.Parse(); err != nil { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -37,7 +37,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - command, err := cmd.New(tc.executable, tc.arguments, tc.env, tc.config, nil) + command, err := cmd.New(tc.arguments, tc.config, nil) require.NoError(t, err) require.IsType(t, tc.expectedType, command) @@ -64,7 +64,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - result, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + result, err := cmd.Parse(tc.arguments) if !tc.expectError { require.NoError(t, err) @@ -106,7 +106,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - _, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + _, err := cmd.Parse(tc.arguments) require.EqualError(t, err, tc.expectedError) }) diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -11,7 +11,6 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -36,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := cmd.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go --- a/cmd/gitlab-shell/command/command.go +++ b/cmd/gitlab-shell/command/command.go @@ -14,12 +14,11 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { - args, err := Parse(e, arguments, env) +func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments, env) if err != nil { return nil, err } @@ -31,7 +30,7 @@ return nil, disallowedcommand.Error } -func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (*commandargs.Shell, error) { +func Parse(arguments []string, env sshenv.Env) (*commandargs.Shell, error) { args := &commandargs.Shell{Arguments: arguments, Env: env} if err := args.Parse(); err != nil { diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -95,7 +95,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - command, err := cmd.New(tc.executable, tc.arguments, tc.env, tc.config, nil) + command, err := cmd.New(tc.arguments, tc.env, tc.config, nil) require.NoError(t, err) require.IsType(t, tc.expectedType, command) @@ -125,7 +125,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - command, err := cmd.New(tc.executable, []string{}, tc.env, basicConfig, nil) + command, err := cmd.New([]string{}, tc.env, basicConfig, nil) require.Nil(t, command) require.Equal(t, tc.expectedError, err) }) @@ -236,7 +236,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - result, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + result, err := cmd.Parse(tc.arguments, tc.env) if !tc.expectError { require.NoError(t, err) @@ -273,7 +273,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - _, err := cmd.Parse(tc.executable, tc.arguments, tc.env) + _, err := cmd.Parse(tc.arguments, tc.env) require.EqualError(t, err, tc.expectedError) }) diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -51,7 +51,7 @@ defer logCloser.Close() env := sshenv.NewFromEnv() - cmd, err := shellCmd.New(executable, os.Args[1:], env, config, readWriter) + cmd, err := shellCmd.New(os.Args[1:], env, config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1631115906 0 # Wed Sep 08 15:45:06 2021 +0000 # Node ID 59bd705b20bab515eb6048a74038aaeb71be932b # Parent e48762224368d26c2fd014c5bd1bf27923987dba refactor: fix style issues diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go --- a/cmd/check/command/command.go +++ b/cmd/check/command/command.go @@ -8,7 +8,6 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) - func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { if cmd := build(config, readWriter); cmd != nil { return cmd, nil diff --git a/internal/executable/executable.go b/internal/executable/executable.go --- a/internal/executable/executable.go +++ b/internal/executable/executable.go @@ -14,8 +14,8 @@ ) type Executable struct { - Name string - RootDir string + Name string + RootDir string } var ( @@ -35,8 +35,8 @@ } executable := &Executable{ - Name: name, - RootDir: rootDir, + Name: name, + RootDir: rootDir, } return executable, nil # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631626953 -3600 # Tue Sep 14 14:42:33 2021 +0100 # Node ID 7052305b4d4968d49d50e72e54d57a904b2f6f76 # Parent 59bd705b20bab515eb6048a74038aaeb71be932b # Parent a6e55095129693b9c697f000caa234685cdc2ba1 Merge branch 'main' into refactor/cmd diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.2 +2.7.4 diff --git a/.tool-versions b/.tool-versions new file mode 100644 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +ruby 2.7.4 +go 1.16.8 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ PREFIX ?= /usr/local +build: bin/gitlab-shell + validate: verify test verify: verify_golang @@ -40,7 +42,6 @@ _script_install: bin/install -build: bin/gitlab-shell compile: bin/gitlab-shell bin/gitlab-shell: $(GO_SOURCES) GOBIN="$(CURDIR)/bin" go install $(GOBUILD_FLAGS) ./cmd/... diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -32,7 +32,7 @@ client, err := config.HttpClient() require.NoError(t, err) - _, err = client.Get("http://host.com/path") + _, err = client.Get(url) require.NoError(t, err) ms, err := prometheus.DefaultGatherer.Gather() # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631627422 0 # Tue Sep 14 13:50:22 2021 +0000 # Node ID 1e55f7044ac9bb3c90328edc2b168941c9affed3 # Parent a6e55095129693b9c697f000caa234685cdc2ba1 # Parent 7052305b4d4968d49d50e72e54d57a904b2f6f76 Merge branch 'refactor/cmd' into 'main' refactor: rearchitect command and executable Go modules Closes #214 See merge request gitlab-org/gitlab-shell!514 diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command.go @@ -0,0 +1,21 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + if cmd := build(config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func build(config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &healthcheck.Command{Config: config, ReadWriter: readWriter} +} diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command_test.go @@ -0,0 +1,42 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Healthcheck command", + config: basicConfig, + expectedType: &healthcheck.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -19,7 +19,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.Healthcheck, false) + executable, err := executable.New(executable.Healthcheck) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -34,7 +34,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := checkCmd.New(config, readWriter) if err != nil { fmt.Fprintf(readWriter.ErrOut, "%v\n", err) os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -0,0 +1,37 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string) (*commandargs.AuthorizedKeys, error) { + args := &commandargs.AuthorizedKeys{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -0,0 +1,120 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedKeys command", + executable: authorizedKeysExec, + arguments: []string{"git", "git", "key"}, + config: basicConfig, + expectedType: &authorizedkeys.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.arguments, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-keys command", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"git", "git", "key"}, + expectedArgs: &commandargs.AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := command.Parse(tc.arguments) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With too many arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", "key", "something-else"}, + expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With missing username for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "", "key"}, + expectedError: "# No username provided", + }, + { + desc: "With missing key for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", ""}, + expectedError: "# No key provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := command.Parse(tc.arguments) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -20,7 +20,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedKeysCheck, true) + executable, err := executable.New(executable.AuthorizedKeysCheck) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -35,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -0,0 +1,37 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string) (*commandargs.AuthorizedPrincipals, error) { + args := &commandargs.AuthorizedPrincipals{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -0,0 +1,114 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedPrincipals command", + executable: authorizedPrincipalsExec, + arguments: []string{"key", "principal"}, + config: basicConfig, + expectedType: &authorizedprincipals.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.arguments, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-principals command", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal-1", "principal-2"}, + expectedArgs: &commandargs.AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.arguments) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", + }, + { + desc: "With missing key_id for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"", "principal"}, + expectedError: "# No key_id provided", + }, + { + desc: "With blank principal for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal", ""}, + expectedError: "# An invalid principal was provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.arguments) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -20,7 +20,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.AuthorizedPrincipalsCheck, true) + executable, err := executable.New(executable.AuthorizedPrincipalsCheck) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -35,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command.go @@ -0,0 +1,64 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments, env) + if err != nil { + return nil, err + } + + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string, env sshenv.Env) (*commandargs.Shell, error) { + args := &commandargs.Shell{Arguments: arguments, Env: env} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func Build(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + switch args.CommandType { + case commandargs.Discover: + return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorRecover: + return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorVerify: + return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.LfsAuthenticate: + return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.ReceivePack: + return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadPack: + return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadArchive: + return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.PersonalAccessToken: + return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} + } + + return nil +} diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command_test.go @@ -0,0 +1,281 @@ +package command_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Discover command", + executable: gitlabShellExec, + env: buildEnv(""), + config: basicConfig, + expectedType: &discover.Command{}, + }, + { + desc: "it returns a TwoFactorRecover command", + executable: gitlabShellExec, + env: buildEnv("2fa_recovery_codes"), + config: basicConfig, + expectedType: &twofactorrecover.Command{}, + }, + { + desc: "it returns a TwoFactorVerify command", + executable: gitlabShellExec, + env: buildEnv("2fa_verify"), + config: basicConfig, + expectedType: &twofactorverify.Command{}, + }, + { + desc: "it returns an LfsAuthenticate command", + executable: gitlabShellExec, + env: buildEnv("git-lfs-authenticate"), + config: basicConfig, + expectedType: &lfsauthenticate.Command{}, + }, + { + desc: "it returns a ReceivePack command", + executable: gitlabShellExec, + env: buildEnv("git-receive-pack"), + config: basicConfig, + expectedType: &receivepack.Command{}, + }, + { + desc: "it returns an UploadPack command", + executable: gitlabShellExec, + env: buildEnv("git-upload-pack"), + config: basicConfig, + expectedType: &uploadpack.Command{}, + }, + { + desc: "it returns an UploadArchive command", + executable: gitlabShellExec, + env: buildEnv("git-upload-archive"), + config: basicConfig, + expectedType: &uploadarchive.Command{}, + }, + { + desc: "it returns a PersonalAccessToken command", + executable: gitlabShellExec, + env: buildEnv("personal_access_token"), + config: basicConfig, + expectedType: &personalaccesstoken.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.arguments, tc.env, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestFailingNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + expectedError error + }{ + { + desc: "Parsing environment failed", + executable: gitlabShellExec, + expectedError: errors.New("Only SSH allowed"), + }, + { + desc: "Unknown command given", + executable: gitlabShellExec, + env: buildEnv("unknown"), + expectedError: disallowedcommand.Error, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New([]string{}, tc.env, basicConfig, nil) + require.Nil(t, command) + require.Equal(t, tc.expectedError, err) + }) + } +} + +func buildEnv(command string) sshenv.Env { + return sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: command, + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It sets discover as the command when the command string was empty", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: commandargs.Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It parses 2fa_recovery_codes command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: commandargs.TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, + }, + { + desc: "It parses git-receive-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, + }, + { + desc: "It parses git-receive-pack command and a project with single quotes", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, + }, + { + desc: `It parses "git receive-pack" command`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, + }, + { + desc: `It parses a command followed by control characters`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, + }, + { + desc: "It parses git-upload-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: commandargs.UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, + }, + { + desc: "It parses git-upload-archive command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: commandargs.UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, + }, + { + desc: "It parses git-lfs-authenticate command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: commandargs.LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.arguments, tc.env) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "It fails if SSH connection is not set", + executable: &executable.Executable{Name: executable.GitlabShell}, + arguments: []string{}, + expectedError: "Only SSH allowed", + }, + { + desc: "It fails if SSH command is invalid", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, + arguments: []string{}, + expectedError: "Invalid SSH command", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.arguments, tc.env) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -4,6 +4,7 @@ "fmt" "os" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -34,7 +35,7 @@ ErrOut: os.Stderr, } - executable, err := executable.New(executable.GitlabShell, true) + executable, err := executable.New(executable.GitlabShell) if err != nil { fmt.Fprintln(readWriter.ErrOut, "Failed to determine executable, exiting") os.Exit(1) @@ -50,7 +51,7 @@ defer logCloser.Close() env := sshenv.NewFromEnv() - cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) + cmd, err := shellCmd.New(os.Args[1:], env, config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,23 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -28,23 +12,6 @@ Execute(ctx context.Context) error } -func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (Command, error) { - var args commandargs.CommandArgs - if e.AcceptArgs { - var err error - args, err = commandargs.Parse(e, arguments, env) - if err != nil { - return nil, err - } - } - - if cmd := buildCommand(e, args, config, readWriter); cmd != nil { - return cmd, nil - } - - return nil, disallowedcommand.Error -} - // Setup() initializes tracing from the configuration file and generates a // background context from which all other contexts in the process should derive // from, as it has a service name and initial correlation ID set. @@ -80,53 +47,3 @@ closer.Close() } } - -func buildCommand(e *executable.Executable, args commandargs.CommandArgs, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch e.Name { - case executable.GitlabShell: - return BuildShellCommand(args.(*commandargs.Shell), config, readWriter) - case executable.AuthorizedKeysCheck: - return buildAuthorizedKeysCommand(args.(*commandargs.AuthorizedKeys), config, readWriter) - case executable.AuthorizedPrincipalsCheck: - return buildAuthorizedPrincipalsCommand(args.(*commandargs.AuthorizedPrincipals), config, readWriter) - case executable.Healthcheck: - return buildHealthcheckCommand(config, readWriter) - } - - return nil -} - -func BuildShellCommand(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch args.CommandType { - case commandargs.Discover: - return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorRecover: - return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorVerify: - return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.LfsAuthenticate: - return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.ReceivePack: - return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadPack: - return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadArchive: - return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.PersonalAccessToken: - return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} - } - - return nil -} - -func buildAuthorizedKeysCommand(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildAuthorizedPrincipalsCommand(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildHealthcheckCommand(config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &healthcheck.Command{Config: config, ReadWriter: readWriter} -} diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -1,173 +1,15 @@ package command import ( - "errors" "os" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" ) -var ( - authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck, AcceptArgs: true} - authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck, AcceptArgs: true} - checkExec = &executable.Executable{Name: executable.Healthcheck, AcceptArgs: false} - gitlabShellExec = &executable.Executable{Name: executable.GitlabShell, AcceptArgs: true} - - basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} - advancedConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket", SslCertDir: "/tmp/certs"} -) - -func buildEnv(command string) sshenv.Env { - return sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: command, - } -} - -func TestNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - config *config.Config - expectedType interface{} - }{ - { - desc: "it returns a Discover command", - executable: gitlabShellExec, - env: buildEnv(""), - config: basicConfig, - expectedType: &discover.Command{}, - }, - { - desc: "it returns a TwoFactorRecover command", - executable: gitlabShellExec, - env: buildEnv("2fa_recovery_codes"), - config: basicConfig, - expectedType: &twofactorrecover.Command{}, - }, - { - desc: "it returns a TwoFactorVerify command", - executable: gitlabShellExec, - env: buildEnv("2fa_verify"), - config: basicConfig, - expectedType: &twofactorverify.Command{}, - }, - { - desc: "it returns an LfsAuthenticate command", - executable: gitlabShellExec, - env: buildEnv("git-lfs-authenticate"), - config: basicConfig, - expectedType: &lfsauthenticate.Command{}, - }, - { - desc: "it returns a ReceivePack command", - executable: gitlabShellExec, - env: buildEnv("git-receive-pack"), - config: basicConfig, - expectedType: &receivepack.Command{}, - }, - { - desc: "it returns an UploadPack command", - executable: gitlabShellExec, - env: buildEnv("git-upload-pack"), - config: basicConfig, - expectedType: &uploadpack.Command{}, - }, - { - desc: "it returns an UploadArchive command", - executable: gitlabShellExec, - env: buildEnv("git-upload-archive"), - config: basicConfig, - expectedType: &uploadarchive.Command{}, - }, - { - desc: "it returns a Healthcheck command", - executable: checkExec, - config: basicConfig, - expectedType: &healthcheck.Command{}, - }, - { - desc: "it returns a AuthorizedKeys command", - executable: authorizedKeysExec, - arguments: []string{"git", "git", "key"}, - config: basicConfig, - expectedType: &authorizedkeys.Command{}, - }, - { - desc: "it returns a AuthorizedPrincipals command", - executable: authorizedPrincipalsExec, - arguments: []string{"key", "principal"}, - config: basicConfig, - expectedType: &authorizedprincipals.Command{}, - }, - { - desc: "it returns a PersonalAccessToken command", - executable: gitlabShellExec, - env: buildEnv("personal_access_token"), - config: basicConfig, - expectedType: &personalaccesstoken.Command{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, tc.arguments, tc.env, tc.config, nil) - - require.NoError(t, err) - require.IsType(t, tc.expectedType, command) - }) - } -} - -func TestFailingNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - expectedError error - }{ - { - desc: "Parsing environment failed", - executable: gitlabShellExec, - expectedError: errors.New("Only SSH allowed"), - }, - { - desc: "Unknown command given", - executable: gitlabShellExec, - env: buildEnv("unknown"), - expectedError: disallowedcommand.Error, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, []string{}, tc.env, basicConfig, nil) - require.Nil(t, command) - require.Equal(t, tc.expectedError, err) - }) - } -} - func TestSetup(t *testing.T) { testCases := []struct { name string diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -1,37 +1,8 @@ package commandargs -import ( - "errors" - "fmt" - - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" -) - type CommandType string type CommandArgs interface { Parse() error GetArguments() []string } - -func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (CommandArgs, error) { - var args CommandArgs - - switch e.Name { - case executable.GitlabShell: - args = &Shell{Arguments: arguments, Env: env} - case executable.AuthorizedKeysCheck: - args = &AuthorizedKeys{Arguments: arguments} - case executable.AuthorizedPrincipalsCheck: - args = &AuthorizedPrincipals{Arguments: arguments} - default: - return nil, errors.New(fmt.Sprintf("unknown executable: %s", e.Name)) - } - - if err := args.Parse(); err != nil { - return nil, err - } - - return args, nil -} diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go deleted file mode 100644 --- a/internal/command/commandargs/command_args_test.go +++ /dev/null @@ -1,197 +0,0 @@ -package commandargs - -import ( - "testing" - - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - - "github.com/stretchr/testify/require" -) - -func TestParseSuccess(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedArgs CommandArgs - expectError bool - }{ - { - desc: "It sets discover as the command when the command string was empty", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id only if the argument is of <key-id> format", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the username in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-jane-doe"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It parses 2fa_recovery_codes command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, - }, { - desc: "It parses git-receive-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, - }, { - desc: "It parses git-receive-pack command and a project with single quotes", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, - }, { - desc: `It parses "git receive-pack" command`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, - }, { - desc: `It parses a command followed by control characters`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, - }, { - desc: "It parses git-upload-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, - }, { - desc: "It parses git-upload-archive command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, - }, { - desc: "It parses git-lfs-authenticate command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, - }, { - desc: "It parses authorized-keys command", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"git", "git", "key"}, - expectedArgs: &AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, - }, { - desc: "It parses authorized-principals command", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal-1", "principal-2"}, - expectedArgs: &AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, - }, { - desc: "Unknown executable", - executable: &executable.Executable{Name: "unknown"}, - arguments: []string{}, - expectError: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := Parse(tc.executable, tc.arguments, tc.env) - - if !tc.expectError { - require.NoError(t, err) - require.Equal(t, tc.expectedArgs, result) - } else { - require.Error(t, err) - } - }) - } -} - -func TestParseFailure(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedError string - }{ - { - desc: "It fails if SSH connection is not set", - executable: &executable.Executable{Name: executable.GitlabShell}, - arguments: []string{}, - expectedError: "Only SSH allowed", - }, - { - desc: "It fails if SSH command is invalid", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, - arguments: []string{}, - expectedError: "Invalid SSH command", - }, - { - desc: "With not enough arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With too many arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", "key", "something-else"}, - expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With missing username for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "", "key"}, - expectedError: "# No username provided", - }, - { - desc: "With missing key for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", ""}, - expectedError: "# No key provided", - }, - { - desc: "With not enough arguments for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", - }, - { - desc: "With missing key_id for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"", "principal"}, - expectedError: "# No key_id provided", - }, - { - desc: "With blank principal for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal", ""}, - expectedError: "# An invalid principal was provided", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - _, err := Parse(tc.executable, tc.arguments, tc.env) - - require.EqualError(t, err, tc.expectedError) - }) - } -} diff --git a/internal/executable/executable.go b/internal/executable/executable.go --- a/internal/executable/executable.go +++ b/internal/executable/executable.go @@ -14,9 +14,8 @@ ) type Executable struct { - Name string - RootDir string - AcceptArgs bool + Name string + RootDir string } var ( @@ -24,7 +23,7 @@ osExecutable = os.Executable ) -func New(name string, acceptArgs bool) (*Executable, error) { +func New(name string) (*Executable, error) { path, err := osExecutable() if err != nil { return nil, err @@ -36,9 +35,8 @@ } executable := &Executable{ - Name: name, - RootDir: rootDir, - AcceptArgs: acceptArgs, + Name: name, + RootDir: rootDir, } return executable, nil diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -59,7 +59,7 @@ fake.Setup() defer fake.Cleanup() - result, err := New("gitlab-shell", true) + result, err := New("gitlab-shell") require.NoError(t, err) require.Equal(t, result.Name, "gitlab-shell") @@ -96,7 +96,7 @@ fake.Setup() defer fake.Cleanup() - _, err := New("gitlab-shell", true) + _, err := New("gitlab-shell") require.Error(t, err) }) diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -6,7 +6,7 @@ "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -125,7 +125,7 @@ ErrOut: s.channel.Stderr(), } - cmd := command.BuildShellCommand(args, s.cfg, rw) + cmd := shellCmd.Build(args, s.cfg, rw) if cmd == nil { s.toStderr("Unknown command: %v\n", args.CommandType) return 128 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631619467 -10800 # Tue Sep 14 14:37:47 2021 +0300 # Node ID ad0c0d6fff0e957bd43ba0bd1813d5325585b689 # Parent 1e55f7044ac9bb3c90328edc2b168941c9affed3 Add TestInvalidClientConfig and TestNewServerWithoutHosts for sshd.go diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -104,6 +104,22 @@ require.Equal(t, 200, r.Result().StatusCode) } +func TestNewServerWithoutHosts(t *testing.T) { + _, err := NewServer(&config.Config{GitlabUrl: "http://localhost"}) + + require.Error(t, err) + require.Equal(t, "No host keys could be loaded, aborting", err.Error()) +} + +func TestInvalidClientConfig(t *testing.T) { + setupServer(t) + + cfg := clientConfig(t) + cfg.User = "unknown" + _, err := ssh.Dial("tcp", serverUrl, cfg) + require.Error(t, err) +} + func setupServer(t *testing.T) *Server { t.Helper() # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631697147 0 # Wed Sep 15 09:12:27 2021 +0000 # Node ID f529d059d39fc51b54a7f166913f43372a3a72f4 # Parent 1e55f7044ac9bb3c90328edc2b168941c9affed3 # Parent ad0c0d6fff0e957bd43ba0bd1813d5325585b689 Merge branch 'id-sshd-tests' into 'main' Add TestInvalidClientConfig and TestNewServerWithoutHosts for sshd.go See merge request gitlab-org/gitlab-shell!518 diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -104,6 +104,22 @@ require.Equal(t, 200, r.Result().StatusCode) } +func TestNewServerWithoutHosts(t *testing.T) { + _, err := NewServer(&config.Config{GitlabUrl: "http://localhost"}) + + require.Error(t, err) + require.Equal(t, "No host keys could be loaded, aborting", err.Error()) +} + +func TestInvalidClientConfig(t *testing.T) { + setupServer(t) + + cfg := clientConfig(t) + cfg.User = "unknown" + _, err := ssh.Dial("tcp", serverUrl, cfg) + require.Error(t, err) +} + func setupServer(t *testing.T) *Server { t.Helper() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631701688 -10800 # Wed Sep 15 13:28:08 2021 +0300 # Node ID ad2f264f1ce8a85761cbaed5f6a490d53d292bf1 # Parent f529d059d39fc51b54a7f166913f43372a3a72f4 Unit test sshd.handleEnv function diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/session_test.go @@ -0,0 +1,44 @@ +package sshd + +import ( + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" +) + +func TestHandleEnv(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedProtocolVersion string + expectedResult bool + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedProtocolVersion: "1", + expectedResult: false, + }, { + desc: "valid payload", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedProtocolVersion: "2", + expectedResult: true, + }, { + desc: "valid payload with forbidden env var", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedProtocolVersion: "1", + expectedResult: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + s := &session{gitProtocolVersion: "1"} + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, s.handleEnv(r), tc.expectedResult) + require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + }) + } +} # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631704869 0 # Wed Sep 15 11:21:09 2021 +0000 # Node ID 1758ccc5961c9f68fc3d9335460059b876539924 # Parent f529d059d39fc51b54a7f166913f43372a3a72f4 # Parent ad2f264f1ce8a85761cbaed5f6a490d53d292bf1 Merge branch 'id-session-test' into 'main' Unit test sshd.handleEnv function See merge request gitlab-org/gitlab-shell!521 diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/session_test.go @@ -0,0 +1,44 @@ +package sshd + +import ( + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" +) + +func TestHandleEnv(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedProtocolVersion string + expectedResult bool + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedProtocolVersion: "1", + expectedResult: false, + }, { + desc: "valid payload", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedProtocolVersion: "2", + expectedResult: true, + }, { + desc: "valid payload with forbidden env var", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedProtocolVersion: "1", + expectedResult: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + s := &session{gitProtocolVersion: "1"} + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, s.handleEnv(r), tc.expectedResult) + require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + }) + } +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631713284 -10800 # Wed Sep 15 16:41:24 2021 +0300 # Node ID d0d81a5dcf44095a9eea8fff7fb4eed271ca113c # Parent 1758ccc5961c9f68fc3d9335460059b876539924 Unit test exit-codes for sshd/session.go diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -1,12 +1,61 @@ package sshd import ( + "bytes" + "context" + "io" + "net/http" "testing" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) +type fakeChannel struct { + stdErr io.ReadWriter + sentRequestName string + sentRequestPayload []byte +} + +func (f *fakeChannel) Read(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Write(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Close() error { + return nil +} + +func (f *fakeChannel) CloseWrite() error { + return nil +} + +func (f *fakeChannel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { + f.sentRequestName = name + f.sentRequestPayload = payload + + return true, nil +} + +func (f *fakeChannel) Stderr() io.ReadWriter { + return f.stdErr +} + +var requests = []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"id": 1000, "name": "Test User", "username": "test-user"}`)) + }, + }, +} + func TestHandleEnv(t *testing.T) { testCases := []struct { desc string @@ -42,3 +91,99 @@ }) } } + +func TestHandleExec(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedExecCmd string + sentRequestName string + sentRequestPayload []byte + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedExecCmd: "", + sentRequestName: "", + }, { + desc: "valid payload", + payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedExecCmd: "discover", + sentRequestName: "exit-status", + sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + f := &fakeChannel{stdErr: out} + s := &session{ + gitlabKeyId: "root", + channel: f, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, false, s.handleExec(context.Background(), r)) + require.Equal(t, tc.sentRequestName, f.sentRequestName) + require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + }) + } +} + +func TestHandleShell(t *testing.T) { + testCases := []struct { + desc string + cmd string + errMsg string + gitlabKeyId string + expectedExitCode uint32 + }{ + { + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: invalid command line string\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedExitCode: 1, + }, { + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedExitCode: 0, + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + s := &session{ + gitlabKeyId: tc.gitlabKeyId, + execCmd: tc.cmd, + channel: &fakeChannel{stdErr: out}, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{} + + require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + require.Equal(t, tc.errMsg, out.String()) + }) + } +} # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631716784 0 # Wed Sep 15 14:39:44 2021 +0000 # Node ID ae1afbe2d7390f14489d9c61baadc06fae4f8d51 # Parent 1758ccc5961c9f68fc3d9335460059b876539924 # Parent d0d81a5dcf44095a9eea8fff7fb4eed271ca113c Merge branch 'id-session-test-2' into 'main' Unit test exit-codes for sshd/session.go Closes #522 See merge request gitlab-org/gitlab-shell!522 diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -1,12 +1,61 @@ package sshd import ( + "bytes" + "context" + "io" + "net/http" "testing" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) +type fakeChannel struct { + stdErr io.ReadWriter + sentRequestName string + sentRequestPayload []byte +} + +func (f *fakeChannel) Read(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Write(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Close() error { + return nil +} + +func (f *fakeChannel) CloseWrite() error { + return nil +} + +func (f *fakeChannel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { + f.sentRequestName = name + f.sentRequestPayload = payload + + return true, nil +} + +func (f *fakeChannel) Stderr() io.ReadWriter { + return f.stdErr +} + +var requests = []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"id": 1000, "name": "Test User", "username": "test-user"}`)) + }, + }, +} + func TestHandleEnv(t *testing.T) { testCases := []struct { desc string @@ -42,3 +91,99 @@ }) } } + +func TestHandleExec(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedExecCmd string + sentRequestName string + sentRequestPayload []byte + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedExecCmd: "", + sentRequestName: "", + }, { + desc: "valid payload", + payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedExecCmd: "discover", + sentRequestName: "exit-status", + sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + f := &fakeChannel{stdErr: out} + s := &session{ + gitlabKeyId: "root", + channel: f, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, false, s.handleExec(context.Background(), r)) + require.Equal(t, tc.sentRequestName, f.sentRequestName) + require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + }) + } +} + +func TestHandleShell(t *testing.T) { + testCases := []struct { + desc string + cmd string + errMsg string + gitlabKeyId string + expectedExitCode uint32 + }{ + { + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: invalid command line string\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedExitCode: 1, + }, { + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedExitCode: 0, + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + s := &session{ + gitlabKeyId: tc.gitlabKeyId, + execCmd: tc.cmd, + channel: &fakeChannel{stdErr: out}, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{} + + require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + require.Equal(t, tc.errMsg, out.String()) + }) + } +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631721507 -10800 # Wed Sep 15 18:58:27 2021 +0300 # Node ID f48622b668b43d66466c50035198c262e66ab6eb # Parent ae1afbe2d7390f14489d9c61baadc06fae4f8d51 Extract server config related code out of sshd.go diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config.go @@ -0,0 +1,94 @@ +package sshd + +import ( + "context" + "encoding/base64" + "fmt" + "os" + "strconv" + "time" + + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + + "gitlab.com/gitlab-org/labkit/log" +) + +type serverConfig struct { + cfg *config.Config + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).Warnf("Failed to read host key %v", filename) + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).Warnf("Failed to parse host key %v", filename) + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") + } + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil +} + +func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { + if user != s.cfg.User { + return nil, fmt.Errorf("unknown user") + } + if key.Type() == ssh.KeyAlgoDSA { + return nil, fmt.Errorf("DSA is prohibited") + } + + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + if err != nil { + return nil, err + } + + return res, nil +} + +func (s *serverConfig) get(ctx context.Context) *ssh.ServerConfig { + sshCfg := &ssh.ServerConfig{ + PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { + res, err := s.getAuthKey(ctx, conn.User(), key) + if err != nil { + return nil, err + } + + return &ssh.Permissions{ + // Record the public key used for authentication. + Extensions: map[string]string{ + "key-id": strconv.FormatInt(res.Id, 10), + }, + }, nil + }, + } + + for _, key := range s.hostKeys { + sshCfg.AddHostKey(key) + } + + return sshCfg +} diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config_test.go @@ -0,0 +1,105 @@ +package sshd + +import ( + "context" + "crypto/dsa" + "crypto/rand" + "crypto/rsa" + "path" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +func TestNewServerConfigWithoutHosts(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "http://localhost"}) + + require.Error(t, err) + require.Equal(t, "No host keys could be loaded, aborting", err.Error()) +} + +func TestFailedAuthorizedKeysClient(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) + + require.Error(t, err) + require.Equal(t, "failed to initialize GitLab client: Error creating http client: unknown GitLab URL prefix", err.Error()) +} + +func TestFailedGetAuthKey(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + testCases := []struct { + desc string + user string + key ssh.PublicKey + expectedError string + }{ + { + desc: "wrong user", + user: "wrong-user", + key: rsaPublicKey(t), + expectedError: "unknown user", + }, { + desc: "prohibited dsa key", + user: "user", + key: dsaPublicKey(t), + expectedError: "DSA is prohibited", + }, { + desc: "API error", + user: "user", + key: rsaPublicKey(t), + expectedError: "Internal API unreachable", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err = cfg.getAuthKey(context.Background(), tc.user, tc.key) + require.Error(t, err) + require.Equal(t, tc.expectedError, err.Error()) + }) + } +} + +func rsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} + +func dsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey := new(dsa.PrivateKey) + params := new(dsa.Parameters) + require.NoError(t, dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160)) + + privateKey.PublicKey.Parameters = *params + require.NoError(t, dsa.GenerateKey(privateKey, rand.Reader)) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -2,13 +2,9 @@ import ( "context" - "encoding/base64" - "errors" "fmt" "net" "net/http" - "os" - "strconv" "sync" "time" @@ -16,7 +12,6 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -35,40 +30,20 @@ type Server struct { Config *config.Config - status status - statusMu sync.Mutex - wg sync.WaitGroup - listener net.Listener - hostKeys []ssh.Signer - authorizedKeysClient *authorizedkeys.Client + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + serverConfig *serverConfig } func NewServer(cfg *config.Config) (*Server, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + serverConfig, err := newServerConfig(cfg) if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + return nil, err } - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := os.ReadFile(filename) - if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) - continue - } - - hostKeys = append(hostKeys, key) - } - if len(hostKeys) == 0 { - return nil, fmt.Errorf("No host keys could be loaded, aborting") - } - - return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + return &Server{Config: cfg, serverConfig: serverConfig}, nil } func (s *Server) ListenAndServe(ctx context.Context) error { @@ -168,38 +143,6 @@ return s.status } -func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { - sshCfg := &ssh.ServerConfig{ - PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != s.Config.User { - return nil, errors.New("unknown user") - } - if key.Type() == ssh.KeyAlgoDSA { - return nil, errors.New("DSA is prohibited") - } - ctx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) - if err != nil { - return nil, err - } - - return &ssh.Permissions{ - // Record the public key used for authentication. - Extensions: map[string]string{ - "key-id": strconv.FormatInt(res.Id, 10), - }, - }, nil - }, - } - - for _, key := range s.hostKeys { - sshCfg.AddHostKey(key) - } - - return sshCfg -} - func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() @@ -216,7 +159,7 @@ ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { log.WithError(err).Info("Failed to initialize SSH connection") return diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -104,13 +104,6 @@ require.Equal(t, 200, r.Result().StatusCode) } -func TestNewServerWithoutHosts(t *testing.T) { - _, err := NewServer(&config.Config{GitlabUrl: "http://localhost"}) - - require.Error(t, err) - require.Equal(t, "No host keys could be loaded, aborting", err.Error()) -} - func TestInvalidClientConfig(t *testing.T) { setupServer(t) @@ -120,6 +113,15 @@ require.Error(t, err) } +func TestInvalidServerConfig(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.ServerConfig{Listen: "invalid"}}} + err := s.ListenAndServe(context.Background()) + + require.Error(t, err) + require.Equal(t, "failed to listen for connection: listen tcp: address invalid: missing port in address", err.Error()) + require.Nil(t, s.Shutdown()) +} + func setupServer(t *testing.T) *Server { t.Helper() # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631724701 0 # Wed Sep 15 16:51:41 2021 +0000 # Node ID e92cc9bfe423906d35663bdc675dc4b30d76f9f8 # Parent ae1afbe2d7390f14489d9c61baadc06fae4f8d51 # Parent f48622b668b43d66466c50035198c262e66ab6eb Merge branch 'id-sshd-test-3' into 'main' Extract server config related code out of sshd.go Closes #523 See merge request gitlab-org/gitlab-shell!523 diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config.go @@ -0,0 +1,94 @@ +package sshd + +import ( + "context" + "encoding/base64" + "fmt" + "os" + "strconv" + "time" + + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + + "gitlab.com/gitlab-org/labkit/log" +) + +type serverConfig struct { + cfg *config.Config + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).Warnf("Failed to read host key %v", filename) + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).Warnf("Failed to parse host key %v", filename) + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") + } + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil +} + +func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { + if user != s.cfg.User { + return nil, fmt.Errorf("unknown user") + } + if key.Type() == ssh.KeyAlgoDSA { + return nil, fmt.Errorf("DSA is prohibited") + } + + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + if err != nil { + return nil, err + } + + return res, nil +} + +func (s *serverConfig) get(ctx context.Context) *ssh.ServerConfig { + sshCfg := &ssh.ServerConfig{ + PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { + res, err := s.getAuthKey(ctx, conn.User(), key) + if err != nil { + return nil, err + } + + return &ssh.Permissions{ + // Record the public key used for authentication. + Extensions: map[string]string{ + "key-id": strconv.FormatInt(res.Id, 10), + }, + }, nil + }, + } + + for _, key := range s.hostKeys { + sshCfg.AddHostKey(key) + } + + return sshCfg +} diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config_test.go @@ -0,0 +1,105 @@ +package sshd + +import ( + "context" + "crypto/dsa" + "crypto/rand" + "crypto/rsa" + "path" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +func TestNewServerConfigWithoutHosts(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "http://localhost"}) + + require.Error(t, err) + require.Equal(t, "No host keys could be loaded, aborting", err.Error()) +} + +func TestFailedAuthorizedKeysClient(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) + + require.Error(t, err) + require.Equal(t, "failed to initialize GitLab client: Error creating http client: unknown GitLab URL prefix", err.Error()) +} + +func TestFailedGetAuthKey(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + testCases := []struct { + desc string + user string + key ssh.PublicKey + expectedError string + }{ + { + desc: "wrong user", + user: "wrong-user", + key: rsaPublicKey(t), + expectedError: "unknown user", + }, { + desc: "prohibited dsa key", + user: "user", + key: dsaPublicKey(t), + expectedError: "DSA is prohibited", + }, { + desc: "API error", + user: "user", + key: rsaPublicKey(t), + expectedError: "Internal API unreachable", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err = cfg.getAuthKey(context.Background(), tc.user, tc.key) + require.Error(t, err) + require.Equal(t, tc.expectedError, err.Error()) + }) + } +} + +func rsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} + +func dsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey := new(dsa.PrivateKey) + params := new(dsa.Parameters) + require.NoError(t, dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160)) + + privateKey.PublicKey.Parameters = *params + require.NoError(t, dsa.GenerateKey(privateKey, rand.Reader)) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -2,13 +2,9 @@ import ( "context" - "encoding/base64" - "errors" "fmt" "net" "net/http" - "os" - "strconv" "sync" "time" @@ -16,7 +12,6 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -35,40 +30,20 @@ type Server struct { Config *config.Config - status status - statusMu sync.Mutex - wg sync.WaitGroup - listener net.Listener - hostKeys []ssh.Signer - authorizedKeysClient *authorizedkeys.Client + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + serverConfig *serverConfig } func NewServer(cfg *config.Config) (*Server, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + serverConfig, err := newServerConfig(cfg) if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + return nil, err } - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := os.ReadFile(filename) - if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) - continue - } - - hostKeys = append(hostKeys, key) - } - if len(hostKeys) == 0 { - return nil, fmt.Errorf("No host keys could be loaded, aborting") - } - - return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + return &Server{Config: cfg, serverConfig: serverConfig}, nil } func (s *Server) ListenAndServe(ctx context.Context) error { @@ -168,38 +143,6 @@ return s.status } -func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { - sshCfg := &ssh.ServerConfig{ - PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != s.Config.User { - return nil, errors.New("unknown user") - } - if key.Type() == ssh.KeyAlgoDSA { - return nil, errors.New("DSA is prohibited") - } - ctx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) - if err != nil { - return nil, err - } - - return &ssh.Permissions{ - // Record the public key used for authentication. - Extensions: map[string]string{ - "key-id": strconv.FormatInt(res.Id, 10), - }, - }, nil - }, - } - - for _, key := range s.hostKeys { - sshCfg.AddHostKey(key) - } - - return sshCfg -} - func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() @@ -216,7 +159,7 @@ ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { log.WithError(err).Info("Failed to initialize SSH connection") return diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -104,13 +104,6 @@ require.Equal(t, 200, r.Result().StatusCode) } -func TestNewServerWithoutHosts(t *testing.T) { - _, err := NewServer(&config.Config{GitlabUrl: "http://localhost"}) - - require.Error(t, err) - require.Equal(t, "No host keys could be loaded, aborting", err.Error()) -} - func TestInvalidClientConfig(t *testing.T) { setupServer(t) @@ -120,6 +113,15 @@ require.Error(t, err) } +func TestInvalidServerConfig(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.ServerConfig{Listen: "invalid"}}} + err := s.ListenAndServe(context.Background()) + + require.Error(t, err) + require.Equal(t, "failed to listen for connection: listen tcp: address invalid: missing port in address", err.Error()) + require.Nil(t, s.Shutdown()) +} + func setupServer(t *testing.T) *Server { t.Helper() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631727960 -10800 # Wed Sep 15 20:46:00 2021 +0300 # Node ID 54350589901ecd0d484ebeab99e6e66be2ea9ef1 # Parent e92cc9bfe423906d35663bdc675dc4b30d76f9f8 Add context fields to logging It adds correlation ids wherever possible diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -97,7 +97,7 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -64,7 +64,7 @@ "endpoint": endpoint, } - log.WithFields(fields).Info("Performing custom action") + log.WithContextFields(ctx, fields).Info("Performing custom action") response, err := c.performRequest(ctx, client, endpoint, request) if err != nil { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -110,7 +110,7 @@ if serviceName == "" { serviceName = "gitlab-shell-unknown" - log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -54,7 +54,7 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) + log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": c.remoteAddr}).Warn("panic handling session") } }() diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -32,12 +32,12 @@ for _, filename := range cfg.Server.HostKeyFiles { keyRaw, err := os.ReadFile(filename) if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") continue } key, err := ssh.ParsePrivateKey(keyRaw) if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to parse host key") continue } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -47,7 +47,7 @@ } func (s *Server) ListenAndServe(ctx context.Context) error { - if err := s.listen(); err != nil { + if err := s.listen(ctx); err != nil { return err } defer s.listener.Close() @@ -85,7 +85,7 @@ return mux } -func (s *Server) listen() error { +func (s *Server) listen(ctx context.Context) error { sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) @@ -97,10 +97,10 @@ ReadHeaderTimeout: ProxyHeaderTimeout, } - log.Info("Proxy protocol is enabled") + log.ContextLogger(ctx).Info("Proxy protocol is enabled") } - log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") + log.WithContextFields(ctx, log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") s.listener = sshListener @@ -117,7 +117,7 @@ break } - log.WithError(err).Warn("Failed to accept connection") + log.ContextLogger(ctx).WithError(err).Warn("Failed to accept connection") continue } @@ -152,7 +152,7 @@ // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) + log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": remoteAddr}).Warn("panic handling session") } }() @@ -161,7 +161,7 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - log.WithError(err).Info("Failed to initialize SSH connection") + log.ContextLogger(ctx).WithError(err).Info("Failed to initialize SSH connection") return } # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1631758488 0 # Thu Sep 16 02:14:48 2021 +0000 # Node ID ddc4c0b005d1fc267d891f99b2fb3e4c2a470a47 # Parent e92cc9bfe423906d35663bdc675dc4b30d76f9f8 # Parent 54350589901ecd0d484ebeab99e6e66be2ea9ef1 Merge branch 'id-context-fields' into 'main' Add context fields to logging See merge request gitlab-org/gitlab-shell!524 diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -97,7 +97,7 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -64,7 +64,7 @@ "endpoint": endpoint, } - log.WithFields(fields).Info("Performing custom action") + log.WithContextFields(ctx, fields).Info("Performing custom action") response, err := c.performRequest(ctx, client, endpoint, request) if err != nil { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -110,7 +110,7 @@ if serviceName == "" { serviceName = "gitlab-shell-unknown" - log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -54,7 +54,7 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) + log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": c.remoteAddr}).Warn("panic handling session") } }() diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -32,12 +32,12 @@ for _, filename := range cfg.Server.HostKeyFiles { keyRaw, err := os.ReadFile(filename) if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") continue } key, err := ssh.ParsePrivateKey(keyRaw) if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to parse host key") continue } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -47,7 +47,7 @@ } func (s *Server) ListenAndServe(ctx context.Context) error { - if err := s.listen(); err != nil { + if err := s.listen(ctx); err != nil { return err } defer s.listener.Close() @@ -85,7 +85,7 @@ return mux } -func (s *Server) listen() error { +func (s *Server) listen(ctx context.Context) error { sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) @@ -97,10 +97,10 @@ ReadHeaderTimeout: ProxyHeaderTimeout, } - log.Info("Proxy protocol is enabled") + log.ContextLogger(ctx).Info("Proxy protocol is enabled") } - log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") + log.WithContextFields(ctx, log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") s.listener = sshListener @@ -117,7 +117,7 @@ break } - log.WithError(err).Warn("Failed to accept connection") + log.ContextLogger(ctx).WithError(err).Warn("Failed to accept connection") continue } @@ -152,7 +152,7 @@ // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) + log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": remoteAddr}).Warn("panic handling session") } }() @@ -161,7 +161,7 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - log.WithError(err).Info("Failed to initialize SSH connection") + log.ContextLogger(ctx).WithError(err).Info("Failed to initialize SSH connection") return } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1631892599 -10800 # Fri Sep 17 18:29:59 2021 +0300 # Node ID 9e1d48c2a47f81c3a3da7bb700b740141dbed88b # Parent ddc4c0b005d1fc267d891f99b2fb3e4c2a470a47 Improve err message given when Gitaly unavailable diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -9,7 +9,9 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" @@ -50,6 +52,12 @@ childCtx := withOutgoingMetadata(ctx, gc.Features) _, err = handler(childCtx, conn) + if err != nil && grpcstatus.Convert(err).Code() == grpccodes.Unavailable { + log.WithError(err).Error("Gitaly is unavailable") + + return fmt.Errorf("Git service is temporarily unavailable") + } + return err } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -7,7 +7,9 @@ "github.com/stretchr/testify/require" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -45,6 +47,18 @@ require.EqualError(t, err, "no gitaly_address given") } +func TestUnavailableGitalyErr(t *testing.T) { + cmd := GitalyCommand{ + Config: &config.Config{}, + Address: "tcp://localhost:9999", + } + + expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) + + require.EqualError(t, err, "Git service is temporarily unavailable") +} + func TestRunGitalyCommandMetadata(t *testing.T) { tests := []struct { name string # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1631895324 0 # Fri Sep 17 16:15:24 2021 +0000 # Node ID 99e9c050b9a714d6ec0848982435c48589c4b1e3 # Parent ddc4c0b005d1fc267d891f99b2fb3e4c2a470a47 # Parent 9e1d48c2a47f81c3a3da7bb700b740141dbed88b Merge branch 'id-clean-up-unavailable-message' into 'main' Improve err message given when Gitaly unavailable Closes gitlab#340819 See merge request gitlab-org/gitlab-shell!526 diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -9,7 +9,9 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" @@ -50,6 +52,12 @@ childCtx := withOutgoingMetadata(ctx, gc.Features) _, err = handler(childCtx, conn) + if err != nil && grpcstatus.Convert(err).Code() == grpccodes.Unavailable { + log.WithError(err).Error("Gitaly is unavailable") + + return fmt.Errorf("Git service is temporarily unavailable") + } + return err } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -7,7 +7,9 @@ "github.com/stretchr/testify/require" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -45,6 +47,18 @@ require.EqualError(t, err, "no gitaly_address given") } +func TestUnavailableGitalyErr(t *testing.T) { + cmd := GitalyCommand{ + Config: &config.Config{}, + Address: "tcp://localhost:9999", + } + + expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) + + require.EqualError(t, err, "Git service is temporarily unavailable") +} + func TestRunGitalyCommandMetadata(t *testing.T) { tests := []struct { name string # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1632125981 0 # Mon Sep 20 08:19:41 2021 +0000 # Node ID 713b025d4a396f053c4939a6010c7502c6bb8afa # Parent ddc4c0b005d1fc267d891f99b2fb3e4c2a470a47 refactor: unify instantiation of command.Shell diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go --- a/cmd/gitlab-shell/command/command.go +++ b/cmd/gitlab-shell/command/command.go @@ -30,6 +30,20 @@ return nil, disallowedcommand.Error } +func NewWithKey(gitlabKeyId string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(nil, env) + if err != nil { + return nil, err + } + + args.GitlabKeyId = gitlabKeyId + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + func Parse(arguments []string, env sshenv.Env) (*commandargs.Shell, error) { args := &commandargs.Shell{Arguments: arguments, Env: env} diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -2,13 +2,14 @@ import ( "context" + "errors" "fmt" "golang.org/x/crypto/ssh" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -104,19 +105,11 @@ req.Reply(true, []byte{}) } - args := &commandargs.Shell{ - GitlabKeyId: s.gitlabKeyId, - Env: sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: s.execCmd, - GitProtocolVersion: s.gitProtocolVersion, - RemoteAddr: s.remoteAddr, - }, - } - - if err := args.ParseCommand(s.execCmd); err != nil { - s.toStderr("Failed to parse command: %v\n", err.Error()) - return 128 + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: s.execCmd, + GitProtocolVersion: s.gitProtocolVersion, + RemoteAddr: s.remoteAddr, } rw := &readwriter.ReadWriter{ @@ -125,9 +118,13 @@ ErrOut: s.channel.Stderr(), } - cmd := shellCmd.Build(args, s.cfg, rw) - if cmd == nil { - s.toStderr("Unknown command: %v\n", args.CommandType) + cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) + + if err != nil { + if !errors.Is(err, disallowedcommand.Error) { + s.toStderr("Failed to parse command: %v\n", err.Error()) + } + s.toStderr("Unknown command: %v\n", s.execCmd) return 128 } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -145,7 +145,7 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: invalid command line string\n", + errMsg: "Failed to parse command: Invalid SSH command\nUnknown command: \\\n", gitlabKeyId: "root", expectedExitCode: 128, }, { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1632125982 0 # Mon Sep 20 08:19:42 2021 +0000 # Node ID 2a7a4328f7ff1125158ea4c13c4d7a7625c96e3d # Parent 99e9c050b9a714d6ec0848982435c48589c4b1e3 # Parent 713b025d4a396f053c4939a6010c7502c6bb8afa Merge branch 'refactor/unify-shell' into 'main' refactor: unify instantiation of command.Shell Closes #517 See merge request gitlab-org/gitlab-shell!520 diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go --- a/cmd/gitlab-shell/command/command.go +++ b/cmd/gitlab-shell/command/command.go @@ -30,6 +30,20 @@ return nil, disallowedcommand.Error } +func NewWithKey(gitlabKeyId string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(nil, env) + if err != nil { + return nil, err + } + + args.GitlabKeyId = gitlabKeyId + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + func Parse(arguments []string, env sshenv.Env) (*commandargs.Shell, error) { args := &commandargs.Shell{Arguments: arguments, Env: env} diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -2,13 +2,14 @@ import ( "context" + "errors" "fmt" "golang.org/x/crypto/ssh" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -104,19 +105,11 @@ req.Reply(true, []byte{}) } - args := &commandargs.Shell{ - GitlabKeyId: s.gitlabKeyId, - Env: sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: s.execCmd, - GitProtocolVersion: s.gitProtocolVersion, - RemoteAddr: s.remoteAddr, - }, - } - - if err := args.ParseCommand(s.execCmd); err != nil { - s.toStderr("Failed to parse command: %v\n", err.Error()) - return 128 + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: s.execCmd, + GitProtocolVersion: s.gitProtocolVersion, + RemoteAddr: s.remoteAddr, } rw := &readwriter.ReadWriter{ @@ -125,9 +118,13 @@ ErrOut: s.channel.Stderr(), } - cmd := shellCmd.Build(args, s.cfg, rw) - if cmd == nil { - s.toStderr("Unknown command: %v\n", args.CommandType) + cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) + + if err != nil { + if !errors.Is(err, disallowedcommand.Error) { + s.toStderr("Failed to parse command: %v\n", err.Error()) + } + s.toStderr("Unknown command: %v\n", s.execCmd) return 128 } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -145,7 +145,7 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: invalid command line string\n", + errMsg: "Failed to parse command: Invalid SSH command\nUnknown command: \\\n", gitlabKeyId: "root", expectedExitCode: 128, }, { # HG changeset patch # User Kevin <gitlab@a.ikke.info> # Date 1631813846 0 # Thu Sep 16 17:37:26 2021 +0000 # Node ID 40a49942db1f297590dad05f5a92ba7b1216e9b8 # Parent ddc4c0b005d1fc267d891f99b2fb3e4c2a470a47 makefile: properly quote '$' in VERSION_STRING If git is not available or gitlab-shell is not built in a repository, it falls back the VERSION file. That command is not properly escaped and results in the message: > awk: cmd. line:1: Unexpected token When you remove the `2>/dev/null`. Escape the '$' characters to solve this. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install GO_SOURCES := $(shell find . -name '*.go') -VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$0="v"$0' VERSION 2>/dev/null || echo unknown) +VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$$0="v"$$0' VERSION 2>/dev/null || echo unknown) BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632130317 0 # Mon Sep 20 09:31:57 2021 +0000 # Node ID 9c4148e7ed0ba75d315ab0f7befcc1e44c9df687 # Parent 2a7a4328f7ff1125158ea4c13c4d7a7625c96e3d # Parent 40a49942db1f297590dad05f5a92ba7b1216e9b8 Merge branch 'fix-makefile-version-string' into 'main' makefile: properly escape '$' in VERSION_STRING See merge request gitlab-org/gitlab-shell!525 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install GO_SOURCES := $(shell find . -name '*.go') -VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$0="v"$0' VERSION 2>/dev/null || echo unknown) +VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$$0="v"$$0' VERSION 2>/dev/null || echo unknown) BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1632379994 25200 # Wed Sep 22 23:53:14 2021 -0700 # Node ID ca40e9ceffb023c7c4bb864a9890194ad0f89297 # Parent 9c4148e7ed0ba75d315ab0f7befcc1e44c9df687 Only validate SSL cert file exists if a value is supplied This fixes a regression in https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/508. If an HTTPS internal API URL were used, gitlab-shell would not work at all. We now handle blank `caFile` properly. Relates to https://gitlab.com/gitlab-org/gitlab-shell/-/issues/529 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -54,6 +54,22 @@ } } +func validateCaFile(filename string) error { + if filename == "" { + return nil + } + + if _, err := os.Stat(filename); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("cannot find cafile '%s': %w", filename, ErrCafileNotFound) + } + + return err + } + + return nil +} + // Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) @@ -73,10 +89,8 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { - if _, err := os.Stat(caFile); err != nil { - if os.IsNotExist(err) { - return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) - } + err = validateCaFile(caFile) + if err != nil { return nil, err } diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -66,10 +66,11 @@ func TestFailedRequests(t *testing.T) { testCases := []struct { - desc string - caFile string - caPath string - expectedError string + desc string + caFile string + caPath string + expectedCaFileNotFound bool + expectedError string }{ { desc: "Invalid CaFile", @@ -77,18 +78,25 @@ expectedError: "Internal API unreachable", }, { - desc: "Invalid CaPath", - caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + desc: "Missing CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/missing.crt"), + expectedCaFileNotFound: true, }, { - desc: "Empty config", + desc: "Invalid CaPath", + caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + expectedError: "Internal API unreachable", + }, + { + desc: "Empty config", + expectedError: "Internal API unreachable", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) - if tc.caFile == "" { + if tc.expectedCaFileNotFound { require.Error(t, err) require.ErrorIs(t, err, ErrCafileNotFound) } else { # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632383296 0 # Thu Sep 23 07:48:16 2021 +0000 # Node ID 131fe8c9ab76327e97ed8f89d5b269de0300e758 # Parent 9c4148e7ed0ba75d315ab0f7befcc1e44c9df687 # Parent ca40e9ceffb023c7c4bb864a9890194ad0f89297 Merge branch 'sh-fix-issue-529' into 'main' Only validate SSL cert file exists if a value is supplied See merge request gitlab-org/gitlab-shell!527 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -54,6 +54,22 @@ } } +func validateCaFile(filename string) error { + if filename == "" { + return nil + } + + if _, err := os.Stat(filename); err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("cannot find cafile '%s': %w", filename, ErrCafileNotFound) + } + + return err + } + + return nil +} + // Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) @@ -73,10 +89,8 @@ } else if strings.HasPrefix(gitlabURL, httpProtocol) { transport, host = buildHttpTransport(gitlabURL) } else if strings.HasPrefix(gitlabURL, httpsProtocol) { - if _, err := os.Stat(caFile); err != nil { - if os.IsNotExist(err) { - return nil, fmt.Errorf("cannot find cafile '%s': %w", caFile, ErrCafileNotFound) - } + err = validateCaFile(caFile) + if err != nil { return nil, err } diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -66,10 +66,11 @@ func TestFailedRequests(t *testing.T) { testCases := []struct { - desc string - caFile string - caPath string - expectedError string + desc string + caFile string + caPath string + expectedCaFileNotFound bool + expectedError string }{ { desc: "Invalid CaFile", @@ -77,18 +78,25 @@ expectedError: "Internal API unreachable", }, { - desc: "Invalid CaPath", - caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + desc: "Missing CaFile", + caFile: path.Join(testhelper.TestRoot, "certs/invalid/missing.crt"), + expectedCaFileNotFound: true, }, { - desc: "Empty config", + desc: "Invalid CaPath", + caPath: path.Join(testhelper.TestRoot, "certs/invalid"), + expectedError: "Internal API unreachable", + }, + { + desc: "Empty config", + expectedError: "Internal API unreachable", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) - if tc.caFile == "" { + if tc.expectedCaFileNotFound { require.Error(t, err) require.ErrorIs(t, err, ErrCafileNotFound) } else { # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632390072 -3600 # Thu Sep 23 10:41:12 2021 +0100 # Node ID c6a89c8f8be2355f1fc80befc68a9aa7ada06d75 # Parent 131fe8c9ab76327e97ed8f89d5b269de0300e758 Respect log-level configuration again This was lost in the move from Ruby to Go. Restore it now. Changelog: fixed diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -46,6 +46,7 @@ RootDir string LogFile string `yaml:"log_file,omitempty"` LogFormat string `yaml:"log_format,omitempty"` + LogLevel string `yaml:"log_level,omitempty"` GitlabUrl string `yaml:"gitlab_url"` GitlabRelativeURLRoot string `yaml:"gitlab_relative_url_root"` GitlabTracing string `yaml:"gitlab_tracing"` @@ -66,6 +67,7 @@ DefaultConfig = Config{ LogFile: "gitlab-shell.log", LogFormat: "json", + LogLevel: "info", Server: DefaultServerConfig, User: "git", } diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -35,6 +35,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), + log.WithLogLevel(cfg.LogLevel), } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -3,7 +3,6 @@ import ( "os" "regexp" - "strings" "testing" "github.com/stretchr/testify/require" @@ -26,12 +25,37 @@ defer closer.Close() log.Info("this is a test") + log.WithFields(log.Fields{}).Debug("debug log message") tmpFile.Close() data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) - require.True(t, strings.Contains(string(data), `msg":"this is a test"`)) + require.Contains(t, string(data), `msg":"this is a test"`) + require.NotContains(t, string(data), `msg:":"debug log message"`) +} + +func TestConfigureWithDebugLogLevel(t *testing.T) { + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") + require.NoError(t, err) + defer tmpFile.Close() + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + LogLevel: "debug", + } + + closer := Configure(&config) + defer closer.Close() + + log.WithFields(log.Fields{}).Debug("debug log message") + + tmpFile.Close() + + data, err := os.ReadFile(tmpFile.Name()) + require.NoError(t, err) + require.Contains(t, string(data), `msg":"debug log message"`) } func TestConfigureWithPermissionError(t *testing.T) { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1632394113 0 # Thu Sep 23 10:48:33 2021 +0000 # Node ID 1638ae747fdece49dba9df3396ce3cbb2bd5d3e1 # Parent 131fe8c9ab76327e97ed8f89d5b269de0300e758 # Parent c6a89c8f8be2355f1fc80befc68a9aa7ada06d75 Merge branch '502-restore-log-level-config' into 'main' Respect log-level configuration again Closes #502 See merge request gitlab-org/gitlab-shell!530 diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -46,6 +46,7 @@ RootDir string LogFile string `yaml:"log_file,omitempty"` LogFormat string `yaml:"log_format,omitempty"` + LogLevel string `yaml:"log_level,omitempty"` GitlabUrl string `yaml:"gitlab_url"` GitlabRelativeURLRoot string `yaml:"gitlab_relative_url_root"` GitlabTracing string `yaml:"gitlab_tracing"` @@ -66,6 +67,7 @@ DefaultConfig = Config{ LogFile: "gitlab-shell.log", LogFormat: "json", + LogLevel: "info", Server: DefaultServerConfig, User: "git", } diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -35,6 +35,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), + log.WithLogLevel(cfg.LogLevel), } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -3,7 +3,6 @@ import ( "os" "regexp" - "strings" "testing" "github.com/stretchr/testify/require" @@ -26,12 +25,37 @@ defer closer.Close() log.Info("this is a test") + log.WithFields(log.Fields{}).Debug("debug log message") tmpFile.Close() data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) - require.True(t, strings.Contains(string(data), `msg":"this is a test"`)) + require.Contains(t, string(data), `msg":"this is a test"`) + require.NotContains(t, string(data), `msg:":"debug log message"`) +} + +func TestConfigureWithDebugLogLevel(t *testing.T) { + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") + require.NoError(t, err) + defer tmpFile.Close() + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + LogLevel: "debug", + } + + closer := Configure(&config) + defer closer.Close() + + log.WithFields(log.Fields{}).Debug("debug log message") + + tmpFile.Close() + + data, err := os.ReadFile(tmpFile.Name()) + require.NoError(t, err) + require.Contains(t, string(data), `msg":"debug log message"`) } func TestConfigureWithPermissionError(t *testing.T) { # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632767286 -3600 # Mon Sep 27 19:28:06 2021 +0100 # Node ID 311bf5c473bb629dd86aa87884931fdd277c0f51 # Parent 1638ae747fdece49dba9df3396ce3cbb2bd5d3e1 Don't swallow an error parsing SSH_ORIGINAL_COMMAND diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -267,7 +267,7 @@ executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, arguments: []string{}, - expectedError: "Invalid SSH command", + expectedError: "Invalid SSH command: invalid command line string", }, } diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -1,7 +1,7 @@ package commandargs import ( - "errors" + "fmt" "regexp" "github.com/mattn/go-shellwords" @@ -49,21 +49,16 @@ func (s *Shell) validate() error { if !s.Env.IsSSHConnection { - return errors.New("Only SSH allowed") + return fmt.Errorf("Only SSH allowed") } - if !s.isValidSSHCommand() { - return errors.New("Invalid SSH command") + if err := s.ParseCommand(s.Env.OriginalCommand); err != nil { + return fmt.Errorf("Invalid SSH command: %w", err) } return nil } -func (s *Shell) isValidSSHCommand() bool { - err := s.ParseCommand(s.Env.OriginalCommand) - return err == nil -} - func (s *Shell) parseWho() { for _, argument := range s.Arguments { if keyId := tryParseKeyId(argument); keyId != "" { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -145,7 +145,7 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command\nUnknown command: \\\n", + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", gitlabKeyId: "root", expectedExitCode: 128, }, { # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632767306 -3600 # Mon Sep 27 19:28:26 2021 +0100 # Node ID b582b99b4d02e9fc445bb6efe7cb760752a11e03 # Parent 311bf5c473bb629dd86aa87884931fdd277c0f51 Add debug logging to gitlab-sshd session diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -5,6 +5,7 @@ "errors" "fmt" + "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" @@ -40,16 +41,27 @@ } func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { + ctxlog := log.ContextLogger(ctx) + + ctxlog.Debug("session: handle: entering request loop") + for req := range requests { + sessionLog := ctxlog.WithFields(log.Fields{ + "bytesize": len(req.Payload), + "type": req.Type, + "want_reply": req.WantReply, + }) + sessionLog.Debug("session: handle: request received") + var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(req) + shouldContinue = s.handleEnv(ctx, req) case "exec": shouldContinue = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -58,18 +70,23 @@ } } + sessionLog.WithField("should_continue", shouldContinue).Debug("session: handle: request processed") + if !shouldContinue { s.channel.Close() break } } + + ctxlog.Debug("session: handle: exiting request loop") } -func (s *session) handleEnv(req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { + log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") return false } @@ -85,6 +102,10 @@ req.Reply(accepted, []byte{}) } + log.WithContextFields( + ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, + ).Debug("session: handleEnv: processed") + return true } @@ -96,7 +117,8 @@ s.execCmd = execRequest.Command - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) + return false } @@ -119,28 +141,30 @@ } cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) - if err != nil { if !errors.Is(err, disallowedcommand.Error) { - s.toStderr("Failed to parse command: %v\n", err.Error()) + s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) } - s.toStderr("Unknown command: %v\n", s.execCmd) + s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) return 128 } if err := cmd.Execute(ctx); err != nil { - s.toStderr("remote: ERROR: %v\n", err.Error()) + s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) return 1 } return 0 } -func (s *session) toStderr(format string, args ...interface{}) { - fmt.Fprintf(s.channel.Stderr(), format, args...) +func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { + out := fmt.Sprintf(format, args...) + log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") + fmt.Fprint(s.channel.Stderr(), out) } -func (s *session) exit(status uint32) { +func (s *session) exit(ctx context.Context, status uint32) { + log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} s.channel.CloseWrite() diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -86,7 +86,7 @@ s := &session{gitProtocolVersion: "1"} r := &ssh.Request{Payload: tc.payload} - require.Equal(t, s.handleEnv(r), tc.expectedResult) + require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) }) } # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632820920 -3600 # Tue Sep 28 10:22:00 2021 +0100 # Node ID 962b8e7cb0931d684cf48da4ace0d0e81b0aaffa # Parent b582b99b4d02e9fc445bb6efe7cb760752a11e03 Add gitlab-sshd connection logging diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -29,21 +29,26 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { + ctxlog.WithField("channel_type", newChannel.ChannelType).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { + ctxlog.Info("connection: handle: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { + ctxlog.Info("connection: handle: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - log.WithError(err).Info("could not accept channel") + ctxlog.WithError(err).Error("connection: handle: accepting channel failed") c.concurrentSessions.Release(1) continue } @@ -54,11 +59,12 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": c.remoteAddr}).Warn("panic handling session") + ctxlog.WithField("recovered_error", err).Warn("panic handling session") } }() handler(ctx, channel, requests) + ctxlog.Info("connection: handle: done") }() } } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -149,19 +149,23 @@ defer s.wg.Done() defer nconn.Close() + ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) + defer cancel() + + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": remoteAddr}).Warn("panic handling session") + ctxlog.Warn("panic handling session") } }() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) - defer cancel() + ctxlog.Info("server: handleConn: start") sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - log.ContextLogger(ctx).WithError(err).Info("Failed to initialize SSH connection") + ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return } @@ -178,4 +182,6 @@ session.handle(ctx, requests) }) + + ctxlog.Info("server: handleConn: done") } # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1632835989 -3600 # Tue Sep 28 14:33:09 2021 +0100 # Node ID 1b5d4bebb4468e9b6cc354e15266f3bed1cf9a78 # Parent 962b8e7cb0931d684cf48da4ace0d0e81b0aaffa Add some initial logging guidelines diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -98,6 +98,21 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. +## Logging Guidelines + +In general, it should be possible to determine the structure, but not content, +of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some +guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging functionality +- **Always** include a correlation ID +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log success cases as well as error cases +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. + ## Releasing See [PROCESS.md](./PROCESS.md) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1632856114 0 # Tue Sep 28 19:08:34 2021 +0000 # Node ID 949d6ed84a338be26e427ac1b315bfb72beba093 # Parent 1638ae747fdece49dba9df3396ce3cbb2bd5d3e1 # Parent 1b5d4bebb4468e9b6cc354e15266f3bed1cf9a78 Merge branch '499-log-me-more' into 'main' Add more logging to gitlab-sshd See merge request gitlab-org/gitlab-shell!531 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -98,6 +98,21 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. +## Logging Guidelines + +In general, it should be possible to determine the structure, but not content, +of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some +guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging functionality +- **Always** include a correlation ID +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log success cases as well as error cases +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. + ## Releasing See [PROCESS.md](./PROCESS.md) diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -267,7 +267,7 @@ executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, arguments: []string{}, - expectedError: "Invalid SSH command", + expectedError: "Invalid SSH command: invalid command line string", }, } diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -1,7 +1,7 @@ package commandargs import ( - "errors" + "fmt" "regexp" "github.com/mattn/go-shellwords" @@ -49,21 +49,16 @@ func (s *Shell) validate() error { if !s.Env.IsSSHConnection { - return errors.New("Only SSH allowed") + return fmt.Errorf("Only SSH allowed") } - if !s.isValidSSHCommand() { - return errors.New("Invalid SSH command") + if err := s.ParseCommand(s.Env.OriginalCommand); err != nil { + return fmt.Errorf("Invalid SSH command: %w", err) } return nil } -func (s *Shell) isValidSSHCommand() bool { - err := s.ParseCommand(s.Env.OriginalCommand) - return err == nil -} - func (s *Shell) parseWho() { for _, argument := range s.Arguments { if keyId := tryParseKeyId(argument); keyId != "" { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -29,21 +29,26 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { + ctxlog.WithField("channel_type", newChannel.ChannelType).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { + ctxlog.Info("connection: handle: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { + ctxlog.Info("connection: handle: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - log.WithError(err).Info("could not accept channel") + ctxlog.WithError(err).Error("connection: handle: accepting channel failed") c.concurrentSessions.Release(1) continue } @@ -54,11 +59,12 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": c.remoteAddr}).Warn("panic handling session") + ctxlog.WithField("recovered_error", err).Warn("panic handling session") } }() handler(ctx, channel, requests) + ctxlog.Info("connection: handle: done") }() } } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -5,6 +5,7 @@ "errors" "fmt" + "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" @@ -40,16 +41,27 @@ } func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { + ctxlog := log.ContextLogger(ctx) + + ctxlog.Debug("session: handle: entering request loop") + for req := range requests { + sessionLog := ctxlog.WithFields(log.Fields{ + "bytesize": len(req.Payload), + "type": req.Type, + "want_reply": req.WantReply, + }) + sessionLog.Debug("session: handle: request received") + var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(req) + shouldContinue = s.handleEnv(ctx, req) case "exec": shouldContinue = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -58,18 +70,23 @@ } } + sessionLog.WithField("should_continue", shouldContinue).Debug("session: handle: request processed") + if !shouldContinue { s.channel.Close() break } } + + ctxlog.Debug("session: handle: exiting request loop") } -func (s *session) handleEnv(req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { + log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") return false } @@ -85,6 +102,10 @@ req.Reply(accepted, []byte{}) } + log.WithContextFields( + ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, + ).Debug("session: handleEnv: processed") + return true } @@ -96,7 +117,8 @@ s.execCmd = execRequest.Command - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) + return false } @@ -119,28 +141,30 @@ } cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) - if err != nil { if !errors.Is(err, disallowedcommand.Error) { - s.toStderr("Failed to parse command: %v\n", err.Error()) + s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) } - s.toStderr("Unknown command: %v\n", s.execCmd) + s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) return 128 } if err := cmd.Execute(ctx); err != nil { - s.toStderr("remote: ERROR: %v\n", err.Error()) + s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) return 1 } return 0 } -func (s *session) toStderr(format string, args ...interface{}) { - fmt.Fprintf(s.channel.Stderr(), format, args...) +func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { + out := fmt.Sprintf(format, args...) + log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") + fmt.Fprint(s.channel.Stderr(), out) } -func (s *session) exit(status uint32) { +func (s *session) exit(ctx context.Context, status uint32) { + log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} s.channel.CloseWrite() diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -86,7 +86,7 @@ s := &session{gitProtocolVersion: "1"} r := &ssh.Request{Payload: tc.payload} - require.Equal(t, s.handleEnv(r), tc.expectedResult) + require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) }) } @@ -145,7 +145,7 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command\nUnknown command: \\\n", + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", gitlabKeyId: "root", expectedExitCode: 128, }, { diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -149,19 +149,23 @@ defer s.wg.Done() defer nconn.Close() + ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) + defer cancel() + + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithContextFields(ctx, log.Fields{"recovered_error": err, "address": remoteAddr}).Warn("panic handling session") + ctxlog.Warn("panic handling session") } }() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) - defer cancel() + ctxlog.Info("server: handleConn: start") sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - log.ContextLogger(ctx).WithError(err).Info("Failed to initialize SSH connection") + ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return } @@ -178,4 +182,6 @@ session.handle(ctx, requests) }) + + ctxlog.Info("server: handleConn: done") } # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1633000806 -3600 # Thu Sep 30 12:20:06 2021 +0100 # Node ID 8ca91312fb2d11efe506f0ef78b866730ed85d9d # Parent 949d6ed84a338be26e427ac1b315bfb72beba093 Resolve an error-swallowing issue diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -6,6 +6,8 @@ "encoding/json" "fmt" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" @@ -58,6 +60,11 @@ payload, err := c.authenticate(ctx, operation, repo, accessResponse.UserId) if err != nil { // return nothing just like Ruby's GitlabShell#lfs_authenticate does + log.WithContextFields( + ctx, + log.Fields{"operation": operation, "repo": repo, "user_id": accessResponse.UserId}, + ).WithError(err).Debug("lfsauthenticate: execute: LFS authentication failed") + return nil } # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1633064762 0 # Fri Oct 01 05:06:02 2021 +0000 # Node ID 323560847fcbbd43b825284c00ab0f6cc585cc88 # Parent 949d6ed84a338be26e427ac1b315bfb72beba093 # Parent 8ca91312fb2d11efe506f0ef78b866730ed85d9d Merge branch '499-log-me-more-more' into 'main' Resolve an error-swallowing issue Closes #499 See merge request gitlab-org/gitlab-shell!533 diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -6,6 +6,8 @@ "encoding/json" "fmt" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" @@ -58,6 +60,11 @@ payload, err := c.authenticate(ctx, operation, repo, accessResponse.UserId) if err != nil { // return nothing just like Ruby's GitlabShell#lfs_authenticate does + log.WithContextFields( + ctx, + log.Fields{"operation": operation, "repo": repo, "user_id": accessResponse.UserId}, + ).WithError(err).Debug("lfsauthenticate: execute: LFS authentication failed") + return nil } # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1633521807 -3600 # Wed Oct 06 13:03:27 2021 +0100 # Node ID c23605b604d1cb11e6a138a1cea3369338985559 # Parent 323560847fcbbd43b825284c00ab0f6cc585cc88 Fix logging channel type Currently we get this in some log messages: logrus_error="can not add field \"channel_type\"" This is because we're trying to add a function, rather than the result of the function call (a string) to the `log.Fields`. Whoops! Changelog: fixed diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -34,7 +34,7 @@ defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { - ctxlog.WithField("channel_type", newChannel.ChannelType).Info("connection: handle: new channel requested") + ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { ctxlog.Info("connection: handle: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1633528226 0 # Wed Oct 06 13:50:26 2021 +0000 # Node ID 032c716977e806109188f1bd22b06ab814f5e34d # Parent 323560847fcbbd43b825284c00ab0f6cc585cc88 # Parent c23605b604d1cb11e6a138a1cea3369338985559 Merge branch 'fix-logging-channel-type' into 'main' Fix logging channel type See merge request gitlab-org/gitlab-shell!534 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -34,7 +34,7 @@ defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { - ctxlog.WithField("channel_type", newChannel.ChannelType).Info("connection: handle: new channel requested") + ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { ctxlog.Info("connection: handle: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1633599807 -3600 # Thu Oct 07 10:43:27 2021 +0100 # Node ID ff79c56dbc2e1522347410ab416c27d188ec49f1 # Parent 032c716977e806109188f1bd22b06ab814f5e34d Log command invocation Use reflection to log the command we are about to execute, both in gitlab-shell and gitlab-sshd. Include the environment, which has all the context we need to understand what the command is expected to do. Changelog: added diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -3,6 +3,9 @@ import ( "fmt" "os" + "reflect" + + "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" @@ -62,8 +65,15 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() - if err = cmd.Execute(ctx); err != nil { + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + + if err := cmd.Execute(ctx); err != nil { + ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) os.Exit(1) } + + ctxlog.Info("gitlab-shell: main: command executed successfully") } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -4,6 +4,7 @@ "context" "errors" "fmt" + "reflect" "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" @@ -149,11 +150,17 @@ return 128 } + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + if err := cmd.Execute(ctx); err != nil { s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) return 1 } + ctxlog.Info("session: handleShell: command executed successfully") + return 0 } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1633601263 0 # Thu Oct 07 10:07:43 2021 +0000 # Node ID 194f995a8cbb8e608b5a81d5ede35f9b9cf7ba0f # Parent 032c716977e806109188f1bd22b06ab814f5e34d # Parent ff79c56dbc2e1522347410ab416c27d188ec49f1 Merge branch '499-log-command-invocation' into 'main' Log command invocation See merge request gitlab-org/gitlab-shell!535 diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -3,6 +3,9 @@ import ( "fmt" "os" + "reflect" + + "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" @@ -62,8 +65,15 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() - if err = cmd.Execute(ctx); err != nil { + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + + if err := cmd.Execute(ctx); err != nil { + ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) os.Exit(1) } + + ctxlog.Info("gitlab-shell: main: command executed successfully") } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -4,6 +4,7 @@ "context" "errors" "fmt" + "reflect" "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" @@ -149,11 +150,17 @@ return 128 } + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + if err := cmd.Execute(ctx); err != nil { s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) return 1 } + ctxlog.Info("session: handleShell: command executed successfully") + return 0 } # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1631115800 0 # Wed Sep 08 15:43:20 2021 +0000 # Node ID 849c7e7f1e78a3cd39fb3f0fd2eaa34feaf35b62 # Parent 9d6099095d58735db722bcca90bc4782f7614ba5 refactor: remove call to BuildNameToCertificate (deprecated) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -159,7 +159,6 @@ return nil, "", err } tlsConfig.Certificates = []tls.Certificate{cert} - tlsConfig.BuildNameToCertificate() } transport := &http.Transport{ diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -73,7 +73,6 @@ Certificates: []tls.Certificate{cer}, MinVersion: tls.VersionTLS12, } - server.TLS.BuildNameToCertificate() if clientCAPath != "" { caCert, err := os.ReadFile(clientCAPath) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1634055177 0 # Tue Oct 12 16:12:57 2021 +0000 # Node ID 037432d36801daacbfe185633c73a63d7a06690f # Parent 194f995a8cbb8e608b5a81d5ede35f9b9cf7ba0f # Parent 849c7e7f1e78a3cd39fb3f0fd2eaa34feaf35b62 Merge branch 'fix/name-certificate' into 'main' refactor: remove call to BuildNameToCertificate (deprecated) See merge request gitlab-org/gitlab-shell!515 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -173,7 +173,6 @@ return nil, "", err } tlsConfig.Certificates = []tls.Certificate{cert} - tlsConfig.BuildNameToCertificate() } transport := &http.Transport{ diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -73,7 +73,6 @@ Certificates: []tls.Certificate{cer}, MinVersion: tls.VersionTLS12, } - server.TLS.BuildNameToCertificate() if clientCAPath != "" { caCert, err := os.ReadFile(clientCAPath) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1634122990 25200 # Wed Oct 13 04:03:10 2021 -0700 # Node ID af06d28d33fd6dc15cf2022b6ccb4a468ce38e61 # Parent 037432d36801daacbfe185633c73a63d7a06690f Update to Go v1.16.9 This is a security release: https://golang.org/doc/devel/release#go1.16 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -go 1.16.8 +go 1.16.9 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1634126081 0 # Wed Oct 13 11:54:41 2021 +0000 # Node ID 6f9d20402b23f29271d243d2e8c8764723b84611 # Parent 037432d36801daacbfe185633c73a63d7a06690f # Parent af06d28d33fd6dc15cf2022b6ccb4a468ce38e61 Merge branch 'sh-update-go-1.16.9' into 'main' Update to Go v1.16.9 See merge request gitlab-org/gitlab-shell!537 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -go 1.16.8 +go 1.16.9 # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1634037154 -3600 # Tue Oct 12 12:12:34 2021 +0100 # Node ID 53b3d6c9963071748b360a1e90081621150dca4c # Parent 194f995a8cbb8e608b5a81d5ede35f9b9cf7ba0f Reject non-proxied connections when proxy protocol is enabled This will help to prevent misconfigurations. Changelog: fixed diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -94,6 +94,7 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, + Policy: unconditionalRequirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } @@ -185,3 +186,7 @@ ctxlog.Info("server: handleConn: done") } + +func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { + return proxyproto.REQUIRE, nil +} diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -47,6 +47,19 @@ verifyStatus(t, s, StatusClosed) } +func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { + s := setupServerWithProxyProtocolEnabled(t) + defer s.Shutdown() + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + if client != nil { + client.Close() + } + + require.Error(t, err, "Expected plain SSH request to be failed") + require.Equal(t, err.Error(), "ssh: handshake failed: EOF") +} + func TestCorrelationId(t *testing.T) { setupServer(t) @@ -125,6 +138,18 @@ func setupServer(t *testing.T) *Server { t.Helper() + return setupServerWithConfig(t, nil) +} + +func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { + t.Helper() + + return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) +} + +func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -148,13 +173,20 @@ testhelper.PrepareTestRootDir(t) url := testserver.StartSocketHttpServer(t, requests) - srvCfg := config.ServerConfig{ - Listen: serverUrl, - ConcurrentSessionsLimit: 1, - HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + + if cfg == nil { + cfg = &config.Config{} } - s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + // All things that don't need to be configurable in tests yet + cfg.GitlabUrl = url + cfg.RootDir = "/tmp" + cfg.User = user + cfg.Server.Listen = serverUrl + cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} + + s, err := NewServer(cfg) require.NoError(t, err) go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1634135548 0 # Wed Oct 13 14:32:28 2021 +0000 # Node ID 3ed8918d8fadde500b017e7600cb8b65dc6b9409 # Parent 6f9d20402b23f29271d243d2e8c8764723b84611 # Parent 53b3d6c9963071748b360a1e90081621150dca4c Merge branch '532-proxy-protocol-require' into 'main' Reject non-proxied connections when proxy protocol is enabled Closes #532 See merge request gitlab-org/gitlab-shell!536 diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -94,6 +94,7 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, + Policy: unconditionalRequirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } @@ -185,3 +186,7 @@ ctxlog.Info("server: handleConn: done") } + +func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { + return proxyproto.REQUIRE, nil +} diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -47,6 +47,19 @@ verifyStatus(t, s, StatusClosed) } +func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { + s := setupServerWithProxyProtocolEnabled(t) + defer s.Shutdown() + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + if client != nil { + client.Close() + } + + require.Error(t, err, "Expected plain SSH request to be failed") + require.Equal(t, err.Error(), "ssh: handshake failed: EOF") +} + func TestCorrelationId(t *testing.T) { setupServer(t) @@ -125,6 +138,18 @@ func setupServer(t *testing.T) *Server { t.Helper() + return setupServerWithConfig(t, nil) +} + +func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { + t.Helper() + + return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) +} + +func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -148,13 +173,20 @@ testhelper.PrepareTestRootDir(t) url := testserver.StartSocketHttpServer(t, requests) - srvCfg := config.ServerConfig{ - Listen: serverUrl, - ConcurrentSessionsLimit: 1, - HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + + if cfg == nil { + cfg = &config.Config{} } - s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + // All things that don't need to be configurable in tests yet + cfg.GitlabUrl = url + cfg.RootDir = "/tmp" + cfg.User = user + cfg.Server.Listen = serverUrl + cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} + + s, err := NewServer(cfg) require.NoError(t, err) go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1634134931 -3600 # Wed Oct 13 15:22:11 2021 +0100 # Node ID 49b5bf76cf6457874952e00c5ff7ee9147142515 # Parent 6f9d20402b23f29271d243d2e8c8764723b84611 Improve logging for non-git commands Several of our commands only touch the internal API, and go nowhere near Gitaly. Improve logging for each of these in a single MR. In general, we want to be able to tell what happened in the execution of each command, and to track failures down to a specific line of code. Changelog: added diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -8,6 +8,8 @@ "strings" "time" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -38,6 +40,10 @@ return err } + log.WithContextFields(ctx, log.Fields{ + "token_args": c.TokenArgs, + }).Info("personalaccesstoken: execute: requesting token") + response, err := c.getPersonalAccessToken(ctx) if err != nil { return err diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -4,19 +4,17 @@ "bytes" "context" "errors" - - "gitlab.com/gitlab-org/gitlab-shell/client" - "io" "net/http" + "gitlab.com/gitlab-org/labkit/log" + + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" - - "gitlab.com/gitlab-org/labkit/log" ) type Request struct { @@ -59,12 +57,12 @@ request.Data.UserId = response.Who for _, endpoint := range data.ApiEndpoints { - fields := log.Fields{ + ctxlog := log.WithContextFields(ctx, log.Fields{ "primary_repo": data.PrimaryRepo, "endpoint": endpoint, - } + }) - log.WithContextFields(ctx, fields).Info("Performing custom action") + ctxlog.Info("customaction: processApiEndpoints: Performing custom action") response, err := c.performRequest(ctx, client, endpoint, request) if err != nil { @@ -90,6 +88,10 @@ } else { output = c.readFromStdinNoEOF() } + ctxlog.WithFields(log.Fields{ + "eof_sent": c.EOFSent, + "stdin_bytes": len(output), + }).Debug("customaction: processApiEndpoints: stdin buffered") request.Output = output } diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -6,6 +6,8 @@ "io" "strings" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -21,9 +23,14 @@ } func (c *Command) Execute(ctx context.Context) error { + ctxlog := log.ContextLogger(ctx) + ctxlog.Debug("twofactorrecover: execute: Waiting for user input") + if c.canContinue() { + ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { + ctxlog.Debug("twofactorrecover: execute: User chose not to continue") fmt.Fprintln(c.ReadWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.") } @@ -43,9 +50,12 @@ } func (c *Command) displayRecoveryCodes(ctx context.Context) { + ctxlog := log.ContextLogger(ctx) + codes, err := c.getRecoveryCodes(ctx) if err == nil { + ctxlog.Debug("twofactorrecover: displayRecoveryCodes: recovery codes successfully generated") messageWithCodes := "\nYour two-factor authentication recovery codes are:\n\n" + strings.Join(codes, "\n") + @@ -54,6 +64,7 @@ "a new device so you do not lose access to your account again.\n" fmt.Fprint(c.ReadWriter.Out, messageWithCodes) } else { + ctxlog.WithError(err).Error("twofactorrecover: displayRecoveryCodes: failed to generate recovery codes") fmt.Fprintf(c.ReadWriter.Out, "\nAn error occurred while trying to generate new recovery codes.\n%v\n", err) } } diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -5,6 +5,8 @@ "fmt" "io" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -18,11 +20,18 @@ } func (c *Command) Execute(ctx context.Context) error { - err := c.verifyOTP(ctx, c.getOTP()) + ctxlog := log.ContextLogger(ctx) + ctxlog.Info("twofactorverify: execute: waiting for user input") + otp := c.getOTP() + + ctxlog.Info("twofactorverify: execute: verifying entered OTP") + err := c.verifyOTP(ctx, otp) if err != nil { + ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } + ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") return nil } # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1634167422 0 # Wed Oct 13 23:23:42 2021 +0000 # Node ID 3c1295f1e290c010533bfba9b81c8afd116c61b4 # Parent 3ed8918d8fadde500b017e7600cb8b65dc6b9409 # Parent 49b5bf76cf6457874952e00c5ff7ee9147142515 Merge branch '499-log-non-git-commands' into 'main' Improve logging for non-git commands See merge request gitlab-org/gitlab-shell!538 diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -8,6 +8,8 @@ "strings" "time" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -38,6 +40,10 @@ return err } + log.WithContextFields(ctx, log.Fields{ + "token_args": c.TokenArgs, + }).Info("personalaccesstoken: execute: requesting token") + response, err := c.getPersonalAccessToken(ctx) if err != nil { return err diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -4,19 +4,17 @@ "bytes" "context" "errors" - - "gitlab.com/gitlab-org/gitlab-shell/client" - "io" "net/http" + "gitlab.com/gitlab-org/labkit/log" + + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" - - "gitlab.com/gitlab-org/labkit/log" ) type Request struct { @@ -59,12 +57,12 @@ request.Data.UserId = response.Who for _, endpoint := range data.ApiEndpoints { - fields := log.Fields{ + ctxlog := log.WithContextFields(ctx, log.Fields{ "primary_repo": data.PrimaryRepo, "endpoint": endpoint, - } + }) - log.WithContextFields(ctx, fields).Info("Performing custom action") + ctxlog.Info("customaction: processApiEndpoints: Performing custom action") response, err := c.performRequest(ctx, client, endpoint, request) if err != nil { @@ -90,6 +88,10 @@ } else { output = c.readFromStdinNoEOF() } + ctxlog.WithFields(log.Fields{ + "eof_sent": c.EOFSent, + "stdin_bytes": len(output), + }).Debug("customaction: processApiEndpoints: stdin buffered") request.Output = output } diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -6,6 +6,8 @@ "io" "strings" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -21,9 +23,14 @@ } func (c *Command) Execute(ctx context.Context) error { + ctxlog := log.ContextLogger(ctx) + ctxlog.Debug("twofactorrecover: execute: Waiting for user input") + if c.canContinue() { + ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { + ctxlog.Debug("twofactorrecover: execute: User chose not to continue") fmt.Fprintln(c.ReadWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.") } @@ -43,9 +50,12 @@ } func (c *Command) displayRecoveryCodes(ctx context.Context) { + ctxlog := log.ContextLogger(ctx) + codes, err := c.getRecoveryCodes(ctx) if err == nil { + ctxlog.Debug("twofactorrecover: displayRecoveryCodes: recovery codes successfully generated") messageWithCodes := "\nYour two-factor authentication recovery codes are:\n\n" + strings.Join(codes, "\n") + @@ -54,6 +64,7 @@ "a new device so you do not lose access to your account again.\n" fmt.Fprint(c.ReadWriter.Out, messageWithCodes) } else { + ctxlog.WithError(err).Error("twofactorrecover: displayRecoveryCodes: failed to generate recovery codes") fmt.Fprintf(c.ReadWriter.Out, "\nAn error occurred while trying to generate new recovery codes.\n%v\n", err) } } diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -5,6 +5,8 @@ "fmt" "io" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -18,11 +20,18 @@ } func (c *Command) Execute(ctx context.Context) error { - err := c.verifyOTP(ctx, c.getOTP()) + ctxlog := log.ContextLogger(ctx) + ctxlog.Info("twofactorverify: execute: waiting for user input") + otp := c.getOTP() + + ctxlog.Info("twofactorverify: execute: verifying entered OTP") + err := c.verifyOTP(ctx, otp) if err != nil { + ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } + ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") return nil } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1634718828 -10800 # Wed Oct 20 11:33:48 2021 +0300 # Node ID 00972efe4bd04602f1243a56c5bfbffb6c7ed184 # Parent 3c1295f1e290c010533bfba9b81c8afd116c61b4 Log SSL_CERT_DIR when it's configured diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,6 +14,8 @@ "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + + "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -93,6 +95,8 @@ func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { + log.WithFields(log.Fields{"ssl_cert_dir": c.SslCertDir}).Info("SSL_CERT_DIR is configured") + os.Setenv("SSL_CERT_DIR", c.SslCertDir) } } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1634718850 -10800 # Wed Oct 20 11:34:10 2021 +0300 # Node ID 67bcabd5a37384dd196ace1d594d7b2e97e10c51 # Parent 00972efe4bd04602f1243a56c5bfbffb6c7ed184 Add logging to RunGitalyCommand func diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -45,17 +45,24 @@ func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { conn, err := getConn(ctx, gc) if err != nil { + log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") + return err } defer conn.Close() childCtx := withOutgoingMetadata(ctx, gc.Features) - _, err = handler(childCtx, conn) + ctxlog := log.ContextLogger(childCtx) + exitStatus, err := handler(childCtx, conn) - if err != nil && grpcstatus.Convert(err).Code() == grpccodes.Unavailable { - log.WithError(err).Error("Gitaly is unavailable") + if err != nil { + if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { + ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") - return fmt.Errorf("Git service is temporarily unavailable") + return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + } + + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") } return err diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -56,7 +56,7 @@ expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) - require.EqualError(t, err, "Git service is temporarily unavailable") + require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") } func TestRunGitalyCommandMetadata(t *testing.T) { # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1634788211 0 # Thu Oct 21 03:50:11 2021 +0000 # Node ID aebee2f15bfbebbbf155b4ac968885deacf868fd # Parent 3c1295f1e290c010533bfba9b81c8afd116c61b4 # Parent 67bcabd5a37384dd196ace1d594d7b2e97e10c51 Merge branch 'id-logging-for-handler' into 'main' Add logging to handler/exec.go and config/config.go See merge request gitlab-org/gitlab-shell!539 diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,6 +14,8 @@ "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + + "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -93,6 +95,8 @@ func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { + log.WithFields(log.Fields{"ssl_cert_dir": c.SslCertDir}).Info("SSL_CERT_DIR is configured") + os.Setenv("SSL_CERT_DIR", c.SslCertDir) } } diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -45,17 +45,24 @@ func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { conn, err := getConn(ctx, gc) if err != nil { + log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") + return err } defer conn.Close() childCtx := withOutgoingMetadata(ctx, gc.Features) - _, err = handler(childCtx, conn) + ctxlog := log.ContextLogger(childCtx) + exitStatus, err := handler(childCtx, conn) - if err != nil && grpcstatus.Convert(err).Code() == grpccodes.Unavailable { - log.WithError(err).Error("Gitaly is unavailable") + if err != nil { + if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { + ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") - return fmt.Errorf("Git service is temporarily unavailable") + return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + } + + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") } return err diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -56,7 +56,7 @@ expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) - require.EqualError(t, err, "Git service is temporarily unavailable") + require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") } func TestRunGitalyCommandMetadata(t *testing.T) { # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1636576318 28800 # Wed Nov 10 12:31:58 2021 -0800 # Node ID 145796e7e2955661ba04f0e5bbd3862dcad84140 # Parent aebee2f15bfbebbbf155b4ac968885deacf868fd Relax key and username matching for sshd Due to the way sshd works, gitlab-shell could be called with a single string in the form: ``` /path/to/gitlab-shell -c key-id ``` However, due to the tightening of the regular expressions in fcff692b this string no longer matches, so logins would fail with: ``` Failed to get username: who='' is invalid ``` This can be reproduced by changing the user's shell to point to gitlab-shell. For example: ``` usermod git -s /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell ``` While setting gitlab-shell as the user's shell isn't officially supported, gitlab-shell still should be able to cope with the key being specified as the last argument. We now split the argument list and use the last value. Relates to https://gitlab.com/gitlab-org/gitlab-shell/-/issues/530 diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -170,6 +170,27 @@ expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, }, { + desc: "It finds the key id if the key is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username if the username is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the last argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { desc: "It finds the username in any passed arguments", executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -3,6 +3,7 @@ import ( "fmt" "regexp" + "strings" "github.com/mattn/go-shellwords" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" @@ -73,26 +74,29 @@ } } -func tryParseKeyId(argument string) string { - matchInfo := whoKeyRegex.FindStringSubmatch(argument) +func tryParse(r *regexp.Regexp, argument string) string { + // sshd may execute the session for AuthorizedKeysCommand in multiple ways: + // 1. key-id + // 2. /path/to/shell -c key-id + args := strings.Split(argument, " ") + lastArg := args[len(args)-1] + + matchInfo := r.FindStringSubmatch(lastArg) if len(matchInfo) == 2 { // The first element is the full matched string - // The second element is the named `keyid` + // The second element is the named `keyid` or `username` return matchInfo[1] } return "" } +func tryParseKeyId(argument string) string { + return tryParse(whoKeyRegex, argument) +} + func tryParseUsername(argument string) string { - matchInfo := whoUsernameRegex.FindStringSubmatch(argument) - if len(matchInfo) == 2 { - // The first element is the full matched string - // The second element is the named `username` - return matchInfo[1] - } - - return "" + return tryParse(whoUsernameRegex, argument) } func (s *Shell) ParseCommand(commandString string) error { # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1636682976 0 # Fri Nov 12 02:09:36 2021 +0000 # Node ID 5396b70d69efbd3f81c5ab5e2ff707ccf37891e9 # Parent aebee2f15bfbebbbf155b4ac968885deacf868fd # Parent 145796e7e2955661ba04f0e5bbd3862dcad84140 Merge branch 'sh-improve-key-matching-sshd' into 'main' Relax key and username matching for sshd See merge request gitlab-org/gitlab-shell!540 diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -170,6 +170,27 @@ expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, }, { + desc: "It finds the key id if the key is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username if the username is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the last argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { desc: "It finds the username in any passed arguments", executable: &executable.Executable{Name: executable.GitlabShell}, env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -3,6 +3,7 @@ import ( "fmt" "regexp" + "strings" "github.com/mattn/go-shellwords" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" @@ -73,26 +74,29 @@ } } -func tryParseKeyId(argument string) string { - matchInfo := whoKeyRegex.FindStringSubmatch(argument) +func tryParse(r *regexp.Regexp, argument string) string { + // sshd may execute the session for AuthorizedKeysCommand in multiple ways: + // 1. key-id + // 2. /path/to/shell -c key-id + args := strings.Split(argument, " ") + lastArg := args[len(args)-1] + + matchInfo := r.FindStringSubmatch(lastArg) if len(matchInfo) == 2 { // The first element is the full matched string - // The second element is the named `keyid` + // The second element is the named `keyid` or `username` return matchInfo[1] } return "" } +func tryParseKeyId(argument string) string { + return tryParse(whoKeyRegex, argument) +} + func tryParseUsername(argument string) string { - matchInfo := whoUsernameRegex.FindStringSubmatch(argument) - if len(matchInfo) == 2 { - // The first element is the full matched string - // The second element is the named `username` - return matchInfo[1] - } - - return "" + return tryParse(whoUsernameRegex, argument) } func (s *Shell) ParseCommand(commandString string) error { # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1636695628 -39600 # Fri Nov 12 16:40:28 2021 +1100 # Node ID 9ae43afdd2f07aafbbd4fdcd94d4a9abe54ce4e8 # Parent 5396b70d69efbd3f81c5ab5e2ff707ccf37891e9 Fix go -> golang in .tool-versions diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -go 1.16.9 +golang 1.16.9 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1636695645 -39600 # Fri Nov 12 16:40:45 2021 +1100 # Node ID ba313aed46dd6720f7c4a3af2b4219b8f51db8c3 # Parent 9ae43afdd2f07aafbbd4fdcd94d4a9abe54ce4e8 Bump golang in .tool-versions to 1.16.10 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -golang 1.16.9 +golang 1.16.10 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1636946261 0 # Mon Nov 15 03:17:41 2021 +0000 # Node ID c9169d5139f0ecbc0c27419cb87f320ebde12d65 # Parent 5396b70d69efbd3f81c5ab5e2ff707ccf37891e9 # Parent ba313aed46dd6720f7c4a3af2b4219b8f51db8c3 Merge branch 'ashmckenzie/fix-go-definition-in-tool-versions' into 'main' Fix golang definition in tool versions See merge request gitlab-org/gitlab-shell!542 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -go 1.16.9 +golang 1.16.10 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1636952256 -39600 # Mon Nov 15 15:57:36 2021 +1100 # Node ID a820a6cf69e0096d959393848619dbcd24312ed1 # Parent c9169d5139f0ecbc0c27419cb87f320ebde12d65 Add missing v13.21.0 changelog entries diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,13 @@ v13.21.0 +- Switch to labkit for logging system setup !504 +- Remove some unreliable tests !503 +- Make gofmt check fail if there are any matching files !500 +- Update go-proxyproto to v0.6.0 !499 +- Switch to labkit/log for logging functionality !498 +- Unit tests for internal/sshd/connection.go !497 +- Prometheus metrics for HTTP requests !496 +- Refactor testhelper.PrepareTestRootDir using t.Cleanup !49 - Change default logging format to JSON !476 - Shutdown sshd gracefully !484 - Provide liveness and readiness probes !494 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1636952283 -39600 # Mon Nov 15 15:58:03 2021 +1100 # Node ID 5a7116d7fe463c64d73cea1ca9fe75b5427eaa5e # Parent a820a6cf69e0096d959393848619dbcd24312ed1 Add missing v13.21.1 changelog entry diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.21.1 + +- Only validate SSL cert file exists if a value is supplied !527 + v13.21.0 - Switch to labkit for logging system setup !504 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1636952314 -39600 # Mon Nov 15 15:58:34 2021 +1100 # Node ID 1fa4f69b6d2c4a63eb332d3964c03832aa63cb2a # Parent 5a7116d7fe463c64d73cea1ca9fe75b5427eaa5e Release v13.22.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,22 @@ +v13.22.0 + +- Relax key and username matching for sshd !540 +- Add logging to handler/exec.go and config/config.go !539 +- Improve logging for non-git commands !538 +- Update to Go v1.16.9 !537 +- Reject non-proxied connections when proxy protocol is enabled !536 +- Log command invocation !535 +- Fix logging channel type !534 +- Resolve an error-swallowing issue !533 +- Add more logging to gitlab-sshd !531 +- Respect log-level configuration again !530 +- Improve err message given when Gitaly unavailable !526 +- makefile: properly escape '$' in VERSION_STRING !525 +- Add context fields to logging !524 +- Extract server config related code out of sshd.go !523 +- Add TestInvalidClientConfig and TestNewServerWithoutHosts for sshd.go !518 +- Update Ruby version to 2.7.4 and add Go version 1.16.8 for tooling !517 + v13.21.1 - Only validate SSL cert file exists if a value is supplied !527 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1636952729 0 # Mon Nov 15 05:05:29 2021 +0000 # Node ID 7adeb3e289bd067e243d5b42fa75461800372f58 # Parent 1fa4f69b6d2c4a63eb332d3964c03832aa63cb2a Fix merge request IID on changelog diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -30,7 +30,7 @@ - Switch to labkit/log for logging functionality !498 - Unit tests for internal/sshd/connection.go !497 - Prometheus metrics for HTTP requests !496 -- Refactor testhelper.PrepareTestRootDir using t.Cleanup !49 +- Refactor testhelper.PrepareTestRootDir using t.Cleanup !493 - Change default logging format to JSON !476 - Shutdown sshd gracefully !484 - Provide liveness and readiness probes !494 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1636954267 0 # Mon Nov 15 05:31:07 2021 +0000 # Node ID 7242f61c8d02f80f1a48936aa283a82526327a8c # Parent c9169d5139f0ecbc0c27419cb87f320ebde12d65 # Parent 7adeb3e289bd067e243d5b42fa75461800372f58 Merge branch 'ashmckenzie/13-22-release' into 'main' Release v13.22.0 See merge request gitlab-org/gitlab-shell!541 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,36 @@ +v13.22.0 + +- Relax key and username matching for sshd !540 +- Add logging to handler/exec.go and config/config.go !539 +- Improve logging for non-git commands !538 +- Update to Go v1.16.9 !537 +- Reject non-proxied connections when proxy protocol is enabled !536 +- Log command invocation !535 +- Fix logging channel type !534 +- Resolve an error-swallowing issue !533 +- Add more logging to gitlab-sshd !531 +- Respect log-level configuration again !530 +- Improve err message given when Gitaly unavailable !526 +- makefile: properly escape '$' in VERSION_STRING !525 +- Add context fields to logging !524 +- Extract server config related code out of sshd.go !523 +- Add TestInvalidClientConfig and TestNewServerWithoutHosts for sshd.go !518 +- Update Ruby version to 2.7.4 and add Go version 1.16.8 for tooling !517 + +v13.21.1 + +- Only validate SSL cert file exists if a value is supplied !527 + v13.21.0 +- Switch to labkit for logging system setup !504 +- Remove some unreliable tests !503 +- Make gofmt check fail if there are any matching files !500 +- Update go-proxyproto to v0.6.0 !499 +- Switch to labkit/log for logging functionality !498 +- Unit tests for internal/sshd/connection.go !497 +- Prometheus metrics for HTTP requests !496 +- Refactor testhelper.PrepareTestRootDir using t.Cleanup !493 - Change default logging format to JSON !476 - Shutdown sshd gracefully !484 - Provide liveness and readiness probes !494 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1636954556 -28800 # Mon Nov 15 13:35:56 2021 +0800 # Node ID e6074be751b66fca60b74d28efaccf0474468b50 # Parent 7242f61c8d02f80f1a48936aa283a82526327a8c Update gitlab-shell VERSION to 13.22.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.21.0 +13.22.0 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1636956284 0 # Mon Nov 15 06:04:44 2021 +0000 # Node ID cf60d9b274666d35bdd31165afdcbe33b162fc4f # Parent 7242f61c8d02f80f1a48936aa283a82526327a8c # Parent e6074be751b66fca60b74d28efaccf0474468b50 Merge branch 'pb-update-version-file-13-22-0' into 'main' Update gitlab-shell VERSION to 13.22.0 See merge request gitlab-org/gitlab-shell!543 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.21.0 +13.22.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1636989303 -10800 # Mon Nov 15 18:15:03 2021 +0300 # Node ID b3ec3749ea59eed941f59f426a35371ff366148a # Parent cf60d9b274666d35bdd31165afdcbe33b162fc4f Refactor flaky test case in sshd_test - Use require.Regexp to expect ssh handshake error - Use require.Eventually to refactor verifyStatus diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -48,8 +48,7 @@ } func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { - s := setupServerWithProxyProtocolEnabled(t) - defer s.Shutdown() + setupServerWithProxyProtocolEnabled(t) client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) if client != nil { @@ -57,7 +56,7 @@ } require.Error(t, err, "Expected plain SSH request to be failed") - require.Equal(t, err.Error(), "ssh: handshake failed: EOF") + require.Regexp(t, "ssh: handshake failed", err.Error()) } func TestCorrelationId(t *testing.T) { @@ -227,14 +226,5 @@ } func verifyStatus(t *testing.T, s *Server, st status) { - for i := 5; i < 500; i += 50 { - if s.getStatus() == st { - break - } - - // Sleep incrementally ~2s in total - time.Sleep(time.Duration(i) * time.Millisecond) - } - - require.Equal(t, st, s.getStatus()) + require.Eventually(t, func() bool { return s.getStatus() == st }, 2*time.Second, time.Millisecond) } # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1637031908 0 # Tue Nov 16 03:05:08 2021 +0000 # Node ID aacf29b3a02a6ac9b18470f1a761232243816c1d # Parent cf60d9b274666d35bdd31165afdcbe33b162fc4f # Parent b3ec3749ea59eed941f59f426a35371ff366148a Merge branch 'id-fix-flaky-test' into 'main' Refactor flaky test case in sshd_test See merge request gitlab-org/gitlab-shell!545 diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -48,8 +48,7 @@ } func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { - s := setupServerWithProxyProtocolEnabled(t) - defer s.Shutdown() + setupServerWithProxyProtocolEnabled(t) client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) if client != nil { @@ -57,7 +56,7 @@ } require.Error(t, err, "Expected plain SSH request to be failed") - require.Equal(t, err.Error(), "ssh: handshake failed: EOF") + require.Regexp(t, "ssh: handshake failed", err.Error()) } func TestCorrelationId(t *testing.T) { @@ -227,14 +226,5 @@ } func verifyStatus(t *testing.T, s *Server, st status) { - for i := 5; i < 500; i += 50 { - if s.getStatus() == st { - break - } - - // Sleep incrementally ~2s in total - time.Sleep(time.Duration(i) * time.Millisecond) - } - - require.Equal(t, st, s.getStatus()) + require.Eventually(t, func() bool { return s.getStatus() == st }, 2*time.Second, time.Millisecond) } # HG changeset patch # User Patrick Steinhardt <psteinhardt@gitlab.com> # Date 1636959561 -3600 # Mon Nov 15 07:59:21 2021 +0100 # Node ID 6e4e76df7ef9d3fbc346c1eebedee19babe99e2f # Parent cf60d9b274666d35bdd31165afdcbe33b162fc4f Fix usage of out-of-date Gitaly images Our CI jobs and docker-compose pull in the "latest" tag of Gitaly. As it turns out though, "latest" is pointing to Gitaly v13.3.0-rc5, which is definitely not the latest versionat this point in time. This is because CNG was converted to not use the "latest" tag anymore, but instead to use a tag called "master" in gitlab-org/build/CNG!519. Fix this by using the new "master" tag instead. diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,7 +45,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:master # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly diff --git a/docker-compose.yml b/docker-compose.yml --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,6 @@ gitaly: environment: - GITALY_TESTING_NO_GIT_HOOKS=1 - image: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + image: registry.gitlab.com/gitlab-org/build/cng/gitaly:master ports: - '8075:8075' # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1637033218 0 # Tue Nov 16 03:26:58 2021 +0000 # Node ID 268af504e4c51836701b070a5ecf81d2ca12ca63 # Parent aacf29b3a02a6ac9b18470f1a761232243816c1d # Parent 6e4e76df7ef9d3fbc346c1eebedee19babe99e2f Merge branch 'pks-gitaly-cng-latest' into 'main' Fix usage of out-of-date Gitaly images See merge request gitlab-org/gitlab-shell!544 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,7 +45,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:master # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly diff --git a/docker-compose.yml b/docker-compose.yml --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,6 @@ gitaly: environment: - GITALY_TESTING_NO_GIT_HOOKS=1 - image: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + image: registry.gitlab.com/gitlab-org/build/cng/gitaly:master ports: - '8075:8075' # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1637672297 -10800 # Tue Nov 23 15:58:17 2021 +0300 # Node ID 2970ae7c21dd298a7ccadad021abbf082b56ccdc # Parent 268af504e4c51836701b070a5ecf81d2ca12ca63 Remove SSL_CERT_DIR logging This log entry doesn't respect log level, because the log level is configured after this logging happens diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,8 +14,6 @@ "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - - "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -95,8 +93,6 @@ func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { - log.WithFields(log.Fields{"ssl_cert_dir": c.SslCertDir}).Info("SSL_CERT_DIR is configured") - os.Setenv("SSL_CERT_DIR", c.SslCertDir) } } # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1637732912 0 # Wed Nov 24 05:48:32 2021 +0000 # Node ID f593018f1e6261b7a130f800ff583494c97ce822 # Parent 268af504e4c51836701b070a5ecf81d2ca12ca63 # Parent 2970ae7c21dd298a7ccadad021abbf082b56ccdc Merge branch 'id-remove-ssl-cert-dir-logging' into 'main' Remove SSL_CERT_DIR logging See merge request gitlab-org/gitlab-shell!546 diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,8 +14,6 @@ "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - - "gitlab.com/gitlab-org/labkit/log" ) const ( @@ -95,8 +93,6 @@ func (c *Config) ApplyGlobalState() { if c.SslCertDir != "" { - log.WithFields(log.Fields{"ssl_cert_dir": c.SslCertDir}).Info("SSL_CERT_DIR is configured") - os.Setenv("SSL_CERT_DIR", c.SslCertDir) } } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1637742836 -10800 # Wed Nov 24 11:33:56 2021 +0300 # Node ID fc0405af6d59acb6168e61f8859a2207fdc8609f # Parent f593018f1e6261b7a130f800ff583494c97ce822 Release v13.22.1 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.22.1 + +- Remove SSL_CERT_DIR logging !546 + v13.22.0 - Relax key and username matching for sshd !540 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.0 +13.22.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1637743366 0 # Wed Nov 24 08:42:46 2021 +0000 # Node ID 20c9325c66f15b775f94cd0b11bb6df45d9510db # Parent f593018f1e6261b7a130f800ff583494c97ce822 # Parent fc0405af6d59acb6168e61f8859a2207fdc8609f Merge branch 'id-release-13-22-1' into 'main' Release v13.22.1 See merge request gitlab-org/gitlab-shell!547 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.22.1 + +- Remove SSL_CERT_DIR logging !546 + v13.22.0 - Relax key and username matching for sshd !540 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.0 +13.22.1 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1639082342 28800 # Thu Dec 09 12:39:02 2021 -0800 # Node ID 2e24492b1690fd146b2031660a60ee7d8c71f697 # Parent 20c9325c66f15b775f94cd0b11bb6df45d9510db Bump .tool_versions to use Go v1.16.12 Part of https://gitlab.com/groups/gitlab-org/-/epics/7111 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -golang 1.16.10 +golang 1.16.12 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1639096011 0 # Fri Dec 10 00:26:51 2021 +0000 # Node ID 0933769f90885c8c0ef6db40d1aeeea758a7632d # Parent 20c9325c66f15b775f94cd0b11bb6df45d9510db # Parent 2e24492b1690fd146b2031660a60ee7d8c71f697 Merge branch 'sh-bump-go-1.16.12' into 'main' Bump .tool_versions to use Go v1.16.12 See merge request gitlab-org/gitlab-shell!548 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -golang 1.16.10 +golang 1.16.12 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1640272000 -3600 # Thu Dec 23 16:06:40 2021 +0100 # Branch heptapod # Node ID 500ed5c3c7f5402868765b8f4e8794a84df9b0e4 # Parent 9e659daeffdf3b711ef6aaba6cf4c737bb9f632c # Parent 20c9325c66f15b775f94cd0b11bb6df45d9510db Merged upstream v13.22.1 into heptapod branch The parts of `internal/command/command.go` that were changed in Heptapod Shell got moved by upstream got `cmd/gitlab-shell/command.go`, so we had to follow suit. Everything else was straightforward. diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,7 +45,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:master # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.2 +2.7.4 diff --git a/.tool-versions b/.tool-versions new file mode 100644 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +ruby 2.7.4 +golang 1.16.10 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,40 @@ +v13.22.1 + +- Remove SSL_CERT_DIR logging !546 + +v13.22.0 + +- Relax key and username matching for sshd !540 +- Add logging to handler/exec.go and config/config.go !539 +- Improve logging for non-git commands !538 +- Update to Go v1.16.9 !537 +- Reject non-proxied connections when proxy protocol is enabled !536 +- Log command invocation !535 +- Fix logging channel type !534 +- Resolve an error-swallowing issue !533 +- Add more logging to gitlab-sshd !531 +- Respect log-level configuration again !530 +- Improve err message given when Gitaly unavailable !526 +- makefile: properly escape '$' in VERSION_STRING !525 +- Add context fields to logging !524 +- Extract server config related code out of sshd.go !523 +- Add TestInvalidClientConfig and TestNewServerWithoutHosts for sshd.go !518 +- Update Ruby version to 2.7.4 and add Go version 1.16.8 for tooling !517 + v13.21.1 - Only validate SSL cert file exists if a value is supplied !527 v13.21.0 +- Switch to labkit for logging system setup !504 +- Remove some unreliable tests !503 +- Make gofmt check fail if there are any matching files !500 +- Update go-proxyproto to v0.6.0 !499 +- Switch to labkit/log for logging functionality !498 +- Unit tests for internal/sshd/connection.go !497 +- Prometheus metrics for HTTP requests !496 +- Refactor testhelper.PrepareTestRootDir using t.Cleanup !493 - Change default logging format to JSON !476 - Shutdown sshd gracefully !484 - Provide liveness and readiness probes !494 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -2,12 +2,13 @@ GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) -BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" PREFIX ?= /usr/local +build: bin/gitlab-shell + validate: verify test verify: verify_golang @@ -40,7 +41,6 @@ _script_install: bin/install -build: bin/gitlab-shell compile: bin/gitlab-shell bin/gitlab-shell: $(GO_SOURCES) GOBIN="$(CURDIR)/bin" go install $(GOBUILD_FLAGS) ./cmd/... diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -102,6 +102,21 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. +## Logging Guidelines + +In general, it should be possible to determine the structure, but not content, +of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some +guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging functionality +- **Always** include a correlation ID +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log success cases as well as error cases +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. + ## Releasing See [PROCESS.md](./PROCESS.md) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.21.1 +13.22.1 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -5,7 +5,7 @@ "encoding/base64" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "path" "strings" @@ -83,7 +83,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) @@ -99,7 +99,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) }) @@ -155,7 +155,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -170,7 +170,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -194,7 +194,7 @@ Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, http.MethodPost, r.Method) - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -6,7 +6,6 @@ "crypto/x509" "errors" "fmt" - "io/ioutil" "net" "net/http" "os" @@ -153,7 +152,7 @@ } if hcc.caPath != "" { - fis, _ := ioutil.ReadDir(hcc.caPath) + fis, _ := os.ReadDir(hcc.caPath) for _, fi := range fis { if fi.IsDir() { continue @@ -174,7 +173,6 @@ return nil, "", err } tlsConfig.Certificates = []tls.Certificate{cert} - tlsConfig.BuildNameToCertificate() } transport := &http.Transport{ @@ -185,7 +183,7 @@ } func addCertToPool(certPool *x509.CertPool, fileName string) { - cert, err := ioutil.ReadFile(fileName) + cert, err := os.ReadFile(fileName) if err == nil { certPool.AppendCertsFromPEM(cert) } diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -4,7 +4,7 @@ "context" "encoding/base64" "fmt" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -64,7 +64,7 @@ defer response.Body.Close() require.NotNil(t, response) - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) headerParts := strings.Split(string(responseBody), " ") diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -3,7 +3,7 @@ import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "path" "testing" @@ -57,7 +57,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,7 +1,6 @@ package testserver import ( - "io/ioutil" "net" "os" "path" @@ -61,7 +60,7 @@ func StartGitalyServer(t *testing.T) (string, *TestGitalyServer) { t.Helper() - tempDir, _ := ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ := os.MkdirTemp("", "gitlab-shell-test-api") gitalySocketPath := path.Join(tempDir, "gitaly.sock") t.Cleanup(func() { os.RemoveAll(tempDir) }) diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -3,7 +3,7 @@ import ( "crypto/tls" "crypto/x509" - "io/ioutil" + "io" "log" "net" "net/http" @@ -18,7 +18,7 @@ ) var ( - tempDir, _ = ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ = os.MkdirTemp("", "gitlab-shell-test-api") testSocket = path.Join(tempDir, "internal.sock") ) @@ -41,7 +41,7 @@ Handler: buildHandler(handlers), // We'll put this server through some nasty stuff we don't want // in our test output - ErrorLog: log.New(ioutil.Discard, "", 0), + ErrorLog: log.New(io.Discard, "", 0), } go server.Serve(socketListener) @@ -73,10 +73,9 @@ Certificates: []tls.Certificate{cer}, MinVersion: tls.VersionTLS12, } - server.TLS.BuildNameToCertificate() if clientCAPath != "" { - caCert, err := ioutil.ReadFile(clientCAPath) + caCert, err := os.ReadFile(clientCAPath) require.NoError(t, err) caCertPool := x509.NewCertPool() diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command.go @@ -0,0 +1,21 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + if cmd := build(config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func build(config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &healthcheck.Command{Config: config, ReadWriter: readWriter} +} diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command_test.go @@ -0,0 +1,42 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Healthcheck command", + config: basicConfig, + expectedType: &healthcheck.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -34,7 +34,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := checkCmd.New(config, readWriter) if err != nil { fmt.Fprintf(readWriter.ErrOut, "%v\n", err) os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -0,0 +1,37 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string) (*commandargs.AuthorizedKeys, error) { + args := &commandargs.AuthorizedKeys{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -0,0 +1,120 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedKeys command", + executable: authorizedKeysExec, + arguments: []string{"git", "git", "key"}, + config: basicConfig, + expectedType: &authorizedkeys.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.arguments, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-keys command", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"git", "git", "key"}, + expectedArgs: &commandargs.AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := command.Parse(tc.arguments) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With too many arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", "key", "something-else"}, + expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With missing username for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "", "key"}, + expectedError: "# No username provided", + }, + { + desc: "With missing key for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", ""}, + expectedError: "# No key provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := command.Parse(tc.arguments) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -35,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -0,0 +1,37 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string) (*commandargs.AuthorizedPrincipals, error) { + args := &commandargs.AuthorizedPrincipals{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -0,0 +1,114 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedPrincipals command", + executable: authorizedPrincipalsExec, + arguments: []string{"key", "principal"}, + config: basicConfig, + expectedType: &authorizedprincipals.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.arguments, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-principals command", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal-1", "principal-2"}, + expectedArgs: &commandargs.AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.arguments) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", + }, + { + desc: "With missing key_id for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"", "principal"}, + expectedError: "# No key_id provided", + }, + { + desc: "With blank principal for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal", ""}, + expectedError: "# An invalid principal was provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.arguments) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -35,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command.go @@ -0,0 +1,81 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/hg" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments, env) + if err != nil { + return nil, err + } + + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func NewWithKey(gitlabKeyId string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(nil, env) + if err != nil { + return nil, err + } + + args.GitlabKeyId = gitlabKeyId + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string, env sshenv.Env) (*commandargs.Shell, error) { + args := &commandargs.Shell{Arguments: arguments, Env: env} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func Build(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + switch args.CommandType { + case commandargs.Discover: + return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorRecover: + return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.Hg: + return &hg.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorVerify: + return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.LfsAuthenticate: + return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.ReceivePack: + return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadPack: + return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadArchive: + return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.PersonalAccessToken: + return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} + } + + return nil +} diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command_test.go @@ -0,0 +1,302 @@ +package command_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Discover command", + executable: gitlabShellExec, + env: buildEnv(""), + config: basicConfig, + expectedType: &discover.Command{}, + }, + { + desc: "it returns a TwoFactorRecover command", + executable: gitlabShellExec, + env: buildEnv("2fa_recovery_codes"), + config: basicConfig, + expectedType: &twofactorrecover.Command{}, + }, + { + desc: "it returns a TwoFactorVerify command", + executable: gitlabShellExec, + env: buildEnv("2fa_verify"), + config: basicConfig, + expectedType: &twofactorverify.Command{}, + }, + { + desc: "it returns an LfsAuthenticate command", + executable: gitlabShellExec, + env: buildEnv("git-lfs-authenticate"), + config: basicConfig, + expectedType: &lfsauthenticate.Command{}, + }, + { + desc: "it returns a ReceivePack command", + executable: gitlabShellExec, + env: buildEnv("git-receive-pack"), + config: basicConfig, + expectedType: &receivepack.Command{}, + }, + { + desc: "it returns an UploadPack command", + executable: gitlabShellExec, + env: buildEnv("git-upload-pack"), + config: basicConfig, + expectedType: &uploadpack.Command{}, + }, + { + desc: "it returns an UploadArchive command", + executable: gitlabShellExec, + env: buildEnv("git-upload-archive"), + config: basicConfig, + expectedType: &uploadarchive.Command{}, + }, + { + desc: "it returns a PersonalAccessToken command", + executable: gitlabShellExec, + env: buildEnv("personal_access_token"), + config: basicConfig, + expectedType: &personalaccesstoken.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.arguments, tc.env, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestFailingNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + expectedError error + }{ + { + desc: "Parsing environment failed", + executable: gitlabShellExec, + expectedError: errors.New("Only SSH allowed"), + }, + { + desc: "Unknown command given", + executable: gitlabShellExec, + env: buildEnv("unknown"), + expectedError: disallowedcommand.Error, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New([]string{}, tc.env, basicConfig, nil) + require.Nil(t, command) + require.Equal(t, tc.expectedError, err) + }) + } +} + +func buildEnv(command string) sshenv.Env { + return sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: command, + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It sets discover as the command when the command string was empty", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: commandargs.Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id if the key is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username if the username is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the last argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It parses 2fa_recovery_codes command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: commandargs.TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, + }, + { + desc: "It parses git-receive-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, + }, + { + desc: "It parses git-receive-pack command and a project with single quotes", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, + }, + { + desc: `It parses "git receive-pack" command`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, + }, + { + desc: `It parses a command followed by control characters`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, + }, + { + desc: "It parses git-upload-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: commandargs.UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, + }, + { + desc: "It parses git-upload-archive command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: commandargs.UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, + }, + { + desc: "It parses git-lfs-authenticate command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: commandargs.LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.arguments, tc.env) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "It fails if SSH connection is not set", + executable: &executable.Executable{Name: executable.GitlabShell}, + arguments: []string{}, + expectedError: "Only SSH allowed", + }, + { + desc: "It fails if SSH command is invalid", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, + arguments: []string{}, + expectedError: "Invalid SSH command: invalid command line string", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.arguments, tc.env) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -3,7 +3,11 @@ import ( "fmt" "os" + "reflect" + "gitlab.com/gitlab-org/labkit/log" + + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -50,7 +54,7 @@ defer logCloser.Close() env := sshenv.NewFromEnv() - cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) + cmd, err := shellCmd.New(os.Args[1:], env, config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment @@ -61,8 +65,15 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() - if err = cmd.Execute(ctx); err != nil { + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + + if err := cmd.Execute(ctx); err != nil { + ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) os.Exit(1) } + + ctxlog.Info("gitlab-shell: main: command executed successfully") } diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -8,7 +8,6 @@ "encoding/pem" "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -112,7 +111,7 @@ case "/api/v4/internal/two_factor_otp_check": fmt.Fprint(w, `{"success": true}`) case "/api/v4/internal/allowed": - body, err := ioutil.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) + body, err := os.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) require.NoError(t, err) response := strings.Replace(string(body), "GITALY_REPOSITORY", testRepo, 1) @@ -198,7 +197,7 @@ func configureSSHD(t *testing.T, apiServer string) (string, ed25519.PublicKey) { t.Helper() - dir, err := ioutil.TempDir("", "gitlab-sshd-acceptance-test-") + dir, err := os.MkdirTemp("", "gitlab-sshd-acceptance-test-") require.NoError(t, err) t.Cleanup(func() { os.RemoveAll(dir) }) @@ -209,11 +208,11 @@ require.NoError(t, err) configFileData := genServerConfig(apiServer, hostKeyFile) - require.NoError(t, ioutil.WriteFile(configFile, configFileData, 0644)) + require.NoError(t, os.WriteFile(configFile, configFileData, 0644)) block := &pem.Block{Type: "OPENSSH PRIVATE KEY", Bytes: edkey.MarshalED25519PrivateKey(priv)} hostKeyData := pem.EncodeToMemory(block) - require.NoError(t, ioutil.WriteFile(hostKeyFile, hostKeyData, 0400)) + require.NoError(t, os.WriteFile(hostKeyFile, hostKeyData, 0400)) return dir, pub } @@ -326,7 +325,7 @@ _, err = fmt.Fprintln(stdin, "yes") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, ` Your two-factor authentication recovery codes are: @@ -365,7 +364,7 @@ _, err = fmt.Fprintln(stdin, "otp123") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, "OTP validation successful. Git operations are now allowed.\n", string(output)) } diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -97,7 +97,7 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() diff --git a/docker-compose.yml b/docker-compose.yml --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,6 @@ gitaly: environment: - GITALY_TESTING_NO_GIT_HOOKS=1 - image: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + image: registry.gitlab.com/gitlab-org/build/cng/gitaly:master ports: - '8075:8075' diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,24 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/hg" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -29,19 +12,6 @@ Execute(ctx context.Context) error } -func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (Command, error) { - args, err := commandargs.Parse(e, arguments, env) - if err != nil { - return nil, err - } - - if cmd := buildCommand(e, args, config, readWriter); cmd != nil { - return cmd, nil - } - - return nil, disallowedcommand.Error -} - // Setup() initializes tracing from the configuration file and generates a // background context from which all other contexts in the process should derive // from, as it has a service name and initial correlation ID set. @@ -77,55 +47,3 @@ closer.Close() } } - -func buildCommand(e *executable.Executable, args commandargs.CommandArgs, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch e.Name { - case executable.GitlabShell: - return BuildShellCommand(args.(*commandargs.Shell), config, readWriter) - case executable.AuthorizedKeysCheck: - return buildAuthorizedKeysCommand(args.(*commandargs.AuthorizedKeys), config, readWriter) - case executable.AuthorizedPrincipalsCheck: - return buildAuthorizedPrincipalsCommand(args.(*commandargs.AuthorizedPrincipals), config, readWriter) - case executable.Healthcheck: - return buildHealthcheckCommand(config, readWriter) - } - - return nil -} - -func BuildShellCommand(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch args.CommandType { - case commandargs.Discover: - return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorRecover: - return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorVerify: - return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.Hg: - return &hg.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.LfsAuthenticate: - return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.ReceivePack: - return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadPack: - return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadArchive: - return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.PersonalAccessToken: - return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} - } - - return nil -} - -func buildAuthorizedKeysCommand(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildAuthorizedPrincipalsCommand(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildHealthcheckCommand(config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &healthcheck.Command{Config: config, ReadWriter: readWriter} -} diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -1,173 +1,15 @@ package command import ( - "errors" "os" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" ) -var ( - authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} - authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} - checkExec = &executable.Executable{Name: executable.Healthcheck} - gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} - - basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} - advancedConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket", SslCertDir: "/tmp/certs"} -) - -func buildEnv(command string) sshenv.Env { - return sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: command, - } -} - -func TestNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - config *config.Config - expectedType interface{} - }{ - { - desc: "it returns a Discover command", - executable: gitlabShellExec, - env: buildEnv(""), - config: basicConfig, - expectedType: &discover.Command{}, - }, - { - desc: "it returns a TwoFactorRecover command", - executable: gitlabShellExec, - env: buildEnv("2fa_recovery_codes"), - config: basicConfig, - expectedType: &twofactorrecover.Command{}, - }, - { - desc: "it returns a TwoFactorVerify command", - executable: gitlabShellExec, - env: buildEnv("2fa_verify"), - config: basicConfig, - expectedType: &twofactorverify.Command{}, - }, - { - desc: "it returns an LfsAuthenticate command", - executable: gitlabShellExec, - env: buildEnv("git-lfs-authenticate"), - config: basicConfig, - expectedType: &lfsauthenticate.Command{}, - }, - { - desc: "it returns a ReceivePack command", - executable: gitlabShellExec, - env: buildEnv("git-receive-pack"), - config: basicConfig, - expectedType: &receivepack.Command{}, - }, - { - desc: "it returns an UploadPack command", - executable: gitlabShellExec, - env: buildEnv("git-upload-pack"), - config: basicConfig, - expectedType: &uploadpack.Command{}, - }, - { - desc: "it returns an UploadArchive command", - executable: gitlabShellExec, - env: buildEnv("git-upload-archive"), - config: basicConfig, - expectedType: &uploadarchive.Command{}, - }, - { - desc: "it returns a Healthcheck command", - executable: checkExec, - config: basicConfig, - expectedType: &healthcheck.Command{}, - }, - { - desc: "it returns a AuthorizedKeys command", - executable: authorizedKeysExec, - arguments: []string{"git", "git", "key"}, - config: basicConfig, - expectedType: &authorizedkeys.Command{}, - }, - { - desc: "it returns a AuthorizedPrincipals command", - executable: authorizedPrincipalsExec, - arguments: []string{"key", "principal"}, - config: basicConfig, - expectedType: &authorizedprincipals.Command{}, - }, - { - desc: "it returns a PersonalAccessToken command", - executable: gitlabShellExec, - env: buildEnv("personal_access_token"), - config: basicConfig, - expectedType: &personalaccesstoken.Command{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, tc.arguments, tc.env, tc.config, nil) - - require.NoError(t, err) - require.IsType(t, tc.expectedType, command) - }) - } -} - -func TestFailingNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - expectedError error - }{ - { - desc: "Parsing environment failed", - executable: gitlabShellExec, - expectedError: errors.New("Only SSH allowed"), - }, - { - desc: "Unknown command given", - executable: gitlabShellExec, - env: buildEnv("unknown"), - expectedError: disallowedcommand.Error, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, []string{}, tc.env, basicConfig, nil) - require.Nil(t, command) - require.Equal(t, tc.expectedError, err) - }) - } -} - func TestSetup(t *testing.T) { testCases := []struct { name string diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -1,32 +1,8 @@ package commandargs -import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" -) - type CommandType string type CommandArgs interface { Parse() error GetArguments() []string } - -func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (CommandArgs, error) { - var args CommandArgs = &GenericArgs{Arguments: arguments} - - switch e.Name { - case executable.GitlabShell: - args = &Shell{Arguments: arguments, Env: env} - case executable.AuthorizedKeysCheck: - args = &AuthorizedKeys{Arguments: arguments} - case executable.AuthorizedPrincipalsCheck: - args = &AuthorizedPrincipals{Arguments: arguments} - } - - if err := args.Parse(); err != nil { - return nil, err - } - - return args, nil -} diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go deleted file mode 100644 --- a/internal/command/commandargs/command_args_test.go +++ /dev/null @@ -1,192 +0,0 @@ -package commandargs - -import ( - "testing" - - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - - "github.com/stretchr/testify/require" -) - -func TestParseSuccess(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedArgs CommandArgs - }{ - { - desc: "It sets discover as the command when the command string was empty", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id only if the argument is of <key-id> format", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the username in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-jane-doe"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It parses 2fa_recovery_codes command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, - }, { - desc: "It parses git-receive-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, - }, { - desc: "It parses git-receive-pack command and a project with single quotes", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, - }, { - desc: `It parses "git receive-pack" command`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, - }, { - desc: `It parses a command followed by control characters`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, - }, { - desc: "It parses git-upload-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, - }, { - desc: "It parses git-upload-archive command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, - }, { - desc: "It parses git-lfs-authenticate command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, - }, { - desc: "It parses authorized-keys command", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"git", "git", "key"}, - expectedArgs: &AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, - }, { - desc: "It parses authorized-principals command", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal-1", "principal-2"}, - expectedArgs: &AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, - }, { - desc: "Unknown executable", - executable: &executable.Executable{Name: "unknown"}, - arguments: []string{}, - expectedArgs: &GenericArgs{Arguments: []string{}}, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := Parse(tc.executable, tc.arguments, tc.env) - - require.NoError(t, err) - require.Equal(t, tc.expectedArgs, result) - }) - } -} - -func TestParseFailure(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedError string - }{ - { - desc: "It fails if SSH connection is not set", - executable: &executable.Executable{Name: executable.GitlabShell}, - arguments: []string{}, - expectedError: "Only SSH allowed", - }, - { - desc: "It fails if SSH command is invalid", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, - arguments: []string{}, - expectedError: "Invalid SSH command", - }, - { - desc: "With not enough arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With too many arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", "key", "something-else"}, - expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With missing username for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "", "key"}, - expectedError: "# No username provided", - }, - { - desc: "With missing key for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", ""}, - expectedError: "# No key provided", - }, - { - desc: "With not enough arguments for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", - }, - { - desc: "With missing key_id for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"", "principal"}, - expectedError: "# No key_id provided", - }, - { - desc: "With blank principal for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal", ""}, - expectedError: "# An invalid principal was provided", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - _, err := Parse(tc.executable, tc.arguments, tc.env) - - require.EqualError(t, err, tc.expectedError) - }) - } -} diff --git a/internal/command/commandargs/generic_args.go b/internal/command/commandargs/generic_args.go deleted file mode 100644 --- a/internal/command/commandargs/generic_args.go +++ /dev/null @@ -1,14 +0,0 @@ -package commandargs - -type GenericArgs struct { - Arguments []string -} - -func (b *GenericArgs) Parse() error { - // Do nothing - return nil -} - -func (b *GenericArgs) GetArguments() []string { - return b.Arguments -} diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -1,8 +1,9 @@ package commandargs import ( - "errors" + "fmt" "regexp" + "strings" "github.com/mattn/go-shellwords" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" @@ -50,21 +51,16 @@ func (s *Shell) validate() error { if !s.Env.IsSSHConnection { - return errors.New("Only SSH allowed") + return fmt.Errorf("Only SSH allowed") } - if !s.isValidSSHCommand() { - return errors.New("Invalid SSH command") + if err := s.ParseCommand(s.Env.OriginalCommand); err != nil { + return fmt.Errorf("Invalid SSH command: %w", err) } return nil } -func (s *Shell) isValidSSHCommand() bool { - err := s.ParseCommand(s.Env.OriginalCommand) - return err == nil -} - func (s *Shell) parseWho() { for _, argument := range s.Arguments { if keyId := tryParseKeyId(argument); keyId != "" { @@ -79,26 +75,29 @@ } } -func tryParseKeyId(argument string) string { - matchInfo := whoKeyRegex.FindStringSubmatch(argument) +func tryParse(r *regexp.Regexp, argument string) string { + // sshd may execute the session for AuthorizedKeysCommand in multiple ways: + // 1. key-id + // 2. /path/to/shell -c key-id + args := strings.Split(argument, " ") + lastArg := args[len(args)-1] + + matchInfo := r.FindStringSubmatch(lastArg) if len(matchInfo) == 2 { // The first element is the full matched string - // The second element is the named `keyid` + // The second element is the named `keyid` or `username` return matchInfo[1] } return "" } +func tryParseKeyId(argument string) string { + return tryParse(whoKeyRegex, argument) +} + func tryParseUsername(argument string) string { - matchInfo := whoUsernameRegex.FindStringSubmatch(argument) - if len(matchInfo) == 2 { - // The first element is the full matched string - // The second element is the named `username` - return matchInfo[1] - } - - return "" + return tryParse(whoUsernameRegex, argument) } func (s *Shell) ParseCommand(commandString string) error { diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -6,6 +6,8 @@ "encoding/json" "fmt" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" @@ -58,6 +60,11 @@ payload, err := c.authenticate(ctx, operation, repo, accessResponse.UserId) if err != nil { // return nothing just like Ruby's GitlabShell#lfs_authenticate does + log.WithContextFields( + ctx, + log.Fields{"operation": operation, "repo": repo, "user_id": accessResponse.UserId}, + ).WithError(err).Debug("lfsauthenticate: execute: LFS authentication failed") + return nil } diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -70,7 +70,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) @@ -94,7 +94,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -8,6 +8,8 @@ "strings" "time" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -38,6 +40,10 @@ return err } + log.WithContextFields(ctx, log.Fields{ + "token_args": c.TokenArgs, + }).Info("personalaccesstoken: execute: requesting token") + response, err := c.getPersonalAccessToken(ctx) if err != nil { return err diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -26,7 +26,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *accessverifier.Request diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -4,19 +4,17 @@ "bytes" "context" "errors" - - "gitlab.com/gitlab-org/gitlab-shell/client" - "io" "net/http" + "gitlab.com/gitlab-org/labkit/log" + + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" - - "gitlab.com/gitlab-org/labkit/log" ) type Request struct { @@ -59,12 +57,12 @@ request.Data.UserId = response.Who for _, endpoint := range data.ApiEndpoints { - fields := log.Fields{ + ctxlog := log.WithContextFields(ctx, log.Fields{ "primary_repo": data.PrimaryRepo, "endpoint": endpoint, - } + }) - log.WithFields(fields).Info("Performing custom action") + ctxlog.Info("customaction: processApiEndpoints: Performing custom action") response, err := c.performRequest(ctx, client, endpoint, request) if err != nil { @@ -90,6 +88,10 @@ } else { output = c.readFromStdinNoEOF() } + ctxlog.WithFields(log.Fields{ + "eof_sent": c.EOFSent, + "stdin_bytes": len(output), + }).Debug("customaction: processApiEndpoints: stdin buffered") request.Output = output } diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -23,7 +23,7 @@ { Path: "/geo/proxy/info_refs_receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -39,7 +39,7 @@ { Path: "/geo/proxy/receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -92,7 +92,7 @@ { Path: "/geo/proxy/info_refs_upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -108,7 +108,7 @@ { Path: "/geo/proxy/upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -6,6 +6,8 @@ "io" "strings" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -21,9 +23,14 @@ } func (c *Command) Execute(ctx context.Context) error { + ctxlog := log.ContextLogger(ctx) + ctxlog.Debug("twofactorrecover: execute: Waiting for user input") + if c.canContinue() { + ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { + ctxlog.Debug("twofactorrecover: execute: User chose not to continue") fmt.Fprintln(c.ReadWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.") } @@ -43,9 +50,12 @@ } func (c *Command) displayRecoveryCodes(ctx context.Context) { + ctxlog := log.ContextLogger(ctx) + codes, err := c.getRecoveryCodes(ctx) if err == nil { + ctxlog.Debug("twofactorrecover: displayRecoveryCodes: recovery codes successfully generated") messageWithCodes := "\nYour two-factor authentication recovery codes are:\n\n" + strings.Join(codes, "\n") + @@ -54,6 +64,7 @@ "a new device so you do not lose access to your account again.\n" fmt.Fprint(c.ReadWriter.Out, messageWithCodes) } else { + ctxlog.WithError(err).Error("twofactorrecover: displayRecoveryCodes: failed to generate recovery codes") fmt.Fprintf(c.ReadWriter.Out, "\nAn error occurred while trying to generate new recovery codes.\n%v\n", err) } } diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -5,6 +5,8 @@ "fmt" "io" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -18,11 +20,18 @@ } func (c *Command) Execute(ctx context.Context) error { - err := c.verifyOTP(ctx, c.getOTP()) + ctxlog := log.ContextLogger(ctx) + ctxlog.Info("twofactorverify: execute: waiting for user input") + otp := c.getOTP() + + ctxlog.Info("twofactorverify: execute: verifying entered OTP") + err := c.verifyOTP(ctx, otp) if err != nil { + ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } + ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") return nil } diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -22,7 +22,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -2,7 +2,6 @@ import ( "errors" - "io/ioutil" "net/url" "os" "path" @@ -73,6 +72,7 @@ RootDir string LogFile string `yaml:"log_file,omitempty"` LogFormat string `yaml:"log_format,omitempty"` + LogLevel string `yaml:"log_level,omitempty"` GitlabUrl string `yaml:"gitlab_url"` GitlabRelativeURLRoot string `yaml:"gitlab_relative_url_root"` GitlabTracing string `yaml:"gitlab_tracing"` @@ -94,6 +94,7 @@ DefaultConfig = Config{ LogFile: "gitlab-shell.log", LogFormat: "json", + LogLevel: "info", Server: DefaultServerConfig, User: "git", } @@ -174,7 +175,7 @@ *cfg = DefaultConfig cfg.RootDir = filepath.Dir(path) - configBytes, err := ioutil.ReadFile(path) + configBytes, err := os.ReadFile(path) if err != nil { return nil, err } @@ -218,7 +219,7 @@ cfg.SecretFilePath = path.Join(cfg.RootDir, cfg.SecretFilePath) } - secretFileContent, err := ioutil.ReadFile(cfg.SecretFilePath) + secretFileContent, err := os.ReadFile(cfg.SecretFilePath) if err != nil { return err } diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -32,7 +32,7 @@ client, err := config.HttpClient() require.NoError(t, err) - _, err = client.Get("http://host.com/path") + _, err = client.Get(url) require.NoError(t, err) ms, err := prometheus.DefaultGatherer.Gather() diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -3,8 +3,9 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" + "os" "path" "testing" @@ -165,14 +166,14 @@ func setup(t *testing.T, allowedPayload string) *Client { testhelper.PrepareTestRootDir(t) - body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) var bodyWithPayload []byte if allowedPayload != "" { allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = ioutil.ReadFile(allowedWithPayloadPath) + bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) require.NoError(t, err) } @@ -180,7 +181,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *Request diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -3,11 +3,12 @@ import ( "context" "encoding/json" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" - "io/ioutil" + "io" "net/http" "testing" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" @@ -20,7 +21,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -9,7 +9,9 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" @@ -43,12 +45,25 @@ func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { conn, err := getConn(ctx, gc) if err != nil { + log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") + return err } defer conn.Close() childCtx := withOutgoingMetadata(ctx, gc.Features) - _, err = handler(childCtx, conn) + ctxlog := log.ContextLogger(childCtx) + exitStatus, err := handler(childCtx, conn) + + if err != nil { + if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { + ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") + + return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + } + + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") + } return err } @@ -110,7 +125,7 @@ if serviceName == "" { serviceName = "gitlab-shell-unknown" - log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -7,7 +7,9 @@ "github.com/stretchr/testify/require" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -45,6 +47,18 @@ require.EqualError(t, err, "no gitaly_address given") } +func TestUnavailableGitalyErr(t *testing.T) { + cmd := GitalyCommand{ + Config: &config.Config{}, + Address: "tcp://localhost:9999", + } + + expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) + + require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") +} + func TestRunGitalyCommandMetadata(t *testing.T) { tests := []struct { name string diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -3,7 +3,6 @@ import ( "fmt" "io" - "io/ioutil" "log/syslog" "os" "time" @@ -36,6 +35,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), + log.WithLogLevel(cfg.LogLevel), } } @@ -43,7 +43,7 @@ // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. func Configure(cfg *config.Config) io.Closer { - var closer io.Closer = ioutil.NopCloser(nil) + var closer io.Closer = io.NopCloser(nil) err := fmt.Errorf("No logfile specified") if cfg.LogFile != "" { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -1,10 +1,8 @@ package logger import ( - "io/ioutil" "os" "regexp" - "strings" "testing" "github.com/stretchr/testify/require" @@ -14,7 +12,7 @@ ) func TestConfigure(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() @@ -27,16 +25,41 @@ defer closer.Close() log.Info("this is a test") + log.WithFields(log.Fields{}).Debug("debug log message") tmpFile.Close() - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) + require.NoError(t, err) + require.Contains(t, string(data), `msg":"this is a test"`) + require.NotContains(t, string(data), `msg:":"debug log message"`) +} + +func TestConfigureWithDebugLogLevel(t *testing.T) { + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) - require.True(t, strings.Contains(string(data), `msg":"this is a test"`)) + defer tmpFile.Close() + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + LogLevel: "debug", + } + + closer := Configure(&config) + defer closer.Close() + + log.WithFields(log.Fields{}).Debug("debug log message") + + tmpFile.Close() + + data, err := os.ReadFile(tmpFile.Name()) + require.NoError(t, err) + require.Contains(t, string(data), `msg":"debug log message"`) } func TestConfigureWithPermissionError(t *testing.T) { - tmpPath, err := ioutil.TempDir(os.TempDir(), "logtest-") + tmpPath, err := os.MkdirTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer os.RemoveAll(tmpPath) @@ -52,7 +75,7 @@ } func TestLogInUTC(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() defer os.Remove(tmpFile.Name()) @@ -67,7 +90,7 @@ log.Info("this is a test") - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -29,21 +29,26 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { + ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { + ctxlog.Info("connection: handle: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { + ctxlog.Info("connection: handle: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - log.WithError(err).Info("could not accept channel") + ctxlog.WithError(err).Error("connection: handle: accepting channel failed") c.concurrentSessions.Release(1) continue } @@ -54,11 +59,12 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) + ctxlog.WithField("recovered_error", err).Warn("panic handling session") } }() handler(ctx, channel, requests) + ctxlog.Info("connection: handle: done") }() } } diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config.go @@ -0,0 +1,94 @@ +package sshd + +import ( + "context" + "encoding/base64" + "fmt" + "os" + "strconv" + "time" + + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + + "gitlab.com/gitlab-org/labkit/log" +) + +type serverConfig struct { + cfg *config.Config + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to parse host key") + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") + } + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil +} + +func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { + if user != s.cfg.User { + return nil, fmt.Errorf("unknown user") + } + if key.Type() == ssh.KeyAlgoDSA { + return nil, fmt.Errorf("DSA is prohibited") + } + + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + if err != nil { + return nil, err + } + + return res, nil +} + +func (s *serverConfig) get(ctx context.Context) *ssh.ServerConfig { + sshCfg := &ssh.ServerConfig{ + PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { + res, err := s.getAuthKey(ctx, conn.User(), key) + if err != nil { + return nil, err + } + + return &ssh.Permissions{ + // Record the public key used for authentication. + Extensions: map[string]string{ + "key-id": strconv.FormatInt(res.Id, 10), + }, + }, nil + }, + } + + for _, key := range s.hostKeys { + sshCfg.AddHostKey(key) + } + + return sshCfg +} diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config_test.go @@ -0,0 +1,105 @@ +package sshd + +import ( + "context" + "crypto/dsa" + "crypto/rand" + "crypto/rsa" + "path" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +func TestNewServerConfigWithoutHosts(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "http://localhost"}) + + require.Error(t, err) + require.Equal(t, "No host keys could be loaded, aborting", err.Error()) +} + +func TestFailedAuthorizedKeysClient(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) + + require.Error(t, err) + require.Equal(t, "failed to initialize GitLab client: Error creating http client: unknown GitLab URL prefix", err.Error()) +} + +func TestFailedGetAuthKey(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + testCases := []struct { + desc string + user string + key ssh.PublicKey + expectedError string + }{ + { + desc: "wrong user", + user: "wrong-user", + key: rsaPublicKey(t), + expectedError: "unknown user", + }, { + desc: "prohibited dsa key", + user: "user", + key: dsaPublicKey(t), + expectedError: "DSA is prohibited", + }, { + desc: "API error", + user: "user", + key: rsaPublicKey(t), + expectedError: "Internal API unreachable", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err = cfg.getAuthKey(context.Background(), tc.user, tc.key) + require.Error(t, err) + require.Equal(t, tc.expectedError, err.Error()) + }) + } +} + +func rsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} + +func dsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey := new(dsa.PrivateKey) + params := new(dsa.Parameters) + require.NoError(t, dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160)) + + privateKey.PublicKey.Parameters = *params + require.NoError(t, dsa.GenerateKey(privateKey, rand.Reader)) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -2,13 +2,16 @@ import ( "context" + "errors" "fmt" + "reflect" + "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -39,16 +42,27 @@ } func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { + ctxlog := log.ContextLogger(ctx) + + ctxlog.Debug("session: handle: entering request loop") + for req := range requests { + sessionLog := ctxlog.WithFields(log.Fields{ + "bytesize": len(req.Payload), + "type": req.Type, + "want_reply": req.WantReply, + }) + sessionLog.Debug("session: handle: request received") + var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(req) + shouldContinue = s.handleEnv(ctx, req) case "exec": shouldContinue = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -57,18 +71,23 @@ } } + sessionLog.WithField("should_continue", shouldContinue).Debug("session: handle: request processed") + if !shouldContinue { s.channel.Close() break } } + + ctxlog.Debug("session: handle: exiting request loop") } -func (s *session) handleEnv(req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { + log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") return false } @@ -84,6 +103,10 @@ req.Reply(accepted, []byte{}) } + log.WithContextFields( + ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, + ).Debug("session: handleEnv: processed") + return true } @@ -95,7 +118,8 @@ s.execCmd = execRequest.Command - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) + return false } @@ -104,19 +128,11 @@ req.Reply(true, []byte{}) } - args := &commandargs.Shell{ - GitlabKeyId: s.gitlabKeyId, - Env: sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: s.execCmd, - GitProtocolVersion: s.gitProtocolVersion, - RemoteAddr: s.remoteAddr, - }, - } - - if err := args.ParseCommand(s.execCmd); err != nil { - s.toStderr("Failed to parse command: %v\n", err.Error()) - return 128 + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: s.execCmd, + GitProtocolVersion: s.gitProtocolVersion, + RemoteAddr: s.remoteAddr, } rw := &readwriter.ReadWriter{ @@ -125,25 +141,37 @@ ErrOut: s.channel.Stderr(), } - cmd := command.BuildShellCommand(args, s.cfg, rw) - if cmd == nil { - s.toStderr("Unknown command: %v\n", args.CommandType) + cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) + if err != nil { + if !errors.Is(err, disallowedcommand.Error) { + s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) + } + s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) return 128 } + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + if err := cmd.Execute(ctx); err != nil { - s.toStderr("remote: ERROR: %v\n", err.Error()) + s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) return 1 } + ctxlog.Info("session: handleShell: command executed successfully") + return 0 } -func (s *session) toStderr(format string, args ...interface{}) { - fmt.Fprintf(s.channel.Stderr(), format, args...) +func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { + out := fmt.Sprintf(format, args...) + log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") + fmt.Fprint(s.channel.Stderr(), out) } -func (s *session) exit(status uint32) { +func (s *session) exit(ctx context.Context, status uint32) { + log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} s.channel.CloseWrite() diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/session_test.go @@ -0,0 +1,189 @@ +package sshd + +import ( + "bytes" + "context" + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +type fakeChannel struct { + stdErr io.ReadWriter + sentRequestName string + sentRequestPayload []byte +} + +func (f *fakeChannel) Read(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Write(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Close() error { + return nil +} + +func (f *fakeChannel) CloseWrite() error { + return nil +} + +func (f *fakeChannel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { + f.sentRequestName = name + f.sentRequestPayload = payload + + return true, nil +} + +func (f *fakeChannel) Stderr() io.ReadWriter { + return f.stdErr +} + +var requests = []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"id": 1000, "name": "Test User", "username": "test-user"}`)) + }, + }, +} + +func TestHandleEnv(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedProtocolVersion string + expectedResult bool + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedProtocolVersion: "1", + expectedResult: false, + }, { + desc: "valid payload", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedProtocolVersion: "2", + expectedResult: true, + }, { + desc: "valid payload with forbidden env var", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedProtocolVersion: "1", + expectedResult: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + s := &session{gitProtocolVersion: "1"} + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) + require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + }) + } +} + +func TestHandleExec(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedExecCmd string + sentRequestName string + sentRequestPayload []byte + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedExecCmd: "", + sentRequestName: "", + }, { + desc: "valid payload", + payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedExecCmd: "discover", + sentRequestName: "exit-status", + sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + f := &fakeChannel{stdErr: out} + s := &session{ + gitlabKeyId: "root", + channel: f, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, false, s.handleExec(context.Background(), r)) + require.Equal(t, tc.sentRequestName, f.sentRequestName) + require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + }) + } +} + +func TestHandleShell(t *testing.T) { + testCases := []struct { + desc string + cmd string + errMsg string + gitlabKeyId string + expectedExitCode uint32 + }{ + { + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedExitCode: 1, + }, { + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedExitCode: 0, + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + s := &session{ + gitlabKeyId: tc.gitlabKeyId, + execCmd: tc.cmd, + channel: &fakeChannel{stdErr: out}, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{} + + require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + require.Equal(t, tc.errMsg, out.String()) + }) + } +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -2,13 +2,9 @@ import ( "context" - "encoding/base64" - "errors" "fmt" - "io/ioutil" "net" "net/http" - "strconv" "sync" "time" @@ -16,7 +12,6 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -35,44 +30,24 @@ type Server struct { Config *config.Config - status status - statusMu sync.Mutex - wg sync.WaitGroup - listener net.Listener - hostKeys []ssh.Signer - authorizedKeysClient *authorizedkeys.Client + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + serverConfig *serverConfig } func NewServer(cfg *config.Config) (*Server, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + serverConfig, err := newServerConfig(cfg) if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + return nil, err } - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) - if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) - continue - } - - hostKeys = append(hostKeys, key) - } - if len(hostKeys) == 0 { - return nil, fmt.Errorf("No host keys could be loaded, aborting") - } - - return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + return &Server{Config: cfg, serverConfig: serverConfig}, nil } func (s *Server) ListenAndServe(ctx context.Context) error { - if err := s.listen(); err != nil { + if err := s.listen(ctx); err != nil { return err } defer s.listener.Close() @@ -110,7 +85,7 @@ return mux } -func (s *Server) listen() error { +func (s *Server) listen(ctx context.Context) error { sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) @@ -119,13 +94,14 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, + Policy: unconditionalRequirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } - log.Info("Proxy protocol is enabled") + log.ContextLogger(ctx).Info("Proxy protocol is enabled") } - log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") + log.WithContextFields(ctx, log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") s.listener = sshListener @@ -142,7 +118,7 @@ break } - log.WithError(err).Warn("Failed to accept connection") + log.ContextLogger(ctx).WithError(err).Warn("Failed to accept connection") continue } @@ -168,57 +144,29 @@ return s.status } -func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { - sshCfg := &ssh.ServerConfig{ - PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != s.Config.User { - return nil, errors.New("unknown user") - } - if key.Type() == ssh.KeyAlgoDSA { - return nil, errors.New("DSA is prohibited") - } - ctx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) - if err != nil { - return nil, err - } - - return &ssh.Permissions{ - // Record the public key used for authentication. - Extensions: map[string]string{ - "key-id": strconv.FormatInt(res.Id, 10), - }, - }, nil - }, - } - - for _, key := range s.hostKeys { - sshCfg.AddHostKey(key) - } - - return sshCfg -} - func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() defer nconn.Close() + ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) + defer cancel() + + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) + ctxlog.Warn("panic handling session") } }() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) - defer cancel() + ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - log.WithError(err).Info("Failed to initialize SSH connection") + ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return } @@ -235,4 +183,10 @@ session.handle(ctx, requests) }) + + ctxlog.Info("server: handleConn: done") } + +func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { + return proxyproto.REQUIRE, nil +} diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,9 +3,9 @@ import ( "context" "fmt" - "io/ioutil" "net/http" "net/http/httptest" + "os" "path" "testing" "time" @@ -47,6 +47,18 @@ verifyStatus(t, s, StatusClosed) } +func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { + setupServerWithProxyProtocolEnabled(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + if client != nil { + client.Close() + } + + require.Error(t, err, "Expected plain SSH request to be failed") + require.Regexp(t, "ssh: handshake failed", err.Error()) +} + func TestCorrelationId(t *testing.T) { setupServer(t) @@ -104,9 +116,39 @@ require.Equal(t, 200, r.Result().StatusCode) } +func TestInvalidClientConfig(t *testing.T) { + setupServer(t) + + cfg := clientConfig(t) + cfg.User = "unknown" + _, err := ssh.Dial("tcp", serverUrl, cfg) + require.Error(t, err) +} + +func TestInvalidServerConfig(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.ServerConfig{Listen: "invalid"}}} + err := s.ListenAndServe(context.Background()) + + require.Error(t, err) + require.Equal(t, "failed to listen for connection: listen tcp: address invalid: missing port in address", err.Error()) + require.Nil(t, s.Shutdown()) +} + func setupServer(t *testing.T) *Server { t.Helper() + return setupServerWithConfig(t, nil) +} + +func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { + t.Helper() + + return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) +} + +func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -130,13 +172,20 @@ testhelper.PrepareTestRootDir(t) url := testserver.StartSocketHttpServer(t, requests) - srvCfg := config.ServerConfig{ - Listen: serverUrl, - ConcurrentSessionsLimit: 1, - HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + + if cfg == nil { + cfg = &config.Config{} } - s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + // All things that don't need to be configurable in tests yet + cfg.GitlabUrl = url + cfg.RootDir = "/tmp" + cfg.User = user + cfg.Server.Listen = serverUrl + cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} + + s, err := NewServer(cfg) require.NoError(t, err) go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() @@ -148,11 +197,11 @@ } func clientConfig(t *testing.T) *ssh.ClientConfig { - keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + keyRaw, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) require.NoError(t, err) - key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + key, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) require.NoError(t, err) signer, err := ssh.ParsePrivateKey(key) require.NoError(t, err) @@ -177,14 +226,5 @@ } func verifyStatus(t *testing.T, s *Server, st status) { - for i := 5; i < 500; i += 50 { - if s.getStatus() == st { - break - } - - // Sleep incrementally ~2s in total - time.Sleep(time.Duration(i) * time.Millisecond) - } - - require.Equal(t, st, s.getStatus()) + require.Eventually(t, func() bool { return s.getStatus() == st }, 2*time.Second, time.Millisecond) } diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -2,7 +2,6 @@ import ( "fmt" - "io/ioutil" "os" "path" "runtime" @@ -13,7 +12,7 @@ ) var ( - TestRoot, _ = ioutil.TempDir("", "test-gitlab-shell") + TestRoot, _ = os.MkdirTemp("", "test-gitlab-shell") ) func TempEnv(env map[string]string) func() { # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1640273261 -3600 # Thu Dec 23 16:27:41 2021 +0100 # Branch heptapod # Node ID dd834f017fa24a407df330ffe8b37fae0d65c2a8 # Parent 500ed5c3c7f5402868765b8f4e8794a84df9b0e4 Heptapod CI: updated Gitaly service version In 6e4e76df7ef9, upstream stops accidentally using the `latest` version, which has stayed at 13.3, but GitLab Shell acceptance tests don't pass with `master` version of the Gitaly image (actual latest development version). They do with the one that matches the GitLab version for GitLab Shell 13.22.1 diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -31,7 +31,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.5.2 # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1640272345 -3600 # Thu Dec 23 16:12:25 2021 +0100 # Branch heptapod # Node ID 7f259a883e58759e4734cb0f38449379bb36aca6 # Parent dd834f017fa24a407df330ffe8b37fae0d65c2a8 Updated Heptapod version files for release Part of heptapod#596 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,6 +9,10 @@ The corresponding tag is heptapod-x.y.z +## 13.22.0 + +- Jump to upstream GitLab Shell v13.22.1 (GitLab 14.5 series) + ## 13.21.0 - Jump to upstream GitLab Shell v13.21.1 (GitLab 14.4 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.21.0 +13.22.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1640540036 -3600 # Sun Dec 26 18:33:56 2021 +0100 # Branch heptapod # Node ID c13639d6d9742fc361e7df2acee2661f37f16cd8 # Parent 7f259a883e58759e4734cb0f38449379bb36aca6 Added tag heptapod-13.22.0 for changeset 7f259a883e58 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -36,3 +36,4 @@ b84ce63181d5c0d07585be867dbe957eb6d35348 heptapod-13.19.1 f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 +7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1642959359 -3600 # Sun Jan 23 18:35:59 2022 +0100 # Branch heptapod-stable # Node ID eed45a48a4bd15aa1f57138e286080b4aaddec37 # Parent 7a9511f85a6a3aca688269a37504d371068a2961 # Parent c13639d6d9742fc361e7df2acee2661f37f16cd8 heptapod#612: Making Heptapod 0.28 the new stable diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -45,7 +45,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:master # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -36,3 +36,4 @@ b84ce63181d5c0d07585be867dbe957eb6d35348 heptapod-13.19.1 f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 +7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.2 +2.7.4 diff --git a/.tool-versions b/.tool-versions new file mode 100644 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +ruby 2.7.4 +golang 1.16.10 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,40 @@ +v13.22.1 + +- Remove SSL_CERT_DIR logging !546 + +v13.22.0 + +- Relax key and username matching for sshd !540 +- Add logging to handler/exec.go and config/config.go !539 +- Improve logging for non-git commands !538 +- Update to Go v1.16.9 !537 +- Reject non-proxied connections when proxy protocol is enabled !536 +- Log command invocation !535 +- Fix logging channel type !534 +- Resolve an error-swallowing issue !533 +- Add more logging to gitlab-sshd !531 +- Respect log-level configuration again !530 +- Improve err message given when Gitaly unavailable !526 +- makefile: properly escape '$' in VERSION_STRING !525 +- Add context fields to logging !524 +- Extract server config related code out of sshd.go !523 +- Add TestInvalidClientConfig and TestNewServerWithoutHosts for sshd.go !518 +- Update Ruby version to 2.7.4 and add Go version 1.16.8 for tooling !517 + v13.21.1 - Only validate SSL cert file exists if a value is supplied !527 v13.21.0 +- Switch to labkit for logging system setup !504 +- Remove some unreliable tests !503 +- Make gofmt check fail if there are any matching files !500 +- Update go-proxyproto to v0.6.0 !499 +- Switch to labkit/log for logging functionality !498 +- Unit tests for internal/sshd/connection.go !497 +- Prometheus metrics for HTTP requests !496 +- Refactor testhelper.PrepareTestRootDir using t.Cleanup !493 - Change default logging format to JSON !476 - Shutdown sshd gracefully !484 - Provide liveness and readiness probes !494 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,6 +9,10 @@ The corresponding tag is heptapod-x.y.z +## 13.22.0 + +- Jump to upstream GitLab Shell v13.22.1 (GitLab 14.5 series) + ## 13.21.0 - Jump to upstream GitLab Shell v13.21.1 (GitLab 14.4 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.21.0 +13.22.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -2,12 +2,13 @@ GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) -BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" PREFIX ?= /usr/local +build: bin/gitlab-shell + validate: verify test verify: verify_golang @@ -40,7 +41,6 @@ _script_install: bin/install -build: bin/gitlab-shell compile: bin/gitlab-shell bin/gitlab-shell: $(GO_SOURCES) GOBIN="$(CURDIR)/bin" go install $(GOBUILD_FLAGS) ./cmd/... diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -102,6 +102,21 @@ Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. +## Logging Guidelines + +In general, it should be possible to determine the structure, but not content, +of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some +guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging functionality +- **Always** include a correlation ID +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log success cases as well as error cases +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. + ## Releasing See [PROCESS.md](./PROCESS.md) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.21.1 +13.22.1 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -5,7 +5,7 @@ "encoding/base64" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "path" "strings" @@ -83,7 +83,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) @@ -99,7 +99,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) }) @@ -155,7 +155,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -170,7 +170,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) header, err := base64.StdEncoding.DecodeString(string(responseBody)) @@ -194,7 +194,7 @@ Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, http.MethodPost, r.Method) - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -6,7 +6,6 @@ "crypto/x509" "errors" "fmt" - "io/ioutil" "net" "net/http" "os" @@ -153,7 +152,7 @@ } if hcc.caPath != "" { - fis, _ := ioutil.ReadDir(hcc.caPath) + fis, _ := os.ReadDir(hcc.caPath) for _, fi := range fis { if fi.IsDir() { continue @@ -174,7 +173,6 @@ return nil, "", err } tlsConfig.Certificates = []tls.Certificate{cert} - tlsConfig.BuildNameToCertificate() } transport := &http.Transport{ @@ -185,7 +183,7 @@ } func addCertToPool(certPool *x509.CertPool, fileName string) { - cert, err := ioutil.ReadFile(fileName) + cert, err := os.ReadFile(fileName) if err == nil { certPool.AppendCertsFromPEM(cert) } diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -4,7 +4,7 @@ "context" "encoding/base64" "fmt" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -64,7 +64,7 @@ defer response.Body.Close() require.NotNil(t, response) - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) headerParts := strings.Split(string(responseBody), " ") diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -3,7 +3,7 @@ import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "path" "testing" @@ -57,7 +57,7 @@ defer response.Body.Close() - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) require.NoError(t, err) require.Equal(t, string(responseBody), "Hello") }) diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,7 +1,6 @@ package testserver import ( - "io/ioutil" "net" "os" "path" @@ -61,7 +60,7 @@ func StartGitalyServer(t *testing.T) (string, *TestGitalyServer) { t.Helper() - tempDir, _ := ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ := os.MkdirTemp("", "gitlab-shell-test-api") gitalySocketPath := path.Join(tempDir, "gitaly.sock") t.Cleanup(func() { os.RemoveAll(tempDir) }) diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -3,7 +3,7 @@ import ( "crypto/tls" "crypto/x509" - "io/ioutil" + "io" "log" "net" "net/http" @@ -18,7 +18,7 @@ ) var ( - tempDir, _ = ioutil.TempDir("", "gitlab-shell-test-api") + tempDir, _ = os.MkdirTemp("", "gitlab-shell-test-api") testSocket = path.Join(tempDir, "internal.sock") ) @@ -41,7 +41,7 @@ Handler: buildHandler(handlers), // We'll put this server through some nasty stuff we don't want // in our test output - ErrorLog: log.New(ioutil.Discard, "", 0), + ErrorLog: log.New(io.Discard, "", 0), } go server.Serve(socketListener) @@ -73,10 +73,9 @@ Certificates: []tls.Certificate{cer}, MinVersion: tls.VersionTLS12, } - server.TLS.BuildNameToCertificate() if clientCAPath != "" { - caCert, err := ioutil.ReadFile(clientCAPath) + caCert, err := os.ReadFile(clientCAPath) require.NoError(t, err) caCertPool := x509.NewCertPool() diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command.go @@ -0,0 +1,21 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + if cmd := build(config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func build(config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &healthcheck.Command{Config: config, ReadWriter: readWriter} +} diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/check/command/command_test.go @@ -0,0 +1,42 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Healthcheck command", + config: basicConfig, + expectedType: &healthcheck.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -34,7 +34,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := checkCmd.New(config, readWriter) if err != nil { fmt.Fprintf(readWriter.ErrOut, "%v\n", err) os.Exit(1) diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -0,0 +1,37 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string) (*commandargs.AuthorizedKeys, error) { + args := &commandargs.AuthorizedKeys{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -0,0 +1,120 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedKeys command", + executable: authorizedKeysExec, + arguments: []string{"git", "git", "key"}, + config: basicConfig, + expectedType: &authorizedkeys.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := command.New(tc.arguments, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-keys command", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"git", "git", "key"}, + expectedArgs: &commandargs.AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := command.Parse(tc.arguments) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With too many arguments for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", "key", "something-else"}, + expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", + }, + { + desc: "With missing username for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "", "key"}, + expectedError: "# No username provided", + }, + { + desc: "With missing key for the AuthorizedKeysCheck", + executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, + arguments: []string{"user", "user", ""}, + expectedError: "# No key provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := command.Parse(tc.arguments) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -35,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -0,0 +1,37 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments) + if err != nil { + return nil, err + } + + if cmd := build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string) (*commandargs.AuthorizedPrincipals, error) { + args := &commandargs.AuthorizedPrincipals{Arguments: arguments} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func build(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} +} diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -0,0 +1,114 @@ +package command_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a AuthorizedPrincipals command", + executable: authorizedPrincipalsExec, + arguments: []string{"key", "principal"}, + config: basicConfig, + expectedType: &authorizedprincipals.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.arguments, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It parses authorized-principals command", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal-1", "principal-2"}, + expectedArgs: &commandargs.AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.arguments) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "With not enough arguments for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key"}, + expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", + }, + { + desc: "With missing key_id for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"", "principal"}, + expectedError: "# No key_id provided", + }, + { + desc: "With blank principal for the AuthorizedPrincipalsCheck", + executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, + arguments: []string{"key", "principal", ""}, + expectedError: "# An invalid principal was provided", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.arguments) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/executable" "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) func main() { @@ -35,7 +35,7 @@ logCloser := logger.Configure(config) defer logCloser.Close() - cmd, err := command.New(executable, os.Args[1:], sshenv.Env{}, config, readWriter) + cmd, err := cmd.New(os.Args[1:], config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command.go @@ -0,0 +1,81 @@ +package command + +import ( + "gitlab.com/gitlab-org/gitlab-shell/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/hg" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(arguments, env) + if err != nil { + return nil, err + } + + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func NewWithKey(gitlabKeyId string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { + args, err := Parse(nil, env) + if err != nil { + return nil, err + } + + args.GitlabKeyId = gitlabKeyId + if cmd := Build(args, config, readWriter); cmd != nil { + return cmd, nil + } + + return nil, disallowedcommand.Error +} + +func Parse(arguments []string, env sshenv.Env) (*commandargs.Shell, error) { + args := &commandargs.Shell{Arguments: arguments, Env: env} + + if err := args.Parse(); err != nil { + return nil, err + } + + return args, nil +} + +func Build(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) command.Command { + switch args.CommandType { + case commandargs.Discover: + return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorRecover: + return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.Hg: + return &hg.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.TwoFactorVerify: + return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.LfsAuthenticate: + return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.ReceivePack: + return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadPack: + return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.UploadArchive: + return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} + case commandargs.PersonalAccessToken: + return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} + } + + return nil +} diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go new file mode 100644 --- /dev/null +++ b/cmd/gitlab-shell/command/command_test.go @@ -0,0 +1,302 @@ +package command_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" +) + +var ( + gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} + basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} +) + +func TestNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + config *config.Config + expectedType interface{} + }{ + { + desc: "it returns a Discover command", + executable: gitlabShellExec, + env: buildEnv(""), + config: basicConfig, + expectedType: &discover.Command{}, + }, + { + desc: "it returns a TwoFactorRecover command", + executable: gitlabShellExec, + env: buildEnv("2fa_recovery_codes"), + config: basicConfig, + expectedType: &twofactorrecover.Command{}, + }, + { + desc: "it returns a TwoFactorVerify command", + executable: gitlabShellExec, + env: buildEnv("2fa_verify"), + config: basicConfig, + expectedType: &twofactorverify.Command{}, + }, + { + desc: "it returns an LfsAuthenticate command", + executable: gitlabShellExec, + env: buildEnv("git-lfs-authenticate"), + config: basicConfig, + expectedType: &lfsauthenticate.Command{}, + }, + { + desc: "it returns a ReceivePack command", + executable: gitlabShellExec, + env: buildEnv("git-receive-pack"), + config: basicConfig, + expectedType: &receivepack.Command{}, + }, + { + desc: "it returns an UploadPack command", + executable: gitlabShellExec, + env: buildEnv("git-upload-pack"), + config: basicConfig, + expectedType: &uploadpack.Command{}, + }, + { + desc: "it returns an UploadArchive command", + executable: gitlabShellExec, + env: buildEnv("git-upload-archive"), + config: basicConfig, + expectedType: &uploadarchive.Command{}, + }, + { + desc: "it returns a PersonalAccessToken command", + executable: gitlabShellExec, + env: buildEnv("personal_access_token"), + config: basicConfig, + expectedType: &personalaccesstoken.Command{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New(tc.arguments, tc.env, tc.config, nil) + + require.NoError(t, err) + require.IsType(t, tc.expectedType, command) + }) + } +} + +func TestFailingNew(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + expectedError error + }{ + { + desc: "Parsing environment failed", + executable: gitlabShellExec, + expectedError: errors.New("Only SSH allowed"), + }, + { + desc: "Unknown command given", + executable: gitlabShellExec, + env: buildEnv("unknown"), + expectedError: disallowedcommand.Error, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + command, err := cmd.New([]string{}, tc.env, basicConfig, nil) + require.Nil(t, command) + require.Equal(t, tc.expectedError, err) + }) + } +} + +func buildEnv(command string) sshenv.Env { + return sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: command, + } +} + +func TestParseSuccess(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedArgs commandargs.CommandArgs + expectError bool + }{ + { + desc: "It sets discover as the command when the command string was empty", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: commandargs.Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id if the key is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username if the username is listed as the last argument", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the key id only if the last argument is of <key-id> format", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "gitlab-shell -c username-key-123"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "gitlab-shell -c username-key-123"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It finds the username in any passed arguments", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, + arguments: []string{"hello", "username-jane-doe"}, + expectedArgs: &commandargs.Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: commandargs.Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, + }, + { + desc: "It parses 2fa_recovery_codes command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: commandargs.TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, + }, + { + desc: "It parses git-receive-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, + }, + { + desc: "It parses git-receive-pack command and a project with single quotes", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, + }, + { + desc: `It parses "git receive-pack" command`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, + }, + { + desc: `It parses a command followed by control characters`, + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: commandargs.ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, + }, + { + desc: "It parses git-upload-pack command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: commandargs.UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, + }, + { + desc: "It parses git-upload-archive command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: commandargs.UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, + }, + { + desc: "It parses git-lfs-authenticate command", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, + arguments: []string{}, + expectedArgs: &commandargs.Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: commandargs.LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := cmd.Parse(tc.arguments, tc.env) + + if !tc.expectError { + require.NoError(t, err) + require.Equal(t, tc.expectedArgs, result) + } else { + require.Error(t, err) + } + }) + } +} + +func TestParseFailure(t *testing.T) { + testCases := []struct { + desc string + executable *executable.Executable + env sshenv.Env + arguments []string + expectedError string + }{ + { + desc: "It fails if SSH connection is not set", + executable: &executable.Executable{Name: executable.GitlabShell}, + arguments: []string{}, + expectedError: "Only SSH allowed", + }, + { + desc: "It fails if SSH command is invalid", + executable: &executable.Executable{Name: executable.GitlabShell}, + env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, + arguments: []string{}, + expectedError: "Invalid SSH command: invalid command line string", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err := cmd.Parse(tc.arguments, tc.env) + + require.EqualError(t, err, tc.expectedError) + }) + } +} diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -3,7 +3,11 @@ import ( "fmt" "os" + "reflect" + "gitlab.com/gitlab-org/labkit/log" + + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -50,7 +54,7 @@ defer logCloser.Close() env := sshenv.NewFromEnv() - cmd, err := command.New(executable, os.Args[1:], env, config, readWriter) + cmd, err := shellCmd.New(os.Args[1:], env, config, readWriter) if err != nil { // For now this could happen if `SSH_CONNECTION` is not set on // the environment @@ -61,8 +65,15 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() - if err = cmd.Execute(ctx); err != nil { + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + + if err := cmd.Execute(ctx); err != nil { + ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) os.Exit(1) } + + ctxlog.Info("gitlab-shell: main: command executed successfully") } diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -8,7 +8,6 @@ "encoding/pem" "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -112,7 +111,7 @@ case "/api/v4/internal/two_factor_otp_check": fmt.Fprint(w, `{"success": true}`) case "/api/v4/internal/allowed": - body, err := ioutil.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) + body, err := os.ReadFile(filepath.Join(testhelper.TestRoot, "responses/allowed_without_console_messages.json")) require.NoError(t, err) response := strings.Replace(string(body), "GITALY_REPOSITORY", testRepo, 1) @@ -198,7 +197,7 @@ func configureSSHD(t *testing.T, apiServer string) (string, ed25519.PublicKey) { t.Helper() - dir, err := ioutil.TempDir("", "gitlab-sshd-acceptance-test-") + dir, err := os.MkdirTemp("", "gitlab-sshd-acceptance-test-") require.NoError(t, err) t.Cleanup(func() { os.RemoveAll(dir) }) @@ -209,11 +208,11 @@ require.NoError(t, err) configFileData := genServerConfig(apiServer, hostKeyFile) - require.NoError(t, ioutil.WriteFile(configFile, configFileData, 0644)) + require.NoError(t, os.WriteFile(configFile, configFileData, 0644)) block := &pem.Block{Type: "OPENSSH PRIVATE KEY", Bytes: edkey.MarshalED25519PrivateKey(priv)} hostKeyData := pem.EncodeToMemory(block) - require.NoError(t, ioutil.WriteFile(hostKeyFile, hostKeyData, 0400)) + require.NoError(t, os.WriteFile(hostKeyFile, hostKeyData, 0400)) return dir, pub } @@ -326,7 +325,7 @@ _, err = fmt.Fprintln(stdin, "yes") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, ` Your two-factor authentication recovery codes are: @@ -365,7 +364,7 @@ _, err = fmt.Fprintln(stdin, "otp123") require.NoError(t, err) - output, err := ioutil.ReadAll(stdout) + output, err := io.ReadAll(stdout) require.NoError(t, err) require.Equal(t, "OTP validation successful. Git operations are now allowed.\n", string(output)) } diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -97,7 +97,7 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithFields(log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() diff --git a/docker-compose.yml b/docker-compose.yml --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,6 @@ gitaly: environment: - GITALY_TESTING_NO_GIT_HOOKS=1 - image: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + image: registry.gitlab.com/gitlab-org/build/cng/gitaly:master ports: - '8075:8075' diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -31,7 +31,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.5.2 # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,24 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/hg" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -29,19 +12,6 @@ Execute(ctx context.Context) error } -func New(e *executable.Executable, arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (Command, error) { - args, err := commandargs.Parse(e, arguments, env) - if err != nil { - return nil, err - } - - if cmd := buildCommand(e, args, config, readWriter); cmd != nil { - return cmd, nil - } - - return nil, disallowedcommand.Error -} - // Setup() initializes tracing from the configuration file and generates a // background context from which all other contexts in the process should derive // from, as it has a service name and initial correlation ID set. @@ -77,55 +47,3 @@ closer.Close() } } - -func buildCommand(e *executable.Executable, args commandargs.CommandArgs, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch e.Name { - case executable.GitlabShell: - return BuildShellCommand(args.(*commandargs.Shell), config, readWriter) - case executable.AuthorizedKeysCheck: - return buildAuthorizedKeysCommand(args.(*commandargs.AuthorizedKeys), config, readWriter) - case executable.AuthorizedPrincipalsCheck: - return buildAuthorizedPrincipalsCommand(args.(*commandargs.AuthorizedPrincipals), config, readWriter) - case executable.Healthcheck: - return buildHealthcheckCommand(config, readWriter) - } - - return nil -} - -func BuildShellCommand(args *commandargs.Shell, config *config.Config, readWriter *readwriter.ReadWriter) Command { - switch args.CommandType { - case commandargs.Discover: - return &discover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorRecover: - return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.TwoFactorVerify: - return &twofactorverify.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.Hg: - return &hg.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.LfsAuthenticate: - return &lfsauthenticate.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.ReceivePack: - return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadPack: - return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.UploadArchive: - return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter} - case commandargs.PersonalAccessToken: - return &personalaccesstoken.Command{Config: config, Args: args, ReadWriter: readWriter} - } - - return nil -} - -func buildAuthorizedKeysCommand(args *commandargs.AuthorizedKeys, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedkeys.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildAuthorizedPrincipalsCommand(args *commandargs.AuthorizedPrincipals, config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &authorizedprincipals.Command{Config: config, Args: args, ReadWriter: readWriter} -} - -func buildHealthcheckCommand(config *config.Config, readWriter *readwriter.ReadWriter) Command { - return &healthcheck.Command{Config: config, ReadWriter: readWriter} -} diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -1,173 +1,15 @@ package command import ( - "errors" "os" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/labkit/correlation" ) -var ( - authorizedKeysExec = &executable.Executable{Name: executable.AuthorizedKeysCheck} - authorizedPrincipalsExec = &executable.Executable{Name: executable.AuthorizedPrincipalsCheck} - checkExec = &executable.Executable{Name: executable.Healthcheck} - gitlabShellExec = &executable.Executable{Name: executable.GitlabShell} - - basicConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket"} - advancedConfig = &config.Config{GitlabUrl: "http+unix://gitlab.socket", SslCertDir: "/tmp/certs"} -) - -func buildEnv(command string) sshenv.Env { - return sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: command, - } -} - -func TestNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - config *config.Config - expectedType interface{} - }{ - { - desc: "it returns a Discover command", - executable: gitlabShellExec, - env: buildEnv(""), - config: basicConfig, - expectedType: &discover.Command{}, - }, - { - desc: "it returns a TwoFactorRecover command", - executable: gitlabShellExec, - env: buildEnv("2fa_recovery_codes"), - config: basicConfig, - expectedType: &twofactorrecover.Command{}, - }, - { - desc: "it returns a TwoFactorVerify command", - executable: gitlabShellExec, - env: buildEnv("2fa_verify"), - config: basicConfig, - expectedType: &twofactorverify.Command{}, - }, - { - desc: "it returns an LfsAuthenticate command", - executable: gitlabShellExec, - env: buildEnv("git-lfs-authenticate"), - config: basicConfig, - expectedType: &lfsauthenticate.Command{}, - }, - { - desc: "it returns a ReceivePack command", - executable: gitlabShellExec, - env: buildEnv("git-receive-pack"), - config: basicConfig, - expectedType: &receivepack.Command{}, - }, - { - desc: "it returns an UploadPack command", - executable: gitlabShellExec, - env: buildEnv("git-upload-pack"), - config: basicConfig, - expectedType: &uploadpack.Command{}, - }, - { - desc: "it returns an UploadArchive command", - executable: gitlabShellExec, - env: buildEnv("git-upload-archive"), - config: basicConfig, - expectedType: &uploadarchive.Command{}, - }, - { - desc: "it returns a Healthcheck command", - executable: checkExec, - config: basicConfig, - expectedType: &healthcheck.Command{}, - }, - { - desc: "it returns a AuthorizedKeys command", - executable: authorizedKeysExec, - arguments: []string{"git", "git", "key"}, - config: basicConfig, - expectedType: &authorizedkeys.Command{}, - }, - { - desc: "it returns a AuthorizedPrincipals command", - executable: authorizedPrincipalsExec, - arguments: []string{"key", "principal"}, - config: basicConfig, - expectedType: &authorizedprincipals.Command{}, - }, - { - desc: "it returns a PersonalAccessToken command", - executable: gitlabShellExec, - env: buildEnv("personal_access_token"), - config: basicConfig, - expectedType: &personalaccesstoken.Command{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, tc.arguments, tc.env, tc.config, nil) - - require.NoError(t, err) - require.IsType(t, tc.expectedType, command) - }) - } -} - -func TestFailingNew(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - expectedError error - }{ - { - desc: "Parsing environment failed", - executable: gitlabShellExec, - expectedError: errors.New("Only SSH allowed"), - }, - { - desc: "Unknown command given", - executable: gitlabShellExec, - env: buildEnv("unknown"), - expectedError: disallowedcommand.Error, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - command, err := New(tc.executable, []string{}, tc.env, basicConfig, nil) - require.Nil(t, command) - require.Equal(t, tc.expectedError, err) - }) - } -} - func TestSetup(t *testing.T) { testCases := []struct { name string diff --git a/internal/command/commandargs/command_args.go b/internal/command/commandargs/command_args.go --- a/internal/command/commandargs/command_args.go +++ b/internal/command/commandargs/command_args.go @@ -1,32 +1,8 @@ package commandargs -import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" -) - type CommandType string type CommandArgs interface { Parse() error GetArguments() []string } - -func Parse(e *executable.Executable, arguments []string, env sshenv.Env) (CommandArgs, error) { - var args CommandArgs = &GenericArgs{Arguments: arguments} - - switch e.Name { - case executable.GitlabShell: - args = &Shell{Arguments: arguments, Env: env} - case executable.AuthorizedKeysCheck: - args = &AuthorizedKeys{Arguments: arguments} - case executable.AuthorizedPrincipalsCheck: - args = &AuthorizedPrincipals{Arguments: arguments} - } - - if err := args.Parse(); err != nil { - return nil, err - } - - return args, nil -} diff --git a/internal/command/commandargs/command_args_test.go b/internal/command/commandargs/command_args_test.go deleted file mode 100644 --- a/internal/command/commandargs/command_args_test.go +++ /dev/null @@ -1,192 +0,0 @@ -package commandargs - -import ( - "testing" - - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - - "github.com/stretchr/testify/require" -) - -func TestParseSuccess(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedArgs CommandArgs - }{ - { - desc: "It sets discover as the command when the command string was empty", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: Discover, Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the key id only if the argument is of <key-id> format", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-key-123"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "key-123", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It finds the username in any passed arguments", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}, - arguments: []string{"hello", "username-jane-doe"}, - expectedArgs: &Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe", Env: sshenv.Env{IsSSHConnection: true, RemoteAddr: "1"}}, - }, { - desc: "It parses 2fa_recovery_codes command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "2fa_recovery_codes"}}, - }, { - desc: "It parses git-receive-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack group/repo"}}, - }, { - desc: "It parses git-receive-pack command and a project with single quotes", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-receive-pack 'group/repo'"}}, - }, { - desc: `It parses "git receive-pack" command`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack "group/repo"`}}, - }, { - desc: `It parses a command followed by control characters`, - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git-receive-pack group/repo; any command`}}, - }, { - desc: "It parses git-upload-pack command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git upload-pack "group/repo"`}}, - }, { - desc: "It parses git-upload-archive command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-upload-archive 'group/repo'"}}, - }, { - desc: "It parses git-lfs-authenticate command", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}, - arguments: []string{}, - expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate, Env: sshenv.Env{IsSSHConnection: true, OriginalCommand: "git-lfs-authenticate 'group/repo' download"}}, - }, { - desc: "It parses authorized-keys command", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"git", "git", "key"}, - expectedArgs: &AuthorizedKeys{Arguments: []string{"git", "git", "key"}, ExpectedUser: "git", ActualUser: "git", Key: "key"}, - }, { - desc: "It parses authorized-principals command", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal-1", "principal-2"}, - expectedArgs: &AuthorizedPrincipals{Arguments: []string{"key", "principal-1", "principal-2"}, KeyId: "key", Principals: []string{"principal-1", "principal-2"}}, - }, { - desc: "Unknown executable", - executable: &executable.Executable{Name: "unknown"}, - arguments: []string{}, - expectedArgs: &GenericArgs{Arguments: []string{}}, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := Parse(tc.executable, tc.arguments, tc.env) - - require.NoError(t, err) - require.Equal(t, tc.expectedArgs, result) - }) - } -} - -func TestParseFailure(t *testing.T) { - testCases := []struct { - desc string - executable *executable.Executable - env sshenv.Env - arguments []string - expectedError string - }{ - { - desc: "It fails if SSH connection is not set", - executable: &executable.Executable{Name: executable.GitlabShell}, - arguments: []string{}, - expectedError: "Only SSH allowed", - }, - { - desc: "It fails if SSH command is invalid", - executable: &executable.Executable{Name: executable.GitlabShell}, - env: sshenv.Env{IsSSHConnection: true, OriginalCommand: `git receive-pack "`}, - arguments: []string{}, - expectedError: "Invalid SSH command", - }, - { - desc: "With not enough arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With too many arguments for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", "key", "something-else"}, - expectedError: "# Insufficient arguments. 4. Usage\n#\tgitlab-shell-authorized-keys-check <expected-username> <actual-username> <key>", - }, - { - desc: "With missing username for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "", "key"}, - expectedError: "# No username provided", - }, - { - desc: "With missing key for the AuthorizedKeysCheck", - executable: &executable.Executable{Name: executable.AuthorizedKeysCheck}, - arguments: []string{"user", "user", ""}, - expectedError: "# No key provided", - }, - { - desc: "With not enough arguments for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key"}, - expectedError: "# Insufficient arguments. 1. Usage\n#\tgitlab-shell-authorized-principals-check <key-id> <principal1> [<principal2>...]", - }, - { - desc: "With missing key_id for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"", "principal"}, - expectedError: "# No key_id provided", - }, - { - desc: "With blank principal for the AuthorizedPrincipalsCheck", - executable: &executable.Executable{Name: executable.AuthorizedPrincipalsCheck}, - arguments: []string{"key", "principal", ""}, - expectedError: "# An invalid principal was provided", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - _, err := Parse(tc.executable, tc.arguments, tc.env) - - require.EqualError(t, err, tc.expectedError) - }) - } -} diff --git a/internal/command/commandargs/generic_args.go b/internal/command/commandargs/generic_args.go deleted file mode 100644 --- a/internal/command/commandargs/generic_args.go +++ /dev/null @@ -1,14 +0,0 @@ -package commandargs - -type GenericArgs struct { - Arguments []string -} - -func (b *GenericArgs) Parse() error { - // Do nothing - return nil -} - -func (b *GenericArgs) GetArguments() []string { - return b.Arguments -} diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -1,8 +1,9 @@ package commandargs import ( - "errors" + "fmt" "regexp" + "strings" "github.com/mattn/go-shellwords" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" @@ -50,21 +51,16 @@ func (s *Shell) validate() error { if !s.Env.IsSSHConnection { - return errors.New("Only SSH allowed") + return fmt.Errorf("Only SSH allowed") } - if !s.isValidSSHCommand() { - return errors.New("Invalid SSH command") + if err := s.ParseCommand(s.Env.OriginalCommand); err != nil { + return fmt.Errorf("Invalid SSH command: %w", err) } return nil } -func (s *Shell) isValidSSHCommand() bool { - err := s.ParseCommand(s.Env.OriginalCommand) - return err == nil -} - func (s *Shell) parseWho() { for _, argument := range s.Arguments { if keyId := tryParseKeyId(argument); keyId != "" { @@ -79,26 +75,29 @@ } } -func tryParseKeyId(argument string) string { - matchInfo := whoKeyRegex.FindStringSubmatch(argument) +func tryParse(r *regexp.Regexp, argument string) string { + // sshd may execute the session for AuthorizedKeysCommand in multiple ways: + // 1. key-id + // 2. /path/to/shell -c key-id + args := strings.Split(argument, " ") + lastArg := args[len(args)-1] + + matchInfo := r.FindStringSubmatch(lastArg) if len(matchInfo) == 2 { // The first element is the full matched string - // The second element is the named `keyid` + // The second element is the named `keyid` or `username` return matchInfo[1] } return "" } +func tryParseKeyId(argument string) string { + return tryParse(whoKeyRegex, argument) +} + func tryParseUsername(argument string) string { - matchInfo := whoUsernameRegex.FindStringSubmatch(argument) - if len(matchInfo) == 2 { - // The first element is the full matched string - // The second element is the named `username` - return matchInfo[1] - } - - return "" + return tryParse(whoUsernameRegex, argument) } func (s *Shell) ParseCommand(commandString string) error { diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -6,6 +6,8 @@ "encoding/json" "fmt" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" @@ -58,6 +60,11 @@ payload, err := c.authenticate(ctx, operation, repo, accessResponse.UserId) if err != nil { // return nothing just like Ruby's GitlabShell#lfs_authenticate does + log.WithContextFields( + ctx, + log.Fields{"operation": operation, "repo": repo, "user_id": accessResponse.UserId}, + ).WithError(err).Debug("lfsauthenticate: execute: LFS authentication failed") + return nil } diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -70,7 +70,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) @@ -94,7 +94,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -8,6 +8,8 @@ "strings" "time" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -38,6 +40,10 @@ return err } + log.WithContextFields(ctx, log.Fields{ + "token_args": c.TokenArgs, + }).Info("personalaccesstoken: execute: requesting token") + response, err := c.getPersonalAccessToken(ctx) if err != nil { return err diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -26,7 +26,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *accessverifier.Request diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -4,19 +4,17 @@ "bytes" "context" "errors" - - "gitlab.com/gitlab-org/gitlab-shell/client" - "io" "net/http" + "gitlab.com/gitlab-org/labkit/log" + + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" - - "gitlab.com/gitlab-org/labkit/log" ) type Request struct { @@ -59,12 +57,12 @@ request.Data.UserId = response.Who for _, endpoint := range data.ApiEndpoints { - fields := log.Fields{ + ctxlog := log.WithContextFields(ctx, log.Fields{ "primary_repo": data.PrimaryRepo, "endpoint": endpoint, - } + }) - log.WithFields(fields).Info("Performing custom action") + ctxlog.Info("customaction: processApiEndpoints: Performing custom action") response, err := c.performRequest(ctx, client, endpoint, request) if err != nil { @@ -90,6 +88,10 @@ } else { output = c.readFromStdinNoEOF() } + ctxlog.WithFields(log.Fields{ + "eof_sent": c.EOFSent, + "stdin_bytes": len(output), + }).Debug("customaction: processApiEndpoints: stdin buffered") request.Output = output } diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -23,7 +23,7 @@ { Path: "/geo/proxy/info_refs_receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -39,7 +39,7 @@ { Path: "/geo/proxy/receive_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -92,7 +92,7 @@ { Path: "/geo/proxy/info_refs_upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request @@ -108,7 +108,7 @@ { Path: "/geo/proxy/upload_pack", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var request *Request diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -6,6 +6,8 @@ "io" "strings" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -21,9 +23,14 @@ } func (c *Command) Execute(ctx context.Context) error { + ctxlog := log.ContextLogger(ctx) + ctxlog.Debug("twofactorrecover: execute: Waiting for user input") + if c.canContinue() { + ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { + ctxlog.Debug("twofactorrecover: execute: User chose not to continue") fmt.Fprintln(c.ReadWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.") } @@ -43,9 +50,12 @@ } func (c *Command) displayRecoveryCodes(ctx context.Context) { + ctxlog := log.ContextLogger(ctx) + codes, err := c.getRecoveryCodes(ctx) if err == nil { + ctxlog.Debug("twofactorrecover: displayRecoveryCodes: recovery codes successfully generated") messageWithCodes := "\nYour two-factor authentication recovery codes are:\n\n" + strings.Join(codes, "\n") + @@ -54,6 +64,7 @@ "a new device so you do not lose access to your account again.\n" fmt.Fprint(c.ReadWriter.Out, messageWithCodes) } else { + ctxlog.WithError(err).Error("twofactorrecover: displayRecoveryCodes: failed to generate recovery codes") fmt.Fprintf(c.ReadWriter.Out, "\nAn error occurred while trying to generate new recovery codes.\n%v\n", err) } } diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -27,7 +27,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -5,6 +5,8 @@ "fmt" "io" + "gitlab.com/gitlab-org/labkit/log" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -18,11 +20,18 @@ } func (c *Command) Execute(ctx context.Context) error { - err := c.verifyOTP(ctx, c.getOTP()) + ctxlog := log.ContextLogger(ctx) + ctxlog.Info("twofactorverify: execute: waiting for user input") + otp := c.getOTP() + + ctxlog.Info("twofactorverify: execute: verifying entered OTP") + err := c.verifyOTP(ctx, otp) if err != nil { + ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } + ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") return nil } diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -4,7 +4,7 @@ "bytes" "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -22,7 +22,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -2,7 +2,6 @@ import ( "errors" - "io/ioutil" "net/url" "os" "path" @@ -73,6 +72,7 @@ RootDir string LogFile string `yaml:"log_file,omitempty"` LogFormat string `yaml:"log_format,omitempty"` + LogLevel string `yaml:"log_level,omitempty"` GitlabUrl string `yaml:"gitlab_url"` GitlabRelativeURLRoot string `yaml:"gitlab_relative_url_root"` GitlabTracing string `yaml:"gitlab_tracing"` @@ -94,6 +94,7 @@ DefaultConfig = Config{ LogFile: "gitlab-shell.log", LogFormat: "json", + LogLevel: "info", Server: DefaultServerConfig, User: "git", } @@ -174,7 +175,7 @@ *cfg = DefaultConfig cfg.RootDir = filepath.Dir(path) - configBytes, err := ioutil.ReadFile(path) + configBytes, err := os.ReadFile(path) if err != nil { return nil, err } @@ -218,7 +219,7 @@ cfg.SecretFilePath = path.Join(cfg.RootDir, cfg.SecretFilePath) } - secretFileContent, err := ioutil.ReadFile(cfg.SecretFilePath) + secretFileContent, err := os.ReadFile(cfg.SecretFilePath) if err != nil { return err } diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -32,7 +32,7 @@ client, err := config.HttpClient() require.NoError(t, err) - _, err = client.Get("http://host.com/path") + _, err = client.Get(url) require.NoError(t, err) ms, err := prometheus.DefaultGatherer.Gather() diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -3,8 +3,9 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" + "os" "path" "testing" @@ -165,14 +166,14 @@ func setup(t *testing.T, allowedPayload string) *Client { testhelper.PrepareTestRootDir(t) - body, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) require.NoError(t, err) var bodyWithPayload []byte if allowedPayload != "" { allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = ioutil.ReadFile(allowedWithPayloadPath) + bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) require.NoError(t, err) } @@ -180,7 +181,7 @@ { Path: "/api/v4/internal/allowed", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) require.NoError(t, err) var requestBody *Request diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/lfs_authenticate", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/personal_access_token", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -3,7 +3,7 @@ import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "testing" @@ -24,7 +24,7 @@ { Path: "/api/v4/internal/two_factor_recovery_codes", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -3,11 +3,12 @@ import ( "context" "encoding/json" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" - "io/ioutil" + "io" "net/http" "testing" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" @@ -20,7 +21,7 @@ { Path: "/api/v4/internal/two_factor_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) defer r.Body.Close() require.NoError(t, err) diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -9,7 +9,9 @@ grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" @@ -43,12 +45,25 @@ func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { conn, err := getConn(ctx, gc) if err != nil { + log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") + return err } defer conn.Close() childCtx := withOutgoingMetadata(ctx, gc.Features) - _, err = handler(childCtx, conn) + ctxlog := log.ContextLogger(childCtx) + exitStatus, err := handler(childCtx, conn) + + if err != nil { + if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { + ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") + + return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + } + + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") + } return err } @@ -110,7 +125,7 @@ if serviceName == "" { serviceName = "gitlab-shell-unknown" - log.WithFields(log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") } serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -7,7 +7,9 @@ "github.com/stretchr/testify/require" "google.golang.org/grpc" + grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -45,6 +47,18 @@ require.EqualError(t, err, "no gitaly_address given") } +func TestUnavailableGitalyErr(t *testing.T) { + cmd := GitalyCommand{ + Config: &config.Config{}, + Address: "tcp://localhost:9999", + } + + expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) + + require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") +} + func TestRunGitalyCommandMetadata(t *testing.T) { tests := []struct { name string diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -3,7 +3,6 @@ import ( "fmt" "io" - "io/ioutil" "log/syslog" "os" "time" @@ -36,6 +35,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), + log.WithLogLevel(cfg.LogLevel), } } @@ -43,7 +43,7 @@ // mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be // opened for writing. func Configure(cfg *config.Config) io.Closer { - var closer io.Closer = ioutil.NopCloser(nil) + var closer io.Closer = io.NopCloser(nil) err := fmt.Errorf("No logfile specified") if cfg.LogFile != "" { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -1,10 +1,8 @@ package logger import ( - "io/ioutil" "os" "regexp" - "strings" "testing" "github.com/stretchr/testify/require" @@ -14,7 +12,7 @@ ) func TestConfigure(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() @@ -27,16 +25,41 @@ defer closer.Close() log.Info("this is a test") + log.WithFields(log.Fields{}).Debug("debug log message") tmpFile.Close() - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) + require.NoError(t, err) + require.Contains(t, string(data), `msg":"this is a test"`) + require.NotContains(t, string(data), `msg:":"debug log message"`) +} + +func TestConfigureWithDebugLogLevel(t *testing.T) { + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) - require.True(t, strings.Contains(string(data), `msg":"this is a test"`)) + defer tmpFile.Close() + + config := config.Config{ + LogFile: tmpFile.Name(), + LogFormat: "json", + LogLevel: "debug", + } + + closer := Configure(&config) + defer closer.Close() + + log.WithFields(log.Fields{}).Debug("debug log message") + + tmpFile.Close() + + data, err := os.ReadFile(tmpFile.Name()) + require.NoError(t, err) + require.Contains(t, string(data), `msg":"debug log message"`) } func TestConfigureWithPermissionError(t *testing.T) { - tmpPath, err := ioutil.TempDir(os.TempDir(), "logtest-") + tmpPath, err := os.MkdirTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer os.RemoveAll(tmpPath) @@ -52,7 +75,7 @@ } func TestLogInUTC(t *testing.T) { - tmpFile, err := ioutil.TempFile(os.TempDir(), "logtest-") + tmpFile, err := os.CreateTemp(os.TempDir(), "logtest-") require.NoError(t, err) defer tmpFile.Close() defer os.Remove(tmpFile.Name()) @@ -67,7 +90,7 @@ log.Info("this is a test") - data, err := ioutil.ReadFile(tmpFile.Name()) + data, err := os.ReadFile(tmpFile.Name()) require.NoError(t, err) utc := `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z` diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -29,21 +29,26 @@ } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { + ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { + ctxlog.Info("connection: handle: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { + ctxlog.Info("connection: handle: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - log.WithError(err).Info("could not accept channel") + ctxlog.WithError(err).Error("connection: handle: accepting channel failed") c.concurrentSessions.Release(1) continue } @@ -54,11 +59,12 @@ // Prevent a panic in a single session from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", c.remoteAddr) + ctxlog.WithField("recovered_error", err).Warn("panic handling session") } }() handler(ctx, channel, requests) + ctxlog.Info("connection: handle: done") }() } } diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config.go @@ -0,0 +1,94 @@ +package sshd + +import ( + "context" + "encoding/base64" + "fmt" + "os" + "strconv" + "time" + + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + + "gitlab.com/gitlab-org/labkit/log" +) + +type serverConfig struct { + cfg *config.Config + hostKeys []ssh.Signer + authorizedKeysClient *authorizedkeys.Client +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + var hostKeys []ssh.Signer + for _, filename := range cfg.Server.HostKeyFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") + continue + } + key, err := ssh.ParsePrivateKey(keyRaw) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to parse host key") + continue + } + + hostKeys = append(hostKeys, key) + } + if len(hostKeys) == 0 { + return nil, fmt.Errorf("No host keys could be loaded, aborting") + } + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil +} + +func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { + if user != s.cfg.User { + return nil, fmt.Errorf("unknown user") + } + if key.Type() == ssh.KeyAlgoDSA { + return nil, fmt.Errorf("DSA is prohibited") + } + + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) + if err != nil { + return nil, err + } + + return res, nil +} + +func (s *serverConfig) get(ctx context.Context) *ssh.ServerConfig { + sshCfg := &ssh.ServerConfig{ + PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { + res, err := s.getAuthKey(ctx, conn.User(), key) + if err != nil { + return nil, err + } + + return &ssh.Permissions{ + // Record the public key used for authentication. + Extensions: map[string]string{ + "key-id": strconv.FormatInt(res.Id, 10), + }, + }, nil + }, + } + + for _, key := range s.hostKeys { + sshCfg.AddHostKey(key) + } + + return sshCfg +} diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/server_config_test.go @@ -0,0 +1,105 @@ +package sshd + +import ( + "context" + "crypto/dsa" + "crypto/rand" + "crypto/rsa" + "path" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" +) + +func TestNewServerConfigWithoutHosts(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "http://localhost"}) + + require.Error(t, err) + require.Equal(t, "No host keys could be loaded, aborting", err.Error()) +} + +func TestFailedAuthorizedKeysClient(t *testing.T) { + _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) + + require.Error(t, err) + require.Equal(t, "failed to initialize GitLab client: Error creating http client: unknown GitLab URL prefix", err.Error()) +} + +func TestFailedGetAuthKey(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + testCases := []struct { + desc string + user string + key ssh.PublicKey + expectedError string + }{ + { + desc: "wrong user", + user: "wrong-user", + key: rsaPublicKey(t), + expectedError: "unknown user", + }, { + desc: "prohibited dsa key", + user: "user", + key: dsaPublicKey(t), + expectedError: "DSA is prohibited", + }, { + desc: "API error", + user: "user", + key: rsaPublicKey(t), + expectedError: "Internal API unreachable", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + _, err = cfg.getAuthKey(context.Background(), tc.user, tc.key) + require.Error(t, err) + require.Equal(t, tc.expectedError, err.Error()) + }) + } +} + +func rsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} + +func dsaPublicKey(t *testing.T) ssh.PublicKey { + privateKey := new(dsa.PrivateKey) + params := new(dsa.Parameters) + require.NoError(t, dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160)) + + privateKey.PublicKey.Parameters = *params + require.NoError(t, dsa.GenerateKey(privateKey, rand.Reader)) + + publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) + require.NoError(t, err) + + return publicKey +} diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -2,13 +2,16 @@ import ( "context" + "errors" "fmt" + "reflect" + "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -39,16 +42,27 @@ } func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { + ctxlog := log.ContextLogger(ctx) + + ctxlog.Debug("session: handle: entering request loop") + for req := range requests { + sessionLog := ctxlog.WithFields(log.Fields{ + "bytesize": len(req.Payload), + "type": req.Type, + "want_reply": req.WantReply, + }) + sessionLog.Debug("session: handle: request received") + var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(req) + shouldContinue = s.handleEnv(ctx, req) case "exec": shouldContinue = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -57,18 +71,23 @@ } } + sessionLog.WithField("should_continue", shouldContinue).Debug("session: handle: request processed") + if !shouldContinue { s.channel.Close() break } } + + ctxlog.Debug("session: handle: exiting request loop") } -func (s *session) handleEnv(req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { + log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") return false } @@ -84,6 +103,10 @@ req.Reply(accepted, []byte{}) } + log.WithContextFields( + ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, + ).Debug("session: handleEnv: processed") + return true } @@ -95,7 +118,8 @@ s.execCmd = execRequest.Command - s.exit(s.handleShell(ctx, req)) + s.exit(ctx, s.handleShell(ctx, req)) + return false } @@ -104,19 +128,11 @@ req.Reply(true, []byte{}) } - args := &commandargs.Shell{ - GitlabKeyId: s.gitlabKeyId, - Env: sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: s.execCmd, - GitProtocolVersion: s.gitProtocolVersion, - RemoteAddr: s.remoteAddr, - }, - } - - if err := args.ParseCommand(s.execCmd); err != nil { - s.toStderr("Failed to parse command: %v\n", err.Error()) - return 128 + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: s.execCmd, + GitProtocolVersion: s.gitProtocolVersion, + RemoteAddr: s.remoteAddr, } rw := &readwriter.ReadWriter{ @@ -125,25 +141,37 @@ ErrOut: s.channel.Stderr(), } - cmd := command.BuildShellCommand(args, s.cfg, rw) - if cmd == nil { - s.toStderr("Unknown command: %v\n", args.CommandType) + cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) + if err != nil { + if !errors.Is(err, disallowedcommand.Error) { + s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) + } + s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) return 128 } + cmdName := reflect.TypeOf(cmd).String() + ctxlog := log.ContextLogger(ctx) + ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + if err := cmd.Execute(ctx); err != nil { - s.toStderr("remote: ERROR: %v\n", err.Error()) + s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) return 1 } + ctxlog.Info("session: handleShell: command executed successfully") + return 0 } -func (s *session) toStderr(format string, args ...interface{}) { - fmt.Fprintf(s.channel.Stderr(), format, args...) +func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { + out := fmt.Sprintf(format, args...) + log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") + fmt.Fprint(s.channel.Stderr(), out) } -func (s *session) exit(status uint32) { +func (s *session) exit(ctx context.Context, status uint32) { + log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} s.channel.CloseWrite() diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go new file mode 100644 --- /dev/null +++ b/internal/sshd/session_test.go @@ -0,0 +1,189 @@ +package sshd + +import ( + "bytes" + "context" + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" +) + +type fakeChannel struct { + stdErr io.ReadWriter + sentRequestName string + sentRequestPayload []byte +} + +func (f *fakeChannel) Read(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Write(data []byte) (int, error) { + return 0, nil +} + +func (f *fakeChannel) Close() error { + return nil +} + +func (f *fakeChannel) CloseWrite() error { + return nil +} + +func (f *fakeChannel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { + f.sentRequestName = name + f.sentRequestPayload = payload + + return true, nil +} + +func (f *fakeChannel) Stderr() io.ReadWriter { + return f.stdErr +} + +var requests = []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"id": 1000, "name": "Test User", "username": "test-user"}`)) + }, + }, +} + +func TestHandleEnv(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedProtocolVersion string + expectedResult bool + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedProtocolVersion: "1", + expectedResult: false, + }, { + desc: "valid payload", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedProtocolVersion: "2", + expectedResult: true, + }, { + desc: "valid payload with forbidden env var", + payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedProtocolVersion: "1", + expectedResult: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + s := &session{gitProtocolVersion: "1"} + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) + require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + }) + } +} + +func TestHandleExec(t *testing.T) { + testCases := []struct { + desc string + payload []byte + expectedExecCmd string + sentRequestName string + sentRequestPayload []byte + }{ + { + desc: "invalid payload", + payload: []byte("invalid"), + expectedExecCmd: "", + sentRequestName: "", + }, { + desc: "valid payload", + payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedExecCmd: "discover", + sentRequestName: "exit-status", + sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + f := &fakeChannel{stdErr: out} + s := &session{ + gitlabKeyId: "root", + channel: f, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{Payload: tc.payload} + + require.Equal(t, false, s.handleExec(context.Background(), r)) + require.Equal(t, tc.sentRequestName, f.sentRequestName) + require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + }) + } +} + +func TestHandleShell(t *testing.T) { + testCases := []struct { + desc string + cmd string + errMsg string + gitlabKeyId string + expectedExitCode uint32 + }{ + { + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedExitCode: 128, + }, { + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedExitCode: 1, + }, { + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedExitCode: 0, + }, + } + + url := testserver.StartHttpServer(t, requests) + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + out := &bytes.Buffer{} + s := &session{ + gitlabKeyId: tc.gitlabKeyId, + execCmd: tc.cmd, + channel: &fakeChannel{stdErr: out}, + cfg: &config.Config{GitlabUrl: url}, + } + r := &ssh.Request{} + + require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + require.Equal(t, tc.errMsg, out.String()) + }) + } +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -2,13 +2,9 @@ import ( "context" - "encoding/base64" - "errors" "fmt" - "io/ioutil" "net" "net/http" - "strconv" "sync" "time" @@ -16,7 +12,6 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -35,44 +30,24 @@ type Server struct { Config *config.Config - status status - statusMu sync.Mutex - wg sync.WaitGroup - listener net.Listener - hostKeys []ssh.Signer - authorizedKeysClient *authorizedkeys.Client + status status + statusMu sync.Mutex + wg sync.WaitGroup + listener net.Listener + serverConfig *serverConfig } func NewServer(cfg *config.Config) (*Server, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + serverConfig, err := newServerConfig(cfg) if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + return nil, err } - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { - keyRaw, err := ioutil.ReadFile(filename) - if err != nil { - log.WithError(err).Warnf("Failed to read host key %v", filename) - continue - } - key, err := ssh.ParsePrivateKey(keyRaw) - if err != nil { - log.WithError(err).Warnf("Failed to parse host key %v", filename) - continue - } - - hostKeys = append(hostKeys, key) - } - if len(hostKeys) == 0 { - return nil, fmt.Errorf("No host keys could be loaded, aborting") - } - - return &Server{Config: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + return &Server{Config: cfg, serverConfig: serverConfig}, nil } func (s *Server) ListenAndServe(ctx context.Context) error { - if err := s.listen(); err != nil { + if err := s.listen(ctx); err != nil { return err } defer s.listener.Close() @@ -110,7 +85,7 @@ return mux } -func (s *Server) listen() error { +func (s *Server) listen(ctx context.Context) error { sshListener, err := net.Listen("tcp", s.Config.Server.Listen) if err != nil { return fmt.Errorf("failed to listen for connection: %w", err) @@ -119,13 +94,14 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, + Policy: unconditionalRequirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } - log.Info("Proxy protocol is enabled") + log.ContextLogger(ctx).Info("Proxy protocol is enabled") } - log.WithFields(log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") + log.WithContextFields(ctx, log.Fields{"tcp_address": sshListener.Addr().String()}).Info("Listening for SSH connections") s.listener = sshListener @@ -142,7 +118,7 @@ break } - log.WithError(err).Warn("Failed to accept connection") + log.ContextLogger(ctx).WithError(err).Warn("Failed to accept connection") continue } @@ -168,57 +144,29 @@ return s.status } -func (s *Server) serverConfig(ctx context.Context) *ssh.ServerConfig { - sshCfg := &ssh.ServerConfig{ - PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { - if conn.User() != s.Config.User { - return nil, errors.New("unknown user") - } - if key.Type() == ssh.KeyAlgoDSA { - return nil, errors.New("DSA is prohibited") - } - ctx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - res, err := s.authorizedKeysClient.GetByKey(ctx, base64.RawStdEncoding.EncodeToString(key.Marshal())) - if err != nil { - return nil, err - } - - return &ssh.Permissions{ - // Record the public key used for authentication. - Extensions: map[string]string{ - "key-id": strconv.FormatInt(res.Id, 10), - }, - }, nil - }, - } - - for _, key := range s.hostKeys { - sshCfg.AddHostKey(key) - } - - return sshCfg -} - func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() defer nconn.Close() + ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) + defer cancel() + + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + // Prevent a panic in a single connection from taking out the whole server defer func() { if err := recover(); err != nil { - log.WithFields(log.Fields{"recovered_error": err}).Warnf("panic handling session from %s", remoteAddr) + ctxlog.Warn("panic handling session") } }() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) - defer cancel() + ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig(ctx)) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - log.WithError(err).Info("Failed to initialize SSH connection") + ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return } @@ -235,4 +183,10 @@ session.handle(ctx, requests) }) + + ctxlog.Info("server: handleConn: done") } + +func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { + return proxyproto.REQUIRE, nil +} diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,9 +3,9 @@ import ( "context" "fmt" - "io/ioutil" "net/http" "net/http/httptest" + "os" "path" "testing" "time" @@ -47,6 +47,18 @@ verifyStatus(t, s, StatusClosed) } +func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { + setupServerWithProxyProtocolEnabled(t) + + client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) + if client != nil { + client.Close() + } + + require.Error(t, err, "Expected plain SSH request to be failed") + require.Regexp(t, "ssh: handshake failed", err.Error()) +} + func TestCorrelationId(t *testing.T) { setupServer(t) @@ -104,9 +116,39 @@ require.Equal(t, 200, r.Result().StatusCode) } +func TestInvalidClientConfig(t *testing.T) { + setupServer(t) + + cfg := clientConfig(t) + cfg.User = "unknown" + _, err := ssh.Dial("tcp", serverUrl, cfg) + require.Error(t, err) +} + +func TestInvalidServerConfig(t *testing.T) { + s := &Server{Config: &config.Config{Server: config.ServerConfig{Listen: "invalid"}}} + err := s.ListenAndServe(context.Background()) + + require.Error(t, err) + require.Equal(t, "failed to listen for connection: listen tcp: address invalid: missing port in address", err.Error()) + require.Nil(t, s.Shutdown()) +} + func setupServer(t *testing.T) *Server { t.Helper() + return setupServerWithConfig(t, nil) +} + +func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { + t.Helper() + + return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) +} + +func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -130,13 +172,20 @@ testhelper.PrepareTestRootDir(t) url := testserver.StartSocketHttpServer(t, requests) - srvCfg := config.ServerConfig{ - Listen: serverUrl, - ConcurrentSessionsLimit: 1, - HostKeyFiles: []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")}, + + if cfg == nil { + cfg = &config.Config{} } - s, err := NewServer(&config.Config{User: user, RootDir: "/tmp", GitlabUrl: url, Server: srvCfg}) + // All things that don't need to be configurable in tests yet + cfg.GitlabUrl = url + cfg.RootDir = "/tmp" + cfg.User = user + cfg.Server.Listen = serverUrl + cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} + + s, err := NewServer(cfg) require.NoError(t, err) go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() @@ -148,11 +197,11 @@ } func clientConfig(t *testing.T) *ssh.ClientConfig { - keyRaw, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) + keyRaw, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server_authorized_key")) pKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) require.NoError(t, err) - key, err := ioutil.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) + key, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/client/key.pem")) require.NoError(t, err) signer, err := ssh.ParsePrivateKey(key) require.NoError(t, err) @@ -177,14 +226,5 @@ } func verifyStatus(t *testing.T, s *Server, st status) { - for i := 5; i < 500; i += 50 { - if s.getStatus() == st { - break - } - - // Sleep incrementally ~2s in total - time.Sleep(time.Duration(i) * time.Millisecond) - } - - require.Equal(t, st, s.getStatus()) + require.Eventually(t, func() bool { return s.getStatus() == st }, 2*time.Second, time.Millisecond) } diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -2,7 +2,6 @@ import ( "fmt" - "io/ioutil" "os" "path" "runtime" @@ -13,7 +12,7 @@ ) var ( - TestRoot, _ = ioutil.TempDir("", "test-gitlab-shell") + TestRoot, _ = os.MkdirTemp("", "test-gitlab-shell") ) func TempEnv(env map[string]string) func() { # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1645871769 -3600 # Sat Feb 26 11:36:09 2022 +0100 # Branch heptapod-stable # Node ID 9f8076c43eab66b8867a86e136f915048237a657 # Parent eed45a48a4bd15aa1f57138e286080b4aaddec37 # Parent 0933769f90885c8c0ef6db40d1aeeea758a7632d heptapod#631: making Heptapod 0.29 the new stable diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.4 -golang 1.16.10 +golang 1.16.12 # HG changeset patch # User Will Chandler <wchandler@gitlab.com> # Date 1640197821 18000 # Wed Dec 22 13:30:21 2021 -0500 # Node ID 5d3302f022b92a5489a46b4fdb86dbc8bc5d043a # Parent 0933769f90885c8c0ef6db40d1aeeea758a7632d Send full git request/response in SSHD tests Before 9deaf47f1ecb00f0f36d18ee4a0fb1576f5a0efe, Gitaly would return success for `SSHUploadPack` and `SSHUploadArchive` regardless of the exit code of the `git upload-pack|archive` process. As a result, the gitlab-sshd acceptance tests could rely on no errors being returned from Gitaly. Currently these tests send the minimum request needed to start a session, causing the server git process to fail as the `0000` flush packet to end the session is never sent. This commit fixes the tests by sending the full request/response needed for a successful git operation. diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -408,18 +408,34 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-pack %s", testRepo)) + require.NoError(t, err) + + line, err := reader.ReadString('\n') + require.NoError(t, err) + require.Regexp(t, "^[0-9a-f]{44} HEAD.+", line) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") - require.Regexp(t, "^[0-9a-f]{44} HEAD.+", outputLines[0]) - for i := 1; i < (len(outputLines) - 1); i++ { require.Regexp(t, "^[0-9a-f]{44} refs/(heads|tags)/[^ ]+", outputLines[i]) } @@ -436,11 +452,29 @@ require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-archive %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-archive %s", testRepo)) require.NoError(t, err) - outputLines := strings.Split(string(output), "\n") + _, err = fmt.Fprintln(stdin, "0012argument HEAD\n0000") + + line, err := reader.ReadString('\n') + require.Equal(t, "0008ACK\n", line) + require.NoError(t, err) - require.Equal(t, "0008ACK", outputLines[0]) - require.Regexp(t, "^0000", outputLines[1]) + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) + require.NoError(t, err) + + require.Equal(t, []byte("0000"), output[len(output)-4:]) } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1640686192 0 # Tue Dec 28 10:09:52 2021 +0000 # Node ID ef3162790f053c321552def3806ea2ce4047c998 # Parent 0933769f90885c8c0ef6db40d1aeeea758a7632d # Parent 5d3302f022b92a5489a46b4fdb86dbc8bc5d043a Merge branch 'wc-sshd-upload-pack' into 'main' Send full git request/response in SSHD tests See merge request gitlab-org/gitlab-shell!550 diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -408,18 +408,34 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-pack %s", testRepo)) + require.NoError(t, err) + + line, err := reader.ReadString('\n') + require.NoError(t, err) + require.Regexp(t, "^[0-9a-f]{44} HEAD.+", line) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") - require.Regexp(t, "^[0-9a-f]{44} HEAD.+", outputLines[0]) - for i := 1; i < (len(outputLines) - 1); i++ { require.Regexp(t, "^[0-9a-f]{44} refs/(heads|tags)/[^ ]+", outputLines[i]) } @@ -436,11 +452,29 @@ require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-archive %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-archive %s", testRepo)) require.NoError(t, err) - outputLines := strings.Split(string(output), "\n") + _, err = fmt.Fprintln(stdin, "0012argument HEAD\n0000") + + line, err := reader.ReadString('\n') + require.Equal(t, "0008ACK\n", line) + require.NoError(t, err) - require.Equal(t, "0008ACK", outputLines[0]) - require.Regexp(t, "^0000", outputLines[1]) + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) + require.NoError(t, err) + + require.Equal(t, []byte("0000"), output[len(output)-4:]) } # HG changeset patch # User Will Chandler <wchandler@gitlab.com> # Date 1639148107 18000 # Fri Dec 10 09:55:07 2021 -0500 # Node ID 81f0009bfceba7a72673b0e55c8a0570ebb5c244 # Parent ef3162790f053c321552def3806ea2ce4047c998 Suppress internal errors in client output Until recently, Gitaly was silently swallowing any errors returned by SSH `git upload-pack` processes. Clients would still receive stderr output and a non-zero return code, but Gitlab-Shell would receive error as nil and log success. With 9deaf47f1ecb00f0f36d18ee4a0fb1576f5a0efe Gitaly will now return an error when git fails, but this causes Gitlab-Shell to print out the GRPC error code as a message to the client: > fatal: couldn't find remote ref not-a-real-ref > fatal: the remote end hung up unexpectedly > remote: > remote: > ======================================================================== > remote: > remote: rpc error: code = Internal desc = SSHUploadPack: exit status 128 > remote: > remote: > ======================================================================== > remote: The `remote:` text gives no additional context for the user and adds clutter. This commit suppresses the additional message added by Gitlab-Shell on failure when the error type is `Internal`, returning client output to the format it was prior to the Gitaly change. diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -5,6 +5,9 @@ "os" "reflect" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" @@ -71,7 +74,9 @@ if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") - console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + if grpcstatus.Convert(err).Code() != grpccodes.Internal { + console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + } os.Exit(1) } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1641380482 0 # Wed Jan 05 11:01:22 2022 +0000 # Node ID 81285a3e83664a7906796d7ddc887879aa266320 # Parent ef3162790f053c321552def3806ea2ce4047c998 # Parent 81f0009bfceba7a72673b0e55c8a0570ebb5c244 Merge branch 'wc-intern-err' into 'main' Suppress internal errors in client output See merge request gitlab-org/gitlab-shell!549 diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -5,6 +5,9 @@ "os" "reflect" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" @@ -71,7 +74,9 @@ if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") - console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + if grpcstatus.Convert(err).Code() != grpccodes.Internal { + console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + } os.Exit(1) } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1641996918 -10800 # Wed Jan 12 17:15:18 2022 +0300 # Node ID 5505522b8cd49fb6723d228adb4f16209e1f2cdb # Parent 81285a3e83664a7906796d7ddc887879aa266320 Deprecate self_signed_cert config setting The option isn't required to accept self-signed certs On the other hand, if the option set to true it makes machine-in-the-middle attack possible Let's clarify it in the code that the option is deprecated diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -162,7 +162,10 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, + RootCAs: certPool, + // The self_signed_cert config setting is deprecated + // The field and its usage is going to be removed in + // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 InsecureSkipVerify: selfSignedCert, MinVersion: tls.VersionTLS12, } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -26,6 +26,11 @@ # password: somepass # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs +# +# The self_signed_cert option is deprecated +# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible +# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed +# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 self_signed_cert: false # File used as authorized_keys for gitlab user # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1642039980 0 # Thu Jan 13 02:13:00 2022 +0000 # Node ID e5c80a0bed6036b81ccec2e4830b038bf146378e # Parent 81285a3e83664a7906796d7ddc887879aa266320 # Parent 5505522b8cd49fb6723d228adb4f16209e1f2cdb Merge branch 'id-deprecate-self-signed-cert' into 'main' Deprecate self_signed_cert config setting See merge request gitlab-org/gitlab-shell!552 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -162,7 +162,10 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, + RootCAs: certPool, + // The self_signed_cert config setting is deprecated + // The field and its usage is going to be removed in + // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 InsecureSkipVerify: selfSignedCert, MinVersion: tls.VersionTLS12, } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -26,6 +26,11 @@ # password: somepass # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs +# +# The self_signed_cert option is deprecated +# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible +# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed +# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 self_signed_cert: false # File used as authorized_keys for gitlab user # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1642140271 28800 # Thu Jan 13 22:04:31 2022 -0800 # Node ID c8a79b1dffb2423ced8c3ce652770108d9632351 # Parent e5c80a0bed6036b81ccec2e4830b038bf146378e Update to Ruby 2.7.5 We don't need Ruby 2.7.4 cluttering our GDK when everything else has been upgraded to 2.7.5. diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.4 +2.7.5 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -ruby 2.7.4 +ruby 2.7.5 golang 1.16.12 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1642140688 0 # Fri Jan 14 06:11:28 2022 +0000 # Node ID 10536301a797522c34722e346ccafe1bb47ca5cc # Parent e5c80a0bed6036b81ccec2e4830b038bf146378e # Parent c8a79b1dffb2423ced8c3ce652770108d9632351 Merge branch 'sh-update-ruby-2.7.5' into 'main' Update to Ruby 2.7.5 See merge request gitlab-org/gitlab-shell!553 diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.4 +2.7.5 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -ruby 2.7.4 +ruby 2.7.5 golang 1.16.12 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1642375469 0 # Sun Jan 16 23:24:29 2022 +0000 # Node ID 4a3f2772fe135c496754bdf2250a9fc901213428 # Parent 10536301a797522c34722e346ccafe1bb47ca5cc Release v13.22.2 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.22.2 + +- Update to Ruby 2.7.5 !553 +- Deprecate self_signed_cert config setting !552 +- Send full git request/response in SSHD tests !550 +- Suppress internal errors in client output !549 +- Bump .tool_versions to use Go v1.16.12 !548 + v13.22.1 - Remove SSL_CERT_DIR logging !546 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.1 +13.22.2 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1642375470 0 # Sun Jan 16 23:24:30 2022 +0000 # Node ID 35c1c2407c4cda8a59d29d847e460c3f7067b267 # Parent 10536301a797522c34722e346ccafe1bb47ca5cc # Parent 4a3f2772fe135c496754bdf2250a9fc901213428 Merge branch 'sh-release-13.22.2' into 'main' Release v13.22.2 See merge request gitlab-org/gitlab-shell!555 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.22.2 + +- Update to Ruby 2.7.5 !553 +- Deprecate self_signed_cert config setting !552 +- Send full git request/response in SSHD tests !550 +- Suppress internal errors in client output !549 +- Bump .tool_versions to use Go v1.16.12 !548 + v13.22.1 - Remove SSL_CERT_DIR logging !546 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.1 +13.22.2 # HG changeset patch # User Sean Carroll <scarroll@gitlab.com> # Date 1642588343 0 # Wed Jan 19 10:32:23 2022 +0000 # Node ID 197a236b521411a7a19204fd5470caad67c3e036 # Parent 35c1c2407c4cda8a59d29d847e460c3f7067b267 Rate limiting documentation diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ tests requiring Gitaly will be skipped. They will always run in the CI environment. -## Git LFS remark +## Git LFS Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. @@ -113,6 +113,16 @@ - Logging too much is better than not logging enough. If a message seems too verbose, consider reducing the log level before removing the message. +## Rate Limiting + +GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. + +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. + +Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. + +There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). + ## Releasing See [PROCESS.md](./PROCESS.md) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1642588344 0 # Wed Jan 19 10:32:24 2022 +0000 # Node ID 72999fcfa91c17621e5aa8d7c5b1a0d5397c9534 # Parent 35c1c2407c4cda8a59d29d847e460c3f7067b267 # Parent 197a236b521411a7a19204fd5470caad67c3e036 Merge branch 'rate-limiting-docs' into 'main' Rate limiting documentation See merge request gitlab-org/gitlab-shell!556 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ tests requiring Gitaly will be skipped. They will always run in the CI environment. -## Git LFS remark +## Git LFS Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. @@ -113,6 +113,16 @@ - Logging too much is better than not logging enough. If a message seems too verbose, consider reducing the log level before removing the message. +## Rate Limiting + +GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. + +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. + +Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. + +There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). + ## Releasing See [PROCESS.md](./PROCESS.md) # HG changeset patch # User Jacob Vosmaer <jacob@gitlab.com> # Date 1642692988 0 # Thu Jan 20 15:36:28 2022 +0000 # Node ID 98fea8ab6995c4f9b3d8a13cd5e43847ce23f515 # Parent e5c80a0bed6036b81ccec2e4830b038bf146378e Refactor client response tests This reduces coupling between tests in internal/gitlabnet/accessverifier/client_test.go, and will make it easier to add new test cases in the future. Note that the test server had a special behavior for the username "second", but this was never used. So we removed that behavior in this commit. diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,7 +11,6 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -54,7 +53,11 @@ } func TestSuccessfulResponses(t *testing.T) { - client := setup(t, "") + okResponse := testResponse{body: responseBody(t, "allowed.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) testCases := []struct { desc string @@ -84,7 +87,12 @@ } func TestGeoPushGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_push_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_push_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, receivePackAction, repo) @@ -106,7 +114,12 @@ } func TestGeoPullGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_pull_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_pull_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, uploadPackAction, repo) @@ -128,7 +141,11 @@ } func TestErrorResponses(t *testing.T) { - client := setup(t, "") + client := setup(t, nil, map[string]testResponse{ + "2": {body: []byte(`{"message":"Not allowed!"}`), status: http.StatusForbidden}, + "3": {body: []byte(`{"message":"broken json!`), status: http.StatusOK}, + "4": {status: http.StatusForbidden}, + }) testCases := []struct { desc string @@ -163,20 +180,21 @@ } } -func setup(t *testing.T, allowedPayload string) *Client { - testhelper.PrepareTestRootDir(t) - - body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) - require.NoError(t, err) +type testResponse struct { + body []byte + status int +} - var bodyWithPayload []byte +func responseBody(t *testing.T, name string) []byte { + t.Helper() + testhelper.PrepareTestRootDir(t) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses", name)) + require.NoError(t, err) + return body +} - if allowedPayload != "" { - allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) - require.NoError(t, err) - } - +func setup(t *testing.T, userResponses, keyResponses map[string]testResponse) *Client { + t.Helper() requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -187,36 +205,14 @@ var requestBody *Request require.NoError(t, json.Unmarshal(b, &requestBody)) - switch requestBody.Username { - case "first": - _, err = w.Write(body) - require.NoError(t, err) - case "second": - errBody := map[string]interface{}{ - "status": false, - "message": "missing user", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "custom": - w.WriteHeader(http.StatusMultipleChoices) - _, err = w.Write(bodyWithPayload) + if tr, ok := userResponses[requestBody.Username]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - } - - switch requestBody.KeyId { - case "1": - _, err = w.Write(body) + } else if tr, ok := keyResponses[requestBody.KeyId]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - case "2": - w.WriteHeader(http.StatusForbidden) - errBody := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) } }, }, # HG changeset patch # User Jacob Vosmaer <jacob@gitlab.com> # Date 1642761447 0 # Fri Jan 21 10:37:27 2022 +0000 # Node ID 27b5f05e21af12f173dd63e0f7f45c5d3b26b549 # Parent 98fea8ab6995c4f9b3d8a13cd5e43847ce23f515 Support parsing `use_sidechannel` API response field This field will act as a feature flag that controls whether gitlab-shell uses the old SSHUploadPack RPC or the new SSHUploadPackWithSidechannel. diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -32,10 +32,11 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` + UseSidechannel bool `json:"use_sidechannel"` } type CustomPayloadData struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -86,6 +86,41 @@ } } +func TestSidechannelFlag(t *testing.T) { + okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) + + testCases := []struct { + desc string + args *commandargs.Shell + who string + }{ + { + desc: "Provide key id within the request", + args: &commandargs.Shell{GitlabKeyId: "1"}, + who: "key-1", + }, { + desc: "Provide username within the request", + args: &commandargs.Shell{GitlabUsername: "first"}, + who: "user-1", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) + require.NoError(t, err) + + response := buildExpectedResponse(tc.who) + response.Gitaly.UseSidechannel = true + require.Equal(t, response, result) + }) + } +} + func TestGeoPushGetCustomAction(t *testing.T) { client := setup(t, map[string]testResponse{ "custom": { diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json @@ -0,0 +1,23 @@ +{ + "status": true, + "gl_repository": "project-26", + "gl_project_path": "group/private", + "gl_id": "user-1", + "gl_username": "root", + "git_config_options": ["option"], + "gitaly": { + "repository": { + "storage_name": "default", + "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", + "git_object_directory": "path/to/git_object_directory", + "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], + "gl_repository": "project-26", + "gl_project_path": "group/private" + }, + "address": "unix:gitaly.socket", + "token": "token", + "use_sidechannel": true + }, + "git_protocol": "protocol", + "gl_console_messages": ["console", "message"] +} # HG changeset patch # User Jacob Vosmaer <jacob@gitlab.com> # Date 1642761101 0 # Fri Jan 21 10:31:41 2022 +0000 # Node ID 77f2fc579a3820bce3b4e32ccf1b9e5a7dc3868c # Parent 27b5f05e21af12f173dd63e0f7f45c5d3b26b549 Update gitaly/v14/client to 2e398afa0490ccdf5a82e1a7c7d824ae491eba16 This updates the Gitaly client go.mod dependency to Gitaly commit 2e398afa0490ccdf5a82e1a7c7d824ae491eba16. This causes a grpc-go version bump, and hence a minor change in some of our test code. diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -13,7 +13,10 @@ "google.golang.org/grpc/metadata" ) -type TestGitalyServer struct{ ReceivedMD metadata.MD } +type TestGitalyServer struct { + ReceivedMD metadata.MD + pb.UnimplementedSSHServiceServer +} func (s *TestGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error { req, err := stream.Recv() diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,10 +11,10 @@ github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 + gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 gitlab.com/gitlab-org/labkit v1.7.0 - golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.37.0 + google.golang.org/grpc v1.38.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ +bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -29,20 +31,54 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 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/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= 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= +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/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-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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= +github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= +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-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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= @@ -52,11 +88,15 @@ github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= github.com/HdrHistogram/hdrhistogram-go v1.1.0 h1:6dpdDPTRoo78HxAJ6T1HfMiKSnqhgRRqzCuPshRkQ7I= github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE= github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -68,24 +108,30 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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/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= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +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 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= 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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -115,6 +161,7 @@ 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/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= @@ -123,7 +170,10 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +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/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= @@ -134,9 +184,16 @@ 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= +github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= 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= @@ -146,6 +203,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -159,41 +218,62 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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/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/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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +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/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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= +github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= @@ -204,6 +284,8 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -249,6 +331,7 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -265,8 +348,11 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= +github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 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/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -285,10 +371,13 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 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 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= 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/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= @@ -331,11 +420,14 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -345,8 +437,51 @@ github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +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/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= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +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/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/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/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= +github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -363,6 +498,7 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= @@ -380,8 +516,9 @@ github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -389,21 +526,33 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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/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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -415,12 +564,17 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 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-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -445,10 +599,13 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -461,7 +618,7 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -504,7 +661,6 @@ github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= @@ -512,6 +668,7 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= 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/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -556,6 +713,9 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -563,17 +723,24 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -590,18 +757,21 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -629,6 +799,8 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= @@ -643,19 +815,27 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 h1:4u44IbgntN1yKgnY/mUabRjHXIchrLPwUwMuDyQ0+ec= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a h1:VeZYyHUa0zvnZwn5hQJMvetcnf+LFUcWJhsqlFsjkEA= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= 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.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= 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= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -669,32 +849,49 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 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 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= 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/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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= 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= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= 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 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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= @@ -708,6 +905,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -733,8 +931,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 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= 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/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= @@ -758,7 +957,9 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -781,8 +982,12 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210505214959-0714010a04ed h1:V9kAVxLvz1lkufatrpHuUVyJ/5tR3Ms7rk951P4mI98= +golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -795,8 +1000,9 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78 h1:rPRtHfUb0UKZeZ6GH4K4Nt4YRbE9V1u+QZX5upZXqJQ= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c h1:SgVl/sCtkicsS7psKkje4H9YtjdEl3xsYh7N+5TDHqY= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -819,8 +1025,10 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -832,13 +1040,17 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -855,6 +1067,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -864,12 +1077,21 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 h1:ZBu6861dZq7xBnG1bn5SRU0vA8nx42at4+kP07FMTog= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -879,13 +1101,15 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -900,15 +1124,19 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -949,20 +1177,25 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -981,13 +1214,15 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0 h1:pqMffJFLBVUDIoYsHcqtxgQVTsmxMDpYLOc5MT4Jrww= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= +google.golang.org/api v0.46.0 h1:jkDWHOBIoNSD0OQpq4rtBVu+Rh325MPjXG1rakAp8JU= +google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= 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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -998,6 +1233,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1036,8 +1272,12 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3 h1:K+7Ig5hjiLVA/i1UFUUbCGimWz5/Ey0lAQjT3QiLaPY= google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= 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= @@ -1063,8 +1303,9 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1085,8 +1326,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= @@ -1095,6 +1337,7 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= @@ -1102,6 +1345,7 @@ gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1126,6 +1370,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= # HG changeset patch # User Jacob Vosmaer <jacob@gitlab.com> # Date 1642763119 0 # Fri Jan 21 11:05:19 2022 +0000 # Node ID ea5bfbbec2229fd964ac559b40fbe13021da868f # Parent 77f2fc579a3820bce3b4e32ccf1b9e5a7dc3868c Optionally use SSHUploadPackWithSidechannel If the GitLab API returns an allowed response with use_sidechannel set to true, gitlab-shell will establish a sidechannel connection and use SSHUploadPackWithSidechannel instead of SSHUploadPack. This is an efficiency improvement. diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,6 +1,8 @@ package testserver import ( + "context" + "fmt" "net" "os" "path" @@ -8,8 +10,11 @@ "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" ) @@ -46,6 +51,26 @@ return nil } +func (s *TestGitalyServer) SSHUploadPackWithSidechannel(ctx context.Context, req *pb.SSHUploadPackWithSidechannelRequest) (*pb.SSHUploadPackWithSidechannelResponse, error) { + conn, err := client.OpenServerSidechannel(ctx) + if err != nil { + return nil, err + } + defer conn.Close() + + s.ReceivedMD, _ = metadata.FromIncomingContext(ctx) + + response := []byte("SSHUploadPackWithSidechannel: " + req.Repository.GlRepository) + if _, err := fmt.Fprintf(conn, "%04x\x01%s", len(response)+5, response); err != nil { + return nil, err + } + if err := conn.Close(); err != nil { + return nil, err + } + + return &pb.SSHUploadPackWithSidechannelResponse{}, nil +} + func (s *TestGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error { req, err := stream.Recv() if err != nil { @@ -70,7 +95,9 @@ err := os.MkdirAll(filepath.Dir(gitalySocketPath), 0700) require.NoError(t, err) - server := grpc.NewServer() + server := grpc.NewServer( + client.SidechannelServer(log.ContextLogger(context.Background()), insecure.NewCredentials()), + ) listener, err := net.Listen("unix", gitalySocketPath) require.NoError(t, err) diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -30,7 +30,7 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -23,7 +23,7 @@ request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -21,13 +21,30 @@ Features: response.Gitaly.Features, } + if response.Gitaly.UseSidechannel { + gc.DialSidechannel = true + request := &pb.SSHUploadPackWithSidechannelRequest{ + Repository: &response.Gitaly.Repo, + GitProtocol: c.Args.Env.GitProtocolVersion, + GitConfigOptions: response.GitConfigOptions, + } + + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + defer cancel() + + rw := c.ReadWriter + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) + }) + } + request := &pb.SSHUploadPackRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -71,3 +71,59 @@ require.Empty(t, testServer.ReceivedMD["some-other-ff"]) require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } + +func TestUploadPack_withSidechannel(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) + + requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) + url := testserver.StartHttpServer(t, requests) + + output := &bytes.Buffer{} + input := &bytes.Buffer{} + + userId := "1" + repo := "group/repo" + + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: args, + ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, + } + + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + err := cmd.Execute(ctx) + require.NoError(t, err) + + require.Equal(t, "SSHUploadPackWithSidechannel: "+repo, output.String()) + + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") +} diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -29,21 +29,23 @@ // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string + Config *config.Config + ServiceName string + Address string + Token string + Features map[string]string + DialSidechannel bool } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - conn, err := getConn(ctx, gc) + registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) + conn, err := getConn(ctx, gc, registry) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") @@ -53,7 +55,7 @@ childCtx := withOutgoingMetadata(ctx, gc.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn) + exitStatus, err := handler(childCtx, conn, registry) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -116,7 +118,7 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand) (*grpc.ClientConn, error) { +func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { if gc.Address == "" { return nil, fmt.Errorf("no gitaly_address given") } @@ -160,5 +162,9 @@ ) } + if gc.DialSidechannel { + return client.DialSidechannel(ctx, gc.Address, registry, connOpts) + } + return client.DialContext(ctx, gc.Address, connOpts) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,14 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -86,7 +87,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -29,6 +29,14 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) +} + +func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) +} + +func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -56,6 +64,9 @@ }, }, } + if useSidechannel { + body["gitaly"].(map[string]interface{})["use_sidechannel"] = true + } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643110793 0 # Tue Jan 25 11:39:53 2022 +0000 # Node ID 3b5a0ff21f311a0075abc54e810ea0f82945d627 # Parent 72999fcfa91c17621e5aa8d7c5b1a0d5397c9534 # Parent ea5bfbbec2229fd964ac559b40fbe13021da868f Merge branch 'jv-ssh-sidechannel' into 'main' Add support for SSHUploadPackWithSidechannel RPC See merge request gitlab-org/gitlab-shell!557 diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,6 +1,8 @@ package testserver import ( + "context" + "fmt" "net" "os" "path" @@ -8,12 +10,18 @@ "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" ) -type TestGitalyServer struct{ ReceivedMD metadata.MD } +type TestGitalyServer struct { + ReceivedMD metadata.MD + pb.UnimplementedSSHServiceServer +} func (s *TestGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error { req, err := stream.Recv() @@ -43,6 +51,26 @@ return nil } +func (s *TestGitalyServer) SSHUploadPackWithSidechannel(ctx context.Context, req *pb.SSHUploadPackWithSidechannelRequest) (*pb.SSHUploadPackWithSidechannelResponse, error) { + conn, err := client.OpenServerSidechannel(ctx) + if err != nil { + return nil, err + } + defer conn.Close() + + s.ReceivedMD, _ = metadata.FromIncomingContext(ctx) + + response := []byte("SSHUploadPackWithSidechannel: " + req.Repository.GlRepository) + if _, err := fmt.Fprintf(conn, "%04x\x01%s", len(response)+5, response); err != nil { + return nil, err + } + if err := conn.Close(); err != nil { + return nil, err + } + + return &pb.SSHUploadPackWithSidechannelResponse{}, nil +} + func (s *TestGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error { req, err := stream.Recv() if err != nil { @@ -67,7 +95,9 @@ err := os.MkdirAll(filepath.Dir(gitalySocketPath), 0700) require.NoError(t, err) - server := grpc.NewServer() + server := grpc.NewServer( + client.SidechannelServer(log.ContextLogger(context.Background()), insecure.NewCredentials()), + ) listener, err := net.Listen("unix", gitalySocketPath) require.NoError(t, err) diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,10 +11,10 @@ github.com/pires/go-proxyproto v0.6.0 github.com/prometheus/client_golang v1.10.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 + gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 gitlab.com/gitlab-org/labkit v1.7.0 - golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.37.0 + google.golang.org/grpc v1.38.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ +bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -29,20 +31,54 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 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/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= 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= +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/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-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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= +github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= +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-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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= @@ -52,11 +88,15 @@ github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= github.com/HdrHistogram/hdrhistogram-go v1.1.0 h1:6dpdDPTRoo78HxAJ6T1HfMiKSnqhgRRqzCuPshRkQ7I= github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE= github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= @@ -68,24 +108,30 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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/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= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +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 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= 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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -115,6 +161,7 @@ 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/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= @@ -123,7 +170,10 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +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/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= @@ -134,9 +184,16 @@ 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= +github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= 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= @@ -146,6 +203,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -159,41 +218,62 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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/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/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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +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/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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= +github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= @@ -204,6 +284,8 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -249,6 +331,7 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -265,8 +348,11 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= +github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 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/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -285,10 +371,13 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 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 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= 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/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= @@ -331,11 +420,14 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -345,8 +437,51 @@ github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +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/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= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +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/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/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/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= +github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -363,6 +498,7 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= @@ -380,8 +516,9 @@ github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -389,21 +526,33 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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/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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -415,12 +564,17 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 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-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -445,10 +599,13 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -461,7 +618,7 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -504,7 +661,6 @@ github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= @@ -512,6 +668,7 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= 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/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -556,6 +713,9 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -563,17 +723,24 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -590,18 +757,21 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -629,6 +799,8 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= @@ -643,19 +815,27 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 h1:4u44IbgntN1yKgnY/mUabRjHXIchrLPwUwMuDyQ0+ec= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a h1:VeZYyHUa0zvnZwn5hQJMvetcnf+LFUcWJhsqlFsjkEA= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= 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.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= 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= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -669,32 +849,49 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 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 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= 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/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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= 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= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= 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 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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= @@ -708,6 +905,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -733,8 +931,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 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= 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/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= @@ -758,7 +957,9 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -781,8 +982,12 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210505214959-0714010a04ed h1:V9kAVxLvz1lkufatrpHuUVyJ/5tR3Ms7rk951P4mI98= +golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -795,8 +1000,9 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78 h1:rPRtHfUb0UKZeZ6GH4K4Nt4YRbE9V1u+QZX5upZXqJQ= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c h1:SgVl/sCtkicsS7psKkje4H9YtjdEl3xsYh7N+5TDHqY= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -819,8 +1025,10 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -832,13 +1040,17 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -855,6 +1067,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -864,12 +1077,21 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 h1:ZBu6861dZq7xBnG1bn5SRU0vA8nx42at4+kP07FMTog= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -879,13 +1101,15 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -900,15 +1124,19 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -949,20 +1177,25 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -981,13 +1214,15 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0 h1:pqMffJFLBVUDIoYsHcqtxgQVTsmxMDpYLOc5MT4Jrww= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= +google.golang.org/api v0.46.0 h1:jkDWHOBIoNSD0OQpq4rtBVu+Rh325MPjXG1rakAp8JU= +google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= 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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -998,6 +1233,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1036,8 +1272,12 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3 h1:K+7Ig5hjiLVA/i1UFUUbCGimWz5/Ey0lAQjT3QiLaPY= google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= +google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= 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= @@ -1063,8 +1303,9 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1085,8 +1326,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= @@ -1095,6 +1337,7 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= @@ -1102,6 +1345,7 @@ gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1126,6 +1370,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -30,7 +30,7 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -23,7 +23,7 @@ request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -21,13 +21,30 @@ Features: response.Gitaly.Features, } + if response.Gitaly.UseSidechannel { + gc.DialSidechannel = true + request := &pb.SSHUploadPackWithSidechannelRequest{ + Repository: &response.Gitaly.Repo, + GitProtocol: c.Args.Env.GitProtocolVersion, + GitConfigOptions: response.GitConfigOptions, + } + + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + defer cancel() + + rw := c.ReadWriter + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) + }) + } + request := &pb.SSHUploadPackRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -71,3 +71,59 @@ require.Empty(t, testServer.ReceivedMD["some-other-ff"]) require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } + +func TestUploadPack_withSidechannel(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) + + requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) + url := testserver.StartHttpServer(t, requests) + + output := &bytes.Buffer{} + input := &bytes.Buffer{} + + userId := "1" + repo := "group/repo" + + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: args, + ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, + } + + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + err := cmd.Execute(ctx) + require.NoError(t, err) + + require.Equal(t, "SSHUploadPackWithSidechannel: "+repo, output.String()) + + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") +} diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -32,10 +32,11 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` + UseSidechannel bool `json:"use_sidechannel"` } type CustomPayloadData struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,7 +11,6 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -54,7 +53,11 @@ } func TestSuccessfulResponses(t *testing.T) { - client := setup(t, "") + okResponse := testResponse{body: responseBody(t, "allowed.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) testCases := []struct { desc string @@ -83,8 +86,48 @@ } } +func TestSidechannelFlag(t *testing.T) { + okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) + + testCases := []struct { + desc string + args *commandargs.Shell + who string + }{ + { + desc: "Provide key id within the request", + args: &commandargs.Shell{GitlabKeyId: "1"}, + who: "key-1", + }, { + desc: "Provide username within the request", + args: &commandargs.Shell{GitlabUsername: "first"}, + who: "user-1", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) + require.NoError(t, err) + + response := buildExpectedResponse(tc.who) + response.Gitaly.UseSidechannel = true + require.Equal(t, response, result) + }) + } +} + func TestGeoPushGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_push_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_push_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, receivePackAction, repo) @@ -106,7 +149,12 @@ } func TestGeoPullGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_pull_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_pull_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, uploadPackAction, repo) @@ -128,7 +176,11 @@ } func TestErrorResponses(t *testing.T) { - client := setup(t, "") + client := setup(t, nil, map[string]testResponse{ + "2": {body: []byte(`{"message":"Not allowed!"}`), status: http.StatusForbidden}, + "3": {body: []byte(`{"message":"broken json!`), status: http.StatusOK}, + "4": {status: http.StatusForbidden}, + }) testCases := []struct { desc string @@ -163,20 +215,21 @@ } } -func setup(t *testing.T, allowedPayload string) *Client { - testhelper.PrepareTestRootDir(t) - - body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) - require.NoError(t, err) +type testResponse struct { + body []byte + status int +} - var bodyWithPayload []byte +func responseBody(t *testing.T, name string) []byte { + t.Helper() + testhelper.PrepareTestRootDir(t) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses", name)) + require.NoError(t, err) + return body +} - if allowedPayload != "" { - allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) - require.NoError(t, err) - } - +func setup(t *testing.T, userResponses, keyResponses map[string]testResponse) *Client { + t.Helper() requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -187,36 +240,14 @@ var requestBody *Request require.NoError(t, json.Unmarshal(b, &requestBody)) - switch requestBody.Username { - case "first": - _, err = w.Write(body) - require.NoError(t, err) - case "second": - errBody := map[string]interface{}{ - "status": false, - "message": "missing user", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "custom": - w.WriteHeader(http.StatusMultipleChoices) - _, err = w.Write(bodyWithPayload) + if tr, ok := userResponses[requestBody.Username]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - } - - switch requestBody.KeyId { - case "1": - _, err = w.Write(body) + } else if tr, ok := keyResponses[requestBody.KeyId]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - case "2": - w.WriteHeader(http.StatusForbidden) - errBody := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) } }, }, diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -29,21 +29,23 @@ // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string + Config *config.Config + ServiceName string + Address string + Token string + Features map[string]string + DialSidechannel bool } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - conn, err := getConn(ctx, gc) + registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) + conn, err := getConn(ctx, gc, registry) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") @@ -53,7 +55,7 @@ childCtx := withOutgoingMetadata(ctx, gc.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn) + exitStatus, err := handler(childCtx, conn, registry) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -116,7 +118,7 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand) (*grpc.ClientConn, error) { +func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { if gc.Address == "" { return nil, fmt.Errorf("no gitaly_address given") } @@ -160,5 +162,9 @@ ) } + if gc.DialSidechannel { + return client.DialSidechannel(ctx, gc.Address, registry, connOpts) + } + return client.DialContext(ctx, gc.Address, connOpts) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,14 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -86,7 +87,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -29,6 +29,14 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) +} + +func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) +} + +func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -56,6 +64,9 @@ }, }, } + if useSidechannel { + body["gitaly"].(map[string]interface{})["use_sidechannel"] = true + } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json @@ -0,0 +1,23 @@ +{ + "status": true, + "gl_repository": "project-26", + "gl_project_path": "group/private", + "gl_id": "user-1", + "gl_username": "root", + "git_config_options": ["option"], + "gitaly": { + "repository": { + "storage_name": "default", + "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", + "git_object_directory": "path/to/git_object_directory", + "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], + "gl_repository": "project-26", + "gl_project_path": "group/private" + }, + "address": "unix:gitaly.socket", + "token": "token", + "use_sidechannel": true + }, + "git_protocol": "protocol", + "gl_console_messages": ["console", "message"] +} # HG changeset patch # User Jacob Vosmaer <jacob@gitlab.com> # Date 1643115081 0 # Tue Jan 25 12:51:21 2022 +0000 # Node ID 9d7d352114a8c1ba3f79d0b949fcbaec8c9ea061 # Parent 3b5a0ff21f311a0075abc54e810ea0f82945d627 Release 13.23.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v13.23.0 + +- Add support for SSHUploadPackWithSidechannel RPC !557 +- Rate limiting documentation !556 + v13.22.2 - Update to Ruby 2.7.5 !553 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.2 +13.23.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643116085 0 # Tue Jan 25 13:08:05 2022 +0000 # Node ID facb28d2103701af8b625f283d6387d863b51e2e # Parent 3b5a0ff21f311a0075abc54e810ea0f82945d627 # Parent 9d7d352114a8c1ba3f79d0b949fcbaec8c9ea061 Merge branch 'jv-release-13.23.0' into 'main' Release 13.23.0 See merge request gitlab-org/gitlab-shell!558 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v13.23.0 + +- Add support for SSHUploadPackWithSidechannel RPC !557 +- Rate limiting documentation !556 + v13.22.2 - Update to Ruby 2.7.5 !553 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.2 +13.23.0 # HG changeset patch # User Lin Jen-Shin <jen-shin@gitlab.com> # Date 1642178684 -28800 # Sat Jan 15 00:44:44 2022 +0800 # Node ID 5b6fa84dcbcf6e2412f36b939d837ad392b09859 # Parent facb28d2103701af8b625f283d6387d863b51e2e Update bundler to 2.3.6 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,7 +37,7 @@ - apt-get update -qq && apt-get install -y ruby ruby-dev - ruby -v - export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin - - gem install --force --bindir /usr/local/bin bundler -v 2.1.4 + - gem install --force --bindir /usr/local/bin bundler -v 2.3.6 - bundle install # Now set up to run the Golang tests - make build diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,4 +23,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.1.4 + 2.3.6 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1643344168 0 # Fri Jan 28 04:29:28 2022 +0000 # Node ID cbf3c23bde26c1c1cf09e4aa16c11f71e87c0f21 # Parent facb28d2103701af8b625f283d6387d863b51e2e # Parent 5b6fa84dcbcf6e2412f36b939d837ad392b09859 Merge branch 'update-bundler' into 'main' Update bundler to 2.3.6 because 2.1.4 is too old See merge request gitlab-org/gitlab-shell!554 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,7 +37,7 @@ - apt-get update -qq && apt-get install -y ruby ruby-dev - ruby -v - export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin - - gem install --force --bindir /usr/local/bin bundler -v 2.1.4 + - gem install --force --bindir /usr/local/bin bundler -v 2.3.6 - bundle install # Now set up to run the Golang tests - make build diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,4 +23,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.1.4 + 2.3.6 # HG changeset patch # User Costel Maxim <cmaxim@gitlab.com> # Date 1643368859 0 # Fri Jan 28 11:20:59 2022 +0000 # Node ID 3fcba671aca940f27f12117db610bff5f2c4a27f # Parent facb28d2103701af8b625f283d6387d863b51e2e Update link for gitlab-workhorse project location diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server -If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse). +If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab/tree/master/workhorse). An overview of the four cases described above: # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643368859 0 # Fri Jan 28 11:20:59 2022 +0000 # Node ID f11aa3c5289314273b0df987791c85de1a3bc87b # Parent cbf3c23bde26c1c1cf09e4aa16c11f71e87c0f21 # Parent 3fcba671aca940f27f12117db610bff5f2c4a27f Merge branch 'cmaxim-main-patch-05177' into 'main' Update link for gitlab-workhorse project location See merge request gitlab-org/gitlab-shell!559 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server -If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse). +If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab/tree/master/workhorse). An overview of the four cases described above: # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643399070 -10800 # Fri Jan 28 22:44:30 2022 +0300 # Node ID b1e4e2817bfe8fe4f57940279134b0e2c9dec792 # Parent f11aa3c5289314273b0df987791c85de1a3bc87b Replace golang.org/x/crypto with gitlab-org/golang-crypto This fork contains a fix for handling ssh-rsa public keys of gitlab-sshd Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/543 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -18,3 +18,5 @@ google.golang.org/grpc v1.38.0 gopkg.in/yaml.v2 v2.4.0 ) + +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -820,12 +820,12 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a h1:VeZYyHUa0zvnZwn5hQJMvetcnf+LFUcWJhsqlFsjkEA= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= @@ -865,33 +865,6 @@ 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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= -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= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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-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 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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= @@ -947,7 +920,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -986,8 +958,9 @@ golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210505214959-0714010a04ed h1:V9kAVxLvz1lkufatrpHuUVyJ/5tR3Ms7rk951P4mI98= golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -1028,7 +1001,6 @@ golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1092,7 +1064,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1643597794 0 # Mon Jan 31 02:56:34 2022 +0000 # Node ID 5058e80bdd7220b4fd75c9aa3add4c0c5cf8e96c # Parent f11aa3c5289314273b0df987791c85de1a3bc87b # Parent b1e4e2817bfe8fe4f57940279134b0e2c9dec792 Merge branch 'id-add-gitlab-golang-crypto' into 'main' Replace golang.org/x/crypto with gitlab-org/golang-crypto See merge request gitlab-org/gitlab-shell!560 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -18,3 +18,5 @@ google.golang.org/grpc v1.38.0 gopkg.in/yaml.v2 v2.4.0 ) + +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -820,12 +820,12 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a h1:VeZYyHUa0zvnZwn5hQJMvetcnf+LFUcWJhsqlFsjkEA= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220118113436-b58be10dc69a/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= @@ -865,33 +865,6 @@ 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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= -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= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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-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 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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= @@ -947,7 +920,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -986,8 +958,9 @@ golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210505214959-0714010a04ed h1:V9kAVxLvz1lkufatrpHuUVyJ/5tR3Ms7rk951P4mI98= golang.org/x/net v0.0.0-20210505214959-0714010a04ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -1028,7 +1001,6 @@ golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1092,7 +1064,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643608702 -10800 # Mon Jan 31 08:58:22 2022 +0300 # Node ID b9a33a7194ce666ef2bbd78b2387a2e7e000c786 # Parent 5058e80bdd7220b4fd75c9aa3add4c0c5cf8e96c Release 13.23.1 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.23.1 + +- Replace golang.org/x/crypto with gitlab-org/golang-crypto !560 + v13.23.0 - Add support for SSHUploadPackWithSidechannel RPC !557 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.0 +13.23.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643609167 0 # Mon Jan 31 06:06:07 2022 +0000 # Node ID c980b46fd02fa3ba6ff9deae8ea6febd1f7e3692 # Parent 5058e80bdd7220b4fd75c9aa3add4c0c5cf8e96c # Parent b9a33a7194ce666ef2bbd78b2387a2e7e000c786 Merge branch 'id-release-new-tag' into 'main' Release 13.23.1 See merge request gitlab-org/gitlab-shell!561 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.23.1 + +- Replace golang.org/x/crypto with gitlab-org/golang-crypto !560 + v13.23.0 - Add support for SSHUploadPackWithSidechannel RPC !557 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.0 +13.23.1 # HG changeset patch # User Dustin Collins <714871-dustinmm80@users.noreply.gitlab.com> # Date 1643677285 0 # Tue Feb 01 01:01:25 2022 +0000 # Node ID 579aace524610f6a09af31f8018e2ef345263676 # Parent c980b46fd02fa3ba6ff9deae8ea6febd1f7e3692 Update Go to version 1.17.6 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.16.12 +golang 1.17.6 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1643677285 0 # Tue Feb 01 01:01:25 2022 +0000 # Node ID 764b23f3364d4d09e533af02d227c6735ac582da # Parent c980b46fd02fa3ba6ff9deae8ea6febd1f7e3692 # Parent 579aace524610f6a09af31f8018e2ef345263676 Merge branch '547-update-go-to-1176' into 'main' Update Go to version 1.17.6 Closes #547 See merge request gitlab-org/gitlab-shell!562 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.16.12 +golang 1.17.6 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1643762913 -39600 # Wed Feb 02 11:48:33 2022 +1100 # Node ID 1d419ff3814bb884456e3b2b8547054ffc7bc3ed # Parent 764b23f3364d4d09e533af02d227c6735ac582da Alpha sort .gitignore diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,20 @@ -config.yml -cover.out -tmp/* -.idea *.log *.swp -/*.log* -authorized_keys.lock +.bundle +.bundle/ .gitlab_shell_secret -.bundle -tags -.bundle/ -custom_hooks -hooks/*.d -/go_build -/bin/gitlab-sshd +.idea +/*.log* +/bin/check /bin/gitlab-shell /bin/gitlab-shell-authorized-keys-check /bin/gitlab-shell-authorized-principals-check -/bin/check +/bin/gitlab-sshd +/go_build +authorized_keys.lock +config.yml +cover.out +custom_hooks +hooks/*.d +tags +tmp/* # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1643762928 -39600 # Wed Feb 02 11:48:48 2022 +1100 # Node ID 1f269d721dbb7fb21f4bd8a9f9181c5f665cf27f # Parent 1d419ff3814bb884456e3b2b8547054ffc7bc3ed Ignore vendor directory diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ hooks/*.d tags tmp/* +vendor # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1643763633 -39600 # Wed Feb 02 12:00:33 2022 +1100 # Node ID 7782d657e6cf7561d0bdd0947cc91713707a72f6 # Parent 1f269d721dbb7fb21f4bd8a9f9181c5f665cf27f Ignore vendor/ directory even if present diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$$0="v"$$0' VERSION 2>/dev/null || echo unknown) BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver -GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1643782250 0 # Wed Feb 02 06:10:50 2022 +0000 # Node ID e0329c98e29e2ace88a1cc3adf9675ef856d7df8 # Parent 764b23f3364d4d09e533af02d227c6735ac582da # Parent 7782d657e6cf7561d0bdd0947cc91713707a72f6 Merge branch '539-problem-with-upgrading' into 'main' When building, ignore the vendor/ directory if present Closes #539 See merge request gitlab-org/gitlab-shell!565 diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,21 @@ -config.yml -cover.out -tmp/* -.idea *.log *.swp -/*.log* -authorized_keys.lock +.bundle +.bundle/ .gitlab_shell_secret -.bundle -tags -.bundle/ -custom_hooks -hooks/*.d -/go_build -/bin/gitlab-sshd +.idea +/*.log* +/bin/check /bin/gitlab-shell /bin/gitlab-shell-authorized-keys-check /bin/gitlab-shell-authorized-principals-check -/bin/check +/bin/gitlab-sshd +/go_build +authorized_keys.lock +config.yml +cover.out +custom_hooks +hooks/*.d +tags +tmp/* +vendor diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$$0="v"$$0' VERSION 2>/dev/null || echo unknown) BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver -GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643695105 -10800 # Tue Feb 01 08:58:25 2022 +0300 # Node ID d7528d2ae08fbfc36b618727d94172dd98318529 # Parent c980b46fd02fa3ba6ff9deae8ea6febd1f7e3692 Bump go-proxyproto package diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.0 + github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.10.0 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -669,8 +669,8 @@ 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/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= -github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= +github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1643791996 0 # Wed Feb 02 08:53:16 2022 +0000 # Node ID d706e036dece9dd2c04ea2f0adcbd54f241daa5f # Parent e0329c98e29e2ace88a1cc3adf9675ef856d7df8 # Parent d7528d2ae08fbfc36b618727d94172dd98318529 Merge branch 'id-bump-go-proxyproto' into 'main' Bump go-proxyproto package See merge request gitlab-org/gitlab-shell!563 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.0 + github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.10.0 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -669,8 +669,8 @@ 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/pires/go-proxyproto v0.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= -github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= +github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643704780 -10800 # Tue Feb 01 11:39:40 2022 +0300 # Node ID 651e7a11b1acb1bd0826da249c28d2f497d5648a # Parent c980b46fd02fa3ba6ff9deae8ea6febd1f7e3692 Handle and log unhandled errors Currently, we don't process the results of this execution, because it's not really imprortant Let's at least log the err if the execution went wrong That will also make Vulnerability report happy diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -26,7 +26,7 @@ ctxlog := log.ContextLogger(ctx) ctxlog.Debug("twofactorrecover: execute: Waiting for user input") - if c.canContinue() { + if c.getUserAnswer(ctx) == "yes" { ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { @@ -37,16 +37,18 @@ return nil } -func (c *Command) canContinue() bool { +func (c *Command) getUserAnswer(ctx context.Context) string { question := "Are you sure you want to generate new two-factor recovery codes?\n" + "Any existing recovery codes you saved will be invalidated. (yes/no)" fmt.Fprintln(c.ReadWriter.Out, question) var answer string - fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer) + if _, err := fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorrecover: getUserAnswer: Failed to get user input") + } - return answer == "yes" + return answer } func (c *Command) displayRecoveryCodes(ctx context.Context) { diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -22,7 +22,7 @@ func (c *Command) Execute(ctx context.Context) error { ctxlog := log.ContextLogger(ctx) ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP() + otp := c.getOTP(ctx) ctxlog.Info("twofactorverify: execute: verifying entered OTP") err := c.verifyOTP(ctx, otp) @@ -35,14 +35,16 @@ return nil } -func (c *Command) getOTP() string { +func (c *Command) getOTP(ctx context.Context) string { prompt := "OTP: " fmt.Fprint(c.ReadWriter.Out, prompt) var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) - fmt.Fscanln(reader, &answer) + if _, err := fmt.Fscanln(reader, &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") + } return answer } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -66,8 +66,11 @@ default: // Ignore unknown requests but don't terminate the session shouldContinue = true + if req.WantReply { - req.Reply(false, []byte{}) + if err := req.Reply(false, []byte{}); err != nil { + sessionLog.WithError(err).Debug("session: handle: Failed to reply") + } } } @@ -100,7 +103,9 @@ } if req.WantReply { - req.Reply(accepted, []byte{}) + if err := req.Reply(accepted, []byte{}); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("session: handleEnv: Failed to reply") + } } log.WithContextFields( @@ -124,8 +129,12 @@ } func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { + ctxlog := log.ContextLogger(ctx) + if req.WantReply { - req.Reply(true, []byte{}) + if err := req.Reply(true, []byte{}); err != nil { + ctxlog.WithError(err).Debug("session: handleShell: Failed to reply") + } } env := sshenv.Env{ @@ -151,7 +160,6 @@ } cmdName := reflect.TypeOf(cmd).String() - ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") if err := cmd.Execute(ctx); err != nil { # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1643858979 0 # Thu Feb 03 03:29:39 2022 +0000 # Node ID b018dab8a79e595032abed594427df5b2dcc2f88 # Parent d706e036dece9dd2c04ea2f0adcbd54f241daa5f # Parent 651e7a11b1acb1bd0826da249c28d2f497d5648a Merge branch 'id-handle-unhandled-errs' into 'main' Handle and log unhandled errors See merge request gitlab-org/gitlab-shell!564 diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -26,7 +26,7 @@ ctxlog := log.ContextLogger(ctx) ctxlog.Debug("twofactorrecover: execute: Waiting for user input") - if c.canContinue() { + if c.getUserAnswer(ctx) == "yes" { ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { @@ -37,16 +37,18 @@ return nil } -func (c *Command) canContinue() bool { +func (c *Command) getUserAnswer(ctx context.Context) string { question := "Are you sure you want to generate new two-factor recovery codes?\n" + "Any existing recovery codes you saved will be invalidated. (yes/no)" fmt.Fprintln(c.ReadWriter.Out, question) var answer string - fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer) + if _, err := fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorrecover: getUserAnswer: Failed to get user input") + } - return answer == "yes" + return answer } func (c *Command) displayRecoveryCodes(ctx context.Context) { diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -22,7 +22,7 @@ func (c *Command) Execute(ctx context.Context) error { ctxlog := log.ContextLogger(ctx) ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP() + otp := c.getOTP(ctx) ctxlog.Info("twofactorverify: execute: verifying entered OTP") err := c.verifyOTP(ctx, otp) @@ -35,14 +35,16 @@ return nil } -func (c *Command) getOTP() string { +func (c *Command) getOTP(ctx context.Context) string { prompt := "OTP: " fmt.Fprint(c.ReadWriter.Out, prompt) var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) - fmt.Fscanln(reader, &answer) + if _, err := fmt.Fscanln(reader, &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") + } return answer } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -66,8 +66,11 @@ default: // Ignore unknown requests but don't terminate the session shouldContinue = true + if req.WantReply { - req.Reply(false, []byte{}) + if err := req.Reply(false, []byte{}); err != nil { + sessionLog.WithError(err).Debug("session: handle: Failed to reply") + } } } @@ -100,7 +103,9 @@ } if req.WantReply { - req.Reply(accepted, []byte{}) + if err := req.Reply(accepted, []byte{}); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("session: handleEnv: Failed to reply") + } } log.WithContextFields( @@ -124,8 +129,12 @@ } func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { + ctxlog := log.ContextLogger(ctx) + if req.WantReply { - req.Reply(true, []byte{}) + if err := req.Reply(true, []byte{}); err != nil { + ctxlog.WithError(err).Debug("session: handleShell: Failed to reply") + } } env := sshenv.Env{ @@ -151,7 +160,6 @@ } cmdName := reflect.TypeOf(cmd).String() - ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") if err := cmd.Execute(ctx); err != nil { # HG changeset patch # User Sean Carroll <scarroll@gitlab.com> # Date 1643835576 0 # Wed Feb 02 20:59:36 2022 +0000 # Node ID 3ee55a99af18602455e86ca82ccfe41a44c40786 # Parent d706e036dece9dd2c04ea2f0adcbd54f241daa5f Update LICENSE to 2022 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2018 GitLab B.V. +Copyright (c) 2011-2022 GitLab B.V. With regard to the GitLab Software: # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643871009 0 # Thu Feb 03 06:50:09 2022 +0000 # Node ID ec9cb207066e44ae038f29d35766d7a42a6f6c97 # Parent b018dab8a79e595032abed594427df5b2dcc2f88 # Parent 3ee55a99af18602455e86ca82ccfe41a44c40786 Merge branch 'sean_carroll-main-patch-51330' into 'main' Update LICENSE to 2022 See merge request gitlab-org/gitlab-shell!566 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2018 GitLab B.V. +Copyright (c) 2011-2022 GitLab B.V. With regard to the GitLab Software: # HG changeset patch # User Dan Rhodes <drhodes@gitlab.com> # Date 1643897533 0 # Thu Feb 03 14:12:13 2022 +0000 # Node ID e3dcb762bb25f717f38fe358aaa043e0036e1491 # Parent ec9cb207066e44ae038f29d35766d7a42a6f6c97 Add title and correct c.right notice to license diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -Copyright (c) 2011-2022 GitLab B.V. +MIT License -With regard to the GitLab Software: +Copyright (c) 2011-present GitLab B.V. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,17 +9,13 @@ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For all third party components incorporated into the GitLab Software, those -components are licensed under the original license provided by the owner of the -applicable component. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1643900695 0 # Thu Feb 03 15:04:55 2022 +0000 # Node ID 8ce047910bdc4933916b05a9c63eeaee4351c744 # Parent ec9cb207066e44ae038f29d35766d7a42a6f6c97 # Parent e3dcb762bb25f717f38fe358aaa043e0036e1491 Merge branch 'dfrhodes-main-patch-08696' into 'main' Add title and correct copyright notice to license See merge request gitlab-org/gitlab-shell!568 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -Copyright (c) 2011-2022 GitLab B.V. +MIT License -With regard to the GitLab Software: +Copyright (c) 2011-present GitLab B.V. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,17 +9,13 @@ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For all third party components incorporated into the GitLab Software, those -components are licensed under the original license provided by the owner of the -applicable component. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1644526720 -10800 # Thu Feb 10 23:58:40 2022 +0300 # Node ID b25ff657093910467ba52a6de806b3945ff9ad53 # Parent 8ce047910bdc4933916b05a9c63eeaee4351c744 Bump labkit version to 1.12.0 It also bumps minor versions of its dependencies diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -9,13 +9,13 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.1 - github.com/prometheus/client_golang v1.10.0 + github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 - gitlab.com/gitlab-org/labkit v1.7.0 + gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.38.0 + google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -21,8 +21,13 @@ cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +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/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= @@ -32,6 +37,8 @@ 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/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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -44,6 +51,8 @@ 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/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= 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= @@ -88,17 +97,22 @@ github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= +github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= +github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= -github.com/HdrHistogram/hdrhistogram-go v1.1.0 h1:6dpdDPTRoo78HxAJ6T1HfMiKSnqhgRRqzCuPshRkQ7I= 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= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE= github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -116,6 +130,7 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -145,6 +160,9 @@ github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= +github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -161,6 +179,7 @@ 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/xds/go v0.0.0-20210312221358-fbca930ec8ed/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= @@ -212,6 +231,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 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/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= @@ -233,6 +253,7 @@ github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= +github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -310,8 +331,9 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -345,16 +367,20 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 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-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= 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= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 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/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= @@ -367,8 +393,12 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/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= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595 h1:uNrRgpnKjTfxu4qHaZAAs3eKTYV1EzGF3dAykpnxgDE= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= @@ -396,6 +426,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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= @@ -495,8 +526,8 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -559,8 +590,9 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0 h1:qGUbkzHP64NA9r+uIbCvf303IzHPr0M4JlkaDMxXqqk= github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= +github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= +github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -663,8 +695,9 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= 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= @@ -685,8 +718,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -698,8 +732,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -709,6 +744,7 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -733,6 +769,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= +github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -750,6 +788,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -779,11 +818,16 @@ github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible h1:6WVONolFJiB8Vx9bq4z9ddyV/SXSpfvvtb7Yl/TGHiE= github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= +github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= @@ -815,6 +859,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= @@ -831,8 +876,8 @@ 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.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= -gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= +gitlab.com/gitlab-org/labkit v1.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= +gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= 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= @@ -847,6 +892,7 @@ go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 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= @@ -893,8 +939,9 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -905,7 +952,6 @@ 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/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= @@ -956,6 +1002,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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= @@ -974,8 +1021,11 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c h1:SgVl/sCtkicsS7psKkje4H9YtjdEl3xsYh7N+5TDHqY= 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/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= @@ -1048,6 +1098,7 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1055,13 +1106,21 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= @@ -1146,8 +1205,13 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1186,8 +1250,13 @@ google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= -google.golang.org/api v0.46.0 h1:jkDWHOBIoNSD0OQpq4rtBVu+Rh325MPjXG1rakAp8JU= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +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/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= @@ -1225,6 +1294,7 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1247,8 +1317,18 @@ google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= 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-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= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +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/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= @@ -1269,14 +1349,20 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 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/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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1288,11 +1374,13 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= 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= 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 h1:yJJrDYzAlUsDPpAVBjv4VFnXKTbgvaJFTX0646xDPi4= 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= +gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1324,6 +1412,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1644549365 0 # Fri Feb 11 03:16:05 2022 +0000 # Node ID b028fb8e0da292d66af6578395a6b03fd094be38 # Parent 8ce047910bdc4933916b05a9c63eeaee4351c744 # Parent b25ff657093910467ba52a6de806b3945ff9ad53 Merge branch 'id-update-labkit-version' into 'main' Bump labkit version to 1.12.0 See merge request gitlab-org/gitlab-shell!569 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -9,13 +9,13 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.1 - github.com/prometheus/client_golang v1.10.0 + github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 - gitlab.com/gitlab-org/labkit v1.7.0 + gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.38.0 + google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -21,8 +21,13 @@ cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +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/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= @@ -32,6 +37,8 @@ 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/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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -44,6 +51,8 @@ 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/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= 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= @@ -88,17 +97,22 @@ github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= +github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= +github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= -github.com/HdrHistogram/hdrhistogram-go v1.1.0 h1:6dpdDPTRoo78HxAJ6T1HfMiKSnqhgRRqzCuPshRkQ7I= 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= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE= github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -116,6 +130,7 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -145,6 +160,9 @@ github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= +github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -161,6 +179,7 @@ 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/xds/go v0.0.0-20210312221358-fbca930ec8ed/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= @@ -212,6 +231,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 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/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= @@ -233,6 +253,7 @@ github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= +github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -310,8 +331,9 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -345,16 +367,20 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 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-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= 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= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 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/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= @@ -367,8 +393,12 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/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= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595 h1:uNrRgpnKjTfxu4qHaZAAs3eKTYV1EzGF3dAykpnxgDE= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= @@ -396,6 +426,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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= @@ -495,8 +526,8 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -559,8 +590,9 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0 h1:qGUbkzHP64NA9r+uIbCvf303IzHPr0M4JlkaDMxXqqk= github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= +github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= +github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -663,8 +695,9 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= 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= @@ -685,8 +718,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -698,8 +732,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -709,6 +744,7 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -733,6 +769,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= +github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -750,6 +788,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -779,11 +818,16 @@ github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible h1:6WVONolFJiB8Vx9bq4z9ddyV/SXSpfvvtb7Yl/TGHiE= github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= +github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= @@ -815,6 +859,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= @@ -831,8 +876,8 @@ 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.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= -gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= +gitlab.com/gitlab-org/labkit v1.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= +gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= 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= @@ -847,6 +892,7 @@ go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 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= @@ -893,8 +939,9 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -905,7 +952,6 @@ 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/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= @@ -956,6 +1002,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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= @@ -974,8 +1021,11 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c h1:SgVl/sCtkicsS7psKkje4H9YtjdEl3xsYh7N+5TDHqY= 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/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= @@ -1048,6 +1098,7 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1055,13 +1106,21 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= @@ -1146,8 +1205,13 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1186,8 +1250,13 @@ google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= -google.golang.org/api v0.46.0 h1:jkDWHOBIoNSD0OQpq4rtBVu+Rh325MPjXG1rakAp8JU= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +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/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= @@ -1225,6 +1294,7 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1247,8 +1317,18 @@ google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210506142907-4a47615972c2 h1:pl8qT5D+48655f14yDURpIZwSPvMWuuekfAP+gxtjvk= 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-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= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +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/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= @@ -1269,14 +1349,20 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 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/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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1288,11 +1374,13 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= 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= 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 h1:yJJrDYzAlUsDPpAVBjv4VFnXKTbgvaJFTX0646xDPi4= 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= +gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1324,6 +1412,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1644557128 -10800 # Fri Feb 11 08:25:28 2022 +0300 # Node ID 4d0cb80af195a05eb5f019f57ad00be260db925c # Parent b028fb8e0da292d66af6578395a6b03fd094be38 Release 13.23.2 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +v13.23.2 + +- Bump labkit version to 1.12.0 !569 +- Add title and correct copyright notice to license !568 +- Bump go-proxyproto package !563 +- Update Go to version 1.17.6 !562 + v13.23.1 - Replace golang.org/x/crypto with gitlab-org/golang-crypto !560 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.1 +13.23.2 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1644557600 0 # Fri Feb 11 05:33:20 2022 +0000 # Node ID 7298cb147cee1f199041abc6e9d7649d369e4164 # Parent b028fb8e0da292d66af6578395a6b03fd094be38 # Parent 4d0cb80af195a05eb5f019f57ad00be260db925c Merge branch 'id-release-13-23-2' into 'main' Release 13.23.2 See merge request gitlab-org/gitlab-shell!570 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +v13.23.2 + +- Bump labkit version to 1.12.0 !569 +- Add title and correct copyright notice to license !568 +- Bump go-proxyproto package !563 +- Update Go to version 1.17.6 !562 + v13.23.1 - Replace golang.org/x/crypto with gitlab-org/golang-crypto !560 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.1 +13.23.2 # HG changeset patch # User Amy Qualls <aqualls@gitlab.com> # Date 1644941285 0 # Tue Feb 15 16:08:05 2022 +0000 # Node ID d4783460ff560256ff4008674064e88134689cb1 # Parent 7298cb147cee1f199041abc6e9d7649d369e4164 Add aqualls as codeowner for docs files diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,1 +1,4 @@ * @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao + +[Documentation] +*.md @aqualls # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1644941286 0 # Tue Feb 15 16:08:06 2022 +0000 # Node ID fb67d0891763f5844078fee22094149cfe162725 # Parent 7298cb147cee1f199041abc6e9d7649d369e4164 # Parent d4783460ff560256ff4008674064e88134689cb1 Merge branch 'aqualls-codeowner-addition' into 'main' Add aqualls as codeowner for docs files See merge request gitlab-org/gitlab-shell!573 diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,1 +1,4 @@ * @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao + +[Documentation] +*.md @aqualls # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1644916972 -10800 # Tue Feb 15 12:22:52 2022 +0300 # Node ID b8965ff7051e334de43515156b0141cb7fdb6e7b # Parent 7298cb147cee1f199041abc6e9d7649d369e4164 Add docs for full feature list Describe what Gitlab Shell is capable of diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ 1. git pull over SSH -> gitlab-shell -> API call to gitlab-rails (Authorization) -> accept or decline -> establish Gitaly session 1. git push over SSH -> gitlab-shell (git command is not executed yet) -> establish Gitaly session -> (in Gitaly) gitlab-shell pre-receive hook -> API call to gitlab-rails (authorization) -> accept or decline push +[Full feature list](/doc/features.md) + ## Code status [![pipeline status](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main) @@ -94,10 +96,6 @@ tests requiring Gitaly will be skipped. They will always run in the CI environment. -## Git LFS - -Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. - ## Logging Guidelines In general, it should be possible to determine the structure, but not content, diff --git a/doc/features.md b/doc/features.md new file mode 100644 --- /dev/null +++ b/doc/features.md @@ -0,0 +1,69 @@ +### Discover + +Allows users to identify themselves on an instance via SSH. The command is useful for checking out quickly whether a user has SSH access to the instance: + +```bash +ssh git@<hostname> + +PTY allocation request failed on channel 0 +Welcome to GitLab, @username! +Connection to staging.gitlab.com closed. +``` + +When permission is denied: + +```bash +ssh git@<hostname> +git@<hostname>: Permission denied (publickey). +``` + +### Git operations + +Gitlab Shell provides support for Git operations over SSH via processing `git-upload-pack`, `git-receive-pack` and `git-upload-archive` SSH commands. It limit the set of commands to predefined git commands (git push, git clone/pull, git archive). + +### Generate new 2FA recovery codes + +Allows users to [generate new 2FA recovery codes](https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html#generate-new-recovery-codes-using-ssh). + +```bash +ssh git@<hostname> 2fa_recovery_codes +Are you sure you want to generate new two-factor recovery codes? +Any existing recovery codes you saved will be invalidated. (yes/no) +yes + +Your two-factor authentication recovery codes are: +... +``` + +### Verify 2FA OTP + +Allows users to [verify their 2FA OTP](https://docs.gitlab.com/ee/security/two_factor_authentication.html#2fa-for-git-over-ssh-operations). + +```bash +ssh git@<hostname> 2fa_verify +OTP: 347419 + +OTP validation failed. +``` + +### LFS authentication + +Allows users to generate credentials for LFS authentication. + +```bash +ssh git@<hostname> git-lfs-authenticate <project-path> <upload/download> + +{"header":{"Authorization":"Basic ..."},"href":"https://gitlab.com/user/project.git/info/lfs","expires_in":7200} +``` + +### Personal access token + +Allows users to personal access tokens via SSH + +```bash +ssh git@<hostname> personal_access_token <name> <scope1[,scope2,...]> [ttl_days] + +Token: glpat-... +Scopes: api +Expires: 2022-02-05 +``` # HG changeset patch # User Amy Qualls <aqualls@gitlab.com> # Date 1644940151 28800 # Tue Feb 15 07:49:11 2022 -0800 # Node ID 917d7140aefce92a7b5df2d641471c2f132c7ce2 # Parent b8965ff7051e334de43515156b0141cb7fdb6e7b Fix link in README Shouldn't start with a leading slash. diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ 1. git pull over SSH -> gitlab-shell -> API call to gitlab-rails (Authorization) -> accept or decline -> establish Gitaly session 1. git push over SSH -> gitlab-shell (git command is not executed yet) -> establish Gitaly session -> (in Gitaly) gitlab-shell pre-receive hook -> API call to gitlab-rails (authorization) -> accept or decline push -[Full feature list](/doc/features.md) +[Full feature list](doc/features.md) ## Code status @@ -115,7 +115,7 @@ GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. -The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. # HG changeset patch # User Amy Qualls <aqualls@gitlab.com> # Date 1644940170 28800 # Tue Feb 15 07:49:30 2022 -0800 # Node ID 5ed6fda2a66f36a8943a0aec6f488dcc2d018b09 # Parent 917d7140aefce92a7b5df2d641471c2f132c7ce2 Revisions for tone and style Do an initial cleanup pass: - Line wraps - Change 'allows' to 'enables' - Clean up syntax highlighting - Fix spelling and capitalization - Standardize on colons at the end of the introductory sentences diff --git a/doc/features.md b/doc/features.md --- a/doc/features.md +++ b/doc/features.md @@ -1,8 +1,11 @@ -### Discover +# Feature list + +## Discover -Allows users to identify themselves on an instance via SSH. The command is useful for checking out quickly whether a user has SSH access to the instance: +Allows users to identify themselves on an instance via SSH. The command helps to +confirm quickly whether a user has SSH access to the instance: -```bash +```shell ssh git@<hostname> PTY allocation request failed on channel 0 @@ -10,22 +13,30 @@ Connection to staging.gitlab.com closed. ``` -When permission is denied: +When permission is denied, it returns: -```bash +```shell ssh git@<hostname> git@<hostname>: Permission denied (publickey). ``` -### Git operations +## Git operations -Gitlab Shell provides support for Git operations over SSH via processing `git-upload-pack`, `git-receive-pack` and `git-upload-archive` SSH commands. It limit the set of commands to predefined git commands (git push, git clone/pull, git archive). +GitLab Shell provides support for Git operations over SSH by processing +`git-upload-pack`, `git-receive-pack` and `git-upload-archive` SSH commands. +It limits the set of commands to predefined Git commands: -### Generate new 2FA recovery codes +- `git archive` +- `git clone` +- `git pull` +- `git push` -Allows users to [generate new 2FA recovery codes](https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html#generate-new-recovery-codes-using-ssh). +## Generate new 2FA recovery codes -```bash +Enables users to +[generate new 2FA recovery codes](https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html#generate-new-recovery-codes-using-ssh): + +```plaintext ssh git@<hostname> 2fa_recovery_codes Are you sure you want to generate new two-factor recovery codes? Any existing recovery codes you saved will be invalidated. (yes/no) @@ -35,32 +46,33 @@ ... ``` -### Verify 2FA OTP +## Verify 2FA OTP -Allows users to [verify their 2FA OTP](https://docs.gitlab.com/ee/security/two_factor_authentication.html#2fa-for-git-over-ssh-operations). +Allows users to verify their +[2FA one-time password (OTP)](https://docs.gitlab.com/ee/security/two_factor_authentication.html#2fa-for-git-over-ssh-operations): -```bash +```shell ssh git@<hostname> 2fa_verify OTP: 347419 OTP validation failed. ``` -### LFS authentication +## LFS authentication -Allows users to generate credentials for LFS authentication. +Enables users to generate credentials for LFS authentication: -```bash +```shell ssh git@<hostname> git-lfs-authenticate <project-path> <upload/download> {"header":{"Authorization":"Basic ..."},"href":"https://gitlab.com/user/project.git/info/lfs","expires_in":7200} ``` -### Personal access token +## Personal access token -Allows users to personal access tokens via SSH +Enables users to use personal access tokens via SSH: -```bash +```shell ssh git@<hostname> personal_access_token <name> <scope1[,scope2,...]> [ttl_days] Token: glpat-... # HG changeset patch # User Amy Qualls <aqualls@gitlab.com> # Date 1644940300 28800 # Tue Feb 15 07:51:40 2022 -0800 # Node ID 679b2636650368f6dd11f00c9a89c887212076af # Parent 5ed6fda2a66f36a8943a0aec6f488dcc2d018b09 Add metadata for these pages These pages should get credited to Source Code. (I should also check about CODEOWNERS entries too.) diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + # GitLab Shell ## GitLab Shell handles git SSH sessions for GitLab diff --git a/doc/features.md b/doc/features.md --- a/doc/features.md +++ b/doc/features.md @@ -1,3 +1,9 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + # Feature list ## Discover # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1644986027 0 # Wed Feb 16 04:33:47 2022 +0000 # Node ID f9a29a150ebc159cbe4ad1d32e2be2adc8adbfd4 # Parent fb67d0891763f5844078fee22094149cfe162725 # Parent 679b2636650368f6dd11f00c9a89c887212076af Merge branch 'id-add-features-description' into 'main' Add docs for full feature list See merge request gitlab-org/gitlab-shell!571 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + # GitLab Shell ## GitLab Shell handles git SSH sessions for GitLab @@ -18,6 +24,8 @@ 1. git pull over SSH -> gitlab-shell -> API call to gitlab-rails (Authorization) -> accept or decline -> establish Gitaly session 1. git push over SSH -> gitlab-shell (git command is not executed yet) -> establish Gitaly session -> (in Gitaly) gitlab-shell pre-receive hook -> API call to gitlab-rails (authorization) -> accept or decline push +[Full feature list](doc/features.md) + ## Code status [![pipeline status](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main) @@ -94,10 +102,6 @@ tests requiring Gitaly will be skipped. They will always run in the CI environment. -## Git LFS - -Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. - ## Logging Guidelines In general, it should be possible to determine the structure, but not content, @@ -117,7 +121,7 @@ GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. -The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. diff --git a/doc/features.md b/doc/features.md new file mode 100644 --- /dev/null +++ b/doc/features.md @@ -0,0 +1,87 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Feature list + +## Discover + +Allows users to identify themselves on an instance via SSH. The command helps to +confirm quickly whether a user has SSH access to the instance: + +```shell +ssh git@<hostname> + +PTY allocation request failed on channel 0 +Welcome to GitLab, @username! +Connection to staging.gitlab.com closed. +``` + +When permission is denied, it returns: + +```shell +ssh git@<hostname> +git@<hostname>: Permission denied (publickey). +``` + +## Git operations + +GitLab Shell provides support for Git operations over SSH by processing +`git-upload-pack`, `git-receive-pack` and `git-upload-archive` SSH commands. +It limits the set of commands to predefined Git commands: + +- `git archive` +- `git clone` +- `git pull` +- `git push` + +## Generate new 2FA recovery codes + +Enables users to +[generate new 2FA recovery codes](https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html#generate-new-recovery-codes-using-ssh): + +```plaintext +ssh git@<hostname> 2fa_recovery_codes +Are you sure you want to generate new two-factor recovery codes? +Any existing recovery codes you saved will be invalidated. (yes/no) +yes + +Your two-factor authentication recovery codes are: +... +``` + +## Verify 2FA OTP + +Allows users to verify their +[2FA one-time password (OTP)](https://docs.gitlab.com/ee/security/two_factor_authentication.html#2fa-for-git-over-ssh-operations): + +```shell +ssh git@<hostname> 2fa_verify +OTP: 347419 + +OTP validation failed. +``` + +## LFS authentication + +Enables users to generate credentials for LFS authentication: + +```shell +ssh git@<hostname> git-lfs-authenticate <project-path> <upload/download> + +{"header":{"Authorization":"Basic ..."},"href":"https://gitlab.com/user/project.git/info/lfs","expires_in":7200} +``` + +## Personal access token + +Enables users to use personal access tokens via SSH: + +```shell +ssh git@<hostname> personal_access_token <name> <scope1[,scope2,...]> [ttl_days] + +Token: glpat-... +Scopes: api +Expires: 2022-02-05 +``` # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1644917812 -10800 # Tue Feb 15 12:36:52 2022 +0300 # Node ID 61382697d85cbf0241d0e014812af72bec72042d # Parent f9a29a150ebc159cbe4ad1d32e2be2adc8adbfd4 Move code guidelines to doc/beginners_guide.md It helps to have less verbose README.md diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -42,81 +42,6 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Check - -Checks if GitLab API access and redis via internal API can be reached: - - make check - -## Compile - -Builds the `gitlab-shell` binaries, placing them into `bin/`. - - make compile - -## Install - -Builds the `gitlab-shell` binaries and installs them onto the filesystem. The -default location is `/usr/local`, but can be controlled by use of the `PREFIX` -and `DESTDIR` environment variables. - - make install - -## Setup - -This command is intended for use when installing GitLab from source on a single -machine. In addition to compiling the gitlab-shell binaries, it ensures that -various paths on the filesystem exist with the correct permissions. Do not run -it unless instructed to by your installation method documentation. - - make setup - - -## Testing - -Run tests: - - bundle install - make test - -Run gofmt: - - make verify - -Run both test and verify (the default Makefile target): - - bundle install - make validate - -### Gitaly - -Some tests need a Gitaly server. The -[`docker-compose.yml`](./docker-compose.yml) file will run Gitaly on -port 8075. To tell the tests where Gitaly is, set -`GITALY_CONNECTION_INFO`: - - export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' - make test - -If no `GITALY_CONNECTION_INFO` is set, the test suite will still run, but any -tests requiring Gitaly will be skipped. They will always run in the CI -environment. - -## Logging Guidelines - -In general, it should be possible to determine the structure, but not content, -of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some -guidelines: - -- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) - for logging functionality -- **Always** include a correlation ID -- Log messages should be invariant and unique. Include accessory information in - fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. -- Log success cases as well as error cases -- Logging too much is better than not logging enough. If a message seems too - verbose, consider reducing the log level before removing the message. - ## Rate Limiting GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. @@ -133,7 +58,8 @@ ## Contributing -See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See the [beginner's guide](doc/beginners_guide.md). ## License diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md new file mode 100644 --- /dev/null +++ b/doc/beginners_guide.md @@ -0,0 +1,76 @@ +## Beginner's guide to Gitlab Shell contributions + +### Check + +Checks if GitLab API access and redis via internal API can be reached: + + make check + +### Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + + make compile + +### Install + +Builds the `gitlab-shell` binaries and installs them onto the filesystem. The +default location is `/usr/local`, but can be controlled by use of the `PREFIX` +and `DESTDIR` environment variables. + + make install + +### Setup + +This command is intended for use when installing GitLab from source on a single +machine. In addition to compiling the gitlab-shell binaries, it ensures that +various paths on the filesystem exist with the correct permissions. Do not run +it unless instructed to by your installation method documentation. + + make setup + + +### Testing + +Run tests: + + bundle install + make test + +Run gofmt: + + make verify + +Run both test and verify (the default Makefile target): + + bundle install + make validate + +### Gitaly + +Some tests need a Gitaly server. The +[`docker-compose.yml`](./docker-compose.yml) file will run Gitaly on +port 8075. To tell the tests where Gitaly is, set +`GITALY_CONNECTION_INFO`: + + export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' + make test + +If no `GITALY_CONNECTION_INFO` is set, the test suite will still run, but any +tests requiring Gitaly will be skipped. They will always run in the CI +environment. + +### Logging Guidelines + +In general, it should be possible to determine the structure, but not content, +of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some +guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging functionality +- **Always** include a correlation ID +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log success cases as well as error cases +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1645025533 0 # Wed Feb 16 15:32:13 2022 +0000 # Node ID 265cd8bc4277717dc0bfec08fbe33ab90dee4605 # Parent 61382697d85cbf0241d0e014812af72bec72042d Add metadata to page diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md --- a/doc/beginners_guide.md +++ b/doc/beginners_guide.md @@ -1,3 +1,9 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + ## Beginner's guide to Gitlab Shell contributions ### Check # HG changeset patch # User Amy Qualls <aqualls@gitlab.com> # Date 1645026786 28800 # Wed Feb 16 07:53:06 2022 -0800 # Node ID 61e323eceabe34bd463aa02724763c0e63f2cf17 # Parent 265cd8bc4277717dc0bfec08fbe33ab90dee4605 First pass of tone and style polish Bring the page a lot closer to GitLab tone and style. Not perfect, but we've gotta start somewhere. diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md --- a/doc/beginners_guide.md +++ b/doc/beginners_guide.md @@ -4,79 +4,91 @@ info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -## Beginner's guide to Gitlab Shell contributions +# Beginner's guide to GitLab Shell contributions -### Check +## Check + +Checks if GitLab API access and Redis via internal API can be reached: -Checks if GitLab API access and redis via internal API can be reached: +```shell +make check +``` - make check - -### Compile +## Compile Builds the `gitlab-shell` binaries, placing them into `bin/`. - make compile +```shell +make compile +``` -### Install +## Install -Builds the `gitlab-shell` binaries and installs them onto the filesystem. The -default location is `/usr/local`, but can be controlled by use of the `PREFIX` +Builds the `gitlab-shell` binaries and installs them onto the file system. The +default location is `/usr/local`, but you can change the location by setting the `PREFIX` and `DESTDIR` environment variables. - make install +```shell +make install +``` -### Setup +## Setup This command is intended for use when installing GitLab from source on a single -machine. In addition to compiling the gitlab-shell binaries, it ensures that -various paths on the filesystem exist with the correct permissions. Do not run -it unless instructed to by your installation method documentation. +machine. It compiles the GitLab Shell binaries, and ensures that +various paths on the file system exist with the correct permissions. Do not run +this command unless your installation method documentation instructs you to. - make setup +```shell +make setup +``` - -### Testing +## Testing Run tests: - bundle install - make test +```shell +bundle install +make test +``` -Run gofmt: +Run Gofmt: - make verify +```shell +make verify +``` Run both test and verify (the default Makefile target): - bundle install - make validate +```shell +bundle install +make validate +``` -### Gitaly +## Gitaly Some tests need a Gitaly server. The -[`docker-compose.yml`](./docker-compose.yml) file will run Gitaly on -port 8075. To tell the tests where Gitaly is, set -`GITALY_CONNECTION_INFO`: +[`docker-compose.yml`](../docker-compose.yml) file runs Gitaly on port 8075. +To tell the tests where Gitaly is, set `GITALY_CONNECTION_INFO`: - export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' - make test +```plaintext +export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' +make test +``` -If no `GITALY_CONNECTION_INFO` is set, the test suite will still run, but any -tests requiring Gitaly will be skipped. They will always run in the CI -environment. +If no `GITALY_CONNECTION_INFO` is set, the test suite still runs, but any +tests requiring Gitaly are skipped. The tests always run in the CI environment. -### Logging Guidelines +## Logging Guidelines -In general, it should be possible to determine the structure, but not content, -of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some -guidelines: +In general, you can determine the structure, but not content, of a GitLab Shell +or `gitlab-sshd` session by inspecting the logs. Some guidelines: - We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) - for logging functionality -- **Always** include a correlation ID + for logging. +- Always include a correlation ID. - Log messages should be invariant and unique. Include accessory information in fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. -- Log success cases as well as error cases +- Log both success cases and error cases. - Logging too much is better than not logging enough. If a message seems too verbose, consider reducing the log level before removing the message. # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1645071804 0 # Thu Feb 17 04:23:24 2022 +0000 # Node ID 6ea91f81fdce307685c6d4455a6717d3e9f8c3e6 # Parent f9a29a150ebc159cbe4ad1d32e2be2adc8adbfd4 # Parent 61e323eceabe34bd463aa02724763c0e63f2cf17 Merge branch 'id-create-beginners-guide' into 'main' Move code guidelines to doc/beginners_guide.md See merge request gitlab-org/gitlab-shell!572 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -42,81 +42,6 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Check - -Checks if GitLab API access and redis via internal API can be reached: - - make check - -## Compile - -Builds the `gitlab-shell` binaries, placing them into `bin/`. - - make compile - -## Install - -Builds the `gitlab-shell` binaries and installs them onto the filesystem. The -default location is `/usr/local`, but can be controlled by use of the `PREFIX` -and `DESTDIR` environment variables. - - make install - -## Setup - -This command is intended for use when installing GitLab from source on a single -machine. In addition to compiling the gitlab-shell binaries, it ensures that -various paths on the filesystem exist with the correct permissions. Do not run -it unless instructed to by your installation method documentation. - - make setup - - -## Testing - -Run tests: - - bundle install - make test - -Run gofmt: - - make verify - -Run both test and verify (the default Makefile target): - - bundle install - make validate - -### Gitaly - -Some tests need a Gitaly server. The -[`docker-compose.yml`](./docker-compose.yml) file will run Gitaly on -port 8075. To tell the tests where Gitaly is, set -`GITALY_CONNECTION_INFO`: - - export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' - make test - -If no `GITALY_CONNECTION_INFO` is set, the test suite will still run, but any -tests requiring Gitaly will be skipped. They will always run in the CI -environment. - -## Logging Guidelines - -In general, it should be possible to determine the structure, but not content, -of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some -guidelines: - -- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) - for logging functionality -- **Always** include a correlation ID -- Log messages should be invariant and unique. Include accessory information in - fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. -- Log success cases as well as error cases -- Logging too much is better than not logging enough. If a message seems too - verbose, consider reducing the log level before removing the message. - ## Rate Limiting GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. @@ -133,7 +58,8 @@ ## Contributing -See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See the [beginner's guide](doc/beginners_guide.md). ## License diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md new file mode 100644 --- /dev/null +++ b/doc/beginners_guide.md @@ -0,0 +1,94 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Beginner's guide to GitLab Shell contributions + +## Check + +Checks if GitLab API access and Redis via internal API can be reached: + +```shell +make check +``` + +## Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + +```shell +make compile +``` + +## Install + +Builds the `gitlab-shell` binaries and installs them onto the file system. The +default location is `/usr/local`, but you can change the location by setting the `PREFIX` +and `DESTDIR` environment variables. + +```shell +make install +``` + +## Setup + +This command is intended for use when installing GitLab from source on a single +machine. It compiles the GitLab Shell binaries, and ensures that +various paths on the file system exist with the correct permissions. Do not run +this command unless your installation method documentation instructs you to. + +```shell +make setup +``` + +## Testing + +Run tests: + +```shell +bundle install +make test +``` + +Run Gofmt: + +```shell +make verify +``` + +Run both test and verify (the default Makefile target): + +```shell +bundle install +make validate +``` + +## Gitaly + +Some tests need a Gitaly server. The +[`docker-compose.yml`](../docker-compose.yml) file runs Gitaly on port 8075. +To tell the tests where Gitaly is, set `GITALY_CONNECTION_INFO`: + +```plaintext +export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' +make test +``` + +If no `GITALY_CONNECTION_INFO` is set, the test suite still runs, but any +tests requiring Gitaly are skipped. The tests always run in the CI environment. + +## Logging Guidelines + +In general, you can determine the structure, but not content, of a GitLab Shell +or `gitlab-sshd` session by inspecting the logs. Some guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging. +- Always include a correlation ID. +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log both success cases and error cases. +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1645029164 -10800 # Wed Feb 16 19:32:44 2022 +0300 # Node ID 5d134925d763e644f7aea3a09bb2e682df8c4dce # Parent f9a29a150ebc159cbe4ad1d32e2be2adc8adbfd4 Add more metrics for gitlab-sshd - Counter of HTTP merge requests - Gauge of HTTP requests currently being performed - Gauge of connections currently handled by gitlab sshd diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -9,7 +9,6 @@ "sync" "time" - "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -114,7 +113,7 @@ } tr := client.Transport - client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) + client.Transport = metrics.NewRoundTripper(tr) c.httpClient = client }) diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -25,7 +25,7 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } -func TestHttpClient(t *testing.T) { +func TestCustomPrometheusMetrics(t *testing.T) { url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) config := &Config{GitlabUrl: url} @@ -38,14 +38,19 @@ ms, err := prometheus.DefaultGatherer.Gather() require.NoError(t, err) - lastMetric := ms[0] - require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") - - labels := lastMetric.GetMetric()[0].Label + var actualNames []string + for _, m := range ms[0:6] { + actualNames = append(actualNames, m.GetName()) + } - require.Equal(t, "code", labels[0].GetName()) - require.Equal(t, "404", labels[0].GetValue()) + expectedMetricNames := []string{ + "gitlab_shell_http_in_flight_requests", + "gitlab_shell_http_request_duration_seconds", + "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_concurrent_limited_sessions_total", + "gitlab_shell_sshd_connection_duration_seconds", + "gitlab_shell_sshd_in_flight_connections", + } - require.Equal(t, "method", labels[1].GetName()) - require.Equal(t, "get", labels[1].GetValue()) + require.Equal(t, expectedMetricNames, actualNames) } diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -1,14 +1,25 @@ package metrics import ( + "net/http" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" ) const ( namespace = "gitlab_shell" sshdSubsystem = "sshd" httpSubsystem = "http" + + httpInFlightRequestsMetricName = "in_flight_requests" + httpRequestsTotalMetricName = "requests_total" + httpRequestDurationSecondsMetricName = "request_duration_seconds" + + sshdConnectionsInFlightName = "in_flight_connections" + sshdConnectionDuration = "connection_duration_seconds" + sshdHitMaxSessions = "concurrent_limited_sessions_total" ) var ( @@ -16,7 +27,7 @@ prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", + Name: sshdConnectionDuration, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ 0.005, /* 5ms */ @@ -32,32 +43,72 @@ }, ) + SshdConnectionsInFlight = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdConnectionsInFlightName, + Help: "A gauge of connections currently being served by gitlab-shell sshd.", + }, + ) + SshdHitMaxSessions = promauto.NewCounter( prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", + Name: sshdHitMaxSessions, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) - HttpRequestDuration = promauto.NewHistogramVec( + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit + // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, + // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit + httpRequestsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpRequestsTotalMetricName, + Help: "A counter for http requests.", + }, + []string{"code", "method"}, + ) + + httpRequestDurationSeconds = promauto.NewHistogramVec( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: httpSubsystem, - Name: "request_seconds", - Help: "A histogram of latencies for gitlab-shell http requests", + Name: httpRequestDurationSecondsMetricName, + Help: "A histogram of latencies for http requests.", Buckets: []float64{ - 0.01, /* 10ms */ - 0.05, /* 50ms */ - 0.1, /* 100ms */ - 0.25, /* 250ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 5.0, /* 5s */ - 10.0, /* 10s */ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ }, }, []string{"code", "method"}, ) + + httpInFlightRequests = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpInFlightRequestsMetricName, + Help: "A gauge of requests currently being performed.", + }, + ) ) + +func NewRoundTripper(next http.RoundTripper) promhttp.RoundTripperFunc { + rt := next + + rt = promhttp.InstrumentRoundTripperCounter(httpRequestsTotal, rt) + rt = promhttp.InstrumentRoundTripperDuration(httpRequestDurationSeconds, rt) + return promhttp.InstrumentRoundTripperInFlight(httpInFlightRequests, rt) +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -31,6 +31,9 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + metrics.SshdConnectionsInFlight.Inc() + defer metrics.SshdConnectionsInFlight.Dec() + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1645501214 0 # Tue Feb 22 03:40:14 2022 +0000 # Node ID f93b7e6dd81a3ff0cef31d2621913110588e857a # Parent 6ea91f81fdce307685c6d4455a6717d3e9f8c3e6 # Parent 5d134925d763e644f7aea3a09bb2e682df8c4dce Merge branch 'id-concurrent-connections-prometheus' into 'main' Add more metrics for gitlab-sshd See merge request gitlab-org/gitlab-shell!574 diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -9,7 +9,6 @@ "sync" "time" - "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -114,7 +113,7 @@ } tr := client.Transport - client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) + client.Transport = metrics.NewRoundTripper(tr) c.httpClient = client }) diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -25,7 +25,7 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } -func TestHttpClient(t *testing.T) { +func TestCustomPrometheusMetrics(t *testing.T) { url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) config := &Config{GitlabUrl: url} @@ -38,14 +38,19 @@ ms, err := prometheus.DefaultGatherer.Gather() require.NoError(t, err) - lastMetric := ms[0] - require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") - - labels := lastMetric.GetMetric()[0].Label + var actualNames []string + for _, m := range ms[0:6] { + actualNames = append(actualNames, m.GetName()) + } - require.Equal(t, "code", labels[0].GetName()) - require.Equal(t, "404", labels[0].GetValue()) + expectedMetricNames := []string{ + "gitlab_shell_http_in_flight_requests", + "gitlab_shell_http_request_duration_seconds", + "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_concurrent_limited_sessions_total", + "gitlab_shell_sshd_connection_duration_seconds", + "gitlab_shell_sshd_in_flight_connections", + } - require.Equal(t, "method", labels[1].GetName()) - require.Equal(t, "get", labels[1].GetValue()) + require.Equal(t, expectedMetricNames, actualNames) } diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -1,14 +1,25 @@ package metrics import ( + "net/http" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" ) const ( namespace = "gitlab_shell" sshdSubsystem = "sshd" httpSubsystem = "http" + + httpInFlightRequestsMetricName = "in_flight_requests" + httpRequestsTotalMetricName = "requests_total" + httpRequestDurationSecondsMetricName = "request_duration_seconds" + + sshdConnectionsInFlightName = "in_flight_connections" + sshdConnectionDuration = "connection_duration_seconds" + sshdHitMaxSessions = "concurrent_limited_sessions_total" ) var ( @@ -16,7 +27,7 @@ prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", + Name: sshdConnectionDuration, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ 0.005, /* 5ms */ @@ -32,32 +43,72 @@ }, ) + SshdConnectionsInFlight = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdConnectionsInFlightName, + Help: "A gauge of connections currently being served by gitlab-shell sshd.", + }, + ) + SshdHitMaxSessions = promauto.NewCounter( prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", + Name: sshdHitMaxSessions, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) - HttpRequestDuration = promauto.NewHistogramVec( + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit + // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, + // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit + httpRequestsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpRequestsTotalMetricName, + Help: "A counter for http requests.", + }, + []string{"code", "method"}, + ) + + httpRequestDurationSeconds = promauto.NewHistogramVec( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: httpSubsystem, - Name: "request_seconds", - Help: "A histogram of latencies for gitlab-shell http requests", + Name: httpRequestDurationSecondsMetricName, + Help: "A histogram of latencies for http requests.", Buckets: []float64{ - 0.01, /* 10ms */ - 0.05, /* 50ms */ - 0.1, /* 100ms */ - 0.25, /* 250ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 5.0, /* 5s */ - 10.0, /* 10s */ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ }, }, []string{"code", "method"}, ) + + httpInFlightRequests = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpInFlightRequestsMetricName, + Help: "A gauge of requests currently being performed.", + }, + ) ) + +func NewRoundTripper(next http.RoundTripper) promhttp.RoundTripperFunc { + rt := next + + rt = promhttp.InstrumentRoundTripperCounter(httpRequestsTotal, rt) + rt = promhttp.InstrumentRoundTripperDuration(httpRequestDurationSeconds, rt) + return promhttp.InstrumentRoundTripperInFlight(httpInFlightRequests, rt) +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -31,6 +31,9 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + metrics.SshdConnectionsInFlight.Inc() + defer metrics.SshdConnectionsInFlight.Dec() + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1645483885 -39600 # Tue Feb 22 09:51:25 2022 +1100 # Node ID 3a505abeb647a2a56ee5a06296654410a688f1db # Parent 6ea91f81fdce307685c6d4455a6717d3e9f8c3e6 Upgrade golang to 1.17.7 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.6 +golang 1.17.7 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1645501280 0 # Tue Feb 22 03:41:20 2022 +0000 # Node ID 902a8d109069fb53769ad066378df468847743f3 # Parent f93b7e6dd81a3ff0cef31d2621913110588e857a # Parent 3a505abeb647a2a56ee5a06296654410a688f1db Merge branch 'ashmckenzie/golang-1-17-7' into 'main' Upgrade golang to 1.17.7 See merge request gitlab-org/gitlab-shell!576 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.6 +golang 1.17.7 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1645579675 -39600 # Wed Feb 23 12:27:55 2022 +1100 # Node ID e08954f51999499800a68c5b2f6ff72626572d5d # Parent 902a8d109069fb53769ad066378df468847743f3 Release 13.24.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.24.0 + +- Upgrade golang to 1.17.7 !576 +- Add more metrics for gitlab-sshd !574 +- Move code guidelines to doc/beginners_guide.md !572 +- Add docs for full feature list !571 +- Add aqualls as codeowner for docs files !573 + v13.23.2 - Bump labkit version to 1.12.0 !569 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.2 +13.24.0 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1645593511 0 # Wed Feb 23 05:18:31 2022 +0000 # Node ID d8e5a6bac1b1712956515f079a43e701cd5adb32 # Parent 902a8d109069fb53769ad066378df468847743f3 # Parent e08954f51999499800a68c5b2f6ff72626572d5d Merge branch 'ashmckenzie/gitlab-shell-v13-24-0' into 'main' Release 13.24.0 See merge request gitlab-org/gitlab-shell!577 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.24.0 + +- Upgrade golang to 1.17.7 !576 +- Add more metrics for gitlab-sshd !574 +- Move code guidelines to doc/beginners_guide.md !572 +- Add docs for full feature list !571 +- Add aqualls as codeowner for docs files !573 + v13.23.2 - Bump labkit version to 1.12.0 !569 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.2 +13.24.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1646562661 -3600 # Sun Mar 06 11:31:01 2022 +0100 # Branch heptapod # Node ID 932706903e9732d2d671f456428e81e466d779ce # Parent c13639d6d9742fc361e7df2acee2661f37f16cd8 # Parent 7298cb147cee1f199041abc6e9d7649d369e4164 Merged upstream v13.23.2 (GitLab 14.8.2) into heptapod branch And applied the diff for `.gitlab-ci.yml` directly to `heptapod-ci.yml` No conflict, no local test failure diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,21 @@ -config.yml -cover.out -tmp/* -.idea *.log *.swp -/*.log* -authorized_keys.lock +.bundle +.bundle/ .gitlab_shell_secret -.bundle -tags -.bundle/ -custom_hooks -hooks/*.d -/go_build -/bin/gitlab-sshd +.idea +/*.log* +/bin/check /bin/gitlab-shell /bin/gitlab-shell-authorized-keys-check /bin/gitlab-shell-authorized-principals-check -/bin/check +/bin/gitlab-sshd +/go_build +authorized_keys.lock +config.yml +cover.out +custom_hooks +hooks/*.d +tags +tmp/* +vendor diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,7 +37,7 @@ - apt-get update -qq && apt-get install -y ruby ruby-dev - ruby -v - export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin - - gem install --force --bindir /usr/local/bin bundler -v 2.1.4 + - gem install --force --bindir /usr/local/bin bundler -v 2.3.6 - bundle install # Now set up to run the Golang tests - make build diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.4 +2.7.5 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -ruby 2.7.4 -golang 1.16.10 +ruby 2.7.5 +golang 1.17.6 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,27 @@ +v13.23.2 + +- Bump labkit version to 1.12.0 !569 +- Add title and correct copyright notice to license !568 +- Bump go-proxyproto package !563 +- Update Go to version 1.17.6 !562 + +v13.23.1 + +- Replace golang.org/x/crypto with gitlab-org/golang-crypto !560 + +v13.23.0 + +- Add support for SSHUploadPackWithSidechannel RPC !557 +- Rate limiting documentation !556 + +v13.22.2 + +- Update to Ruby 2.7.5 !553 +- Deprecate self_signed_cert config setting !552 +- Send full git request/response in SSHD tests !550 +- Suppress internal errors in client output !549 +- Bump .tool_versions to use Go v1.16.12 !548 + v13.22.1 - Remove SSL_CERT_DIR logging !546 diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,4 +23,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.1.4 + 2.3.6 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -Copyright (c) 2011-2018 GitLab B.V. +MIT License -With regard to the GitLab Software: +Copyright (c) 2011-present GitLab B.V. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,17 +9,13 @@ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For all third party components incorporated into the GitLab Software, those -components are licensed under the original license provided by the owner of the -applicable component. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver -GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server -If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse). +If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab/tree/master/workhorse). An overview of the four cases described above: @@ -98,7 +98,7 @@ tests requiring Gitaly will be skipped. They will always run in the CI environment. -## Git LFS remark +## Git LFS Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. @@ -117,6 +117,16 @@ - Logging too much is better than not logging enough. If a message seems too verbose, consider reducing the log level before removing the message. +## Rate Limiting + +GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. + +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. + +Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. + +There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). + ## Releasing See [PROCESS.md](./PROCESS.md) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.1 +13.23.2 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -162,7 +162,10 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, + RootCAs: certPool, + // The self_signed_cert config setting is deprecated + // The field and its usage is going to be removed in + // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 InsecureSkipVerify: selfSignedCert, MinVersion: tls.VersionTLS12, } diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,6 +1,8 @@ package testserver import ( + "context" + "fmt" "net" "os" "path" @@ -8,12 +10,18 @@ "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" ) -type TestGitalyServer struct{ ReceivedMD metadata.MD } +type TestGitalyServer struct { + ReceivedMD metadata.MD + pb.UnimplementedSSHServiceServer +} func (s *TestGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error { req, err := stream.Recv() @@ -43,6 +51,26 @@ return nil } +func (s *TestGitalyServer) SSHUploadPackWithSidechannel(ctx context.Context, req *pb.SSHUploadPackWithSidechannelRequest) (*pb.SSHUploadPackWithSidechannelResponse, error) { + conn, err := client.OpenServerSidechannel(ctx) + if err != nil { + return nil, err + } + defer conn.Close() + + s.ReceivedMD, _ = metadata.FromIncomingContext(ctx) + + response := []byte("SSHUploadPackWithSidechannel: " + req.Repository.GlRepository) + if _, err := fmt.Fprintf(conn, "%04x\x01%s", len(response)+5, response); err != nil { + return nil, err + } + if err := conn.Close(); err != nil { + return nil, err + } + + return &pb.SSHUploadPackWithSidechannelResponse{}, nil +} + func (s *TestGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error { req, err := stream.Recv() if err != nil { @@ -67,7 +95,9 @@ err := os.MkdirAll(filepath.Dir(gitalySocketPath), 0700) require.NoError(t, err) - server := grpc.NewServer() + server := grpc.NewServer( + client.SidechannelServer(log.ContextLogger(context.Background()), insecure.NewCredentials()), + ) listener, err := net.Listen("unix", gitalySocketPath) require.NoError(t, err) diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -5,6 +5,9 @@ "os" "reflect" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" @@ -71,7 +74,9 @@ if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") - console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + if grpcstatus.Convert(err).Code() != grpccodes.Internal { + console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + } os.Exit(1) } diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -408,18 +408,34 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-pack %s", testRepo)) + require.NoError(t, err) + + line, err := reader.ReadString('\n') + require.NoError(t, err) + require.Regexp(t, "^[0-9a-f]{44} HEAD.+", line) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") - require.Regexp(t, "^[0-9a-f]{44} HEAD.+", outputLines[0]) - for i := 1; i < (len(outputLines) - 1); i++ { require.Regexp(t, "^[0-9a-f]{44} refs/(heads|tags)/[^ ]+", outputLines[i]) } @@ -436,11 +452,29 @@ require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-archive %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-archive %s", testRepo)) require.NoError(t, err) - outputLines := strings.Split(string(output), "\n") + _, err = fmt.Fprintln(stdin, "0012argument HEAD\n0000") + + line, err := reader.ReadString('\n') + require.Equal(t, "0008ACK\n", line) + require.NoError(t, err) - require.Equal(t, "0008ACK", outputLines[0]) - require.Regexp(t, "^0000", outputLines[1]) + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) + require.NoError(t, err) + + require.Equal(t, []byte("0000"), output[len(output)-4:]) } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -42,6 +42,11 @@ # password: somepass # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs +# +# The self_signed_cert option is deprecated +# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible +# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed +# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 self_signed_cert: false # File used as authorized_keys for gitlab user diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -8,13 +8,15 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.0 - github.com/prometheus/client_golang v1.10.0 + github.com/pires/go-proxyproto v0.6.1 + github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 - gitlab.com/gitlab-org/labkit v1.7.0 - golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad + gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 + gitlab.com/gitlab-org/labkit v1.12.0 + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.37.0 + google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 ) + +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ +bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -19,8 +21,13 @@ cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +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/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= @@ -29,20 +36,58 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 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/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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= 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/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= +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/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-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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= +github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= +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-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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= @@ -52,13 +97,22 @@ github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= -github.com/HdrHistogram/hdrhistogram-go v1.1.0 h1:6dpdDPTRoo78HxAJ6T1HfMiKSnqhgRRqzCuPshRkQ7I= +github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= +github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= 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= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -68,24 +122,31 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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/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= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +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 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= 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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -99,6 +160,9 @@ github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= +github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -115,6 +179,8 @@ 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/xds/go v0.0.0-20210312221358-fbca930ec8ed/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= @@ -123,7 +189,10 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +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/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= @@ -134,9 +203,16 @@ 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= +github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= 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= @@ -146,6 +222,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -153,47 +231,70 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 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/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= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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/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/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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= +github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +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/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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= +github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= @@ -204,6 +305,8 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -228,8 +331,9 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -249,6 +353,7 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -262,13 +367,20 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 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-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= +github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= 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= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 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/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= @@ -281,14 +393,21 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/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= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595 h1:uNrRgpnKjTfxu4qHaZAAs3eKTYV1EzGF3dAykpnxgDE= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 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 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= 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/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= @@ -307,6 +426,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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= @@ -331,11 +451,14 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -345,8 +468,51 @@ github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +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/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= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +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/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/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/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= +github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -360,9 +526,10 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= @@ -380,8 +547,9 @@ github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -389,38 +557,56 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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/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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0 h1:qGUbkzHP64NA9r+uIbCvf303IzHPr0M4JlkaDMxXqqk= github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= +github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= +github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 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-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -445,10 +631,13 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -461,7 +650,7 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -504,16 +693,17 @@ github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= 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.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= -github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= +github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= @@ -528,8 +718,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -541,8 +732,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -552,10 +744,14 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -563,17 +759,26 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= +github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= +github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -583,6 +788,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -590,18 +796,21 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -609,11 +818,16 @@ github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible h1:6WVONolFJiB8Vx9bq4z9ddyV/SXSpfvvtb7Yl/TGHiE= github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= +github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= @@ -629,6 +843,8 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= @@ -643,19 +859,28 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 h1:4u44IbgntN1yKgnY/mUabRjHXIchrLPwUwMuDyQ0+ec= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= -gitlab.com/gitlab-org/labkit v1.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= -gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= +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.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= +gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= 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= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -667,34 +892,25 @@ go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 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 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= 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/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= -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= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/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 h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +gocloud.dev v0.23.0/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= 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= @@ -708,6 +924,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -722,8 +939,9 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -733,8 +951,8 @@ 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 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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= @@ -748,7 +966,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -758,7 +975,9 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -781,8 +1000,14 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +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-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -795,8 +1020,12 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78 h1:rPRtHfUb0UKZeZ6GH4K4Nt4YRbE9V1u+QZX5upZXqJQ= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +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/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= @@ -819,6 +1048,7 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -832,13 +1062,17 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -855,6 +1089,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -863,14 +1098,31 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 h1:ZBu6861dZq7xBnG1bn5SRU0vA8nx42at4+kP07FMTog= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -879,13 +1131,15 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -900,15 +1154,19 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -947,22 +1205,32 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -981,13 +1249,20 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0 h1:pqMffJFLBVUDIoYsHcqtxgQVTsmxMDpYLOc5MT4Jrww= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= +google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +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/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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -998,6 +1273,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1018,6 +1294,7 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1036,8 +1313,22 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3 h1:K+7Ig5hjiLVA/i1UFUUbCGimWz5/Ey0lAQjT3QiLaPY= google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +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-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= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +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/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= @@ -1058,13 +1349,20 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +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/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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1076,17 +1374,20 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= 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= 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 h1:yJJrDYzAlUsDPpAVBjv4VFnXKTbgvaJFTX0646xDPi4= 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= +gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= @@ -1095,6 +1396,7 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= @@ -1102,6 +1404,7 @@ gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1109,6 +1412,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1126,6 +1430,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -23,7 +23,7 @@ - apt-get update -qq && apt-get install -y ruby ruby-dev - ruby -v - export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin - - gem install --force --bindir /usr/local/bin bundler -v 2.1.4 + - gem install --force --bindir /usr/local/bin bundler -v 2.3.6 - bundle install # Now set up to run the Golang tests - make build diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -30,7 +30,7 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -26,7 +26,7 @@ ctxlog := log.ContextLogger(ctx) ctxlog.Debug("twofactorrecover: execute: Waiting for user input") - if c.canContinue() { + if c.getUserAnswer(ctx) == "yes" { ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { @@ -37,16 +37,18 @@ return nil } -func (c *Command) canContinue() bool { +func (c *Command) getUserAnswer(ctx context.Context) string { question := "Are you sure you want to generate new two-factor recovery codes?\n" + "Any existing recovery codes you saved will be invalidated. (yes/no)" fmt.Fprintln(c.ReadWriter.Out, question) var answer string - fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer) + if _, err := fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorrecover: getUserAnswer: Failed to get user input") + } - return answer == "yes" + return answer } func (c *Command) displayRecoveryCodes(ctx context.Context) { diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -22,7 +22,7 @@ func (c *Command) Execute(ctx context.Context) error { ctxlog := log.ContextLogger(ctx) ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP() + otp := c.getOTP(ctx) ctxlog.Info("twofactorverify: execute: verifying entered OTP") err := c.verifyOTP(ctx, otp) @@ -35,14 +35,16 @@ return nil } -func (c *Command) getOTP() string { +func (c *Command) getOTP(ctx context.Context) string { prompt := "OTP: " fmt.Fprint(c.ReadWriter.Out, prompt) var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) - fmt.Fscanln(reader, &answer) + if _, err := fmt.Fscanln(reader, &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") + } return answer } diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -23,7 +23,7 @@ request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -21,13 +21,30 @@ Features: response.Gitaly.Features, } + if response.Gitaly.UseSidechannel { + gc.DialSidechannel = true + request := &pb.SSHUploadPackWithSidechannelRequest{ + Repository: &response.Gitaly.Repo, + GitProtocol: c.Args.Env.GitProtocolVersion, + GitConfigOptions: response.GitConfigOptions, + } + + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + defer cancel() + + rw := c.ReadWriter + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) + }) + } + request := &pb.SSHUploadPackRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -71,3 +71,59 @@ require.Empty(t, testServer.ReceivedMD["some-other-ff"]) require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } + +func TestUploadPack_withSidechannel(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) + + requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) + url := testserver.StartHttpServer(t, requests) + + output := &bytes.Buffer{} + input := &bytes.Buffer{} + + userId := "1" + repo := "group/repo" + + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: args, + ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, + } + + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + err := cmd.Execute(ctx) + require.NoError(t, err) + + require.Equal(t, "SSHUploadPackWithSidechannel: "+repo, output.String()) + + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") +} diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -32,10 +32,11 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` + UseSidechannel bool `json:"use_sidechannel"` } type CustomPayloadData struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,7 +11,6 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -54,7 +53,11 @@ } func TestSuccessfulResponses(t *testing.T) { - client := setup(t, "") + okResponse := testResponse{body: responseBody(t, "allowed.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) testCases := []struct { desc string @@ -83,8 +86,48 @@ } } +func TestSidechannelFlag(t *testing.T) { + okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) + + testCases := []struct { + desc string + args *commandargs.Shell + who string + }{ + { + desc: "Provide key id within the request", + args: &commandargs.Shell{GitlabKeyId: "1"}, + who: "key-1", + }, { + desc: "Provide username within the request", + args: &commandargs.Shell{GitlabUsername: "first"}, + who: "user-1", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) + require.NoError(t, err) + + response := buildExpectedResponse(tc.who) + response.Gitaly.UseSidechannel = true + require.Equal(t, response, result) + }) + } +} + func TestGeoPushGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_push_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_push_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, receivePackAction, repo) @@ -106,7 +149,12 @@ } func TestGeoPullGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_pull_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_pull_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, uploadPackAction, repo) @@ -128,7 +176,11 @@ } func TestErrorResponses(t *testing.T) { - client := setup(t, "") + client := setup(t, nil, map[string]testResponse{ + "2": {body: []byte(`{"message":"Not allowed!"}`), status: http.StatusForbidden}, + "3": {body: []byte(`{"message":"broken json!`), status: http.StatusOK}, + "4": {status: http.StatusForbidden}, + }) testCases := []struct { desc string @@ -163,20 +215,21 @@ } } -func setup(t *testing.T, allowedPayload string) *Client { - testhelper.PrepareTestRootDir(t) - - body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) - require.NoError(t, err) +type testResponse struct { + body []byte + status int +} - var bodyWithPayload []byte +func responseBody(t *testing.T, name string) []byte { + t.Helper() + testhelper.PrepareTestRootDir(t) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses", name)) + require.NoError(t, err) + return body +} - if allowedPayload != "" { - allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) - require.NoError(t, err) - } - +func setup(t *testing.T, userResponses, keyResponses map[string]testResponse) *Client { + t.Helper() requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -187,36 +240,14 @@ var requestBody *Request require.NoError(t, json.Unmarshal(b, &requestBody)) - switch requestBody.Username { - case "first": - _, err = w.Write(body) - require.NoError(t, err) - case "second": - errBody := map[string]interface{}{ - "status": false, - "message": "missing user", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "custom": - w.WriteHeader(http.StatusMultipleChoices) - _, err = w.Write(bodyWithPayload) + if tr, ok := userResponses[requestBody.Username]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - } - - switch requestBody.KeyId { - case "1": - _, err = w.Write(body) + } else if tr, ok := keyResponses[requestBody.KeyId]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - case "2": - w.WriteHeader(http.StatusForbidden) - errBody := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) } }, }, diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -29,21 +29,23 @@ // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string + Config *config.Config + ServiceName string + Address string + Token string + Features map[string]string + DialSidechannel bool } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - conn, err := getConn(ctx, gc) + registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) + conn, err := getConn(ctx, gc, registry) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") @@ -53,7 +55,7 @@ childCtx := withOutgoingMetadata(ctx, gc.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn) + exitStatus, err := handler(childCtx, conn, registry) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -116,7 +118,7 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand) (*grpc.ClientConn, error) { +func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { if gc.Address == "" { return nil, fmt.Errorf("no gitaly_address given") } @@ -160,5 +162,9 @@ ) } + if gc.DialSidechannel { + return client.DialSidechannel(ctx, gc.Address, registry, connOpts) + } + return client.DialContext(ctx, gc.Address, connOpts) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,14 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -86,7 +87,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -66,8 +66,11 @@ default: // Ignore unknown requests but don't terminate the session shouldContinue = true + if req.WantReply { - req.Reply(false, []byte{}) + if err := req.Reply(false, []byte{}); err != nil { + sessionLog.WithError(err).Debug("session: handle: Failed to reply") + } } } @@ -100,7 +103,9 @@ } if req.WantReply { - req.Reply(accepted, []byte{}) + if err := req.Reply(accepted, []byte{}); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("session: handleEnv: Failed to reply") + } } log.WithContextFields( @@ -124,8 +129,12 @@ } func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { + ctxlog := log.ContextLogger(ctx) + if req.WantReply { - req.Reply(true, []byte{}) + if err := req.Reply(true, []byte{}); err != nil { + ctxlog.WithError(err).Debug("session: handleShell: Failed to reply") + } } env := sshenv.Env{ @@ -151,7 +160,6 @@ } cmdName := reflect.TypeOf(cmd).String() - ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") if err := cmd.Execute(ctx); err != nil { diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -81,6 +81,14 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) +} + +func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) +} + +func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -108,6 +116,9 @@ }, }, } + if useSidechannel { + body["gitaly"].(map[string]interface{})["use_sidechannel"] = true + } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json @@ -0,0 +1,23 @@ +{ + "status": true, + "gl_repository": "project-26", + "gl_project_path": "group/private", + "gl_id": "user-1", + "gl_username": "root", + "git_config_options": ["option"], + "gitaly": { + "repository": { + "storage_name": "default", + "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", + "git_object_directory": "path/to/git_object_directory", + "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], + "gl_repository": "project-26", + "gl_project_path": "group/private" + }, + "address": "unix:gitaly.socket", + "token": "token", + "use_sidechannel": true + }, + "git_protocol": "protocol", + "gl_console_messages": ["console", "message"] +} # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1647102567 -3600 # Sat Mar 12 17:29:27 2022 +0100 # Branch heptapod # Node ID d93b03881cd6645d9d682ef7c2df356ae3389f8f # Parent 932706903e9732d2d671f456428e81e466d779ce HEPTAPOD_CHANGELOG: mentioning GitLab 14.6 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -11,7 +11,7 @@ ## 13.22.0 -- Jump to upstream GitLab Shell v13.22.1 (GitLab 14.5 series) +- Jump to upstream GitLab Shell v13.22.1 (GitLab 14.5 and 14.6 series) ## 13.21.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1647102529 -3600 # Sat Mar 12 17:28:49 2022 +0100 # Branch heptapod # Node ID 61814961ec7c871e9a081f4399536e5b8a62fabf # Parent d93b03881cd6645d9d682ef7c2df356ae3389f8f Setting version files for release diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,6 +9,10 @@ The corresponding tag is heptapod-x.y.z +## 13.23.0 + +- Jump to upstream GitLab Shell v13.23.2 (GitLab 14.8 series) + ## 13.22.0 - Jump to upstream GitLab Shell v13.22.1 (GitLab 14.5 and 14.6 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.22.0 +13.23.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1647102623 -3600 # Sat Mar 12 17:30:23 2022 +0100 # Branch heptapod # Node ID e7e00e40f1d49d8585386a65c2f83bee9c09dd80 # Parent 61814961ec7c871e9a081f4399536e5b8a62fabf Added tag heptapod-13.23.0 for changeset 61814961ec7c diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -37,3 +37,4 @@ f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 +61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1649193949 -7200 # Tue Apr 05 23:25:49 2022 +0200 # Branch heptapod-stable # Node ID bcbcabd3963c27047fe50a5765ba6992a4449bad # Parent 9f8076c43eab66b8867a86e136f915048237a657 # Parent e7e00e40f1d49d8585386a65c2f83bee9c09dd80 heptapod#658: making 0.30 the new stable diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,21 @@ -config.yml -cover.out -tmp/* -.idea *.log *.swp -/*.log* -authorized_keys.lock +.bundle +.bundle/ .gitlab_shell_secret -.bundle -tags -.bundle/ -custom_hooks -hooks/*.d -/go_build -/bin/gitlab-sshd +.idea +/*.log* +/bin/check /bin/gitlab-shell /bin/gitlab-shell-authorized-keys-check /bin/gitlab-shell-authorized-principals-check -/bin/check +/bin/gitlab-sshd +/go_build +authorized_keys.lock +config.yml +cover.out +custom_hooks +hooks/*.d +tags +tmp/* +vendor diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,7 +37,7 @@ - apt-get update -qq && apt-get install -y ruby ruby-dev - ruby -v - export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin - - gem install --force --bindir /usr/local/bin bundler -v 2.1.4 + - gem install --force --bindir /usr/local/bin bundler -v 2.3.6 - bundle install # Now set up to run the Golang tests - make build diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -37,3 +37,4 @@ f593b81abfe52ca2083440f3f470dce3d13079da heptapod-13.19.2 b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 +61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 diff --git a/.ruby-version b/.ruby-version --- a/.ruby-version +++ b/.ruby-version @@ -1,1 +1,1 @@ -2.7.4 +2.7.5 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -ruby 2.7.4 -golang 1.16.12 +ruby 2.7.5 +golang 1.17.6 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,27 @@ +v13.23.2 + +- Bump labkit version to 1.12.0 !569 +- Add title and correct copyright notice to license !568 +- Bump go-proxyproto package !563 +- Update Go to version 1.17.6 !562 + +v13.23.1 + +- Replace golang.org/x/crypto with gitlab-org/golang-crypto !560 + +v13.23.0 + +- Add support for SSHUploadPackWithSidechannel RPC !557 +- Rate limiting documentation !556 + +v13.22.2 + +- Update to Ruby 2.7.5 !553 +- Deprecate self_signed_cert config setting !552 +- Send full git request/response in SSHD tests !550 +- Suppress internal errors in client output !549 +- Bump .tool_versions to use Go v1.16.12 !548 + v13.22.1 - Remove SSL_CERT_DIR logging !546 diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,4 +23,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.1.4 + 2.3.6 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -9,9 +9,13 @@ The corresponding tag is heptapod-x.y.z +## 13.23.0 + +- Jump to upstream GitLab Shell v13.23.2 (GitLab 14.8 series) + ## 13.22.0 -- Jump to upstream GitLab Shell v13.22.1 (GitLab 14.5 series) +- Jump to upstream GitLab Shell v13.22.1 (GitLab 14.5 and 14.6 series) ## 13.21.0 diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.22.0 +13.23.0 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -Copyright (c) 2011-2018 GitLab B.V. +MIT License -With regard to the GitLab Software: +Copyright (c) 2011-present GitLab B.V. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,17 +9,13 @@ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For all third party components incorporated into the GitLab Software, those -components are licensed under the original license provided by the owner of the -applicable component. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver -GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" +GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ 1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on 1. Copy data back and forth between the SSH client and the Gitaly server -If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse). +If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab/tree/master/workhorse). An overview of the four cases described above: @@ -98,7 +98,7 @@ tests requiring Gitaly will be skipped. They will always run in the CI environment. -## Git LFS remark +## Git LFS Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. @@ -117,6 +117,16 @@ - Logging too much is better than not logging enough. If a message seems too verbose, consider reducing the log level before removing the message. +## Rate Limiting + +GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. + +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. + +Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. + +There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). + ## Releasing See [PROCESS.md](./PROCESS.md) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.22.1 +13.23.2 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -162,7 +162,10 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, + RootCAs: certPool, + // The self_signed_cert config setting is deprecated + // The field and its usage is going to be removed in + // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 InsecureSkipVerify: selfSignedCert, MinVersion: tls.VersionTLS12, } diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -1,6 +1,8 @@ package testserver import ( + "context" + "fmt" "net" "os" "path" @@ -8,12 +10,18 @@ "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" ) -type TestGitalyServer struct{ ReceivedMD metadata.MD } +type TestGitalyServer struct { + ReceivedMD metadata.MD + pb.UnimplementedSSHServiceServer +} func (s *TestGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error { req, err := stream.Recv() @@ -43,6 +51,26 @@ return nil } +func (s *TestGitalyServer) SSHUploadPackWithSidechannel(ctx context.Context, req *pb.SSHUploadPackWithSidechannelRequest) (*pb.SSHUploadPackWithSidechannelResponse, error) { + conn, err := client.OpenServerSidechannel(ctx) + if err != nil { + return nil, err + } + defer conn.Close() + + s.ReceivedMD, _ = metadata.FromIncomingContext(ctx) + + response := []byte("SSHUploadPackWithSidechannel: " + req.Repository.GlRepository) + if _, err := fmt.Fprintf(conn, "%04x\x01%s", len(response)+5, response); err != nil { + return nil, err + } + if err := conn.Close(); err != nil { + return nil, err + } + + return &pb.SSHUploadPackWithSidechannelResponse{}, nil +} + func (s *TestGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error { req, err := stream.Recv() if err != nil { @@ -67,7 +95,9 @@ err := os.MkdirAll(filepath.Dir(gitalySocketPath), 0700) require.NoError(t, err) - server := grpc.NewServer() + server := grpc.NewServer( + client.SidechannelServer(log.ContextLogger(context.Background()), insecure.NewCredentials()), + ) listener, err := net.Listen("unix", gitalySocketPath) require.NoError(t, err) diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -5,6 +5,9 @@ "os" "reflect" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" @@ -71,7 +74,9 @@ if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") - console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + if grpcstatus.Convert(err).Code() != grpccodes.Internal { + console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) + } os.Exit(1) } diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -408,18 +408,34 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-pack %s", testRepo)) + require.NoError(t, err) + + line, err := reader.ReadString('\n') + require.NoError(t, err) + require.Regexp(t, "^[0-9a-f]{44} HEAD.+", line) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") - require.Regexp(t, "^[0-9a-f]{44} HEAD.+", outputLines[0]) - for i := 1; i < (len(outputLines) - 1); i++ { require.Regexp(t, "^[0-9a-f]{44} refs/(heads|tags)/[^ ]+", outputLines[i]) } @@ -436,11 +452,29 @@ require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-upload-archive %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + reader := bufio.NewReader(stdout) + + err = session.Start(fmt.Sprintf("git-upload-archive %s", testRepo)) require.NoError(t, err) - outputLines := strings.Split(string(output), "\n") + _, err = fmt.Fprintln(stdin, "0012argument HEAD\n0000") + + line, err := reader.ReadString('\n') + require.Equal(t, "0008ACK\n", line) + require.NoError(t, err) - require.Equal(t, "0008ACK", outputLines[0]) - require.Regexp(t, "^0000", outputLines[1]) + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + + output, err := io.ReadAll(stdout) + require.NoError(t, err) + + require.Equal(t, []byte("0000"), output[len(output)-4:]) } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -42,6 +42,11 @@ # password: somepass # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs +# +# The self_signed_cert option is deprecated +# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible +# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed +# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 self_signed_cert: false # File used as authorized_keys for gitlab user diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -8,13 +8,15 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.0 - github.com/prometheus/client_golang v1.10.0 + github.com/pires/go-proxyproto v0.6.1 + github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 - gitlab.com/gitlab-org/labkit v1.7.0 - golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad + gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 + gitlab.com/gitlab-org/labkit v1.12.0 + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.37.0 + google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 ) + +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ +bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -19,8 +21,13 @@ cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= 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 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +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/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= @@ -29,20 +36,58 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 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/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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= 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/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= +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/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-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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= +github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= +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-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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= @@ -52,13 +97,22 @@ github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= -github.com/HdrHistogram/hdrhistogram-go v1.1.0 h1:6dpdDPTRoo78HxAJ6T1HfMiKSnqhgRRqzCuPshRkQ7I= +github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= +github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= 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= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -68,24 +122,31 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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/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= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +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 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= 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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -99,6 +160,9 @@ github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= +github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -115,6 +179,8 @@ 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/xds/go v0.0.0-20210312221358-fbca930ec8ed/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= @@ -123,7 +189,10 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +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/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= @@ -134,9 +203,16 @@ 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= +github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= 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= @@ -146,6 +222,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -153,47 +231,70 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 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/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= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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/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/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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= +github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +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/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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= +github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= @@ -204,6 +305,8 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -228,8 +331,9 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -249,6 +353,7 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -262,13 +367,20 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 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-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= +github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= 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= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 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/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= @@ -281,14 +393,21 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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 h1:zIaiqGYDQwa4HVx5wGRTXbx38Pqxjemn4BP98wpzpXo= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/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= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595 h1:uNrRgpnKjTfxu4qHaZAAs3eKTYV1EzGF3dAykpnxgDE= +github.com/google/pprof v0.0.0-20210804190019-f964ff605595/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 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 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= 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/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= @@ -307,6 +426,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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= @@ -331,11 +451,14 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -345,8 +468,51 @@ github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +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/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= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +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/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/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/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= +github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -360,9 +526,10 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= @@ -380,8 +547,9 @@ github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -389,38 +557,56 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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/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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0 h1:qGUbkzHP64NA9r+uIbCvf303IzHPr0M4JlkaDMxXqqk= github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= +github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= +github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 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-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -445,10 +631,13 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -461,7 +650,7 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -504,16 +693,17 @@ github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= 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.6.0 h1:cLJUPnuQdiNf7P/wbeOKmM1khVdaMgTFDLj8h9ZrVYk= -github.com/pires/go-proxyproto v0.6.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= +github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= @@ -528,8 +718,9 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -541,8 +732,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -552,10 +744,14 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -563,17 +759,26 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= +github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= +github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -583,6 +788,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -590,18 +796,21 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -609,11 +818,16 @@ github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible h1:6WVONolFJiB8Vx9bq4z9ddyV/SXSpfvvtb7Yl/TGHiE= github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= +github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= @@ -629,6 +843,8 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= @@ -643,19 +859,28 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1 h1:4u44IbgntN1yKgnY/mUabRjHXIchrLPwUwMuDyQ0+ec= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= +gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= -gitlab.com/gitlab-org/labkit v1.7.0 h1:ufG42cvJ+VkqaUWVEoat/h9PGcW9FFSUPQFz7uwL5wc= -gitlab.com/gitlab-org/labkit v1.7.0/go.mod h1:1ZuVZpjSpCKUgjLx8P6jzkkQFxJI1thUKr6yKV3p0vY= +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.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= +gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= 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= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -667,34 +892,25 @@ go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 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 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= 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/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= -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= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/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 h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +gocloud.dev v0.23.0/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= 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= @@ -708,6 +924,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -722,8 +939,9 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -733,8 +951,8 @@ 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 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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= @@ -748,7 +966,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -758,7 +975,9 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -781,8 +1000,14 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +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-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -795,8 +1020,12 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78 h1:rPRtHfUb0UKZeZ6GH4K4Nt4YRbE9V1u+QZX5upZXqJQ= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +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/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= @@ -819,6 +1048,7 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -832,13 +1062,17 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -855,6 +1089,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -863,14 +1098,31 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 h1:ZBu6861dZq7xBnG1bn5SRU0vA8nx42at4+kP07FMTog= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -879,13 +1131,15 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -900,15 +1154,19 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -947,22 +1205,32 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -981,13 +1249,20 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0 h1:pqMffJFLBVUDIoYsHcqtxgQVTsmxMDpYLOc5MT4Jrww= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= +google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +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/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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -998,6 +1273,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1018,6 +1294,7 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1036,8 +1313,22 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3 h1:K+7Ig5hjiLVA/i1UFUUbCGimWz5/Ey0lAQjT3QiLaPY= google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +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-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= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +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/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= @@ -1058,13 +1349,20 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +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/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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1076,17 +1374,20 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= 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= 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 h1:yJJrDYzAlUsDPpAVBjv4VFnXKTbgvaJFTX0646xDPi4= 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= +gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= @@ -1095,6 +1396,7 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= @@ -1102,6 +1404,7 @@ gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1109,6 +1412,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1126,6 +1430,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -23,7 +23,7 @@ - apt-get update -qq && apt-get install -y ruby ruby-dev - ruby -v - export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin - - gem install --force --bindir /usr/local/bin bundler -v 2.1.4 + - gem install --force --bindir /usr/local/bin bundler -v 2.3.6 - bundle install # Now set up to run the Golang tests - make build diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -30,7 +30,7 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -26,7 +26,7 @@ ctxlog := log.ContextLogger(ctx) ctxlog.Debug("twofactorrecover: execute: Waiting for user input") - if c.canContinue() { + if c.getUserAnswer(ctx) == "yes" { ctxlog.Debug("twofactorrecover: execute: User chose to continue") c.displayRecoveryCodes(ctx) } else { @@ -37,16 +37,18 @@ return nil } -func (c *Command) canContinue() bool { +func (c *Command) getUserAnswer(ctx context.Context) string { question := "Are you sure you want to generate new two-factor recovery codes?\n" + "Any existing recovery codes you saved will be invalidated. (yes/no)" fmt.Fprintln(c.ReadWriter.Out, question) var answer string - fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer) + if _, err := fmt.Fscanln(io.LimitReader(c.ReadWriter.In, readerLimit), &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorrecover: getUserAnswer: Failed to get user input") + } - return answer == "yes" + return answer } func (c *Command) displayRecoveryCodes(ctx context.Context) { diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -22,7 +22,7 @@ func (c *Command) Execute(ctx context.Context) error { ctxlog := log.ContextLogger(ctx) ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP() + otp := c.getOTP(ctx) ctxlog.Info("twofactorverify: execute: verifying entered OTP") err := c.verifyOTP(ctx, otp) @@ -35,14 +35,16 @@ return nil } -func (c *Command) getOTP() string { +func (c *Command) getOTP(ctx context.Context) string { prompt := "OTP: " fmt.Fprint(c.ReadWriter.Out, prompt) var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) - fmt.Fscanln(reader, &answer) + if _, err := fmt.Fscanln(reader, &answer); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") + } return answer } diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -23,7 +23,7 @@ request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -21,13 +21,30 @@ Features: response.Gitaly.Features, } + if response.Gitaly.UseSidechannel { + gc.DialSidechannel = true + request := &pb.SSHUploadPackWithSidechannelRequest{ + Repository: &response.Gitaly.Repo, + GitProtocol: c.Args.Env.GitProtocolVersion, + GitConfigOptions: response.GitConfigOptions, + } + + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + defer cancel() + + rw := c.ReadWriter + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) + }) + } + request := &pb.SSHUploadPackRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) defer cancel() diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -71,3 +71,59 @@ require.Empty(t, testServer.ReceivedMD["some-other-ff"]) require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") } + +func TestUploadPack_withSidechannel(t *testing.T) { + gitalyAddress, testServer := testserver.StartGitalyServer(t) + + requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) + url := testserver.StartHttpServer(t, requests) + + output := &bytes.Buffer{} + input := &bytes.Buffer{} + + userId := "1" + repo := "group/repo" + + env := sshenv.Env{ + IsSSHConnection: true, + OriginalCommand: "git-upload-pack " + repo, + RemoteAddr: "127.0.0.1", + } + + args := &commandargs.Shell{ + GitlabKeyId: userId, + CommandType: commandargs.UploadPack, + SshArgs: []string{"git-upload-pack", repo}, + Env: env, + } + + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: args, + ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, + } + + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + err := cmd.Execute(ctx) + require.NoError(t, err) + + require.Equal(t, "SSHUploadPackWithSidechannel: "+repo, output.String()) + + for k, v := range map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", + "key_id": "123", + "user_id": "1", + "remote_ip": "127.0.0.1", + "key_type": "key", + } { + actual := testServer.ReceivedMD[k] + require.Len(t, actual, 1) + require.Equal(t, v, actual[0]) + } + require.Empty(t, testServer.ReceivedMD["some-other-ff"]) + require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") +} diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -32,10 +32,11 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` + UseSidechannel bool `json:"use_sidechannel"` } type CustomPayloadData struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,7 +11,6 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -54,7 +53,11 @@ } func TestSuccessfulResponses(t *testing.T) { - client := setup(t, "") + okResponse := testResponse{body: responseBody(t, "allowed.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) testCases := []struct { desc string @@ -83,8 +86,48 @@ } } +func TestSidechannelFlag(t *testing.T) { + okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} + client := setup(t, + map[string]testResponse{"first": okResponse}, + map[string]testResponse{"1": okResponse}, + ) + + testCases := []struct { + desc string + args *commandargs.Shell + who string + }{ + { + desc: "Provide key id within the request", + args: &commandargs.Shell{GitlabKeyId: "1"}, + who: "key-1", + }, { + desc: "Provide username within the request", + args: &commandargs.Shell{GitlabUsername: "first"}, + who: "user-1", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) + require.NoError(t, err) + + response := buildExpectedResponse(tc.who) + response.Gitaly.UseSidechannel = true + require.Equal(t, response, result) + }) + } +} + func TestGeoPushGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_push_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_push_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, receivePackAction, repo) @@ -106,7 +149,12 @@ } func TestGeoPullGetCustomAction(t *testing.T) { - client := setup(t, "responses/allowed_with_pull_payload.json") + client := setup(t, map[string]testResponse{ + "custom": { + body: responseBody(t, "allowed_with_pull_payload.json"), + status: 300, + }, + }, nil) args := &commandargs.Shell{GitlabUsername: "custom"} result, err := client.Verify(context.Background(), args, uploadPackAction, repo) @@ -128,7 +176,11 @@ } func TestErrorResponses(t *testing.T) { - client := setup(t, "") + client := setup(t, nil, map[string]testResponse{ + "2": {body: []byte(`{"message":"Not allowed!"}`), status: http.StatusForbidden}, + "3": {body: []byte(`{"message":"broken json!`), status: http.StatusOK}, + "4": {status: http.StatusForbidden}, + }) testCases := []struct { desc string @@ -163,20 +215,21 @@ } } -func setup(t *testing.T, allowedPayload string) *Client { - testhelper.PrepareTestRootDir(t) - - body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses/allowed.json")) - require.NoError(t, err) +type testResponse struct { + body []byte + status int +} - var bodyWithPayload []byte +func responseBody(t *testing.T, name string) []byte { + t.Helper() + testhelper.PrepareTestRootDir(t) + body, err := os.ReadFile(path.Join(testhelper.TestRoot, "responses", name)) + require.NoError(t, err) + return body +} - if allowedPayload != "" { - allowedWithPayloadPath := path.Join(testhelper.TestRoot, allowedPayload) - bodyWithPayload, err = os.ReadFile(allowedWithPayloadPath) - require.NoError(t, err) - } - +func setup(t *testing.T, userResponses, keyResponses map[string]testResponse) *Client { + t.Helper() requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -187,36 +240,14 @@ var requestBody *Request require.NoError(t, json.Unmarshal(b, &requestBody)) - switch requestBody.Username { - case "first": - _, err = w.Write(body) - require.NoError(t, err) - case "second": - errBody := map[string]interface{}{ - "status": false, - "message": "missing user", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "custom": - w.WriteHeader(http.StatusMultipleChoices) - _, err = w.Write(bodyWithPayload) + if tr, ok := userResponses[requestBody.Username]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - } - - switch requestBody.KeyId { - case "1": - _, err = w.Write(body) + } else if tr, ok := keyResponses[requestBody.KeyId]; ok { + w.WriteHeader(tr.status) + _, err := w.Write(tr.body) require.NoError(t, err) - case "2": - w.WriteHeader(http.StatusForbidden) - errBody := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(errBody)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) } }, }, diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -29,21 +29,23 @@ // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string + Config *config.Config + ServiceName string + Address string + Token string + Features map[string]string + DialSidechannel bool } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - conn, err := getConn(ctx, gc) + registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) + conn, err := getConn(ctx, gc, registry) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") @@ -53,7 +55,7 @@ childCtx := withOutgoingMetadata(ctx, gc.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn) + exitStatus, err := handler(childCtx, conn, registry) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -116,7 +118,7 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand) (*grpc.ClientConn, error) { +func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { if gc.Address == "" { return nil, fmt.Errorf("no gitaly_address given") } @@ -160,5 +162,9 @@ ) } + if gc.DialSidechannel { + return client.DialSidechannel(ctx, gc.Address, registry, connOpts) + } + return client.DialContext(ctx, gc.Address, connOpts) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,14 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -86,7 +87,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -66,8 +66,11 @@ default: // Ignore unknown requests but don't terminate the session shouldContinue = true + if req.WantReply { - req.Reply(false, []byte{}) + if err := req.Reply(false, []byte{}); err != nil { + sessionLog.WithError(err).Debug("session: handle: Failed to reply") + } } } @@ -100,7 +103,9 @@ } if req.WantReply { - req.Reply(accepted, []byte{}) + if err := req.Reply(accepted, []byte{}); err != nil { + log.ContextLogger(ctx).WithError(err).Debug("session: handleEnv: Failed to reply") + } } log.WithContextFields( @@ -124,8 +129,12 @@ } func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { + ctxlog := log.ContextLogger(ctx) + if req.WantReply { - req.Reply(true, []byte{}) + if err := req.Reply(true, []byte{}); err != nil { + ctxlog.WithError(err).Debug("session: handleShell: Failed to reply") + } } env := sshenv.Env{ @@ -151,7 +160,6 @@ } cmdName := reflect.TypeOf(cmd).String() - ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") if err := cmd.Execute(ctx); err != nil { diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -81,6 +81,14 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) +} + +func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { + return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) +} + +func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -108,6 +116,9 @@ }, }, } + if useSidechannel { + body["gitaly"].(map[string]interface{})["use_sidechannel"] = true + } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json @@ -0,0 +1,23 @@ +{ + "status": true, + "gl_repository": "project-26", + "gl_project_path": "group/private", + "gl_id": "user-1", + "gl_username": "root", + "git_config_options": ["option"], + "gitaly": { + "repository": { + "storage_name": "default", + "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", + "git_object_directory": "path/to/git_object_directory", + "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], + "gl_repository": "project-26", + "gl_project_path": "group/private" + }, + "address": "unix:gitaly.socket", + "token": "token", + "use_sidechannel": true + }, + "git_protocol": "protocol", + "gl_console_messages": ["console", "message"] +} # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1649262323 -7200 # Wed Apr 06 18:25:23 2022 +0200 # Branch heptapod # Node ID 2ffbe5787a8e76b7856e447ca406889930fe0691 # Parent e7e00e40f1d49d8585386a65c2f83bee9c09dd80 HEPTAPOD_CHANGELOG: more explicit wording diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -1,6 +1,7 @@ # Changelog for Heptapod Shell -The CHANGELOG file is about the upstream GitLab Shell. +See the `CHANGELOG` file for information about upstream GitLab Shell +versions. ## Versioning policy # HG changeset patch # User Sami Hiltunen <shiltunen@gitlab.com> # Date 1646660844 0 # Mon Mar 07 13:47:24 2022 +0000 # Node ID 2eafbb7a098ed56d9ef4daae16ea046da3222229 # Parent d8e5a6bac1b1712956515f079a43e701cd5adb32 Update Gitaly dependency to v14.9.0-rc1 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 + gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= 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/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= @@ -583,7 +585,7 @@ github.com/lib/pq v1.10.2/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= +github.com/libgit2/git2go/v33 v33.0.6/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -865,8 +867,8 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 h1:9vStRdXxcBQ8dHlVnpV28fwLOgyDkSFIpGnPqwzdTvw= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1/go.mod h1:Xk5pn6IWsejg3z2X6BRczC5QaI97PRF3GU5OrJ5Amkg= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1646660844 0 # Mon Mar 07 13:47:24 2022 +0000 # Node ID 76009d797db772436a1e917396dd0dc38769cbe4 # Parent d8e5a6bac1b1712956515f079a43e701cd5adb32 # Parent 2eafbb7a098ed56d9ef4daae16ea046da3222229 Merge branch 'smh-update-gitaly-vendor' into 'main' Update Gitaly dependency to v14.9.0-rc1 See merge request gitlab-org/gitlab-shell!578 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 + gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= 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/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= @@ -583,7 +585,7 @@ github.com/lib/pq v1.10.2/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= +github.com/libgit2/git2go/v33 v33.0.6/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -865,8 +867,8 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 h1:9vStRdXxcBQ8dHlVnpV28fwLOgyDkSFIpGnPqwzdTvw= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1/go.mod h1:Xk5pn6IWsejg3z2X6BRczC5QaI97PRF3GU5OrJ5Amkg= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= # HG changeset patch # User Nick Thomas <nick@gitlab.com> # Date 1647356020 0 # Tue Mar 15 14:53:40 2022 +0000 # Node ID 112571ac88ed42af4ae969e73550809db307c6d5 # Parent 76009d797db772436a1e917396dd0dc38769cbe4 Default to info level for an empty log-level I'd assumed that the `omitempty` directive for LogLevel in internal/config/config.go would get us this behaviour. If it did, we wouldn't have had to specify the default twice. Unfortunately, it doesn't, which is to say that given a config file like: ``` log_level: ``` The default *is* overridden by the empty string. It's an easy enough fix. Changelog: fixed diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -22,6 +22,14 @@ return inFmt } +func logLevel(inLevel string) string { + if inLevel == "" { + return "info" + } + + return inLevel +} + func logFile(inFile string) string { if inFile == "" { return "stderr" @@ -35,7 +43,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), - log.WithLogLevel(cfg.LogLevel), + log.WithLogLevel(logLevel(cfg.LogLevel)), } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -30,9 +30,11 @@ tmpFile.Close() data, err := os.ReadFile(tmpFile.Name()) + dataStr := string(data) require.NoError(t, err) - require.Contains(t, string(data), `msg":"this is a test"`) - require.NotContains(t, string(data), `msg:":"debug log message"`) + require.Contains(t, dataStr, `"msg":"this is a test"`) + require.NotContains(t, dataStr, `"msg":"debug log message"`) + require.NotContains(t, dataStr, `"msg":"unknown log level`) } func TestConfigureWithDebugLogLevel(t *testing.T) { # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1647396566 0 # Wed Mar 16 02:09:26 2022 +0000 # Node ID 2c4cb630f85ca652c04d738dddc53fc2c2aca5e2 # Parent 76009d797db772436a1e917396dd0dc38769cbe4 # Parent 112571ac88ed42af4ae969e73550809db307c6d5 Merge branch '550-fix-unknown-log-level-message' into 'main' Default to info level for an empty log-level Closes #550 See merge request gitlab-org/gitlab-shell!579 diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -22,6 +22,14 @@ return inFmt } +func logLevel(inLevel string) string { + if inLevel == "" { + return "info" + } + + return inLevel +} + func logFile(inFile string) string { if inFile == "" { return "stderr" @@ -35,7 +43,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), - log.WithLogLevel(cfg.LogLevel), + log.WithLogLevel(logLevel(cfg.LogLevel)), } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -30,9 +30,11 @@ tmpFile.Close() data, err := os.ReadFile(tmpFile.Name()) + dataStr := string(data) require.NoError(t, err) - require.Contains(t, string(data), `msg":"this is a test"`) - require.NotContains(t, string(data), `msg:":"debug log message"`) + require.Contains(t, dataStr, `"msg":"this is a test"`) + require.NotContains(t, dataStr, `"msg":"debug log message"`) + require.NotContains(t, dataStr, `"msg":"unknown log level`) } func TestConfigureWithDebugLogLevel(t *testing.T) { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1645179038 -10800 # Fri Feb 18 13:10:38 2022 +0300 # Node ID 1682d4cfdc27e9e5d86a6187e4068fa37ca1ddc3 # Parent 76009d797db772436a1e917396dd0dc38769cbe4 Reuse Gitaly conns and Sidechannel When gitlab-sshd has been introduced we've started running our own SSH server. In this case we're able to cache and reuse Gitaly connections and Registry. It helps to reduce memory usage. diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -68,6 +68,8 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() + config.GitalyClient.InitSidechannelRegistry(ctx) + cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -69,6 +69,8 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + cfg.GitalyClient.InitSidechannelRegistry(ctx) + server, err := sshd.NewServer(cfg) if err != nil { log.WithError(err).Fatal("Failed to start GitLab built-in sshd") diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -13,13 +13,7 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.ReceivePack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.ReceivePack), response) request := &pb.SSHReceivePackRequest{ Repository: &response.Gitaly.Repo, @@ -30,8 +24,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -13,18 +13,12 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadArchive), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadArchive), response) request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -13,26 +13,20 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadPack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) if response.Gitaly.UseSidechannel { - gc.DialSidechannel = true request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) @@ -44,8 +38,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -97,15 +97,18 @@ Env: env, } + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - err := cmd.Execute(ctx) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,6 +12,7 @@ yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -59,6 +60,8 @@ httpClient *client.HttpClient httpClientErr error httpClientOnce sync.Once + + GitalyClient gitaly.Client } // The defaults to apply before parsing the config file(s). diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly.go @@ -0,0 +1,133 @@ +package gitaly + +import ( + "context" + "fmt" + "sync" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "google.golang.org/grpc" + + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" + "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + "gitlab.com/gitlab-org/labkit/correlation" + grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" + grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +type Command struct { + ServiceName string + Address string + Token string + DialSidechannel bool +} + +type connectionsCache struct { + sync.RWMutex + + connections map[Command]*grpc.ClientConn +} + +type Client struct { + SidechannelRegistry *gitalyclient.SidechannelRegistry + + cache connectionsCache +} + +func (c *Client) InitSidechannelRegistry(ctx context.Context) { + c.SidechannelRegistry = gitalyclient.NewSidechannelRegistry(log.ContextLogger(ctx)) +} + +func (c *Client) GetConnection(ctx context.Context, cmd Command) (*grpc.ClientConn, error) { + c.cache.RLock() + conn := c.cache.connections[cmd] + c.cache.RUnlock() + + if conn != nil { + return conn, nil + } + + c.cache.Lock() + defer c.cache.Unlock() + + if conn := c.cache.connections[cmd]; conn != nil { + return conn, nil + } + + conn, err := c.newConnection(ctx, cmd) + if err != nil { + return nil, err + } + + if c.cache.connections == nil { + c.cache.connections = make(map[Command]*grpc.ClientConn) + } + + c.cache.connections[cmd] = conn + + return conn, nil +} + +func (c *Client) newConnection(ctx context.Context, cmd Command) (conn *grpc.ClientConn, err error) { + defer func() { + label := "ok" + if err != nil { + label = "fail" + } + metrics.GitalyConnectionsTotal.WithLabelValues(label).Inc() + }() + + if cmd.Address == "" { + return nil, fmt.Errorf("no gitaly_address given") + } + + serviceName := correlation.ExtractClientNameFromContext(ctx) + if serviceName == "" { + serviceName = "gitlab-shell-unknown" + + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + } + + serviceName = fmt.Sprintf("%s-%s", serviceName, cmd.ServiceName) + + connOpts := client.DefaultDialOpts + connOpts = append( + connOpts, + grpc.WithStreamInterceptor( + grpc_middleware.ChainStreamClient( + grpctracing.StreamClientTracingInterceptor(), + grpc_prometheus.StreamClientInterceptor, + grpccorrelation.StreamClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + + grpc.WithUnaryInterceptor( + grpc_middleware.ChainUnaryClient( + grpctracing.UnaryClientTracingInterceptor(), + grpc_prometheus.UnaryClientInterceptor, + grpccorrelation.UnaryClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + ) + + if cmd.Token != "" { + connOpts = append(connOpts, + grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cmd.Token)), + ) + } + + if cmd.DialSidechannel { + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) + } + + return client.DialContext(ctx, cmd.Address, connOpts) +} diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly_test.go @@ -0,0 +1,53 @@ +package gitaly + +import ( + "context" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +func TestPrometheusMetrics(t *testing.T) { + metrics.GitalyConnectionsTotal.Reset() + + c := &Client{} + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + c.newConnection(context.Background(), cmd) + c.newConnection(context.Background(), cmd) + + require.Equal(t, 1, testutil.CollectAndCount(metrics.GitalyConnectionsTotal)) + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 0, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) + + cmd = Command{Address: ""} + c.newConnection(context.Background(), cmd) + + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 1, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) +} + +func TestCachedConnections(t *testing.T) { + c := &Client{} + + require.Len(t, c.cache.connections, 0) + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + + conn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + + newConn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + require.Equal(t, conn, newConn) + + cmd = Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9998"} + _, err = c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 2) +} diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -6,56 +6,57 @@ "strconv" "strings" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/labkit/correlation" - grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" - grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" ) // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string - DialSidechannel bool + Config *config.Config + Response *accessverifier.Response + Command gitaly.Command +} + +func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { + gc := gitaly.Command{ + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, + DialSidechannel: response.Gitaly.UseSidechannel, + } + + return &GitalyCommand{Config: cfg, Response: response, Command: gc} } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) - conn, err := getConn(ctx, gc, registry) + // We leave the connection open for future reuse + conn, err := gc.getConn(ctx) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") return err } - defer conn.Close() - childCtx := withOutgoingMetadata(ctx, gc.Features) + childCtx := withOutgoingMetadata(ctx, gc.Response.Gitaly.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn, registry) + exitStatus, err := handler(childCtx, conn) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -72,35 +73,35 @@ // PrepareContext wraps a given context with a correlation ID and logs the command to // be run. -func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) (context.Context, context.CancelFunc) { +func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, env sshenv.Env) (context.Context, context.CancelFunc) { ctx, cancel := context.WithCancel(ctx) - gc.LogExecution(ctx, repository, response, env) + gc.LogExecution(ctx, repository, env) md, ok := metadata.FromOutgoingContext(ctx) if !ok { md = metadata.New(nil) } - md.Append("key_id", strconv.Itoa(response.KeyId)) - md.Append("key_type", response.KeyType) - md.Append("user_id", response.UserId) - md.Append("username", response.Username) + md.Append("key_id", strconv.Itoa(gc.Response.KeyId)) + md.Append("key_type", gc.Response.KeyType) + md.Append("user_id", gc.Response.UserId) + md.Append("username", gc.Response.Username) md.Append("remote_ip", env.RemoteAddr) ctx = metadata.NewOutgoingContext(ctx, md) return ctx, cancel } -func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { +func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, env sshenv.Env) { fields := log.Fields{ - "command": gc.ServiceName, + "command": gc.Command.ServiceName, "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, - "user_id": response.UserId, - "username": response.Username, + "user_id": gc.Response.UserId, + "username": gc.Response.Username, "git_protocol": env.GitProtocolVersion, "remote_ip": env.RemoteAddr, - "gl_key_type": response.KeyType, - "gl_key_id": response.KeyId, + "gl_key_type": gc.Response.KeyType, + "gl_key_id": gc.Response.KeyId, } log.WithContextFields(ctx, fields).Info("executing git command") @@ -118,53 +119,6 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { - if gc.Address == "" { - return nil, fmt.Errorf("no gitaly_address given") - } - - serviceName := correlation.ExtractClientNameFromContext(ctx) - if serviceName == "" { - serviceName = "gitlab-shell-unknown" - - log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") - } - - serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) - - connOpts := client.DefaultDialOpts - connOpts = append( - connOpts, - grpc.WithStreamInterceptor( - grpc_middleware.ChainStreamClient( - grpctracing.StreamClientTracingInterceptor(), - grpc_prometheus.StreamClientInterceptor, - grpccorrelation.StreamClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - - grpc.WithUnaryInterceptor( - grpc_middleware.ChainUnaryClient( - grpctracing.UnaryClientTracingInterceptor(), - grpc_prometheus.UnaryClientInterceptor, - grpccorrelation.UnaryClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - ) - - if gc.Token != "" { - connOpts = append(connOpts, - grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(gc.Token)), - ) - } - - if gc.DialSidechannel { - return client.DialSidechannel(ctx, gc.Address, registry, connOpts) - } - - return client.DialContext(ctx, gc.Address, connOpts) +func (gc *GitalyCommand) getConn(ctx context.Context) (*grpc.ClientConn, error) { + return gc.Config.GitalyClient.GetConnection(ctx, gc.Command) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,15 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -28,10 +28,13 @@ } func TestRunGitalyCommand(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.NoError(t, err) @@ -41,6 +44,32 @@ require.Equal(t, err, expectedErr) } +func TestCachingOfGitalyConnections(t *testing.T) { + ctx := context.Background() + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + response := &accessverifier.Response{ + Username: "user", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Token: "token", + UseSidechannel: true, + }, + } + + cmd := NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + + conn, err := cmd.getConn(ctx) + require.NoError(t, err) + + // Reuses connection for different users + response.Username = "another-user" + cmd = NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + newConn, err := cmd.getConn(ctx) + require.NoError(t, err) + require.Equal(t, conn, newConn) +} + func TestMissingGitalyAddress(t *testing.T) { cmd := GitalyCommand{Config: &config.Config{}} @@ -49,10 +78,13 @@ } func TestUnavailableGitalyErr(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) @@ -68,15 +100,20 @@ }{ { name: "gitaly_feature_flags", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - Features: map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "other-ff": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Features: map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "other-ff": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + }, + }, }, - }, + ), want: map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", @@ -87,7 +124,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) @@ -117,10 +154,19 @@ }{ { name: "client_identity", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - }, + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + KeyId: 1, + KeyType: "key", + UserId: "6", + Username: "jane.doe", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + }, + }, + ), env: sshenv.Env{ GitProtocolVersion: "protocol", IsSSHConnection: true, @@ -134,12 +180,6 @@ GlRepository: "project-26", GlProjectPath: "group/private", }, - response: &accessverifier.Response{ - KeyId: 1, - KeyType: "key", - UserId: "6", - Username: "jane.doe", - }, want: map[string]string{ "key_id": "1", "key_type": "key", @@ -153,7 +193,7 @@ t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.response, tt.env) + ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.env) defer cancel() md, exists := metadata.FromOutgoingContext(ctx) diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -9,9 +9,10 @@ ) const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" - httpSubsystem = "http" + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" + gitalySubsystem = "gitaly" httpInFlightRequestsMetricName = "in_flight_requests" httpRequestsTotalMetricName = "requests_total" @@ -20,6 +21,8 @@ sshdConnectionsInFlightName = "in_flight_connections" sshdConnectionDuration = "connection_duration_seconds" sshdHitMaxSessions = "concurrent_limited_sessions_total" + + gitalyConnectionsTotalName = "connections_total" ) var ( @@ -61,6 +64,16 @@ }, ) + GitalyConnectionsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: gitalySubsystem, + Name: gitalyConnectionsTotalName, + Help: "Number of Gitaly connections that have been established", + }, + []string{"status"}, + ) + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1647614831 0 # Fri Mar 18 14:47:11 2022 +0000 # Node ID 80642f2839758d20b0e5a87fb36460e1a9e6e0bf # Parent 2c4cb630f85ca652c04d738dddc53fc2c2aca5e2 # Parent 1682d4cfdc27e9e5d86a6187e4068fa37ca1ddc3 Merge branch 'id-reuse-grpc-connections-and-sidechannel' into 'main' Reuse Gitaly connections and sidechannel See merge request gitlab-org/gitlab-shell!575 diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -68,6 +68,8 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() + config.GitalyClient.InitSidechannelRegistry(ctx) + cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -69,6 +69,8 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + cfg.GitalyClient.InitSidechannelRegistry(ctx) + server, err := sshd.NewServer(cfg) if err != nil { log.WithError(err).Fatal("Failed to start GitLab built-in sshd") diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -13,13 +13,7 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.ReceivePack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.ReceivePack), response) request := &pb.SSHReceivePackRequest{ Repository: &response.Gitaly.Repo, @@ -30,8 +24,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -13,18 +13,12 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadArchive), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadArchive), response) request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -13,26 +13,20 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadPack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) if response.Gitaly.UseSidechannel { - gc.DialSidechannel = true request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) @@ -44,8 +38,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -97,15 +97,18 @@ Env: env, } + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - err := cmd.Execute(ctx) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,6 +12,7 @@ yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -59,6 +60,8 @@ httpClient *client.HttpClient httpClientErr error httpClientOnce sync.Once + + GitalyClient gitaly.Client } // The defaults to apply before parsing the config file(s). diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly.go @@ -0,0 +1,133 @@ +package gitaly + +import ( + "context" + "fmt" + "sync" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "google.golang.org/grpc" + + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" + "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + "gitlab.com/gitlab-org/labkit/correlation" + grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" + grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +type Command struct { + ServiceName string + Address string + Token string + DialSidechannel bool +} + +type connectionsCache struct { + sync.RWMutex + + connections map[Command]*grpc.ClientConn +} + +type Client struct { + SidechannelRegistry *gitalyclient.SidechannelRegistry + + cache connectionsCache +} + +func (c *Client) InitSidechannelRegistry(ctx context.Context) { + c.SidechannelRegistry = gitalyclient.NewSidechannelRegistry(log.ContextLogger(ctx)) +} + +func (c *Client) GetConnection(ctx context.Context, cmd Command) (*grpc.ClientConn, error) { + c.cache.RLock() + conn := c.cache.connections[cmd] + c.cache.RUnlock() + + if conn != nil { + return conn, nil + } + + c.cache.Lock() + defer c.cache.Unlock() + + if conn := c.cache.connections[cmd]; conn != nil { + return conn, nil + } + + conn, err := c.newConnection(ctx, cmd) + if err != nil { + return nil, err + } + + if c.cache.connections == nil { + c.cache.connections = make(map[Command]*grpc.ClientConn) + } + + c.cache.connections[cmd] = conn + + return conn, nil +} + +func (c *Client) newConnection(ctx context.Context, cmd Command) (conn *grpc.ClientConn, err error) { + defer func() { + label := "ok" + if err != nil { + label = "fail" + } + metrics.GitalyConnectionsTotal.WithLabelValues(label).Inc() + }() + + if cmd.Address == "" { + return nil, fmt.Errorf("no gitaly_address given") + } + + serviceName := correlation.ExtractClientNameFromContext(ctx) + if serviceName == "" { + serviceName = "gitlab-shell-unknown" + + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + } + + serviceName = fmt.Sprintf("%s-%s", serviceName, cmd.ServiceName) + + connOpts := client.DefaultDialOpts + connOpts = append( + connOpts, + grpc.WithStreamInterceptor( + grpc_middleware.ChainStreamClient( + grpctracing.StreamClientTracingInterceptor(), + grpc_prometheus.StreamClientInterceptor, + grpccorrelation.StreamClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + + grpc.WithUnaryInterceptor( + grpc_middleware.ChainUnaryClient( + grpctracing.UnaryClientTracingInterceptor(), + grpc_prometheus.UnaryClientInterceptor, + grpccorrelation.UnaryClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + ) + + if cmd.Token != "" { + connOpts = append(connOpts, + grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cmd.Token)), + ) + } + + if cmd.DialSidechannel { + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) + } + + return client.DialContext(ctx, cmd.Address, connOpts) +} diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly_test.go @@ -0,0 +1,53 @@ +package gitaly + +import ( + "context" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +func TestPrometheusMetrics(t *testing.T) { + metrics.GitalyConnectionsTotal.Reset() + + c := &Client{} + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + c.newConnection(context.Background(), cmd) + c.newConnection(context.Background(), cmd) + + require.Equal(t, 1, testutil.CollectAndCount(metrics.GitalyConnectionsTotal)) + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 0, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) + + cmd = Command{Address: ""} + c.newConnection(context.Background(), cmd) + + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 1, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) +} + +func TestCachedConnections(t *testing.T) { + c := &Client{} + + require.Len(t, c.cache.connections, 0) + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + + conn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + + newConn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + require.Equal(t, conn, newConn) + + cmd = Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9998"} + _, err = c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 2) +} diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -6,56 +6,57 @@ "strconv" "strings" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/labkit/correlation" - grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" - grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" ) // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string - DialSidechannel bool + Config *config.Config + Response *accessverifier.Response + Command gitaly.Command +} + +func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { + gc := gitaly.Command{ + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, + DialSidechannel: response.Gitaly.UseSidechannel, + } + + return &GitalyCommand{Config: cfg, Response: response, Command: gc} } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) - conn, err := getConn(ctx, gc, registry) + // We leave the connection open for future reuse + conn, err := gc.getConn(ctx) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") return err } - defer conn.Close() - childCtx := withOutgoingMetadata(ctx, gc.Features) + childCtx := withOutgoingMetadata(ctx, gc.Response.Gitaly.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn, registry) + exitStatus, err := handler(childCtx, conn) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -72,35 +73,35 @@ // PrepareContext wraps a given context with a correlation ID and logs the command to // be run. -func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) (context.Context, context.CancelFunc) { +func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, env sshenv.Env) (context.Context, context.CancelFunc) { ctx, cancel := context.WithCancel(ctx) - gc.LogExecution(ctx, repository, response, env) + gc.LogExecution(ctx, repository, env) md, ok := metadata.FromOutgoingContext(ctx) if !ok { md = metadata.New(nil) } - md.Append("key_id", strconv.Itoa(response.KeyId)) - md.Append("key_type", response.KeyType) - md.Append("user_id", response.UserId) - md.Append("username", response.Username) + md.Append("key_id", strconv.Itoa(gc.Response.KeyId)) + md.Append("key_type", gc.Response.KeyType) + md.Append("user_id", gc.Response.UserId) + md.Append("username", gc.Response.Username) md.Append("remote_ip", env.RemoteAddr) ctx = metadata.NewOutgoingContext(ctx, md) return ctx, cancel } -func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { +func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, env sshenv.Env) { fields := log.Fields{ - "command": gc.ServiceName, + "command": gc.Command.ServiceName, "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, - "user_id": response.UserId, - "username": response.Username, + "user_id": gc.Response.UserId, + "username": gc.Response.Username, "git_protocol": env.GitProtocolVersion, "remote_ip": env.RemoteAddr, - "gl_key_type": response.KeyType, - "gl_key_id": response.KeyId, + "gl_key_type": gc.Response.KeyType, + "gl_key_id": gc.Response.KeyId, } log.WithContextFields(ctx, fields).Info("executing git command") @@ -118,53 +119,6 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { - if gc.Address == "" { - return nil, fmt.Errorf("no gitaly_address given") - } - - serviceName := correlation.ExtractClientNameFromContext(ctx) - if serviceName == "" { - serviceName = "gitlab-shell-unknown" - - log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") - } - - serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) - - connOpts := client.DefaultDialOpts - connOpts = append( - connOpts, - grpc.WithStreamInterceptor( - grpc_middleware.ChainStreamClient( - grpctracing.StreamClientTracingInterceptor(), - grpc_prometheus.StreamClientInterceptor, - grpccorrelation.StreamClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - - grpc.WithUnaryInterceptor( - grpc_middleware.ChainUnaryClient( - grpctracing.UnaryClientTracingInterceptor(), - grpc_prometheus.UnaryClientInterceptor, - grpccorrelation.UnaryClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - ) - - if gc.Token != "" { - connOpts = append(connOpts, - grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(gc.Token)), - ) - } - - if gc.DialSidechannel { - return client.DialSidechannel(ctx, gc.Address, registry, connOpts) - } - - return client.DialContext(ctx, gc.Address, connOpts) +func (gc *GitalyCommand) getConn(ctx context.Context) (*grpc.ClientConn, error) { + return gc.Config.GitalyClient.GetConnection(ctx, gc.Command) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,15 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -28,10 +28,13 @@ } func TestRunGitalyCommand(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.NoError(t, err) @@ -41,6 +44,32 @@ require.Equal(t, err, expectedErr) } +func TestCachingOfGitalyConnections(t *testing.T) { + ctx := context.Background() + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + response := &accessverifier.Response{ + Username: "user", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Token: "token", + UseSidechannel: true, + }, + } + + cmd := NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + + conn, err := cmd.getConn(ctx) + require.NoError(t, err) + + // Reuses connection for different users + response.Username = "another-user" + cmd = NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + newConn, err := cmd.getConn(ctx) + require.NoError(t, err) + require.Equal(t, conn, newConn) +} + func TestMissingGitalyAddress(t *testing.T) { cmd := GitalyCommand{Config: &config.Config{}} @@ -49,10 +78,13 @@ } func TestUnavailableGitalyErr(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) @@ -68,15 +100,20 @@ }{ { name: "gitaly_feature_flags", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - Features: map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "other-ff": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Features: map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "other-ff": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + }, + }, }, - }, + ), want: map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", @@ -87,7 +124,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) @@ -117,10 +154,19 @@ }{ { name: "client_identity", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - }, + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + KeyId: 1, + KeyType: "key", + UserId: "6", + Username: "jane.doe", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + }, + }, + ), env: sshenv.Env{ GitProtocolVersion: "protocol", IsSSHConnection: true, @@ -134,12 +180,6 @@ GlRepository: "project-26", GlProjectPath: "group/private", }, - response: &accessverifier.Response{ - KeyId: 1, - KeyType: "key", - UserId: "6", - Username: "jane.doe", - }, want: map[string]string{ "key_id": "1", "key_type": "key", @@ -153,7 +193,7 @@ t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.response, tt.env) + ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.env) defer cancel() md, exists := metadata.FromOutgoingContext(ctx) diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -9,9 +9,10 @@ ) const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" - httpSubsystem = "http" + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" + gitalySubsystem = "gitaly" httpInFlightRequestsMetricName = "in_flight_requests" httpRequestsTotalMetricName = "requests_total" @@ -20,6 +21,8 @@ sshdConnectionsInFlightName = "in_flight_connections" sshdConnectionDuration = "connection_duration_seconds" sshdHitMaxSessions = "concurrent_limited_sessions_total" + + gitalyConnectionsTotalName = "connections_total" ) var ( @@ -61,6 +64,16 @@ }, ) + GitalyConnectionsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: gitalySubsystem, + Name: gitalyConnectionsTotalName, + Help: "Number of Gitaly connections that have been established", + }, + []string{"status"}, + ) + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1647615010 -10800 # Fri Mar 18 17:50:10 2022 +0300 # Node ID bab1c219318e2954384d384e53d4db2bb221fd59 # Parent 80642f2839758d20b0e5a87fb36460e1a9e6e0bf Release 13.24.1 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.24.1 + +- Default to info level for an empty log-level !579 +- Update Gitaly dependency to v14.9.0-rc1 !578 +- Reuse Gitaly connections and sidechannel !575 + v13.24.0 - Upgrade golang to 1.17.7 !576 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.0 +13.24.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1647615461 0 # Fri Mar 18 14:57:41 2022 +0000 # Node ID b4a5351f09c840d4e1d17cd2a3aac596b875829c # Parent 80642f2839758d20b0e5a87fb36460e1a9e6e0bf # Parent bab1c219318e2954384d384e53d4db2bb221fd59 Merge branch 'id-release-v-13-24-1' into 'main' Release 13.24.1 See merge request gitlab-org/gitlab-shell!580 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.24.1 + +- Default to info level for an empty log-level !579 +- Update Gitaly dependency to v14.9.0-rc1 !578 +- Reuse Gitaly connections and sidechannel !575 + v13.24.0 - Upgrade golang to 1.17.7 !576 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.0 +13.24.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1648165224 0 # Thu Mar 24 23:40:24 2022 +0000 # Node ID ffeae5042b1188817e8e83c66735fae5976257ce # Parent b4a5351f09c840d4e1d17cd2a3aac596b875829c Add docs for grace-period and probes config options diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -78,6 +78,12 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + grace_period: 10 + # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". + readiness_probe: "/start" + # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". + liveness_probe: "/health" # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1648165224 0 # Thu Mar 24 23:40:24 2022 +0000 # Node ID 9152c3a4030722b823f663307ae59781cd40f9e2 # Parent b4a5351f09c840d4e1d17cd2a3aac596b875829c # Parent ffeae5042b1188817e8e83c66735fae5976257ce Merge branch 'id-config-fields-docs' into 'main' Add docs for grace-period and probes config options See merge request gitlab-org/gitlab-shell!581 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -78,6 +78,12 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + grace_period: 10 + # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". + readiness_probe: "/start" + # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". + liveness_probe: "/health" # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key # HG changeset patch # User Jacob Vosmaer <jacob@gitlab.com> # Date 1648557348 0 # Tue Mar 29 12:35:48 2022 +0000 # Node ID 5f7a2441e28f8c095ef8a07c5ff688a111d6a76f # Parent 9152c3a4030722b823f663307ae59781cd40f9e2 Bump gitaly client Bump gitaly client to 51da8bc17059e4ccd39873e4f3def935341472b8 to get changes from https://gitlab.com/gitlab-org/gitaly/-/merge_requests/4439. diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 + gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -585,7 +585,7 @@ github.com/lib/pq v1.10.2/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.6/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= +github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -867,8 +867,8 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 h1:9vStRdXxcBQ8dHlVnpV28fwLOgyDkSFIpGnPqwzdTvw= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1/go.mod h1:Xk5pn6IWsejg3z2X6BRczC5QaI97PRF3GU5OrJ5Amkg= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1648558269 0 # Tue Mar 29 12:51:09 2022 +0000 # Node ID b58720b5e49212484119bfbe0aff2f0c2726cd92 # Parent 9152c3a4030722b823f663307ae59781cd40f9e2 # Parent 5f7a2441e28f8c095ef8a07c5ff688a111d6a76f Merge branch 'jv-bump-gitaly' into 'main' Bump gitaly client See merge request gitlab-org/gitlab-shell!584 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 + gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -585,7 +585,7 @@ github.com/lib/pq v1.10.2/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.6/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= +github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -867,8 +867,8 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 h1:9vStRdXxcBQ8dHlVnpV28fwLOgyDkSFIpGnPqwzdTvw= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1/go.mod h1:Xk5pn6IWsejg3z2X6BRczC5QaI97PRF3GU5OrJ5Amkg= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1648559332 -10800 # Tue Mar 29 16:08:52 2022 +0300 # Node ID 917c5038c617e2e4e6c0bd9c31396695671cd949 # Parent b58720b5e49212484119bfbe0aff2f0c2726cd92 Release 13.24.2 - Bump gitaly client !584 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.24.2 + +- Bump gitaly client !584 + v13.24.1 - Default to info level for an empty log-level !579 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1648559902 0 # Tue Mar 29 13:18:22 2022 +0000 # Node ID c1490bc3ce020ca4971628342e390b7e9f4c2423 # Parent b58720b5e49212484119bfbe0aff2f0c2726cd92 # Parent 917c5038c617e2e4e6c0bd9c31396695671cd949 Merge branch 'id-release-13-24-2' into 'main' Release 13.24.2 See merge request gitlab-org/gitlab-shell!585 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v13.24.2 + +- Bump gitaly client !584 + v13.24.1 - Default to info level for an empty log-level !579 # HG changeset patch # User Rémy Coutable <remy@rymai.me> # Date 1648545694 -7200 # Tue Mar 29 11:21:34 2022 +0200 # Node ID 25a0daf39d2edcc23b60d850c921d62b624d3363 # Parent 9152c3a4030722b823f663307ae59781cd40f9e2 Use gitlab-dangerfiles to improve MR hygiene Signed-off-by: Rémy Coutable <remy@rymai.me> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,9 @@ - template: Security/SAST.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml + - project: 'gitlab-org/quality/pipeline-common' + file: + - '/ci/danger-review.yml' variables: DOCKER_VERSION: "20.10.3" diff --git a/Dangerfile b/Dangerfile new file mode 100644 --- /dev/null +++ b/Dangerfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'gitlab-dangerfiles' + +Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| + gitlab_dangerfiles.import_plugins + + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) +end diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,7 @@ group :development, :test do gem 'rspec', '~> 3.8.0' end + +group :development, :danger do + gem 'gitlab-dangerfiles', '~> 3.0.0' +end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,89 @@ GEM remote: https://rubygems.org/ specs: + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) + claide (1.1.0) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + colored2 (3.1.2) + cork (0.3.0) + colored2 (~> 3.1) + danger (8.5.0) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (>= 0.9.0, < 2.0) + faraday-http-cache (~> 2.0) + git (~> 1.7) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + no_proxy_fix + octokit (~> 4.7) + terminal-table (>= 1, < 4) + danger-gitlab (8.0.0) + danger + gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) + faraday (1.10.0) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-http-cache (2.2.0) + faraday (>= 0.8) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.3) + multipart-post (>= 1.2, < 3) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + git (1.10.2) + rchardet (~> 1.8) + gitlab (4.18.0) + httparty (~> 0.18) + terminal-table (>= 1.5.1) + gitlab-dangerfiles (3.0.0) + danger (>= 8.4.5) + danger-gitlab (>= 8.0.0) + rake + httparty (0.20.0) + mime-types (~> 3.0) + multi_xml (>= 0.5.2) + kramdown (2.3.2) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2022.0105) + multi_xml (0.6.0) + multipart-post (2.1.1) + nap (1.1.0) + no_proxy_fix (0.1.2) + octokit (4.22.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + open4 (1.3.4) + public_suffix (4.0.6) + rake (13.0.6) + rchardet (1.8.0) + rexml (3.2.5) rspec (3.8.0) rspec-core (~> 3.8.0) rspec-expectations (~> 3.8.0) @@ -15,11 +97,19 @@ diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) + ruby2_keywords (0.0.5) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.1.0) PLATFORMS ruby DEPENDENCIES + gitlab-dangerfiles (~> 3.0.0) rspec (~> 3.8.0) BUNDLED WITH # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1648625945 0 # Wed Mar 30 07:39:05 2022 +0000 # Node ID ee32473559d6881f8f895afe5d4714544bf129d7 # Parent c1490bc3ce020ca4971628342e390b7e9f4c2423 # Parent 25a0daf39d2edcc23b60d850c921d62b624d3363 Merge branch 'use-gitlab-dangerfiles' into 'main' Use gitlab-dangerfiles to improve MR hygiene See merge request gitlab-org/gitlab-shell!583 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,9 @@ - template: Security/SAST.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml + - project: 'gitlab-org/quality/pipeline-common' + file: + - '/ci/danger-review.yml' variables: DOCKER_VERSION: "20.10.3" diff --git a/Dangerfile b/Dangerfile new file mode 100644 --- /dev/null +++ b/Dangerfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'gitlab-dangerfiles' + +Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| + gitlab_dangerfiles.import_plugins + + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) +end diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,7 @@ group :development, :test do gem 'rspec', '~> 3.8.0' end + +group :development, :danger do + gem 'gitlab-dangerfiles', '~> 3.0.0' +end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,89 @@ GEM remote: https://rubygems.org/ specs: + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) + claide (1.1.0) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + colored2 (3.1.2) + cork (0.3.0) + colored2 (~> 3.1) + danger (8.5.0) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (>= 0.9.0, < 2.0) + faraday-http-cache (~> 2.0) + git (~> 1.7) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + no_proxy_fix + octokit (~> 4.7) + terminal-table (>= 1, < 4) + danger-gitlab (8.0.0) + danger + gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) + faraday (1.10.0) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-http-cache (2.2.0) + faraday (>= 0.8) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.3) + multipart-post (>= 1.2, < 3) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + git (1.10.2) + rchardet (~> 1.8) + gitlab (4.18.0) + httparty (~> 0.18) + terminal-table (>= 1.5.1) + gitlab-dangerfiles (3.0.0) + danger (>= 8.4.5) + danger-gitlab (>= 8.0.0) + rake + httparty (0.20.0) + mime-types (~> 3.0) + multi_xml (>= 0.5.2) + kramdown (2.3.2) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2022.0105) + multi_xml (0.6.0) + multipart-post (2.1.1) + nap (1.1.0) + no_proxy_fix (0.1.2) + octokit (4.22.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + open4 (1.3.4) + public_suffix (4.0.6) + rake (13.0.6) + rchardet (1.8.0) + rexml (3.2.5) rspec (3.8.0) rspec-core (~> 3.8.0) rspec-expectations (~> 3.8.0) @@ -15,11 +97,19 @@ diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) + ruby2_keywords (0.0.5) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.1.0) PLATFORMS ruby DEPENDENCIES + gitlab-dangerfiles (~> 3.0.0) rspec (~> 3.8.0) BUNDLED WITH # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1648628224 0 # Wed Mar 30 08:17:04 2022 +0000 # Node ID aeac3ba0ed947c1e404d81b3b29f45c6061ea177 # Parent ee32473559d6881f8f895afe5d4714544bf129d7 Abort long-running unauthenticated SSH connections diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -84,6 +84,8 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" + # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. + login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -26,6 +26,7 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` GracePeriodSeconds uint64 `yaml:"grace_period"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` @@ -78,6 +79,7 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + LoginGraceTimeSeconds: 60, GracePeriodSeconds: 10, ReadinessProbe: "/start", LivenessProbe: "/health", @@ -89,6 +91,10 @@ } ) +func (sc *ServerConfig) LoginGraceTime() time.Duration { + return time.Duration(sc.LoginGraceTimeSeconds) * time.Second +} + func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -164,7 +164,7 @@ ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) + sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) if err != nil { ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return @@ -187,6 +187,20 @@ ctxlog.Info("server: handleConn: done") } +func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { + timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { + nconn.Close() + }) + defer func() { + // If time.Stop() equals false, that means that AfterFunc has been executed + if !timer.Stop() { + err = fmt.Errorf("initSSHConnection: ssh handshake timeout") + } + }() + + return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) +} + func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" "net/http/httptest" "os" @@ -134,6 +135,33 @@ require.Nil(t, s.Shutdown()) } +func TestLoginGraceTime(t *testing.T) { + s := setupServer(t) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Verify that the server shutdowns instantly without waiting for any connection to execute + // That means that the server doesn't have any connections to wait for + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -183,6 +211,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.LoginGraceTimeSeconds = 1 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1648628224 0 # Wed Mar 30 08:17:04 2022 +0000 # Node ID 25dad1ff6b70811873f8826160431ae92e07f231 # Parent ee32473559d6881f8f895afe5d4714544bf129d7 # Parent aeac3ba0ed947c1e404d81b3b29f45c6061ea177 Merge branch 'id-logic-grace-time' into 'main' Abort long-running unauthenticated SSH connections See merge request gitlab-org/gitlab-shell!582 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -84,6 +84,8 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" + # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. + login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -26,6 +26,7 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` GracePeriodSeconds uint64 `yaml:"grace_period"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` @@ -78,6 +79,7 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + LoginGraceTimeSeconds: 60, GracePeriodSeconds: 10, ReadinessProbe: "/start", LivenessProbe: "/health", @@ -89,6 +91,10 @@ } ) +func (sc *ServerConfig) LoginGraceTime() time.Duration { + return time.Duration(sc.LoginGraceTimeSeconds) * time.Second +} + func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -164,7 +164,7 @@ ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) + sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) if err != nil { ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return @@ -187,6 +187,20 @@ ctxlog.Info("server: handleConn: done") } +func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { + timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { + nconn.Close() + }) + defer func() { + // If time.Stop() equals false, that means that AfterFunc has been executed + if !timer.Stop() { + err = fmt.Errorf("initSSHConnection: ssh handshake timeout") + } + }() + + return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) +} + func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" "net/http/httptest" "os" @@ -134,6 +135,33 @@ require.Nil(t, s.Shutdown()) } +func TestLoginGraceTime(t *testing.T) { + s := setupServer(t) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Verify that the server shutdowns instantly without waiting for any connection to execute + // That means that the server doesn't have any connections to wait for + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -183,6 +211,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.LoginGraceTimeSeconds = 1 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1648714502 -14400 # Thu Mar 31 12:15:02 2022 +0400 # Node ID c31ba1247c79fc4654062188a9560673f8877cdc # Parent 25dad1ff6b70811873f8826160431ae92e07f231 Improve login grace timeout message diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -194,7 +194,7 @@ defer func() { // If time.Stop() equals false, that means that AfterFunc has been executed if !timer.Stop() { - err = fmt.Errorf("initSSHConnection: ssh handshake timeout") + err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) } }() # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1648774768 0 # Fri Apr 01 00:59:28 2022 +0000 # Node ID a3d2ed5acfd10018e5e23fbcf782cc0b7dc48560 # Parent 25dad1ff6b70811873f8826160431ae92e07f231 # Parent c31ba1247c79fc4654062188a9560673f8877cdc Merge branch 'improve-login-grace-timeout-msg' into 'main' Improve login grace timeout message Closes #553 See merge request gitlab-org/gitlab-shell!586 diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -194,7 +194,7 @@ defer func() { // If time.Stop() equals false, that means that AfterFunc has been executed if !timer.Stop() { - err = fmt.Errorf("initSSHConnection: ssh handshake timeout") + err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) } }() # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1648815245 -7200 # Fri Apr 01 14:14:05 2022 +0200 # Node ID 3bf27c48724cce6c96a3640bfa06c4fd1136296c # Parent a3d2ed5acfd10018e5e23fbcf782cc0b7dc48560 ci: start integrating go 1.18 into the CI pipelines diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -55,23 +55,19 @@ script: - make verify test -go:1.16: +tests: extends: .test - image: golang:1.16 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.17: - extends: .test - image: golang:1.17 + image: golang:${GO_VERSION} + parallel: + matrix: + - GO_VERSION: ["1.16", "1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' race: extends: .test - image: golang:1.17 + image: golang:1.18 script: - make test_golang_race # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649218442 0 # Wed Apr 06 04:14:02 2022 +0000 # Node ID 715513fde9e9b351e181d3063dfc236a29ba4b60 # Parent a3d2ed5acfd10018e5e23fbcf782cc0b7dc48560 # Parent 3bf27c48724cce6c96a3640bfa06c4fd1136296c Merge branch 'ci/go-1.18' into 'main' ci: start integrating go 1.18 into the CI pipelines See merge request gitlab-org/gitlab-shell!587 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -55,23 +55,19 @@ script: - make verify test -go:1.16: +tests: extends: .test - image: golang:1.16 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.17: - extends: .test - image: golang:1.17 + image: golang:${GO_VERSION} + parallel: + matrix: + - GO_VERSION: ["1.16", "1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' race: extends: .test - image: golang:1.17 + image: golang:1.18 script: - make test_golang_race # HG changeset patch # User Jason Goodman <jgoodman@gitlab.com> # Date 1649218579 0 # Wed Apr 06 04:16:19 2022 +0000 # Node ID 96addbc8b7783117167ef41d1fe6699b2bdb147c # Parent a3d2ed5acfd10018e5e23fbcf782cc0b7dc48560 Update Version File diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.1 +13.24.2 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649218581 0 # Wed Apr 06 04:16:21 2022 +0000 # Node ID c28b67cac739dce1c4549b7ed746d3fd1688ed26 # Parent 715513fde9e9b351e181d3063dfc236a29ba4b60 # Parent 96addbc8b7783117167ef41d1fe6699b2bdb147c Merge branch 'update-version-file' into 'main' Update Version File See merge request gitlab-org/gitlab-shell!589 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.1 +13.24.2 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649149365 -14400 # Tue Apr 05 13:02:45 2022 +0400 # Node ID 24b6ef0325ddd63dca7a0763e057c3a3b5293a37 # Parent a3d2ed5acfd10018e5e23fbcf782cc0b7dc48560 Fix connections duration metrics We need to pass time.Now as a param, otherwise it's calculated on call diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -13,7 +13,6 @@ ) type connection struct { - begin time.Time concurrentSessions *semaphore.Weighted remoteAddr string } @@ -22,7 +21,6 @@ func newConnection(maxSessions int64, remoteAddr string) *connection { return &connection{ - begin: time.Now(), concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, } @@ -32,9 +30,11 @@ ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) metrics.SshdConnectionsInFlight.Inc() - defer metrics.SshdConnectionsInFlight.Dec() - defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) + defer func(started time.Time) { + metrics.SshdConnectionsInFlight.Dec() + metrics.SshdConnectionDuration.Observe(time.Since(started).Seconds()) + }(time.Now()) for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1649230580 0 # Wed Apr 06 07:36:20 2022 +0000 # Node ID 19b356eaefe883046e2d240533cfdb4096da2025 # Parent c28b67cac739dce1c4549b7ed746d3fd1688ed26 # Parent 24b6ef0325ddd63dca7a0763e057c3a3b5293a37 Merge branch 'id-fix-connections-duration-metrics' into 'main' Fix connections duration metrics See merge request gitlab-org/gitlab-shell!588 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -13,7 +13,6 @@ ) type connection struct { - begin time.Time concurrentSessions *semaphore.Weighted remoteAddr string } @@ -22,7 +21,6 @@ func newConnection(maxSessions int64, remoteAddr string) *connection { return &connection{ - begin: time.Now(), concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, } @@ -32,9 +30,11 @@ ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) metrics.SshdConnectionsInFlight.Inc() - defer metrics.SshdConnectionsInFlight.Dec() - defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) + defer func(started time.Time) { + metrics.SshdConnectionsInFlight.Dec() + metrics.SshdConnectionDuration.Observe(time.Since(started).Seconds()) + }(time.Now()) for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649261638 -14400 # Wed Apr 06 20:13:58 2022 +0400 # Node ID 57759a36f83b7fc23536df8108959c0c1c2818ad # Parent 19b356eaefe883046e2d240533cfdb4096da2025 Release 13.25.0 - Fix connections duration metrics !588 - ci: start integrating go 1.18 into the CI pipelines !587 - Abort long-running unauthenticated SSH connections !582 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.25.0 + +- Fix connections duration metrics !588 +- ci: start integrating go 1.18 into the CI pipelines !587 +- Abort long-running unauthenticated SSH connections !582 + v13.24.2 - Bump gitaly client !584 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.2 +13.25.0 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1649301418 0 # Thu Apr 07 03:16:58 2022 +0000 # Node ID bdac88e392d8f4a931262f8370b693c127d1f807 # Parent 19b356eaefe883046e2d240533cfdb4096da2025 # Parent 57759a36f83b7fc23536df8108959c0c1c2818ad Merge branch 'id-release-13.25.0' into 'main' Release 13.25.0 See merge request gitlab-org/gitlab-shell!591 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.25.0 + +- Fix connections duration metrics !588 +- ci: start integrating go 1.18 into the CI pipelines !587 +- Abort long-running unauthenticated SSH connections !582 + v13.24.2 - Bump gitaly client !584 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.2 +13.25.0 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1649309538 -36000 # Thu Apr 07 15:32:18 2022 +1000 # Node ID a7fc1e82349c296099277708965f0ed40fe064ae # Parent bdac88e392d8f4a931262f8370b693c127d1f807 Upgrade golang to 1.17.8 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.7 +golang 1.17.8 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649311195 0 # Thu Apr 07 05:59:55 2022 +0000 # Node ID b631a53700c80225142a25d9ca0d97fc1b1d1bfe # Parent bdac88e392d8f4a931262f8370b693c127d1f807 # Parent a7fc1e82349c296099277708965f0ed40fe064ae Merge branch '554-support-using-go-version-1-17-8' into 'main' Upgrade golang to 1.17.8 Closes #554 See merge request gitlab-org/gitlab-shell!592 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.7 +golang 1.17.8 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649355549 -14400 # Thu Apr 07 22:19:09 2022 +0400 # Node ID ada43a89fc2357b359022b91c972b57db67aa93f # Parent b631a53700c80225142a25d9ca0d97fc1b1d1bfe Add additional metrics to gitlab-sshd - Observe time to establish a session - Log the duration of the successfully established connection - Observe total time to handle the connection - Log the duration of the successfully executed connection - Observe the count of ssh connections - Observe the count of failed ssh connections diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:6] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -48,8 +48,11 @@ "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", "gitlab_shell_sshd_concurrent_limited_sessions_total", - "gitlab_shell_sshd_connection_duration_seconds", "gitlab_shell_sshd_in_flight_connections", + "gitlab_shell_sshd_session_duration_seconds", + "gitlab_shell_sshd_session_established_duration_seconds", + "gitlab_sli:shell_sshd_sessions:errors_total", + "gitlab_sli:shell_sshd_sessions:total", } require.Equal(t, expectedMetricNames, actualNames) diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -18,30 +18,42 @@ httpRequestsTotalMetricName = "requests_total" httpRequestDurationSecondsMetricName = "request_duration_seconds" - sshdConnectionsInFlightName = "in_flight_connections" - sshdConnectionDuration = "connection_duration_seconds" - sshdHitMaxSessions = "concurrent_limited_sessions_total" + sshdConnectionsInFlightName = "in_flight_connections" + sshdHitMaxSessionsName = "concurrent_limited_sessions_total" + sshdSessionDurationSecondsName = "session_duration_seconds" + sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + + sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" + sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" gitalyConnectionsTotalName = "connections_total" ) var ( - SshdConnectionDuration = promauto.NewHistogram( + SshdSessionDuration = promauto.NewHistogram( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdConnectionDuration, + Name: sshdSessionDurationSecondsName, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ + 5.0, /* 5s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + }, + }, + ) + + SshdSessionEstablishedDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdSessionEstablishedDurationSecondsName, + Help: "A histogram of latencies until session established to gitlab-shell sshd.", + Buckets: []float64{ + 0.5, /* 5ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ }, }, ) @@ -59,11 +71,25 @@ prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdHitMaxSessions, + Name: sshdHitMaxSessionsName, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) + SliSshdSessionsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsTotalName, + Help: "Number of SSH sessions that have been established", + }, + ) + + SliSshdSessionsErrorsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsErrorsTotalName, + Help: "Number of SSH sessions that have failed", + }, + ) + GitalyConnectionsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Namespace: namespace, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,7 +2,6 @@ import ( "context" - "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" @@ -29,13 +28,6 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) - metrics.SshdConnectionsInFlight.Inc() - - defer func(started time.Time) { - metrics.SshdConnectionsInFlight.Dec() - metrics.SshdConnectionDuration.Observe(time.Since(started).Seconds()) - }(time.Now()) - for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,6 +22,7 @@ channel ssh.Channel gitlabKeyId string remoteAddr string + success bool // State managed by the session execCmd string @@ -182,6 +183,8 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} + s.success = status == 0 + s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -99,6 +99,7 @@ expectedExecCmd string sentRequestName string sentRequestPayload []byte + success bool }{ { desc: "invalid payload", @@ -111,6 +112,7 @@ expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + success: true, }, } @@ -130,6 +132,7 @@ require.Equal(t, false, s.handleExec(context.Background(), r)) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + require.Equal(t, tc.success, s.success) }) } } @@ -141,6 +144,7 @@ errMsg string gitlabKeyId string expectedExitCode uint32 + success bool }{ { desc: "fails to parse command", diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,6 +12,7 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -145,6 +146,20 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + success := false + + metrics.SshdConnectionsInFlight.Inc() + started := time.Now() + defer func() { + metrics.SshdConnectionsInFlight.Dec() + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + + metrics.SliSshdSessionsTotal.Inc() + if !success { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + }() + remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() @@ -172,8 +187,12 @@ go ssh.DiscardRequests(reqs) + var establishSessionDuration float64 conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + establishSessionDuration = time.Since(started).Seconds() + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) + session := &session{ cfg: s.Config, channel: channel, @@ -182,9 +201,14 @@ } session.handle(ctx, requests) + + success = session.success }) - ctxlog.Info("server: handleConn: done") + ctxlog.WithFields(log.Fields{ + "duration_s": time.Since(started).Seconds(), + "establish_session_duration_s": establishSessionDuration, + }).Info("server: handleConn: done") } func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1649915254 0 # Thu Apr 14 05:47:34 2022 +0000 # Node ID 6d98b57cd11cdde998f1ef17fea98d4b23d96e20 # Parent b631a53700c80225142a25d9ca0d97fc1b1d1bfe # Parent ada43a89fc2357b359022b91c972b57db67aa93f Merge branch 'id-metrics-for-results' into 'main' Add additional metrics to gitlab-sshd See merge request gitlab-org/gitlab-shell!593 diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:6] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -48,8 +48,11 @@ "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", "gitlab_shell_sshd_concurrent_limited_sessions_total", - "gitlab_shell_sshd_connection_duration_seconds", "gitlab_shell_sshd_in_flight_connections", + "gitlab_shell_sshd_session_duration_seconds", + "gitlab_shell_sshd_session_established_duration_seconds", + "gitlab_sli:shell_sshd_sessions:errors_total", + "gitlab_sli:shell_sshd_sessions:total", } require.Equal(t, expectedMetricNames, actualNames) diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -18,30 +18,42 @@ httpRequestsTotalMetricName = "requests_total" httpRequestDurationSecondsMetricName = "request_duration_seconds" - sshdConnectionsInFlightName = "in_flight_connections" - sshdConnectionDuration = "connection_duration_seconds" - sshdHitMaxSessions = "concurrent_limited_sessions_total" + sshdConnectionsInFlightName = "in_flight_connections" + sshdHitMaxSessionsName = "concurrent_limited_sessions_total" + sshdSessionDurationSecondsName = "session_duration_seconds" + sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + + sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" + sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" gitalyConnectionsTotalName = "connections_total" ) var ( - SshdConnectionDuration = promauto.NewHistogram( + SshdSessionDuration = promauto.NewHistogram( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdConnectionDuration, + Name: sshdSessionDurationSecondsName, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ + 5.0, /* 5s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + }, + }, + ) + + SshdSessionEstablishedDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdSessionEstablishedDurationSecondsName, + Help: "A histogram of latencies until session established to gitlab-shell sshd.", + Buckets: []float64{ + 0.5, /* 5ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ }, }, ) @@ -59,11 +71,25 @@ prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdHitMaxSessions, + Name: sshdHitMaxSessionsName, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) + SliSshdSessionsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsTotalName, + Help: "Number of SSH sessions that have been established", + }, + ) + + SliSshdSessionsErrorsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsErrorsTotalName, + Help: "Number of SSH sessions that have failed", + }, + ) + GitalyConnectionsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Namespace: namespace, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,7 +2,6 @@ import ( "context" - "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" @@ -29,13 +28,6 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) - metrics.SshdConnectionsInFlight.Inc() - - defer func(started time.Time) { - metrics.SshdConnectionsInFlight.Dec() - metrics.SshdConnectionDuration.Observe(time.Since(started).Seconds()) - }(time.Now()) - for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,6 +22,7 @@ channel ssh.Channel gitlabKeyId string remoteAddr string + success bool // State managed by the session execCmd string @@ -182,6 +183,8 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} + s.success = status == 0 + s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -99,6 +99,7 @@ expectedExecCmd string sentRequestName string sentRequestPayload []byte + success bool }{ { desc: "invalid payload", @@ -111,6 +112,7 @@ expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + success: true, }, } @@ -130,6 +132,7 @@ require.Equal(t, false, s.handleExec(context.Background(), r)) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + require.Equal(t, tc.success, s.success) }) } } @@ -141,6 +144,7 @@ errMsg string gitlabKeyId string expectedExitCode uint32 + success bool }{ { desc: "fails to parse command", diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,6 +12,7 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -145,6 +146,20 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + success := false + + metrics.SshdConnectionsInFlight.Inc() + started := time.Now() + defer func() { + metrics.SshdConnectionsInFlight.Dec() + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + + metrics.SliSshdSessionsTotal.Inc() + if !success { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + }() + remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() @@ -172,8 +187,12 @@ go ssh.DiscardRequests(reqs) + var establishSessionDuration float64 conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + establishSessionDuration = time.Since(started).Seconds() + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) + session := &session{ cfg: s.Config, channel: channel, @@ -182,9 +201,14 @@ } session.handle(ctx, requests) + + success = session.success }) - ctxlog.Info("server: handleConn: done") + ctxlog.WithFields(log.Fields{ + "duration_s": time.Since(started).Seconds(), + "establish_session_duration_s": establishSessionDuration, + }).Info("server: handleConn: done") } func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1650309091 25200 # Mon Apr 18 12:11:31 2022 -0700 # Node ID 64fb809c76dfdb5350e57d1576eacf76121b6b48 # Parent 6d98b57cd11cdde998f1ef17fea98d4b23d96e20 Add support for FIPS encryption This commit adds support of using a FIPS-validated SSL library with compiled Go executables when `FIPS_MODE=1 make` is run. A Go compiler that supports BoringSSL either directly (e.g. the `dev.boringcrypto` branch) or with a dynamically linked OpenSSL (e.g. https://github.com/golang-fips/go) is required. This is similar to the changes to support FIPS in GitLab Runner and in GitLab Pages: https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/716 Changelog: added diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,9 +1,15 @@ .PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install +FIPS_MODE ?= 0 GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$$0="v"$$0' VERSION 2>/dev/null || echo unknown) BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver + +ifeq (${FIPS_MODE}, 1) + BUILD_TAGS += boringcrypto +endif + GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,6 +11,7 @@ "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -73,6 +74,7 @@ cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + boring.CheckBoring() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/internal/boring/boring.go b/internal/boring/boring.go new file mode 100644 --- /dev/null +++ b/internal/boring/boring.go @@ -0,0 +1,23 @@ +//go:build boringcrypto +// +build boringcrypto + +package boring + +import ( + "crypto/boring" + + "gitlab.com/gitlab-org/labkit/log" +) + +// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go +// compiler in https://github.com/golang-fips/go, this requires that: +// +// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). +// 2. A system OpenSSL can be dynamically loaded via ldopen(). +func CheckBoring() { + if boring.Enabled() { + log.Info("FIPS mode is enabled. Using an external SSL library.") + return + } + log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") +} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go new file mode 100644 --- /dev/null +++ b/internal/boring/notboring.go @@ -0,0 +1,9 @@ +//go:build !boringcrypto +// +build !boringcrypto + +package boring + +// CheckBoring does nothing when the boringcrypto tag is not in the +// build. +func CheckBoring() { +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650368543 0 # Tue Apr 19 11:42:23 2022 +0000 # Node ID 66fce7a79fc2e0b2e5f7482aeeb0df6754fd4586 # Parent 6d98b57cd11cdde998f1ef17fea98d4b23d96e20 # Parent 64fb809c76dfdb5350e57d1576eacf76121b6b48 Merge branch 'sh-fips-mode' into 'main' Add support for FIPS encryption See merge request gitlab-org/gitlab-shell!597 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,9 +1,15 @@ .PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install +FIPS_MODE ?= 0 GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$$0="v"$$0' VERSION 2>/dev/null || echo unknown) BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver + +ifeq (${FIPS_MODE}, 1) + BUILD_TAGS += boringcrypto +endif + GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,6 +11,7 @@ "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -73,6 +74,7 @@ cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + boring.CheckBoring() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/internal/boring/boring.go b/internal/boring/boring.go new file mode 100644 --- /dev/null +++ b/internal/boring/boring.go @@ -0,0 +1,23 @@ +//go:build boringcrypto +// +build boringcrypto + +package boring + +import ( + "crypto/boring" + + "gitlab.com/gitlab-org/labkit/log" +) + +// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go +// compiler in https://github.com/golang-fips/go, this requires that: +// +// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). +// 2. A system OpenSSL can be dynamically loaded via ldopen(). +func CheckBoring() { + if boring.Enabled() { + log.Info("FIPS mode is enabled. Using an external SSL library.") + return + } + log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") +} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go new file mode 100644 --- /dev/null +++ b/internal/boring/notboring.go @@ -0,0 +1,9 @@ +//go:build !boringcrypto +// +build !boringcrypto + +package boring + +// CheckBoring does nothing when the boringcrypto tag is not in the +// build. +func CheckBoring() { +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650368868 -14400 # Tue Apr 19 15:47:48 2022 +0400 # Node ID 13c1bfd3c5cdbdc0ad5bdc3e7a6668f01370c5c1 # Parent 66fce7a79fc2e0b2e5f7482aeeb0df6754fd4586 Release 13.25.1 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.25.1 + +- Upgrade golang to 1.17.8 !591 +- Add additional metrics to gitlab-sshd !593 +- Add support for FIPS encryption !597 + v13.25.0 - Fix connections duration metrics !588 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.0 +13.25.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650369339 0 # Tue Apr 19 11:55:39 2022 +0000 # Node ID 6712c68c42156ec09eefaab72446f498341d0464 # Parent 66fce7a79fc2e0b2e5f7482aeeb0df6754fd4586 # Parent 13c1bfd3c5cdbdc0ad5bdc3e7a6668f01370c5c1 Merge branch 'id-release-13-25-1' into 'main' Release 13.25.1 See merge request gitlab-org/gitlab-shell!598 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.25.1 + +- Upgrade golang to 1.17.8 !591 +- Add additional metrics to gitlab-sshd !593 +- Add support for FIPS encryption !597 + v13.25.0 - Fix connections duration metrics !588 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.0 +13.25.1 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1650377784 25200 # Tue Apr 19 07:16:24 2022 -0700 # Node ID a840f4d80bd90e7c69d7e6e4556f468a63063c63 # Parent 6712c68c42156ec09eefaab72446f498341d0464 Fix typo in FIPS mode message Rename Gitaly -> gitlab-shell diff --git a/internal/boring/boring.go b/internal/boring/boring.go --- a/internal/boring/boring.go +++ b/internal/boring/boring.go @@ -19,5 +19,5 @@ log.Info("FIPS mode is enabled. Using an external SSL library.") return } - log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") + log.Info("gitlab-shell was compiled with FIPS mode, but an external SSL library was not enabled.") } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650523534 0 # Thu Apr 21 06:45:34 2022 +0000 # Node ID 6a516f324c6ed4a62995ebccb54d967c85b0b8c0 # Parent 6712c68c42156ec09eefaab72446f498341d0464 # Parent a840f4d80bd90e7c69d7e6e4556f468a63063c63 Merge branch 'sh-fix-typo-fips' into 'main' Fix typo in FIPS mode message See merge request gitlab-org/gitlab-shell!599 diff --git a/internal/boring/boring.go b/internal/boring/boring.go --- a/internal/boring/boring.go +++ b/internal/boring/boring.go @@ -19,5 +19,5 @@ log.Info("FIPS mode is enabled. Using an external SSL library.") return } - log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") + log.Info("gitlab-shell was compiled with FIPS mode, but an external SSL library was not enabled.") } # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1650483924 -7200 # Wed Apr 20 21:45:24 2022 +0200 # Node ID 7bdc7bddd3c8ceb182e43af090c35dc8a4b0eb64 # Parent 6712c68c42156ec09eefaab72446f498341d0464 Bump Go to 1.17.9 for asdf users diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.8 +golang 1.17.9 # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1650525150 0 # Thu Apr 21 07:12:30 2022 +0000 # Node ID 5c5ea97a01d86c20b2843fa1b81d54a287a37fad # Parent 6a516f324c6ed4a62995ebccb54d967c85b0b8c0 # Parent 7bdc7bddd3c8ceb182e43af090c35dc8a4b0eb64 Merge branch 'bump/go-tool-version' into 'main' Bump Go to 1.17.9 for asdf users See merge request gitlab-org/gitlab-shell!600 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.8 +golang 1.17.9 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650889855 -14400 # Mon Apr 25 16:30:55 2022 +0400 # Node ID c78f2ea27d8184ce358ae0710d6b78c71dd4c34e # Parent 5c5ea97a01d86c20b2843fa1b81d54a287a37fad Revert "Abort long-running unauthenticated SSH connections" This reverts commit 3a2c8f2c47774a35d840ec8baf54341beede5d43. diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -84,8 +84,6 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" - # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. - login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -26,7 +26,6 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` GracePeriodSeconds uint64 `yaml:"grace_period"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` @@ -79,7 +78,6 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - LoginGraceTimeSeconds: 60, GracePeriodSeconds: 10, ReadinessProbe: "/start", LivenessProbe: "/health", @@ -91,10 +89,6 @@ } ) -func (sc *ServerConfig) LoginGraceTime() time.Duration { - return time.Duration(sc.LoginGraceTimeSeconds) * time.Second -} - func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -179,12 +179,11 @@ ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return } - go ssh.DiscardRequests(reqs) var establishSessionDuration float64 @@ -211,20 +210,6 @@ }).Info("server: handleConn: done") } -func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { - timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { - nconn.Close() - }) - defer func() { - // If time.Stop() equals false, that means that AfterFunc has been executed - if !timer.Stop() { - err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) - } - }() - - return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) -} - func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,7 +3,6 @@ import ( "context" "fmt" - "net" "net/http" "net/http/httptest" "os" @@ -135,33 +134,6 @@ require.Nil(t, s.Shutdown()) } -func TestLoginGraceTime(t *testing.T) { - s := setupServer(t) - - unauthenticatedRequestStatus := make(chan string) - completed := make(chan bool) - - clientCfg := clientConfig(t) - clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { - unauthenticatedRequestStatus <- "authentication-started" - <-completed // Wait infinitely - - return nil - } - - go func() { - // Start an SSH connection that never ends - ssh.Dial("tcp", serverUrl, clientCfg) - }() - - require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) - - // Verify that the server shutdowns instantly without waiting for any connection to execute - // That means that the server doesn't have any connections to wait for - require.NoError(t, s.Shutdown()) - verifyStatus(t, s, StatusClosed) -} - func setupServer(t *testing.T) *Server { t.Helper() @@ -211,7 +183,6 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.LoginGraceTimeSeconds = 1 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1650943475 0 # Tue Apr 26 03:24:35 2022 +0000 # Node ID 74166f5062a6becbc92fb7401b1e0ffaef7ac8cd # Parent 5c5ea97a01d86c20b2843fa1b81d54a287a37fad # Parent c78f2ea27d8184ce358ae0710d6b78c71dd4c34e Merge branch 'id-revert-ssh-connection-timeouts' into 'main' Revert "Abort long-running unauthenticated SSH connections" See merge request gitlab-org/gitlab-shell!605 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -84,8 +84,6 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" - # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. - login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -26,7 +26,6 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` GracePeriodSeconds uint64 `yaml:"grace_period"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` @@ -79,7 +78,6 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - LoginGraceTimeSeconds: 60, GracePeriodSeconds: 10, ReadinessProbe: "/start", LivenessProbe: "/health", @@ -91,10 +89,6 @@ } ) -func (sc *ServerConfig) LoginGraceTime() time.Duration { - return time.Duration(sc.LoginGraceTimeSeconds) * time.Second -} - func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -179,12 +179,11 @@ ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return } - go ssh.DiscardRequests(reqs) var establishSessionDuration float64 @@ -211,20 +210,6 @@ }).Info("server: handleConn: done") } -func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { - timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { - nconn.Close() - }) - defer func() { - // If time.Stop() equals false, that means that AfterFunc has been executed - if !timer.Stop() { - err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) - } - }() - - return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) -} - func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,7 +3,6 @@ import ( "context" "fmt" - "net" "net/http" "net/http/httptest" "os" @@ -135,33 +134,6 @@ require.Nil(t, s.Shutdown()) } -func TestLoginGraceTime(t *testing.T) { - s := setupServer(t) - - unauthenticatedRequestStatus := make(chan string) - completed := make(chan bool) - - clientCfg := clientConfig(t) - clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { - unauthenticatedRequestStatus <- "authentication-started" - <-completed // Wait infinitely - - return nil - } - - go func() { - // Start an SSH connection that never ends - ssh.Dial("tcp", serverUrl, clientCfg) - }() - - require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) - - // Verify that the server shutdowns instantly without waiting for any connection to execute - // That means that the server doesn't have any connections to wait for - require.NoError(t, s.Shutdown()) - verifyStatus(t, s, StatusClosed) -} - func setupServer(t *testing.T) *Server { t.Helper() @@ -211,7 +183,6 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.LoginGraceTimeSeconds = 1 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650943629 -14400 # Tue Apr 26 07:27:09 2022 +0400 # Node ID c7ed2cccab7d03a92e70f77bb4eaecfe0d832707 # Parent 74166f5062a6becbc92fb7401b1e0ffaef7ac8cd Release v13.25.2 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v13.25.2 + +- Revert "Abort long-running unauthenticated SSH connections" !605 +- Bump Go to 1.17.9 for asdf users !600 + v13.25.1 - Upgrade golang to 1.17.8 !591 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.1 +13.25.2 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650944082 0 # Tue Apr 26 03:34:42 2022 +0000 # Node ID 3ab9ac91927af7dec6116509b5614a0d23048673 # Parent 74166f5062a6becbc92fb7401b1e0ffaef7ac8cd # Parent c7ed2cccab7d03a92e70f77bb4eaecfe0d832707 Merge branch 'id-release-13-25-2' into 'main' Release v13.25.2 See merge request gitlab-org/gitlab-shell!606 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v13.25.2 + +- Revert "Abort long-running unauthenticated SSH connections" !605 +- Bump Go to 1.17.9 for asdf users !600 + v13.25.1 - Upgrade golang to 1.17.8 !591 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.1 +13.25.2 # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1650661577 -7200 # Fri Apr 22 23:06:17 2022 +0200 # Node ID 48fc1074c7d11801c7fe3dd57d9ebaa90bd0e354 # Parent 5c5ea97a01d86c20b2843fa1b81d54a287a37fad feat: replace status mutex with RWMutex diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -32,7 +32,7 @@ Config *config.Config status status - statusMu sync.Mutex + statusMu sync.RWMutex wg sync.WaitGroup listener net.Listener serverConfig *serverConfig @@ -139,8 +139,8 @@ } func (s *Server) getStatus() status { - s.statusMu.Lock() - defer s.statusMu.Unlock() + s.statusMu.RLock() + defer s.statusMu.RUnlock() return s.status } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650949884 0 # Tue Apr 26 05:11:24 2022 +0000 # Node ID b2afbed301d648dec2caa9efc52027cb72a2e0e4 # Parent 3ab9ac91927af7dec6116509b5614a0d23048673 # Parent 48fc1074c7d11801c7fe3dd57d9ebaa90bd0e354 Merge branch 'feat/status-rwmutex' into 'main' feat: replace status mutex with RWMutex See merge request gitlab-org/gitlab-shell!604 diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -32,7 +32,7 @@ Config *config.Config status status - statusMu sync.Mutex + statusMu sync.RWMutex wg sync.WaitGroup listener net.Listener serverConfig *serverConfig @@ -139,8 +139,8 @@ } func (s *Server) getStatus() status { - s.statusMu.Lock() - defer s.statusMu.Unlock() + s.statusMu.RLock() + defer s.statusMu.RUnlock() return s.status } # HG changeset patch # User Vasilii Iakliushin <viakliushin@gitlab.com> # Date 1650626839 -7200 # Fri Apr 22 13:27:19 2022 +0200 # Node ID 25cf56ca13b111ce13fcc2d0b57cbf73e826787e # Parent 5c5ea97a01d86c20b2843fa1b81d54a287a37fad Remove `self_signed_cert` option Contributes to https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 Changelog: removed diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -59,7 +59,7 @@ secret := "sssh, it's a secret" - httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) client, err := NewGitlabNetClient("", "", secret, httpClient) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -71,8 +71,8 @@ } // Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 -func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { - c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) +func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64) *HttpClient { + c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, readTimeoutSeconds, nil) if err != nil { log.WithError(err).Error("new http client with opts") } @@ -80,7 +80,7 @@ } // NewHTTPClientWithOpts builds an HTTP client using the provided options -func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { +func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { var transport *http.Transport var host string var err error @@ -103,7 +103,7 @@ opt(hcc) } - transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) + transport, host, err = buildHttpsTransport(*hcc, gitlabURL) if err != nil { return nil, err } @@ -140,7 +140,7 @@ return transport, host } -func buildHttpsTransport(hcc httpClientCfg, selfSignedCert bool, gitlabURL string) (*http.Transport, string, error) { +func buildHttpsTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport, string, error) { certPool, err := x509.SystemCertPool() if err != nil { @@ -162,12 +162,8 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, - // The self_signed_cert config setting is deprecated - // The field and its usage is going to be removed in - // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 - InsecureSkipVerify: selfSignedCert, - MinVersion: tls.VersionTLS12, + RootCAs: certPool, + MinVersion: tls.VersionTLS12, } if hcc.HaveCertAndKey() { diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,7 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", expectedSeconds, nil) require.NoError(t, err) require.NotNil(t, client) @@ -123,7 +123,7 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", 1, nil) require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -18,7 +18,6 @@ testCases := []struct { desc string caFile, caPath string - selfSigned bool clientCAPath, clientCertPath, clientKeyPath string // used for TLS client certs }{ { @@ -31,9 +30,8 @@ caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { - desc: "Invalid cert with self signed cert option enabled", - caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), - selfSigned: true, + desc: "Invalid cert with self signed cert option enabled", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Client certs with CA", @@ -48,7 +46,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath) require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") @@ -95,7 +93,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "") if tc.expectedCaFileNotFound { require.Error(t, err) require.ErrorIs(t, err, ErrCafileNotFound) @@ -109,7 +107,7 @@ } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string) (*GitlabNetClient, error) { testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ @@ -130,7 +128,7 @@ opts = append(opts, WithClientCert(clientCertPath, clientKeyPath)) } - httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) + httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, 1, opts) if err != nil { return nil, err } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -27,11 +27,6 @@ # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs # -# The self_signed_cert option is deprecated -# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible -# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed -# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 - self_signed_cert: false # File used as authorized_keys for gitlab user auth_file: "/home/git/.ssh/authorized_keys" diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -39,7 +39,6 @@ ReadTimeoutSeconds uint64 `yaml:"read_timeout"` CaFile string `yaml:"ca_file"` CaPath string `yaml:"ca_path"` - SelfSignedCert bool `yaml:"self_signed_cert"` } type Config struct { @@ -112,7 +111,6 @@ c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, - c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, nil, ) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650949949 0 # Tue Apr 26 05:12:29 2022 +0000 # Node ID 14d2e1cc1ddc0a2859d2100e599aac602b19f2ed # Parent b2afbed301d648dec2caa9efc52027cb72a2e0e4 # Parent 25cf56ca13b111ce13fcc2d0b57cbf73e826787e Merge branch '541_remove_self_signed_cert_option' into 'main' Remove `self_signed_cert` option See merge request gitlab-org/gitlab-shell!602 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -59,7 +59,7 @@ secret := "sssh, it's a secret" - httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) client, err := NewGitlabNetClient("", "", secret, httpClient) diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -71,8 +71,8 @@ } // Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 -func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { - c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) +func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64) *HttpClient { + c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, readTimeoutSeconds, nil) if err != nil { log.WithError(err).Error("new http client with opts") } @@ -80,7 +80,7 @@ } // NewHTTPClientWithOpts builds an HTTP client using the provided options -func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { +func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { var transport *http.Transport var host string var err error @@ -103,7 +103,7 @@ opt(hcc) } - transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) + transport, host, err = buildHttpsTransport(*hcc, gitlabURL) if err != nil { return nil, err } @@ -140,7 +140,7 @@ return transport, host } -func buildHttpsTransport(hcc httpClientCfg, selfSignedCert bool, gitlabURL string) (*http.Transport, string, error) { +func buildHttpsTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport, string, error) { certPool, err := x509.SystemCertPool() if err != nil { @@ -162,12 +162,8 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, - // The self_signed_cert config setting is deprecated - // The field and its usage is going to be removed in - // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 - InsecureSkipVerify: selfSignedCert, - MinVersion: tls.VersionTLS12, + RootCAs: certPool, + MinVersion: tls.VersionTLS12, } if hcc.HaveCertAndKey() { diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,7 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", expectedSeconds, nil) require.NoError(t, err) require.NotNil(t, client) @@ -123,7 +123,7 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", 1, nil) require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -18,7 +18,6 @@ testCases := []struct { desc string caFile, caPath string - selfSigned bool clientCAPath, clientCertPath, clientKeyPath string // used for TLS client certs }{ { @@ -31,9 +30,8 @@ caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { - desc: "Invalid cert with self signed cert option enabled", - caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), - selfSigned: true, + desc: "Invalid cert with self signed cert option enabled", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Client certs with CA", @@ -48,7 +46,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath) require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") @@ -95,7 +93,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "") if tc.expectedCaFileNotFound { require.Error(t, err) require.ErrorIs(t, err, ErrCafileNotFound) @@ -109,7 +107,7 @@ } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string) (*GitlabNetClient, error) { testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ @@ -130,7 +128,7 @@ opts = append(opts, WithClientCert(clientCertPath, clientKeyPath)) } - httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) + httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, 1, opts) if err != nil { return nil, err } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -27,11 +27,6 @@ # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs # -# The self_signed_cert option is deprecated -# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible -# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed -# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 - self_signed_cert: false # File used as authorized_keys for gitlab user auth_file: "/home/git/.ssh/authorized_keys" diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -38,7 +38,6 @@ ReadTimeoutSeconds uint64 `yaml:"read_timeout"` CaFile string `yaml:"ca_file"` CaPath string `yaml:"ca_path"` - SelfSignedCert bool `yaml:"self_signed_cert"` } type Config struct { @@ -106,7 +105,6 @@ c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, - c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, nil, ) # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1650571670 -7200 # Thu Apr 21 22:07:50 2022 +0200 # Node ID 1731d21061f74aa89279aa2ec48ebdfe559f18d2 # Parent 5c5ea97a01d86c20b2843fa1b81d54a287a37fad drop go 1.16 support diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,7 +60,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.16", "1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.16 +go 1.17 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 @@ -19,4 +19,65 @@ gopkg.in/yaml.v2 v2.4.0 ) +require ( + cloud.google.com/go v0.92.2 // indirect + cloud.google.com/go/profiler v0.1.0 // indirect + cloud.google.com/go/trace v0.1.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // 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/aws/aws-sdk-go v1.38.35 // 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/cespare/xxhash/v2 v2.1.1 // indirect + github.com/client9/reopen v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // 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/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect + github.com/google/uuid v1.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/jmespath/go-jmespath v0.4.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // 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.26.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect + github.com/shirou/gopsutil/v3 v3.21.2 // indirect + github.com/sirupsen/logrus v1.8.1 // 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.7.0 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect + golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/api v0.54.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) + replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1650950261 0 # Tue Apr 26 05:17:41 2022 +0000 # Node ID 8765ffeb4cd1ec3b83c1bee95cca77db68310ee6 # Parent 14d2e1cc1ddc0a2859d2100e599aac602b19f2ed # Parent 1731d21061f74aa89279aa2ec48ebdfe559f18d2 Merge branch 'drop/go-1.16' into 'main' drop go 1.16 support See merge request gitlab-org/gitlab-shell!601 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,7 +60,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.16", "1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.16 +go 1.17 require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 @@ -19,4 +19,65 @@ gopkg.in/yaml.v2 v2.4.0 ) +require ( + cloud.google.com/go v0.92.2 // indirect + cloud.google.com/go/profiler v0.1.0 // indirect + cloud.google.com/go/trace v0.1.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // 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/aws/aws-sdk-go v1.38.35 // 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/cespare/xxhash/v2 v2.1.1 // indirect + github.com/client9/reopen v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // 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/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect + github.com/google/uuid v1.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/jmespath/go-jmespath v0.4.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // 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.26.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect + github.com/shirou/gopsutil/v3 v3.21.2 // indirect + github.com/sirupsen/logrus v1.8.1 // 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.7.0 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect + golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/api v0.54.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) + replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649777758 -14400 # Tue Apr 12 19:35:58 2022 +0400 # Node ID 3b998028e5d01f5e5479935b0d928664fed26593 # Parent 8765ffeb4cd1ec3b83c1bee95cca77db68310ee6 Add JWT token to GitLab Rails request It is passed as a Gitlab-Shell-Api-Request header and uses the same shared secret in order to encrypt the token diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -10,13 +10,19 @@ "path" "strings" "testing" + "time" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) +var ( + secret = []byte("sssh, it's a secret") +) + func TestClients(t *testing.T) { testhelper.PrepareTestRootDir(t) @@ -57,12 +63,10 @@ t.Run(tc.desc, func(t *testing.T) { url := tc.server(t, buildRequests(t, tc.relativeURLRoot)) - secret := "sssh, it's a secret" - httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", secret, httpClient) + client, err := NewGitlabNetClient("", "", string(secret), httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -71,6 +75,7 @@ testMissing(t, client) testErrorMessage(t, client) testAuthenticationHeader(t, client) + testJWTAuthenticationHeader(t, client) }) } } @@ -160,7 +165,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -175,7 +180,44 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) + }) +} + +func testJWTAuthenticationHeader(t *testing.T, client *GitlabNetClient) { + verifyJWTToken := func(t *testing.T, response *http.Response) { + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + + claims := &jwt.RegisteredClaims{} + token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { + return secret, nil + }) + require.NoError(t, err) + require.True(t, token.Valid) + require.Equal(t, "gitlab-shell", claims.Issuer) + require.Equal(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) + require.Equal(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) + } + + t.Run("JWT authentication headers for GET", func(t *testing.T) { + response, err := client.Get(context.Background(), "/jwt_auth") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) + }) + + t.Run("JWT authentication headers for POST", func(t *testing.T) { + response, err := client.Post(context.Background(), "/jwt_auth", map[string]string{}) + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) }) } @@ -209,6 +251,12 @@ }, }, { + Path: "/api/v4/internal/jwt_auth", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get(apiSecretHeaderName)) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,13 +11,18 @@ "strings" "time" + "github.com/golang-jwt/jwt/v4" + "gitlab.com/gitlab-org/labkit/log" ) const ( - internalApiPath = "/api/v4/internal" - secretHeaderName = "Gitlab-Shared-Secret" - defaultUserAgent = "GitLab-Shell" + internalApiPath = "/api/v4/internal" + secretHeaderName = "Gitlab-Shared-Secret" + apiSecretHeaderName = "Gitlab-Shell-Api-Request" + defaultUserAgent = "GitLab-Shell" + jwtTTL = time.Minute + jwtIssuer = "gitlab-shell" ) type ErrorResponse struct { @@ -121,10 +126,22 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } + secretBytes := []byte(c.secret) - encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) + encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) request.Header.Set(secretHeaderName, encodedSecret) + claims := jwt.RegisteredClaims{ + Issuer: jwtIssuer, + IssuedAt: jwt.NewNumericDate(time.Now()), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), + } + tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) + if err != nil { + return nil, err + } + request.Header.Set(apiSecretHeaderName, tokenString) + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ go 1.17 require ( + github.com/golang-jwt/jwt/v4 v4.4.1 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mattn/go-shellwords v1.0.11 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -316,6 +316,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/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/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1651028661 0 # Wed Apr 27 03:04:21 2022 +0000 # Node ID b4864e1ab2682169d8909119ac7d8fec30700611 # Parent 8765ffeb4cd1ec3b83c1bee95cca77db68310ee6 # Parent 3b998028e5d01f5e5479935b0d928664fed26593 Merge branch 'id-gitlabnet-jwt' into 'main' Add JWT token to GitLab Rails request See merge request gitlab-org/gitlab-shell!596 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -10,13 +10,19 @@ "path" "strings" "testing" + "time" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) +var ( + secret = []byte("sssh, it's a secret") +) + func TestClients(t *testing.T) { testhelper.PrepareTestRootDir(t) @@ -57,12 +63,10 @@ t.Run(tc.desc, func(t *testing.T) { url := tc.server(t, buildRequests(t, tc.relativeURLRoot)) - secret := "sssh, it's a secret" - httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", secret, httpClient) + client, err := NewGitlabNetClient("", "", string(secret), httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -71,6 +75,7 @@ testMissing(t, client) testErrorMessage(t, client) testAuthenticationHeader(t, client) + testJWTAuthenticationHeader(t, client) }) } } @@ -160,7 +165,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -175,7 +180,44 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) + }) +} + +func testJWTAuthenticationHeader(t *testing.T, client *GitlabNetClient) { + verifyJWTToken := func(t *testing.T, response *http.Response) { + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + + claims := &jwt.RegisteredClaims{} + token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { + return secret, nil + }) + require.NoError(t, err) + require.True(t, token.Valid) + require.Equal(t, "gitlab-shell", claims.Issuer) + require.Equal(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) + require.Equal(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) + } + + t.Run("JWT authentication headers for GET", func(t *testing.T) { + response, err := client.Get(context.Background(), "/jwt_auth") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) + }) + + t.Run("JWT authentication headers for POST", func(t *testing.T) { + response, err := client.Post(context.Background(), "/jwt_auth", map[string]string{}) + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) }) } @@ -209,6 +251,12 @@ }, }, { + Path: "/api/v4/internal/jwt_auth", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get(apiSecretHeaderName)) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,13 +11,18 @@ "strings" "time" + "github.com/golang-jwt/jwt/v4" + "gitlab.com/gitlab-org/labkit/log" ) const ( - internalApiPath = "/api/v4/internal" - secretHeaderName = "Gitlab-Shared-Secret" - defaultUserAgent = "GitLab-Shell" + internalApiPath = "/api/v4/internal" + secretHeaderName = "Gitlab-Shared-Secret" + apiSecretHeaderName = "Gitlab-Shell-Api-Request" + defaultUserAgent = "GitLab-Shell" + jwtTTL = time.Minute + jwtIssuer = "gitlab-shell" ) type ErrorResponse struct { @@ -121,10 +126,22 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } + secretBytes := []byte(c.secret) - encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) + encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) request.Header.Set(secretHeaderName, encodedSecret) + claims := jwt.RegisteredClaims{ + Issuer: jwtIssuer, + IssuedAt: jwt.NewNumericDate(time.Now()), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), + } + tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) + if err != nil { + return nil, err + } + request.Header.Set(apiSecretHeaderName, tokenString) + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ go 1.17 require ( + github.com/golang-jwt/jwt/v4 v4.4.1 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mattn/go-shellwords v1.0.11 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -316,6 +316,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/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/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= # HG changeset patch # User Vasilii Iakliushin <viakliushin@gitlab.com> # Date 1650628326 -7200 # Fri Apr 22 13:52:06 2022 +0200 # Node ID f3c8a64c2ceb8534f4477e2fcf7c186a3ba0371f # Parent 8765ffeb4cd1ec3b83c1bee95cca77db68310ee6 Remove deprecated function NewHTTPClient Contributes to https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 Changelog: removed diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -14,7 +14,6 @@ "time" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -70,15 +69,6 @@ return nil } -// Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 -func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64) *HttpClient { - c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, readTimeoutSeconds, nil) - if err != nil { - log.WithError(err).Error("new http client with opts") - } - return c -} - // NewHTTPClientWithOpts builds an HTTP client using the provided options func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { var transport *http.Transport # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1651031456 0 # Wed Apr 27 03:50:56 2022 +0000 # Node ID f88343229f1a7b8ea007cd89a13062aae2af4e5d # Parent b4864e1ab2682169d8909119ac7d8fec30700611 # Parent f3c8a64c2ceb8534f4477e2fcf7c186a3ba0371f Merge branch '484_remove_outdated_func' into 'main' Remove deprecated function NewHTTPClient See merge request gitlab-org/gitlab-shell!603 diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -14,7 +14,6 @@ "time" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -70,15 +69,6 @@ return nil } -// Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 -func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64) *HttpClient { - c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, readTimeoutSeconds, nil) - if err != nil { - log.WithError(err).Error("new http client with opts") - } - return c -} - // NewHTTPClientWithOpts builds an HTTP client using the provided options func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { var transport *http.Transport # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1651248601 -14400 # Fri Apr 29 20:10:01 2022 +0400 # Node ID 2185e876d016c0962bd17d3761418b86237a07ef # Parent f88343229f1a7b8ea007cd89a13062aae2af4e5d Release 13.26.0 - Add JWT token to GitLab Rails request !596 - Drop go 1.16 support !601 - Remove `self_signed_cert` option !602 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.26.0 + +- Add JWT token to GitLab Rails request !596 +- Drop go 1.16 support !601 +- Remove `self_signed_cert` option !602 + v13.25.2 - Revert "Abort long-running unauthenticated SSH connections" !605 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.2 +13.26.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1651249091 0 # Fri Apr 29 16:18:11 2022 +0000 # Node ID ef77ff827274a4897a5bfe7ca6dfe172502e541c # Parent f88343229f1a7b8ea007cd89a13062aae2af4e5d # Parent 2185e876d016c0962bd17d3761418b86237a07ef Merge branch 'id-release-13-26-0' into 'main' Release 13.26.0 See merge request gitlab-org/gitlab-shell!608 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +v13.26.0 + +- Add JWT token to GitLab Rails request !596 +- Drop go 1.16 support !601 +- Remove `self_signed_cert` option !602 + v13.25.2 - Revert "Abort long-running unauthenticated SSH connections" !605 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.2 +13.26.0 # HG changeset patch # User Jacob Vosmaer <jacob@gitlab.com> # Date 1651484092 0 # Mon May 02 09:34:52 2022 +0000 # Node ID 44f238a331bfd171b1b5282a4449d108fe71cc28 # Parent ef77ff827274a4897a5bfe7ca6dfe172502e541c Always use Gitaly sidechannel connections Before this change, the GitLab internal API could use a boolean response field to indicate whether gitlab-shell should make sidechannel connections go Gitaly. We now ignore that response field and always use sidechannel connections. diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -57,8 +57,10 @@ args.GitlabKeyId = tc.keyId } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -41,8 +41,10 @@ Env: env, } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -15,24 +15,7 @@ func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) - if response.Gitaly.UseSidechannel { - request := &pb.SSHUploadPackWithSidechannelRequest{ - Repository: &response.Gitaly.Repo, - GitProtocol: c.Args.Env.GitProtocolVersion, - GitConfigOptions: response.GitConfigOptions, - } - - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) - defer cancel() - - registry := c.Config.GitalyClient.SidechannelRegistry - rw := c.ReadWriter - return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) - }) - } - - request := &pb.SSHUploadPackRequest{ + request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, @@ -42,7 +25,8 @@ ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter - return client.UploadPack(ctx, conn, rw.In, rw.Out, rw.ErrOut, request) + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -41,62 +41,6 @@ Env: env, } - cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, - Args: args, - ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, - } - - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - - err := cmd.Execute(ctx) - require.NoError(t, err) - - require.Equal(t, "UploadPack: "+repo, output.String()) - - for k, v := range map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", - "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", - "key_id": "123", - "user_id": "1", - "remote_ip": "127.0.0.1", - "key_type": "key", - } { - actual := testServer.ReceivedMD[k] - require.Len(t, actual, 1) - require.Equal(t, v, actual[0]) - } - require.Empty(t, testServer.ReceivedMD["some-other-ff"]) - require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") -} - -func TestUploadPack_withSidechannel(t *testing.T) { - gitalyAddress, testServer := testserver.StartGitalyServer(t) - - requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) - url := testserver.StartHttpServer(t, requests) - - output := &bytes.Buffer{} - input := &bytes.Buffer{} - - userId := "1" - repo := "group/repo" - - env := sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: "git-upload-pack " + repo, - RemoteAddr: "127.0.0.1", - } - - args := &commandargs.Shell{ - GitlabKeyId: userId, - CommandType: commandargs.UploadPack, - SshArgs: []string{"git-upload-pack", repo}, - Env: env, - } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -21,10 +21,9 @@ ) type Command struct { - ServiceName string - Address string - Token string - DialSidechannel bool + ServiceName string + Address string + Token string } type connectionsCache struct { @@ -125,9 +124,5 @@ ) } - if cmd.DialSidechannel { - return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) - } - - return client.DialContext(ctx, cmd.Address, connOpts) + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) } diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -13,7 +13,7 @@ func TestPrometheusMetrics(t *testing.T) { metrics.GitalyConnectionsTotal.Reset() - c := &Client{} + c := newClient() cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} c.newConnection(context.Background(), cmd) @@ -31,7 +31,7 @@ } func TestCachedConnections(t *testing.T) { - c := &Client{} + c := newClient() require.Len(t, c.cache.connections, 0) @@ -51,3 +51,9 @@ require.NoError(t, err) require.Len(t, c.cache.connections, 2) } + +func newClient() *Client { + c := &Client{} + c.InitSidechannelRegistry(context.Background()) + return c +} diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -32,11 +32,10 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` - UseSidechannel bool `json:"use_sidechannel"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` } type CustomPayloadData struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -86,41 +86,6 @@ } } -func TestSidechannelFlag(t *testing.T) { - okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} - client := setup(t, - map[string]testResponse{"first": okResponse}, - map[string]testResponse{"1": okResponse}, - ) - - testCases := []struct { - desc string - args *commandargs.Shell - who string - }{ - { - desc: "Provide key id within the request", - args: &commandargs.Shell{GitlabKeyId: "1"}, - who: "key-1", - }, { - desc: "Provide username within the request", - args: &commandargs.Shell{GitlabUsername: "first"}, - who: "user-1", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) - require.NoError(t, err) - - response := buildExpectedResponse(tc.who) - response.Gitaly.UseSidechannel = true - require.Equal(t, response, result) - }) - } -} - func TestGeoPushGetCustomAction(t *testing.T) { client := setup(t, map[string]testResponse{ "custom": { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -33,10 +33,9 @@ func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { gc := gitaly.Command{ - ServiceName: serviceName, - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - DialSidechannel: response.Gitaly.UseSidechannel, + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, } return &GitalyCommand{Config: cfg, Response: response, Command: gc} diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -29,7 +29,7 @@ func TestRunGitalyCommand(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -46,14 +46,12 @@ func TestCachingOfGitalyConnections(t *testing.T) { ctx := context.Background() - cfg := &config.Config{} - cfg.GitalyClient.InitSidechannelRegistry(ctx) + cfg := newConfig() response := &accessverifier.Response{ Username: "user", Gitaly: accessverifier.Gitaly{ - Address: "tcp://localhost:9999", - Token: "token", - UseSidechannel: true, + Address: "tcp://localhost:9999", + Token: "token", }, } @@ -71,7 +69,7 @@ } func TestMissingGitalyAddress(t *testing.T) { - cmd := GitalyCommand{Config: &config.Config{}} + cmd := GitalyCommand{Config: newConfig()} err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.EqualError(t, err, "no gitaly_address given") @@ -79,7 +77,7 @@ func TestUnavailableGitalyErr(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -101,7 +99,7 @@ { name: "gitaly_feature_flags", gc: NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{ @@ -209,3 +207,9 @@ }) } } + +func newConfig() *config.Config { + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) + return cfg +} diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -29,14 +29,6 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) -} - -func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) -} - -func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -64,9 +56,6 @@ }, }, } - if useSidechannel { - body["gitaly"].(map[string]interface{})["use_sidechannel"] = true - } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json deleted file mode 100644 --- a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "status": true, - "gl_repository": "project-26", - "gl_project_path": "group/private", - "gl_id": "user-1", - "gl_username": "root", - "git_config_options": ["option"], - "gitaly": { - "repository": { - "storage_name": "default", - "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", - "git_object_directory": "path/to/git_object_directory", - "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], - "gl_repository": "project-26", - "gl_project_path": "group/private" - }, - "address": "unix:gitaly.socket", - "token": "token", - "use_sidechannel": true - }, - "git_protocol": "protocol", - "gl_console_messages": ["console", "message"] -} # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1651640158 0 # Wed May 04 04:55:58 2022 +0000 # Node ID b41ecc049cf116629da59b050505665a3cdce3dd # Parent ef77ff827274a4897a5bfe7ca6dfe172502e541c # Parent 44f238a331bfd171b1b5282a4449d108fe71cc28 Merge branch 'jv-always-use-sidechannel' into 'main' Always use Gitaly sidechannel connections See merge request gitlab-org/gitlab-shell!567 diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -57,8 +57,10 @@ args.GitlabKeyId = tc.keyId } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -41,8 +41,10 @@ Env: env, } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -15,24 +15,7 @@ func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) - if response.Gitaly.UseSidechannel { - request := &pb.SSHUploadPackWithSidechannelRequest{ - Repository: &response.Gitaly.Repo, - GitProtocol: c.Args.Env.GitProtocolVersion, - GitConfigOptions: response.GitConfigOptions, - } - - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) - defer cancel() - - registry := c.Config.GitalyClient.SidechannelRegistry - rw := c.ReadWriter - return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) - }) - } - - request := &pb.SSHUploadPackRequest{ + request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, @@ -42,7 +25,8 @@ ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter - return client.UploadPack(ctx, conn, rw.In, rw.Out, rw.ErrOut, request) + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -41,62 +41,6 @@ Env: env, } - cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, - Args: args, - ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, - } - - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - - err := cmd.Execute(ctx) - require.NoError(t, err) - - require.Equal(t, "UploadPack: "+repo, output.String()) - - for k, v := range map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", - "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", - "key_id": "123", - "user_id": "1", - "remote_ip": "127.0.0.1", - "key_type": "key", - } { - actual := testServer.ReceivedMD[k] - require.Len(t, actual, 1) - require.Equal(t, v, actual[0]) - } - require.Empty(t, testServer.ReceivedMD["some-other-ff"]) - require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") -} - -func TestUploadPack_withSidechannel(t *testing.T) { - gitalyAddress, testServer := testserver.StartGitalyServer(t) - - requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) - url := testserver.StartHttpServer(t, requests) - - output := &bytes.Buffer{} - input := &bytes.Buffer{} - - userId := "1" - repo := "group/repo" - - env := sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: "git-upload-pack " + repo, - RemoteAddr: "127.0.0.1", - } - - args := &commandargs.Shell{ - GitlabKeyId: userId, - CommandType: commandargs.UploadPack, - SshArgs: []string{"git-upload-pack", repo}, - Env: env, - } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -21,10 +21,9 @@ ) type Command struct { - ServiceName string - Address string - Token string - DialSidechannel bool + ServiceName string + Address string + Token string } type connectionsCache struct { @@ -125,9 +124,5 @@ ) } - if cmd.DialSidechannel { - return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) - } - - return client.DialContext(ctx, cmd.Address, connOpts) + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) } diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -13,7 +13,7 @@ func TestPrometheusMetrics(t *testing.T) { metrics.GitalyConnectionsTotal.Reset() - c := &Client{} + c := newClient() cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} c.newConnection(context.Background(), cmd) @@ -31,7 +31,7 @@ } func TestCachedConnections(t *testing.T) { - c := &Client{} + c := newClient() require.Len(t, c.cache.connections, 0) @@ -51,3 +51,9 @@ require.NoError(t, err) require.Len(t, c.cache.connections, 2) } + +func newClient() *Client { + c := &Client{} + c.InitSidechannelRegistry(context.Background()) + return c +} diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -32,11 +32,10 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` - UseSidechannel bool `json:"use_sidechannel"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` } type CustomPayloadData struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -86,41 +86,6 @@ } } -func TestSidechannelFlag(t *testing.T) { - okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} - client := setup(t, - map[string]testResponse{"first": okResponse}, - map[string]testResponse{"1": okResponse}, - ) - - testCases := []struct { - desc string - args *commandargs.Shell - who string - }{ - { - desc: "Provide key id within the request", - args: &commandargs.Shell{GitlabKeyId: "1"}, - who: "key-1", - }, { - desc: "Provide username within the request", - args: &commandargs.Shell{GitlabUsername: "first"}, - who: "user-1", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) - require.NoError(t, err) - - response := buildExpectedResponse(tc.who) - response.Gitaly.UseSidechannel = true - require.Equal(t, response, result) - }) - } -} - func TestGeoPushGetCustomAction(t *testing.T) { client := setup(t, map[string]testResponse{ "custom": { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -33,10 +33,9 @@ func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { gc := gitaly.Command{ - ServiceName: serviceName, - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - DialSidechannel: response.Gitaly.UseSidechannel, + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, } return &GitalyCommand{Config: cfg, Response: response, Command: gc} diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -29,7 +29,7 @@ func TestRunGitalyCommand(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -46,14 +46,12 @@ func TestCachingOfGitalyConnections(t *testing.T) { ctx := context.Background() - cfg := &config.Config{} - cfg.GitalyClient.InitSidechannelRegistry(ctx) + cfg := newConfig() response := &accessverifier.Response{ Username: "user", Gitaly: accessverifier.Gitaly{ - Address: "tcp://localhost:9999", - Token: "token", - UseSidechannel: true, + Address: "tcp://localhost:9999", + Token: "token", }, } @@ -71,7 +69,7 @@ } func TestMissingGitalyAddress(t *testing.T) { - cmd := GitalyCommand{Config: &config.Config{}} + cmd := GitalyCommand{Config: newConfig()} err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.EqualError(t, err, "no gitaly_address given") @@ -79,7 +77,7 @@ func TestUnavailableGitalyErr(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -101,7 +99,7 @@ { name: "gitaly_feature_flags", gc: NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{ @@ -209,3 +207,9 @@ }) } } + +func newConfig() *config.Config { + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) + return cfg +} diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -29,14 +29,6 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) -} - -func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) -} - -func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -64,9 +56,6 @@ }, }, } - if useSidechannel { - body["gitaly"].(map[string]interface{})["use_sidechannel"] = true - } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json deleted file mode 100644 --- a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "status": true, - "gl_repository": "project-26", - "gl_project_path": "group/private", - "gl_id": "user-1", - "gl_username": "root", - "git_config_options": ["option"], - "gitaly": { - "repository": { - "storage_name": "default", - "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", - "git_object_directory": "path/to/git_object_directory", - "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], - "gl_repository": "project-26", - "gl_project_path": "group/private" - }, - "address": "unix:gitaly.socket", - "token": "token", - "use_sidechannel": true - }, - "git_protocol": "protocol", - "gl_console_messages": ["console", "message"] -} # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1651645849 -28800 # Wed May 04 14:30:49 2022 +0800 # Node ID eb2615521afa008fc46f51ac8f1b3c901fd17a14 # Parent b41ecc049cf116629da59b050505665a3cdce3dd Release 14.0.0 Always use Gitaly sidechannel connections !567 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v14.0.0 +- Always use Gitaly sidechannel connections !567 + v13.26.0 - Add JWT token to GitLab Rails request !596 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.26.0 +14.0.0 # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1651646584 0 # Wed May 04 06:43:04 2022 +0000 # Node ID 7b17b1d00467952ade430e1753f00ff2b92a303c # Parent b41ecc049cf116629da59b050505665a3cdce3dd # Parent eb2615521afa008fc46f51ac8f1b3c901fd17a14 Merge branch 'pb-release-14-0-0' into 'main' Release 14.0.0 See merge request gitlab-org/gitlab-shell!609 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v14.0.0 +- Always use Gitaly sidechannel connections !567 + v13.26.0 - Add JWT token to GitLab Rails request !596 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.26.0 +14.0.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1651050070 -14400 # Wed Apr 27 13:01:10 2022 +0400 # Node ID c782ae82a861f685035658c042bf5253497b86e8 # Parent 7b17b1d00467952ade430e1753f00ff2b92a303c Use labkit for FIPS check New version of LabKit provides FIPS checks that we can use instead of the custom code diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -7,7 +7,11 @@ BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver ifeq (${FIPS_MODE}, 1) - BUILD_TAGS += boringcrypto + # boringcrypto tag is added automatically by golang-fips compiler + BUILD_TAGS += fips + # If the golang-fips compiler is built with CGO_ENABLED=0, this needs to be + # explicitly switched on. + export CGO_ENABLED=1 endif GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -8,10 +8,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -74,7 +74,7 @@ cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") - boring.CheckBoring() + fips.Check() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,11 +10,11 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.1 - github.com/prometheus/client_golang v1.11.0 + github.com/prometheus/client_golang v1.12.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.12.0 - golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 + gitlab.com/gitlab-org/labkit v1.14.0 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 @@ -33,7 +33,7 @@ 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/cespare/xxhash/v2 v2.1.1 // 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/go-ole/go-ole v1.2.4 // indirect @@ -55,8 +55,8 @@ 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.26.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect github.com/shirou/gopsutil/v3 v3.21.2 // indirect github.com/sirupsen/logrus v1.8.1 // indirect @@ -69,8 +69,8 @@ go.uber.org/atomic v1.7.0 // indirect golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect - golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect - golang.org/x/text v0.3.6 // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/api v0.54.0 // indirect diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -165,8 +165,9 @@ github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -255,12 +256,13 @@ github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= -github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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.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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= @@ -294,6 +296,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -316,6 +319,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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.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= @@ -531,6 +536,7 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= @@ -577,6 +583,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -603,6 +610,8 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= @@ -611,6 +620,7 @@ 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/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= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -641,6 +651,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= @@ -723,8 +734,9 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -737,15 +749,17 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -846,6 +860,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= @@ -880,8 +895,8 @@ 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.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= -gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= +gitlab.com/gitlab-org/labkit v1.14.0 h1:LSrvHgybidPyH8fHnsy1GBghrLR4kFObFrtZwUfCgAI= +gitlab.com/gitlab-org/labkit v1.14.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= @@ -1010,6 +1025,8 @@ golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1111,6 +1128,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1125,8 +1143,11 @@ 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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +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-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1136,12 +1157,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/boring/boring.go b/internal/boring/boring.go deleted file mode 100644 --- a/internal/boring/boring.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build boringcrypto -// +build boringcrypto - -package boring - -import ( - "crypto/boring" - - "gitlab.com/gitlab-org/labkit/log" -) - -// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go -// compiler in https://github.com/golang-fips/go, this requires that: -// -// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). -// 2. A system OpenSSL can be dynamically loaded via ldopen(). -func CheckBoring() { - if boring.Enabled() { - log.Info("FIPS mode is enabled. Using an external SSL library.") - return - } - log.Info("gitlab-shell was compiled with FIPS mode, but an external SSL library was not enabled.") -} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go deleted file mode 100644 --- a/internal/boring/notboring.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !boringcrypto -// +build !boringcrypto - -package boring - -// CheckBoring does nothing when the boringcrypto tag is not in the -// build. -func CheckBoring() { -} # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1651805059 0 # Fri May 06 02:44:19 2022 +0000 # Node ID fd3b6e6ae179b4abd186a73608301ad17e4ec29c # Parent 7b17b1d00467952ade430e1753f00ff2b92a303c # Parent c782ae82a861f685035658c042bf5253497b86e8 Merge branch 'id-fips-labkit' into 'main' Use labkit for FIPS check See merge request gitlab-org/gitlab-shell!607 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -7,7 +7,11 @@ BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver ifeq (${FIPS_MODE}, 1) - BUILD_TAGS += boringcrypto + # boringcrypto tag is added automatically by golang-fips compiler + BUILD_TAGS += fips + # If the golang-fips compiler is built with CGO_ENABLED=0, this needs to be + # explicitly switched on. + export CGO_ENABLED=1 endif GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -8,10 +8,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -74,7 +74,7 @@ cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") - boring.CheckBoring() + fips.Check() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,11 +10,11 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.1 - github.com/prometheus/client_golang v1.11.0 + github.com/prometheus/client_golang v1.12.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.12.0 - golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 + gitlab.com/gitlab-org/labkit v1.14.0 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 @@ -33,7 +33,7 @@ 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/cespare/xxhash/v2 v2.1.1 // 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/go-ole/go-ole v1.2.4 // indirect @@ -55,8 +55,8 @@ 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.26.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect github.com/shirou/gopsutil/v3 v3.21.2 // indirect github.com/sirupsen/logrus v1.8.1 // indirect @@ -69,8 +69,8 @@ go.uber.org/atomic v1.7.0 // indirect golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect - golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect - golang.org/x/text v0.3.6 // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/api v0.54.0 // indirect diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -165,8 +165,9 @@ github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -255,12 +256,13 @@ github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= -github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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.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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= @@ -294,6 +296,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -316,6 +319,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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.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= @@ -531,6 +536,7 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= @@ -577,6 +583,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -603,6 +610,8 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= @@ -611,6 +620,7 @@ 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/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= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -641,6 +651,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= @@ -723,8 +734,9 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -737,15 +749,17 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -846,6 +860,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= @@ -880,8 +895,8 @@ 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.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= -gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= +gitlab.com/gitlab-org/labkit v1.14.0 h1:LSrvHgybidPyH8fHnsy1GBghrLR4kFObFrtZwUfCgAI= +gitlab.com/gitlab-org/labkit v1.14.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= @@ -1010,6 +1025,8 @@ golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1111,6 +1128,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1125,8 +1143,11 @@ 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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +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-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1136,12 +1157,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/boring/boring.go b/internal/boring/boring.go deleted file mode 100644 --- a/internal/boring/boring.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build boringcrypto -// +build boringcrypto - -package boring - -import ( - "crypto/boring" - - "gitlab.com/gitlab-org/labkit/log" -) - -// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go -// compiler in https://github.com/golang-fips/go, this requires that: -// -// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). -// 2. A system OpenSSL can be dynamically loaded via ldopen(). -func CheckBoring() { - if boring.Enabled() { - log.Info("FIPS mode is enabled. Using an external SSL library.") - return - } - log.Info("gitlab-shell was compiled with FIPS mode, but an external SSL library was not enabled.") -} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go deleted file mode 100644 --- a/internal/boring/notboring.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !boringcrypto -// +build !boringcrypto - -package boring - -// CheckBoring does nothing when the boringcrypto tag is not in the -// build. -func CheckBoring() { -} # HG changeset patch # User Sean Carroll <scarroll@gitlab.com> # Date 1651840720 0 # Fri May 06 12:38:40 2022 +0000 # Node ID 9c034b5890c5768d74b636fbd3713ceaa1acfb13 # Parent fd3b6e6ae179b4abd186a73608301ad17e4ec29c Remove departed team member from CODEOWNERS diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,4 +1,4 @@ -* @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao +* @ashmckenzie @igor.drozdov @patrickbajao [Documentation] *.md @aqualls # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1651842571 0 # Fri May 06 13:09:31 2022 +0000 # Node ID 6655fe3f183fb1bbda190dda9a14c3619c4e1d01 # Parent fd3b6e6ae179b4abd186a73608301ad17e4ec29c # Parent 9c034b5890c5768d74b636fbd3713ceaa1acfb13 Merge branch 'sean_carroll-main-patch-02429' into 'main' Remove departed team member from CODEOWNERS See merge request gitlab-org/gitlab-shell!615 diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,4 +1,4 @@ -* @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao +* @ashmckenzie @igor.drozdov @patrickbajao [Documentation] *.md @aqualls # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652079151 25200 # Sun May 08 23:52:31 2022 -0700 # Node ID 3fd7d5cd3ee2be595d3233f543340940a0d762b7 # Parent 6712c68c42156ec09eefaab72446f498341d0464 Fix check_ip argument when gitlab-sshd used with PROXY protocol When gitlab-sshd were used with the PROXY protocol, the `check_ip` argument passed to `/api/v4/internal/allowed` was the Go remote address, which is a host and port combination (e.g. 127.0.0.1:12345). As a result, This prevents IP restrictions from working properly on Rails. We fix this by stripping out the port if it is present. When OpenSSH is used, this is not an issue because the IP address is extracted from `SSH_CONNECTION`. Changelog: fixed diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -86,7 +87,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = args.Env.RemoteAddr + request.CheckIp = parseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -117,3 +118,18 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } + +func parseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -14,6 +14,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -215,6 +216,51 @@ } } +func TestCheckIP(t *testing.T) { + testCases := []struct { + desc string + remoteAddr string + expectedCheckIp string + }{ + { + desc: "IPv4 address", + remoteAddr: "18.245.0.42", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 address", + remoteAddr: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Host and port", + remoteAddr: "18.245.0.42:6345", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 host and port", + remoteAddr: "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Bad remote addr", + remoteAddr: "[127.0", + expectedCheckIp: "[127.0", + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + client := setupWithApiInspector(t, + func(r *Request) { + require.Equal(t, tc.expectedCheckIp, r.CheckIp) + }) + + sshEnv := sshenv.Env{RemoteAddr: tc.remoteAddr} + client.Verify(context.Background(), &commandargs.Shell{Env: sshEnv}, uploadPackAction, repo) + }) + } +} + type testResponse struct { body []byte status int @@ -260,3 +306,29 @@ return client } + +func setupWithApiInspector(t *testing.T, inspector func(*Request)) *Client { + t.Helper() + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/allowed", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + require.NoError(t, err) + + var requestBody *Request + err = json.Unmarshal(b, &requestBody) + require.NoError(t, err) + + inspector(requestBody) + }, + }, + } + + url := testserver.StartSocketHttpServer(t, requests) + + client, err := NewClient(&config.Config{GitlabUrl: url}) + require.NoError(t, err) + + return client +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652089640 0 # Mon May 09 09:47:20 2022 +0000 # Node ID bf31f366cc78f403ebaf42b21227d100afb3f9b7 # Parent 6655fe3f183fb1bbda190dda9a14c3619c4e1d01 # Parent 3fd7d5cd3ee2be595d3233f543340940a0d762b7 Merge branch 'sh-fix-remote-addr-handling' into 'main' Fix check_ip argument when gitlab-sshd used with PROXY protocol See merge request gitlab-org/gitlab-shell!616 diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -85,7 +86,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = args.Env.RemoteAddr + request.CheckIp = parseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -116,3 +117,18 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } + +func parseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -14,6 +14,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -180,6 +181,51 @@ } } +func TestCheckIP(t *testing.T) { + testCases := []struct { + desc string + remoteAddr string + expectedCheckIp string + }{ + { + desc: "IPv4 address", + remoteAddr: "18.245.0.42", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 address", + remoteAddr: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Host and port", + remoteAddr: "18.245.0.42:6345", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 host and port", + remoteAddr: "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Bad remote addr", + remoteAddr: "[127.0", + expectedCheckIp: "[127.0", + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + client := setupWithApiInspector(t, + func(r *Request) { + require.Equal(t, tc.expectedCheckIp, r.CheckIp) + }) + + sshEnv := sshenv.Env{RemoteAddr: tc.remoteAddr} + client.Verify(context.Background(), &commandargs.Shell{Env: sshEnv}, uploadPackAction, repo) + }) + } +} + type testResponse struct { body []byte status int @@ -225,3 +271,29 @@ return client } + +func setupWithApiInspector(t *testing.T, inspector func(*Request)) *Client { + t.Helper() + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/allowed", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + require.NoError(t, err) + + var requestBody *Request + err = json.Unmarshal(b, &requestBody) + require.NoError(t, err) + + inspector(requestBody) + }, + }, + } + + url := testserver.StartSocketHttpServer(t, requests) + + client, err := NewClient(&config.Config{GitlabUrl: url}) + require.NoError(t, err) + + return client +} # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1651822751 -14400 # Fri May 06 11:39:11 2022 +0400 # Node ID c127d3a0f5fb8732e0ade48b8304d9dfd0b8a7a3 # Parent 7b17b1d00467952ade430e1753f00ff2b92a303c Exclude authentication errors from apdex Most of the time a connection fails due to the client's misconfiguration or when a client cancels a request, so we shouldn't treat them as an error Warnings will help us to track the errors whether they happened on the server-side diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,6 +2,7 @@ import ( "context" + "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" @@ -49,6 +50,10 @@ } go func() { + defer func(started time.Time) { + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + }(time.Now()) + defer c.concurrentSessions.Release(1) // Prevent a panic in a single session from taking out the whole server diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -146,19 +146,8 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { - success := false - metrics.SshdConnectionsInFlight.Inc() - started := time.Now() - defer func() { - metrics.SshdConnectionsInFlight.Dec() - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) - - metrics.SliSshdSessionsTotal.Inc() - if !success { - metrics.SliSshdSessionsErrorsTotal.Inc() - } - }() + defer metrics.SshdConnectionsInFlight.Dec() remoteAddr := nconn.RemoteAddr().String() @@ -174,6 +163,8 @@ defer func() { if err := recover(); err != nil { ctxlog.Warn("panic handling session") + + metrics.SliSshdSessionsErrorsTotal.Inc() } }() @@ -181,11 +172,12 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") + ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") return } go ssh.DiscardRequests(reqs) + started := time.Now() var establishSessionDuration float64 conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { @@ -199,9 +191,11 @@ remoteAddr: remoteAddr, } + metrics.SliSshdSessionsTotal.Inc() session.handle(ctx, requests) - - success = session.success + if !session.success { + metrics.SliSshdSessionsErrorsTotal.Inc() + } }) ctxlog.WithFields(log.Fields{ # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652214221 0 # Tue May 10 20:23:41 2022 +0000 # Node ID b77a725da3688447cf910650d0113fac90ac08e3 # Parent bf31f366cc78f403ebaf42b21227d100afb3f9b7 # Parent c127d3a0f5fb8732e0ade48b8304d9dfd0b8a7a3 Merge branch 'id-improve-errors-metrics' into 'main' Exclude authentication errors from error rate See merge request gitlab-org/gitlab-shell!611 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,6 +2,7 @@ import ( "context" + "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" @@ -49,6 +50,10 @@ } go func() { + defer func(started time.Time) { + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + }(time.Now()) + defer c.concurrentSessions.Release(1) // Prevent a panic in a single session from taking out the whole server diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -146,19 +146,8 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { - success := false - metrics.SshdConnectionsInFlight.Inc() - started := time.Now() - defer func() { - metrics.SshdConnectionsInFlight.Dec() - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) - - metrics.SliSshdSessionsTotal.Inc() - if !success { - metrics.SliSshdSessionsErrorsTotal.Inc() - } - }() + defer metrics.SshdConnectionsInFlight.Dec() remoteAddr := nconn.RemoteAddr().String() @@ -174,6 +163,8 @@ defer func() { if err := recover(); err != nil { ctxlog.Warn("panic handling session") + + metrics.SliSshdSessionsErrorsTotal.Inc() } }() @@ -181,11 +172,12 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") + ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") return } go ssh.DiscardRequests(reqs) + started := time.Now() var establishSessionDuration float64 conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { @@ -199,9 +191,11 @@ remoteAddr: remoteAddr, } + metrics.SliSshdSessionsTotal.Inc() session.handle(ctx, requests) - - success = session.success + if !session.success { + metrics.SliSshdSessionsErrorsTotal.Inc() + } }) ctxlog.WithFields(log.Fields{ # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652210182 -14400 # Tue May 10 23:16:22 2022 +0400 # Node ID 9f6e632206a3bc753f510e0f1eeb40e5e919d842 # Parent bf31f366cc78f403ebaf42b21227d100afb3f9b7 Make PROXY policy configurable It would give us more flexibility when we decide to enable PROXY protocol diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -69,6 +69,9 @@ # Set to true if gitlab-sshd is being fronted by a load balancer that implements # the PROXY protocol. proxy_protocol: false + # Proxy protocol policy ("use", "require", "reject", "ignore"), "use" is the default value + # Values: https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + proxy_policy: "use" # Address which the server listens on HTTP for monitoring/health checks. Defaults to localhost:9122. web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -24,6 +24,7 @@ type ServerConfig struct { Listen string `yaml:"listen,omitempty"` ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` GracePeriodSeconds uint64 `yaml:"grace_period"` diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -5,6 +5,7 @@ "fmt" "net" "net/http" + "strings" "sync" "time" @@ -95,7 +96,7 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, - Policy: unconditionalRequirePolicy, + Policy: s.requirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } @@ -210,6 +211,17 @@ }).Info("server: handleConn: done") } -func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { - return proxyproto.REQUIRE, nil +func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { + // Set the Policy value based on config + // Values are taken from https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + switch strings.ToLower(s.Config.Server.ProxyPolicy) { + case "require": + return proxyproto.REQUIRE, nil + case "ignore": + return proxyproto.IGNORE, nil + case "reject": + return proxyproto.REJECT, nil + default: + return proxyproto.USE, nil + } } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" "net/http/httptest" "os" @@ -10,6 +11,7 @@ "testing" "time" + "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" @@ -48,15 +50,101 @@ } func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { - setupServerWithProxyProtocolEnabled(t) + target, err := net.ResolveTCPAddr("tcp", serverUrl) + require.NoError(t, err) - client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) - if client != nil { - client.Close() + header := &proxyproto.Header{ + Version: 2, + Command: proxyproto.PROXY, + TransportProtocol: proxyproto.TCPv4, + SourceAddr: &net.TCPAddr{ + IP: net.ParseIP("10.1.1.1"), + Port: 1000, + }, + DestinationAddr: target, } - require.Error(t, err, "Expected plain SSH request to be failed") - require.Regexp(t, "ssh: handshake failed", err.Error()) + testCases := []struct { + desc string + proxyPolicy string + header *proxyproto.Header + isRejected bool + }{ + { + desc: "USE (default) without a header", + proxyPolicy: "", + header: nil, + isRejected: false, + }, + { + desc: "USE (default) with a header", + proxyPolicy: "", + header: header, + isRejected: false, + }, + { + desc: "REQUIRE without a header", + proxyPolicy: "require", + header: nil, + isRejected: true, + }, + { + desc: "REQUIRE with a header", + proxyPolicy: "require", + header: header, + isRejected: false, + }, + { + desc: "REJECT without a header", + proxyPolicy: "reject", + header: nil, + isRejected: false, + }, + { + desc: "REJECT with a header", + proxyPolicy: "reject", + header: header, + isRejected: true, + }, + { + desc: "IGNORE without a header", + proxyPolicy: "ignore", + header: nil, + isRejected: false, + }, + { + desc: "IGNORE with a header", + proxyPolicy: "ignore", + header: header, + isRejected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true, ProxyPolicy: tc.proxyPolicy}}) + + conn, err := net.DialTCP("tcp", nil, target) + require.NoError(t, err) + + if tc.header != nil { + _, err := header.WriteTo(conn) + require.NoError(t, err) + } + + sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + if sshConn != nil { + sshConn.Close() + } + + if tc.isRejected { + require.Error(t, err, "Expected plain SSH request to be failed") + require.Regexp(t, "ssh: handshake failed", err.Error()) + } else { + require.NoError(t, err) + } + }) + } } func TestCorrelationId(t *testing.T) { @@ -140,12 +228,6 @@ return setupServerWithConfig(t, nil) } -func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { - t.Helper() - - return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) -} - func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652214306 0 # Tue May 10 20:25:06 2022 +0000 # Node ID 8b5dd2943c0bcf478ea2f5b8c478638034736a67 # Parent b77a725da3688447cf910650d0113fac90ac08e3 # Parent 9f6e632206a3bc753f510e0f1eeb40e5e919d842 Merge branch 'id-make-proxy-policy-configurable' into 'main' Make PROXY policy configurable See merge request gitlab-org/gitlab-shell!619 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -69,6 +69,9 @@ # Set to true if gitlab-sshd is being fronted by a load balancer that implements # the PROXY protocol. proxy_protocol: false + # Proxy protocol policy ("use", "require", "reject", "ignore"), "use" is the default value + # Values: https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + proxy_policy: "use" # Address which the server listens on HTTP for monitoring/health checks. Defaults to localhost:9122. web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -24,6 +24,7 @@ type ServerConfig struct { Listen string `yaml:"listen,omitempty"` ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` GracePeriodSeconds uint64 `yaml:"grace_period"` diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -5,6 +5,7 @@ "fmt" "net" "net/http" + "strings" "sync" "time" @@ -95,7 +96,7 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, - Policy: unconditionalRequirePolicy, + Policy: s.requirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } @@ -204,6 +205,17 @@ }).Info("server: handleConn: done") } -func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { - return proxyproto.REQUIRE, nil +func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { + // Set the Policy value based on config + // Values are taken from https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + switch strings.ToLower(s.Config.Server.ProxyPolicy) { + case "require": + return proxyproto.REQUIRE, nil + case "ignore": + return proxyproto.IGNORE, nil + case "reject": + return proxyproto.REJECT, nil + default: + return proxyproto.USE, nil + } } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" "net/http/httptest" "os" @@ -10,6 +11,7 @@ "testing" "time" + "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" @@ -48,15 +50,101 @@ } func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { - setupServerWithProxyProtocolEnabled(t) + target, err := net.ResolveTCPAddr("tcp", serverUrl) + require.NoError(t, err) - client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) - if client != nil { - client.Close() + header := &proxyproto.Header{ + Version: 2, + Command: proxyproto.PROXY, + TransportProtocol: proxyproto.TCPv4, + SourceAddr: &net.TCPAddr{ + IP: net.ParseIP("10.1.1.1"), + Port: 1000, + }, + DestinationAddr: target, } - require.Error(t, err, "Expected plain SSH request to be failed") - require.Regexp(t, "ssh: handshake failed", err.Error()) + testCases := []struct { + desc string + proxyPolicy string + header *proxyproto.Header + isRejected bool + }{ + { + desc: "USE (default) without a header", + proxyPolicy: "", + header: nil, + isRejected: false, + }, + { + desc: "USE (default) with a header", + proxyPolicy: "", + header: header, + isRejected: false, + }, + { + desc: "REQUIRE without a header", + proxyPolicy: "require", + header: nil, + isRejected: true, + }, + { + desc: "REQUIRE with a header", + proxyPolicy: "require", + header: header, + isRejected: false, + }, + { + desc: "REJECT without a header", + proxyPolicy: "reject", + header: nil, + isRejected: false, + }, + { + desc: "REJECT with a header", + proxyPolicy: "reject", + header: header, + isRejected: true, + }, + { + desc: "IGNORE without a header", + proxyPolicy: "ignore", + header: nil, + isRejected: false, + }, + { + desc: "IGNORE with a header", + proxyPolicy: "ignore", + header: header, + isRejected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true, ProxyPolicy: tc.proxyPolicy}}) + + conn, err := net.DialTCP("tcp", nil, target) + require.NoError(t, err) + + if tc.header != nil { + _, err := header.WriteTo(conn) + require.NoError(t, err) + } + + sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + if sshConn != nil { + sshConn.Close() + } + + if tc.isRejected { + require.Error(t, err, "Expected plain SSH request to be failed") + require.Regexp(t, "ssh: handshake failed", err.Error()) + } else { + require.NoError(t, err) + } + }) + } } func TestCorrelationId(t *testing.T) { @@ -140,12 +228,6 @@ return setupServerWithConfig(t, nil) } -func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { - t.Helper() - - return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) -} - func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652222778 25200 # Tue May 10 15:46:18 2022 -0700 # Node ID d7165070d89aab190f689fca39b42480954d3eef # Parent 8b5dd2943c0bcf478ea2f5b8c478638034736a67 Release 14.1.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,12 @@ +v14.1.0 + +- Make PROXY policy configurable !619 +- Exclude authentication errors from apdex !611 +- Fix check_ip argument when gitlab-sshd used with PROXY protocol !616 +- Use labkit for FIPS check !607 + v14.0.0 + - Always use Gitaly sidechannel connections !567 v13.26.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.0.0 +14.1.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652239007 0 # Wed May 11 03:16:47 2022 +0000 # Node ID a611e711ddf6f21e2cea609256a5c49bb169b82c # Parent 8b5dd2943c0bcf478ea2f5b8c478638034736a67 # Parent d7165070d89aab190f689fca39b42480954d3eef Merge branch 'sh-release-14.1.0' into 'main' Release 14.1.0 See merge request gitlab-org/gitlab-shell!620 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,12 @@ +v14.1.0 + +- Make PROXY policy configurable !619 +- Exclude authentication errors from apdex !611 +- Fix check_ip argument when gitlab-sshd used with PROXY protocol !616 +- Use labkit for FIPS check !607 + v14.0.0 + - Always use Gitaly sidechannel connections !567 v13.26.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.0.0 +14.1.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1651848330 -14400 # Fri May 06 18:45:30 2022 +0400 # Node ID 4bc5a4df33667650f35fff21772e4686efbd8f05 # Parent fd3b6e6ae179b4abd186a73608301ad17e4ec29c Log the error that happens on sconn.Wait() Warning level is used because a non-nil error is logged even for successful scenarios We plan to use it for debug reasons diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -204,9 +204,11 @@ success = session.success }) + reason := sconn.Wait() ctxlog.WithFields(log.Fields{ "duration_s": time.Since(started).Seconds(), "establish_session_duration_s": establishSessionDuration, + "reason": reason, }).Info("server: handleConn: done") } # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1652241740 0 # Wed May 11 04:02:20 2022 +0000 # Node ID cc67d0a846971f52a0179ef69be4f8ebcd1a8ba4 # Parent a611e711ddf6f21e2cea609256a5c49bb169b82c # Parent 4bc5a4df33667650f35fff21772e4686efbd8f05 Merge branch 'id-sync-sshd-sessions' into 'main' Log the error that happens on sconn.Wait() See merge request gitlab-org/gitlab-shell!613 diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -199,9 +199,11 @@ } }) + reason := sconn.Wait() ctxlog.WithFields(log.Fields{ "duration_s": time.Since(started).Seconds(), "establish_session_duration_s": establishSessionDuration, + "reason": reason, }).Info("server: handleConn: done") } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652084433 -14400 # Mon May 09 12:20:33 2022 +0400 # Node ID 7932a05741f89e3174ce9a497cbe1cc68ac7aefb # Parent fd3b6e6ae179b4abd186a73608301ad17e4ec29c Use require.WithinDuration to fix flacky test diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -196,8 +196,8 @@ require.NoError(t, err) require.True(t, token.Valid) require.Equal(t, "gitlab-shell", claims.Issuer) - require.Equal(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) - require.Equal(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) + require.WithinDuration(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) + require.WithinDuration(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) } t.Run("JWT authentication headers for GET", func(t *testing.T) { # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1652243052 0 # Wed May 11 04:24:12 2022 +0000 # Node ID 33198b2ae2a7aea3efa4f1940c0dc26af7a2ac39 # Parent cc67d0a846971f52a0179ef69be4f8ebcd1a8ba4 # Parent 7932a05741f89e3174ce9a497cbe1cc68ac7aefb Merge branch 'id-fix-flacky-test' into 'main' Use require.WithinDuration to fix flaky test See merge request gitlab-org/gitlab-shell!617 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -196,8 +196,8 @@ require.NoError(t, err) require.True(t, token.Valid) require.Equal(t, "gitlab-shell", claims.Issuer) - require.Equal(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) - require.Equal(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) + require.WithinDuration(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) + require.WithinDuration(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) } t.Run("JWT authentication headers for GET", func(t *testing.T) { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652245010 -14400 # Wed May 11 08:56:50 2022 +0400 # Node ID d1a10ab09830476c0d088a46a969bced0f1e5127 # Parent 33198b2ae2a7aea3efa4f1940c0dc26af7a2ac39 Release 14.1.1 - Log the error that happens on sconn.Wait() !613 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.1.1 + +- Log the error that happens on sconn.Wait() !613 + v14.1.0 - Make PROXY policy configurable !619 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.1.0 +14.1.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652245436 0 # Wed May 11 05:03:56 2022 +0000 # Node ID 71e6614f1d1c7420c7ac0a17d346b1653d733c63 # Parent 33198b2ae2a7aea3efa4f1940c0dc26af7a2ac39 # Parent d1a10ab09830476c0d088a46a969bced0f1e5127 Merge branch 'id-release-14-1-0' into 'main' Release 14.1.1 See merge request gitlab-org/gitlab-shell!621 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.1.1 + +- Log the error that happens on sconn.Wait() !613 + v14.1.0 - Make PROXY policy configurable !619 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.1.0 +14.1.1 # HG changeset patch # User feistel <6742251-feistel@users.noreply.gitlab.com> # Date 1651766667 -7200 # Thu May 05 18:04:27 2022 +0200 # Node ID dc2b81b57713f640435b223bf782e82f04c88ce6 # Parent fd3b6e6ae179b4abd186a73608301ad17e4ec29c build: bump go-proxyproto to 0.6.2 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.1 + github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -717,8 +717,8 @@ 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/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= -github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= +github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652246590 0 # Wed May 11 05:23:10 2022 +0000 # Node ID 8a31f4d24683857dd714278ce82ebeb3b14caa0b # Parent 71e6614f1d1c7420c7ac0a17d346b1653d733c63 # Parent dc2b81b57713f640435b223bf782e82f04c88ce6 Merge branch 'bump/goproxyproto-062' into 'main' build: bump go-proxyproto to 0.6.2 See merge request gitlab-org/gitlab-shell!610 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.1 + github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -717,8 +717,8 @@ 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/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= -github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= +github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652286357 -14400 # Wed May 11 20:25:57 2022 +0400 # Node ID 7cb4604a93180774a24f9d00267f49a817543ed7 # Parent 71e6614f1d1c7420c7ac0a17d346b1653d733c63 Implement ClientKeepAlive option Git clients sometimes open a connection and leave it idling, like when compressing objects. Settings like timeout client in HAProxy might cause these idle connections to be terminated. Let's send the keepalive message in order to prevent a client from closing diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -76,6 +76,8 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # Sets an interval after which server will send keepalive message to a client + client_alive_interval: 15 # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. grace_period: 10 # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -22,15 +22,16 @@ ) type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - ProxyPolicy string `yaml:"proxy_policy,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` } type HttpSettingsConfig struct { @@ -75,12 +76,13 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, + ClientAliveIntervalSeconds: 15, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -89,6 +91,10 @@ } ) +func (sc *ServerConfig) ClientAliveInterval() time.Duration { + return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second +} + func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -7,28 +7,41 @@ "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) +const KeepAliveMsg = "keepalive@openssh.com" + type connection struct { + cfg *config.Config concurrentSessions *semaphore.Weighted remoteAddr string + sconn *ssh.ServerConn } type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) -func newConnection(maxSessions int64, remoteAddr string) *connection { +func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { return &connection{ - concurrentSessions: semaphore.NewWeighted(maxSessions), + cfg: cfg, + concurrentSessions: semaphore.NewWeighted(cfg.Server.ConcurrentSessionsLimit), remoteAddr: remoteAddr, + sconn: sconn, } } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + if c.cfg.Server.ClientAliveIntervalSeconds > 0 { + ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) + defer ticker.Stop() + go c.sendKeepAliveMsg(ctx, ticker) + } + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { @@ -68,3 +81,18 @@ }() } } + +func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + ctxlog.Debug("session: handleShell: send keepalive message to a client") + + c.sconn.SendRequest(KeepAliveMsg, true, nil) + } + } +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -3,10 +3,14 @@ import ( "context" "errors" + "sync" "testing" + "time" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) type rejectCall struct { @@ -47,8 +51,32 @@ return f.extraData } +type fakeConn struct { + ssh.Conn + + sentRequestName string + mu sync.Mutex +} + +func (f *fakeConn) SentRequestName() string { + f.mu.Lock() + defer f.mu.Unlock() + + return f.sentRequestName +} + +func (f *fakeConn) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) { + f.mu.Lock() + defer f.mu.Unlock() + + f.sentRequestName = name + + return true, nil, nil +} + func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - conn := newConnection(sessionsNum, "127.0.0.1:50000") + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} + conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -145,3 +173,16 @@ require.False(t, channelHandled) } + +func TestClientAliveInterval(t *testing.T) { + f := &fakeConn{} + + conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) + + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + + go conn.sendKeepAliveMsg(context.Background(), ticker) + + require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -180,7 +180,7 @@ started := time.Now() var establishSessionDuration float64 - conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) + conn := newConnection(s.Config, remoteAddr, sconn) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { establishSessionDuration = time.Since(started).Seconds() metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -265,6 +265,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1652335545 0 # Thu May 12 06:05:45 2022 +0000 # Node ID 522b7fb78312f3073177147e6a23466b32fb6688 # Parent 8a31f4d24683857dd714278ce82ebeb3b14caa0b # Parent 7cb4604a93180774a24f9d00267f49a817543ed7 Merge branch 'id-implement-client-keep-alive' into 'main' Implement ClientKeepAlive option See merge request gitlab-org/gitlab-shell!622 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -76,6 +76,8 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # Sets an interval after which server will send keepalive message to a client + client_alive_interval: 15 # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. grace_period: 10 # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -22,15 +22,16 @@ ) type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - ProxyPolicy string `yaml:"proxy_policy,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` } type HttpSettingsConfig struct { @@ -75,12 +76,13 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, + ClientAliveIntervalSeconds: 15, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -89,6 +91,10 @@ } ) +func (sc *ServerConfig) ClientAliveInterval() time.Duration { + return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second +} + func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -7,28 +7,41 @@ "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) +const KeepAliveMsg = "keepalive@openssh.com" + type connection struct { + cfg *config.Config concurrentSessions *semaphore.Weighted remoteAddr string + sconn *ssh.ServerConn } type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) -func newConnection(maxSessions int64, remoteAddr string) *connection { +func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { return &connection{ - concurrentSessions: semaphore.NewWeighted(maxSessions), + cfg: cfg, + concurrentSessions: semaphore.NewWeighted(cfg.Server.ConcurrentSessionsLimit), remoteAddr: remoteAddr, + sconn: sconn, } } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + if c.cfg.Server.ClientAliveIntervalSeconds > 0 { + ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) + defer ticker.Stop() + go c.sendKeepAliveMsg(ctx, ticker) + } + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { @@ -68,3 +81,18 @@ }() } } + +func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + ctxlog.Debug("session: handleShell: send keepalive message to a client") + + c.sconn.SendRequest(KeepAliveMsg, true, nil) + } + } +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -3,10 +3,14 @@ import ( "context" "errors" + "sync" "testing" + "time" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) type rejectCall struct { @@ -47,8 +51,32 @@ return f.extraData } +type fakeConn struct { + ssh.Conn + + sentRequestName string + mu sync.Mutex +} + +func (f *fakeConn) SentRequestName() string { + f.mu.Lock() + defer f.mu.Unlock() + + return f.sentRequestName +} + +func (f *fakeConn) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) { + f.mu.Lock() + defer f.mu.Unlock() + + f.sentRequestName = name + + return true, nil, nil +} + func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - conn := newConnection(sessionsNum, "127.0.0.1:50000") + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} + conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -145,3 +173,16 @@ require.False(t, channelHandled) } + +func TestClientAliveInterval(t *testing.T) { + f := &fakeConn{} + + conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) + + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + + go conn.sendKeepAliveMsg(context.Background(), ticker) + + require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -180,7 +180,7 @@ started := time.Now() var establishSessionDuration float64 - conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) + conn := newConnection(s.Config, remoteAddr, sconn) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { establishSessionDuration = time.Since(started).Seconds() metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -265,6 +265,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652335626 -14400 # Thu May 12 10:07:06 2022 +0400 # Node ID aa45eb088179b0016ceef62fee7886b91865d4e5 # Parent 522b7fb78312f3073177147e6a23466b32fb6688 Release 14.2.0 - Implement ClientKeepAlive option - build: bump go-proxyproto to 0.6.2 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.2.0 + +- Implement ClientKeepAlive option !622 +- build: bump go-proxyproto to 0.6.2 !610 + v14.1.1 - Log the error that happens on sconn.Wait() !613 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.1.1 +14.2.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652336122 0 # Thu May 12 06:15:22 2022 +0000 # Node ID 95f105751282580f695ff4bec8577de261720bbd # Parent 522b7fb78312f3073177147e6a23466b32fb6688 # Parent aa45eb088179b0016ceef62fee7886b91865d4e5 Merge branch 'id-release-14-2-0' into 'main' Release 14.2.0 See merge request gitlab-org/gitlab-shell!623 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.2.0 + +- Implement ClientKeepAlive option !622 +- build: bump go-proxyproto to 0.6.2 !610 + v14.1.1 - Log the error that happens on sconn.Wait() !613 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.1.1 +14.2.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1652447867 -7200 # Fri May 13 15:17:47 2022 +0200 # Branch heptapod # Node ID ac4c7a46f488458f92bd9357d31b7bd0fe515ca2 # Parent 2ffbe5787a8e76b7856e447ca406889930fe0691 # Parent d8e5a6bac1b1712956515f079a43e701cd5adb32 Merged upstream v13.24.0 into heptapod branch This is the version used in GitLab 14.9.4 diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,1 +1,4 @@ * @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao + +[Documentation] +*.md @aqualls diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.6 +golang 1.17.7 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.24.0 + +- Upgrade golang to 1.17.7 !576 +- Add more metrics for gitlab-sshd !574 +- Move code guidelines to doc/beginners_guide.md !572 +- Add docs for full feature list !571 +- Add aqualls as codeowner for docs files !573 + v13.23.2 - Bump labkit version to 1.12.0 !569 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ What follows is the original README of GitLab Shell +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# GitLab Shell + ## GitLab Shell handles git SSH sessions for GitLab GitLab Shell handles git SSH sessions for GitLab and modifies the list of authorized keys. @@ -22,6 +30,8 @@ 1. git pull over SSH -> gitlab-shell -> API call to gitlab-rails (Authorization) -> accept or decline -> establish Gitaly session 1. git push over SSH -> gitlab-shell (git command is not executed yet) -> establish Gitaly session -> (in Gitaly) gitlab-shell pre-receive hook -> API call to gitlab-rails (authorization) -> accept or decline push +[Full feature list](doc/features.md) + ## Code status [![pipeline status](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main) @@ -38,90 +48,11 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Check - -Checks if GitLab API access and redis via internal API can be reached: - - make check - -## Compile - -Builds the `gitlab-shell` binaries, placing them into `bin/`. - - make compile - -## Install - -Builds the `gitlab-shell` binaries and installs them onto the filesystem. The -default location is `/usr/local`, but can be controlled by use of the `PREFIX` -and `DESTDIR` environment variables. - - make install - -## Setup - -This command is intended for use when installing GitLab from source on a single -machine. In addition to compiling the gitlab-shell binaries, it ensures that -various paths on the filesystem exist with the correct permissions. Do not run -it unless instructed to by your installation method documentation. - - make setup - - -## Testing - -Run tests: - - bundle install - make test - -Run gofmt: - - make verify - -Run both test and verify (the default Makefile target): - - bundle install - make validate - -### Gitaly - -Some tests need a Gitaly server. The -[`docker-compose.yml`](./docker-compose.yml) file will run Gitaly on -port 8075. To tell the tests where Gitaly is, set -`GITALY_CONNECTION_INFO`: - - export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' - make test - -If no `GITALY_CONNECTION_INFO` is set, the test suite will still run, but any -tests requiring Gitaly will be skipped. They will always run in the CI -environment. - -## Git LFS - -Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. - -## Logging Guidelines - -In general, it should be possible to determine the structure, but not content, -of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some -guidelines: - -- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) - for logging functionality -- **Always** include a correlation ID -- Log messages should be invariant and unique. Include accessory information in - fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. -- Log success cases as well as error cases -- Logging too much is better than not logging enough. If a message seems too - verbose, consider reducing the log level before removing the message. - ## Rate Limiting GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. -The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. @@ -133,7 +64,8 @@ ## Contributing -See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See the [beginner's guide](doc/beginners_guide.md). ## License diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.2 +13.24.0 diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md new file mode 100644 --- /dev/null +++ b/doc/beginners_guide.md @@ -0,0 +1,94 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Beginner's guide to GitLab Shell contributions + +## Check + +Checks if GitLab API access and Redis via internal API can be reached: + +```shell +make check +``` + +## Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + +```shell +make compile +``` + +## Install + +Builds the `gitlab-shell` binaries and installs them onto the file system. The +default location is `/usr/local`, but you can change the location by setting the `PREFIX` +and `DESTDIR` environment variables. + +```shell +make install +``` + +## Setup + +This command is intended for use when installing GitLab from source on a single +machine. It compiles the GitLab Shell binaries, and ensures that +various paths on the file system exist with the correct permissions. Do not run +this command unless your installation method documentation instructs you to. + +```shell +make setup +``` + +## Testing + +Run tests: + +```shell +bundle install +make test +``` + +Run Gofmt: + +```shell +make verify +``` + +Run both test and verify (the default Makefile target): + +```shell +bundle install +make validate +``` + +## Gitaly + +Some tests need a Gitaly server. The +[`docker-compose.yml`](../docker-compose.yml) file runs Gitaly on port 8075. +To tell the tests where Gitaly is, set `GITALY_CONNECTION_INFO`: + +```plaintext +export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' +make test +``` + +If no `GITALY_CONNECTION_INFO` is set, the test suite still runs, but any +tests requiring Gitaly are skipped. The tests always run in the CI environment. + +## Logging Guidelines + +In general, you can determine the structure, but not content, of a GitLab Shell +or `gitlab-sshd` session by inspecting the logs. Some guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging. +- Always include a correlation ID. +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log both success cases and error cases. +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. diff --git a/doc/features.md b/doc/features.md new file mode 100644 --- /dev/null +++ b/doc/features.md @@ -0,0 +1,87 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Feature list + +## Discover + +Allows users to identify themselves on an instance via SSH. The command helps to +confirm quickly whether a user has SSH access to the instance: + +```shell +ssh git@<hostname> + +PTY allocation request failed on channel 0 +Welcome to GitLab, @username! +Connection to staging.gitlab.com closed. +``` + +When permission is denied, it returns: + +```shell +ssh git@<hostname> +git@<hostname>: Permission denied (publickey). +``` + +## Git operations + +GitLab Shell provides support for Git operations over SSH by processing +`git-upload-pack`, `git-receive-pack` and `git-upload-archive` SSH commands. +It limits the set of commands to predefined Git commands: + +- `git archive` +- `git clone` +- `git pull` +- `git push` + +## Generate new 2FA recovery codes + +Enables users to +[generate new 2FA recovery codes](https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html#generate-new-recovery-codes-using-ssh): + +```plaintext +ssh git@<hostname> 2fa_recovery_codes +Are you sure you want to generate new two-factor recovery codes? +Any existing recovery codes you saved will be invalidated. (yes/no) +yes + +Your two-factor authentication recovery codes are: +... +``` + +## Verify 2FA OTP + +Allows users to verify their +[2FA one-time password (OTP)](https://docs.gitlab.com/ee/security/two_factor_authentication.html#2fa-for-git-over-ssh-operations): + +```shell +ssh git@<hostname> 2fa_verify +OTP: 347419 + +OTP validation failed. +``` + +## LFS authentication + +Enables users to generate credentials for LFS authentication: + +```shell +ssh git@<hostname> git-lfs-authenticate <project-path> <upload/download> + +{"header":{"Authorization":"Basic ..."},"href":"https://gitlab.com/user/project.git/info/lfs","expires_in":7200} +``` + +## Personal access token + +Enables users to use personal access tokens via SSH: + +```shell +ssh git@<hostname> personal_access_token <name> <scope1[,scope2,...]> [ttl_days] + +Token: glpat-... +Scopes: api +Expires: 2022-02-05 +``` diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -10,7 +10,6 @@ "sync" "time" - "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -141,7 +140,7 @@ } tr := client.Transport - client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) + client.Transport = metrics.NewRoundTripper(tr) c.httpClient = client }) diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -25,7 +25,7 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } -func TestHttpClient(t *testing.T) { +func TestCustomPrometheusMetrics(t *testing.T) { url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) config := &Config{GitlabUrl: url} @@ -38,14 +38,19 @@ ms, err := prometheus.DefaultGatherer.Gather() require.NoError(t, err) - lastMetric := ms[0] - require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") - - labels := lastMetric.GetMetric()[0].Label + var actualNames []string + for _, m := range ms[0:6] { + actualNames = append(actualNames, m.GetName()) + } - require.Equal(t, "code", labels[0].GetName()) - require.Equal(t, "404", labels[0].GetValue()) + expectedMetricNames := []string{ + "gitlab_shell_http_in_flight_requests", + "gitlab_shell_http_request_duration_seconds", + "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_concurrent_limited_sessions_total", + "gitlab_shell_sshd_connection_duration_seconds", + "gitlab_shell_sshd_in_flight_connections", + } - require.Equal(t, "method", labels[1].GetName()) - require.Equal(t, "get", labels[1].GetValue()) + require.Equal(t, expectedMetricNames, actualNames) } diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -1,14 +1,25 @@ package metrics import ( + "net/http" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" ) const ( namespace = "gitlab_shell" sshdSubsystem = "sshd" httpSubsystem = "http" + + httpInFlightRequestsMetricName = "in_flight_requests" + httpRequestsTotalMetricName = "requests_total" + httpRequestDurationSecondsMetricName = "request_duration_seconds" + + sshdConnectionsInFlightName = "in_flight_connections" + sshdConnectionDuration = "connection_duration_seconds" + sshdHitMaxSessions = "concurrent_limited_sessions_total" ) var ( @@ -16,7 +27,7 @@ prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", + Name: sshdConnectionDuration, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ 0.005, /* 5ms */ @@ -32,32 +43,72 @@ }, ) + SshdConnectionsInFlight = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdConnectionsInFlightName, + Help: "A gauge of connections currently being served by gitlab-shell sshd.", + }, + ) + SshdHitMaxSessions = promauto.NewCounter( prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", + Name: sshdHitMaxSessions, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) - HttpRequestDuration = promauto.NewHistogramVec( + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit + // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, + // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit + httpRequestsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpRequestsTotalMetricName, + Help: "A counter for http requests.", + }, + []string{"code", "method"}, + ) + + httpRequestDurationSeconds = promauto.NewHistogramVec( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: httpSubsystem, - Name: "request_seconds", - Help: "A histogram of latencies for gitlab-shell http requests", + Name: httpRequestDurationSecondsMetricName, + Help: "A histogram of latencies for http requests.", Buckets: []float64{ - 0.01, /* 10ms */ - 0.05, /* 50ms */ - 0.1, /* 100ms */ - 0.25, /* 250ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 5.0, /* 5s */ - 10.0, /* 10s */ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ }, }, []string{"code", "method"}, ) + + httpInFlightRequests = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpInFlightRequestsMetricName, + Help: "A gauge of requests currently being performed.", + }, + ) ) + +func NewRoundTripper(next http.RoundTripper) promhttp.RoundTripperFunc { + rt := next + + rt = promhttp.InstrumentRoundTripperCounter(httpRequestsTotal, rt) + rt = promhttp.InstrumentRoundTripperDuration(httpRequestDurationSeconds, rt) + return promhttp.InstrumentRoundTripperInFlight(httpInFlightRequests, rt) +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -31,6 +31,9 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + metrics.SshdConnectionsInFlight.Inc() + defer metrics.SshdConnectionsInFlight.Dec() + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1652447971 -7200 # Fri May 13 15:19:31 2022 +0200 # Branch heptapod # Node ID 3eca478bc6dda51a700df01889a4e0fbc0726fd1 # Parent ac4c7a46f488458f92bd9357d31b7bd0fe515ca2 Updated Heptapod version files A bit in advance of the release (which will be simply a tag creation). diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 13.24.0 + +- Jump to upstream GitLab Shell v13.24.0 (GitLab 14.8 series) + ## 13.23.0 - Jump to upstream GitLab Shell v13.23.2 (GitLab 14.8 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.23.0 +13.24.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1652899311 -7200 # Wed May 18 20:41:51 2022 +0200 # Branch heptapod # Node ID eaa400f46c97a398037f0a72a5a30836f31a3586 # Parent 3eca478bc6dda51a700df01889a4e0fbc0726fd1 HEPTAPOD_CHANGELOG: fixed typo diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -12,7 +12,7 @@ ## 13.24.0 -- Jump to upstream GitLab Shell v13.24.0 (GitLab 14.8 series) +- Jump to upstream GitLab Shell v13.24.0 (GitLab 14.9 series) ## 13.23.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1652899332 -7200 # Wed May 18 20:42:12 2022 +0200 # Branch heptapod # Node ID 0cef84a5b973b0b8be5a3262178120f5d2a35294 # Parent eaa400f46c97a398037f0a72a5a30836f31a3586 Added tag heptapod-13.24.0 for changeset eaa400f46c97 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -38,3 +38,4 @@ b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 +eaa400f46c97a398037f0a72a5a30836f31a3586 heptapod-13.24.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1653996420 -7200 # Tue May 31 13:27:00 2022 +0200 # Branch heptapod-stable # Node ID 3b031eaaaf7b158306134942e70b00abf2182cd0 # Parent bcbcabd3963c27047fe50a5765ba6992a4449bad # Parent 0cef84a5b973b0b8be5a3262178120f5d2a35294 heptapod#675: making 0.31 the new stable diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,1 +1,4 @@ * @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao + +[Documentation] +*.md @aqualls diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -38,3 +38,4 @@ b15301c706769652286af112a4437dc8cdfac86e heptapod-13.21.0 7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 +eaa400f46c97a398037f0a72a5a30836f31a3586 heptapod-13.24.0 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.6 +golang 1.17.7 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,11 @@ +v13.24.0 + +- Upgrade golang to 1.17.7 !576 +- Add more metrics for gitlab-sshd !574 +- Move code guidelines to doc/beginners_guide.md !572 +- Add docs for full feature list !571 +- Add aqualls as codeowner for docs files !573 + v13.23.2 - Bump labkit version to 1.12.0 !569 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -1,6 +1,7 @@ # Changelog for Heptapod Shell -The CHANGELOG file is about the upstream GitLab Shell. +See the `CHANGELOG` file for information about upstream GitLab Shell +versions. ## Versioning policy @@ -9,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 13.24.0 + +- Jump to upstream GitLab Shell v13.24.0 (GitLab 14.9 series) + ## 13.23.0 - Jump to upstream GitLab Shell v13.23.2 (GitLab 14.8 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.23.0 +13.24.0 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ What follows is the original README of GitLab Shell +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# GitLab Shell + ## GitLab Shell handles git SSH sessions for GitLab GitLab Shell handles git SSH sessions for GitLab and modifies the list of authorized keys. @@ -22,6 +30,8 @@ 1. git pull over SSH -> gitlab-shell -> API call to gitlab-rails (Authorization) -> accept or decline -> establish Gitaly session 1. git push over SSH -> gitlab-shell (git command is not executed yet) -> establish Gitaly session -> (in Gitaly) gitlab-shell pre-receive hook -> API call to gitlab-rails (authorization) -> accept or decline push +[Full feature list](doc/features.md) + ## Code status [![pipeline status](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main) @@ -38,90 +48,11 @@ We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy) of supporting the current stable version and the previous two major versions. -## Check - -Checks if GitLab API access and redis via internal API can be reached: - - make check - -## Compile - -Builds the `gitlab-shell` binaries, placing them into `bin/`. - - make compile - -## Install - -Builds the `gitlab-shell` binaries and installs them onto the filesystem. The -default location is `/usr/local`, but can be controlled by use of the `PREFIX` -and `DESTDIR` environment variables. - - make install - -## Setup - -This command is intended for use when installing GitLab from source on a single -machine. In addition to compiling the gitlab-shell binaries, it ensures that -various paths on the filesystem exist with the correct permissions. Do not run -it unless instructed to by your installation method documentation. - - make setup - - -## Testing - -Run tests: - - bundle install - make test - -Run gofmt: - - make verify - -Run both test and verify (the default Makefile target): - - bundle install - make validate - -### Gitaly - -Some tests need a Gitaly server. The -[`docker-compose.yml`](./docker-compose.yml) file will run Gitaly on -port 8075. To tell the tests where Gitaly is, set -`GITALY_CONNECTION_INFO`: - - export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' - make test - -If no `GITALY_CONNECTION_INFO` is set, the test suite will still run, but any -tests requiring Gitaly will be skipped. They will always run in the CI -environment. - -## Git LFS - -Starting with GitLab 8.12, GitLab supports Git LFS authentication through SSH. - -## Logging Guidelines - -In general, it should be possible to determine the structure, but not content, -of a gitlab-shell or gitlab-sshd session just from inspecting the logs. Some -guidelines: - -- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) - for logging functionality -- **Always** include a correlation ID -- Log messages should be invariant and unique. Include accessory information in - fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. -- Log success cases as well as error cases -- Logging too much is better than not logging enough. If a message seems too - verbose, consider reducing the log level before removing the message. - ## Rate Limiting GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`. -The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. +The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute. Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting. @@ -133,7 +64,8 @@ ## Contributing -See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See [CONTRIBUTING.md](./CONTRIBUTING.md). +- See the [beginner's guide](doc/beginners_guide.md). ## License diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.23.2 +13.24.0 diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md new file mode 100644 --- /dev/null +++ b/doc/beginners_guide.md @@ -0,0 +1,94 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Beginner's guide to GitLab Shell contributions + +## Check + +Checks if GitLab API access and Redis via internal API can be reached: + +```shell +make check +``` + +## Compile + +Builds the `gitlab-shell` binaries, placing them into `bin/`. + +```shell +make compile +``` + +## Install + +Builds the `gitlab-shell` binaries and installs them onto the file system. The +default location is `/usr/local`, but you can change the location by setting the `PREFIX` +and `DESTDIR` environment variables. + +```shell +make install +``` + +## Setup + +This command is intended for use when installing GitLab from source on a single +machine. It compiles the GitLab Shell binaries, and ensures that +various paths on the file system exist with the correct permissions. Do not run +this command unless your installation method documentation instructs you to. + +```shell +make setup +``` + +## Testing + +Run tests: + +```shell +bundle install +make test +``` + +Run Gofmt: + +```shell +make verify +``` + +Run both test and verify (the default Makefile target): + +```shell +bundle install +make validate +``` + +## Gitaly + +Some tests need a Gitaly server. The +[`docker-compose.yml`](../docker-compose.yml) file runs Gitaly on port 8075. +To tell the tests where Gitaly is, set `GITALY_CONNECTION_INFO`: + +```plaintext +export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}' +make test +``` + +If no `GITALY_CONNECTION_INFO` is set, the test suite still runs, but any +tests requiring Gitaly are skipped. The tests always run in the CI environment. + +## Logging Guidelines + +In general, you can determine the structure, but not content, of a GitLab Shell +or `gitlab-sshd` session by inspecting the logs. Some guidelines: + +- We use [`gitlab.com/gitlab-org/labkit/log`](https://pkg.go.dev/gitlab.com/gitlab-org/labkit/log) + for logging. +- Always include a correlation ID. +- Log messages should be invariant and unique. Include accessory information in + fields, using `log.WithField`, `log.WithFields`, or `log.WithError`. +- Log both success cases and error cases. +- Logging too much is better than not logging enough. If a message seems too + verbose, consider reducing the log level before removing the message. diff --git a/doc/features.md b/doc/features.md new file mode 100644 --- /dev/null +++ b/doc/features.md @@ -0,0 +1,87 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Feature list + +## Discover + +Allows users to identify themselves on an instance via SSH. The command helps to +confirm quickly whether a user has SSH access to the instance: + +```shell +ssh git@<hostname> + +PTY allocation request failed on channel 0 +Welcome to GitLab, @username! +Connection to staging.gitlab.com closed. +``` + +When permission is denied, it returns: + +```shell +ssh git@<hostname> +git@<hostname>: Permission denied (publickey). +``` + +## Git operations + +GitLab Shell provides support for Git operations over SSH by processing +`git-upload-pack`, `git-receive-pack` and `git-upload-archive` SSH commands. +It limits the set of commands to predefined Git commands: + +- `git archive` +- `git clone` +- `git pull` +- `git push` + +## Generate new 2FA recovery codes + +Enables users to +[generate new 2FA recovery codes](https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html#generate-new-recovery-codes-using-ssh): + +```plaintext +ssh git@<hostname> 2fa_recovery_codes +Are you sure you want to generate new two-factor recovery codes? +Any existing recovery codes you saved will be invalidated. (yes/no) +yes + +Your two-factor authentication recovery codes are: +... +``` + +## Verify 2FA OTP + +Allows users to verify their +[2FA one-time password (OTP)](https://docs.gitlab.com/ee/security/two_factor_authentication.html#2fa-for-git-over-ssh-operations): + +```shell +ssh git@<hostname> 2fa_verify +OTP: 347419 + +OTP validation failed. +``` + +## LFS authentication + +Enables users to generate credentials for LFS authentication: + +```shell +ssh git@<hostname> git-lfs-authenticate <project-path> <upload/download> + +{"header":{"Authorization":"Basic ..."},"href":"https://gitlab.com/user/project.git/info/lfs","expires_in":7200} +``` + +## Personal access token + +Enables users to use personal access tokens via SSH: + +```shell +ssh git@<hostname> personal_access_token <name> <scope1[,scope2,...]> [ttl_days] + +Token: glpat-... +Scopes: api +Expires: 2022-02-05 +``` diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -10,7 +10,6 @@ "sync" "time" - "github.com/prometheus/client_golang/prometheus/promhttp" yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -141,7 +140,7 @@ } tr := client.Transport - client.Transport = promhttp.InstrumentRoundTripperDuration(metrics.HttpRequestDuration, tr) + client.Transport = metrics.NewRoundTripper(tr) c.httpClient = client }) diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -25,7 +25,7 @@ require.Equal(t, "foo", os.Getenv("SSL_CERT_DIR")) } -func TestHttpClient(t *testing.T) { +func TestCustomPrometheusMetrics(t *testing.T) { url := testserver.StartHttpServer(t, []testserver.TestRequestHandler{}) config := &Config{GitlabUrl: url} @@ -38,14 +38,19 @@ ms, err := prometheus.DefaultGatherer.Gather() require.NoError(t, err) - lastMetric := ms[0] - require.Equal(t, lastMetric.GetName(), "gitlab_shell_http_request_seconds") - - labels := lastMetric.GetMetric()[0].Label + var actualNames []string + for _, m := range ms[0:6] { + actualNames = append(actualNames, m.GetName()) + } - require.Equal(t, "code", labels[0].GetName()) - require.Equal(t, "404", labels[0].GetValue()) + expectedMetricNames := []string{ + "gitlab_shell_http_in_flight_requests", + "gitlab_shell_http_request_duration_seconds", + "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_concurrent_limited_sessions_total", + "gitlab_shell_sshd_connection_duration_seconds", + "gitlab_shell_sshd_in_flight_connections", + } - require.Equal(t, "method", labels[1].GetName()) - require.Equal(t, "get", labels[1].GetValue()) + require.Equal(t, expectedMetricNames, actualNames) } diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -1,14 +1,25 @@ package metrics import ( + "net/http" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" ) const ( namespace = "gitlab_shell" sshdSubsystem = "sshd" httpSubsystem = "http" + + httpInFlightRequestsMetricName = "in_flight_requests" + httpRequestsTotalMetricName = "requests_total" + httpRequestDurationSecondsMetricName = "request_duration_seconds" + + sshdConnectionsInFlightName = "in_flight_connections" + sshdConnectionDuration = "connection_duration_seconds" + sshdHitMaxSessions = "concurrent_limited_sessions_total" ) var ( @@ -16,7 +27,7 @@ prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "connection_duration_seconds", + Name: sshdConnectionDuration, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ 0.005, /* 5ms */ @@ -32,32 +43,72 @@ }, ) + SshdConnectionsInFlight = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdConnectionsInFlightName, + Help: "A gauge of connections currently being served by gitlab-shell sshd.", + }, + ) + SshdHitMaxSessions = promauto.NewCounter( prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: "concurrent_limited_sessions_total", + Name: sshdHitMaxSessions, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) - HttpRequestDuration = promauto.NewHistogramVec( + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit + // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, + // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit + httpRequestsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpRequestsTotalMetricName, + Help: "A counter for http requests.", + }, + []string{"code", "method"}, + ) + + httpRequestDurationSeconds = promauto.NewHistogramVec( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: httpSubsystem, - Name: "request_seconds", - Help: "A histogram of latencies for gitlab-shell http requests", + Name: httpRequestDurationSecondsMetricName, + Help: "A histogram of latencies for http requests.", Buckets: []float64{ - 0.01, /* 10ms */ - 0.05, /* 50ms */ - 0.1, /* 100ms */ - 0.25, /* 250ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 5.0, /* 5s */ - 10.0, /* 10s */ + 0.005, /* 5ms */ + 0.025, /* 25ms */ + 0.1, /* 100ms */ + 0.5, /* 500ms */ + 1.0, /* 1s */ + 10.0, /* 10s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + 300.0, /* 5m */ }, }, []string{"code", "method"}, ) + + httpInFlightRequests = promauto.NewGauge( + prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: httpInFlightRequestsMetricName, + Help: "A gauge of requests currently being performed.", + }, + ) ) + +func NewRoundTripper(next http.RoundTripper) promhttp.RoundTripperFunc { + rt := next + + rt = promhttp.InstrumentRoundTripperCounter(httpRequestsTotal, rt) + rt = promhttp.InstrumentRoundTripperDuration(httpRequestDurationSeconds, rt) + return promhttp.InstrumentRoundTripperInFlight(httpInFlightRequests, rt) +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -31,6 +31,9 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + metrics.SshdConnectionsInFlight.Inc() + defer metrics.SshdConnectionsInFlight.Dec() + defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) for newChannel := range chans { # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1654097153 -7200 # Wed Jun 01 17:25:53 2022 +0200 # Branch heptapod # Node ID b2dc62c22d14ce793d1e9ddee673350d2ea6d651 # Parent 0cef84a5b973b0b8be5a3262178120f5d2a35294 # Parent 6712c68c42156ec09eefaab72446f498341d0464 Merged upstream v13.25.1 into heptapod branch diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,9 @@ - template: Security/SAST.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml + - project: 'gitlab-org/quality/pipeline-common' + file: + - '/ci/danger-review.yml' variables: DOCKER_VERSION: "20.10.3" @@ -52,23 +55,19 @@ script: - make verify test -go:1.16: +tests: extends: .test - image: golang:1.16 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.17: - extends: .test - image: golang:1.17 + image: golang:${GO_VERSION} + parallel: + matrix: + - GO_VERSION: ["1.16", "1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' race: extends: .test - image: golang:1.17 + image: golang:1.18 script: - make test_golang_race diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.7 +golang 1.17.8 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,25 @@ +v13.25.1 + +- Upgrade golang to 1.17.8 !591 +- Add additional metrics to gitlab-sshd !593 +- Add support for FIPS encryption !597 + +v13.25.0 + +- Fix connections duration metrics !588 +- ci: start integrating go 1.18 into the CI pipelines !587 +- Abort long-running unauthenticated SSH connections !582 + +v13.24.2 + +- Bump gitaly client !584 + +v13.24.1 + +- Default to info level for an empty log-level !579 +- Update Gitaly dependency to v14.9.0-rc1 !578 +- Reuse Gitaly connections and sidechannel !575 + v13.24.0 - Upgrade golang to 1.17.7 !576 diff --git a/Dangerfile b/Dangerfile new file mode 100644 --- /dev/null +++ b/Dangerfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'gitlab-dangerfiles' + +Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| + gitlab_dangerfiles.import_plugins + + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) +end diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,7 @@ group :development, :test do gem 'rspec', '~> 3.8.0' end + +group :development, :danger do + gem 'gitlab-dangerfiles', '~> 3.0.0' +end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,89 @@ GEM remote: https://rubygems.org/ specs: + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) + claide (1.1.0) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + colored2 (3.1.2) + cork (0.3.0) + colored2 (~> 3.1) + danger (8.5.0) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (>= 0.9.0, < 2.0) + faraday-http-cache (~> 2.0) + git (~> 1.7) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + no_proxy_fix + octokit (~> 4.7) + terminal-table (>= 1, < 4) + danger-gitlab (8.0.0) + danger + gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) + faraday (1.10.0) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-http-cache (2.2.0) + faraday (>= 0.8) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.3) + multipart-post (>= 1.2, < 3) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + git (1.10.2) + rchardet (~> 1.8) + gitlab (4.18.0) + httparty (~> 0.18) + terminal-table (>= 1.5.1) + gitlab-dangerfiles (3.0.0) + danger (>= 8.4.5) + danger-gitlab (>= 8.0.0) + rake + httparty (0.20.0) + mime-types (~> 3.0) + multi_xml (>= 0.5.2) + kramdown (2.3.2) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2022.0105) + multi_xml (0.6.0) + multipart-post (2.1.1) + nap (1.1.0) + no_proxy_fix (0.1.2) + octokit (4.22.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + open4 (1.3.4) + public_suffix (4.0.6) + rake (13.0.6) + rchardet (1.8.0) + rexml (3.2.5) rspec (3.8.0) rspec-core (~> 3.8.0) rspec-expectations (~> 3.8.0) @@ -15,11 +97,19 @@ diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) + ruby2_keywords (0.0.5) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.1.0) PLATFORMS ruby DEPENDENCIES + gitlab-dangerfiles (~> 3.0.0) rspec (~> 3.8.0) BUNDLED WITH diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 13.25.0 + +- Jump to upstream GitLab Shell v13.25.1 (GitLab 14.10 series) + ## 13.24.0 - Jump to upstream GitLab Shell v13.24.0 (GitLab 14.9 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.24.0 +13.25.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,8 +1,14 @@ .PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install +FIPS_MODE ?= 0 GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver + +ifeq (${FIPS_MODE}, 1) + BUILD_TAGS += boringcrypto +endif + GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.0 +13.25.1 diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,6 +11,7 @@ "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -68,9 +69,12 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() + config.GitalyClient.InitSidechannelRegistry(ctx) + cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + boring.CheckBoring() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -69,6 +69,8 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + cfg.GitalyClient.InitSidechannelRegistry(ctx) + server, err := sshd.NewServer(cfg) if err != nil { log.WithError(err).Fatal("Failed to start GitLab built-in sshd") diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -94,6 +94,14 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + grace_period: 10 + # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". + readiness_probe: "/start" + # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". + liveness_probe: "/health" + # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. + login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 + gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= 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/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= @@ -583,7 +585,7 @@ github.com/lib/pq v1.10.2/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= +github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -865,8 +867,8 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= diff --git a/internal/boring/boring.go b/internal/boring/boring.go new file mode 100644 --- /dev/null +++ b/internal/boring/boring.go @@ -0,0 +1,23 @@ +//go:build boringcrypto +// +build boringcrypto + +package boring + +import ( + "crypto/boring" + + "gitlab.com/gitlab-org/labkit/log" +) + +// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go +// compiler in https://github.com/golang-fips/go, this requires that: +// +// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). +// 2. A system OpenSSL can be dynamically loaded via ldopen(). +func CheckBoring() { + if boring.Enabled() { + log.Info("FIPS mode is enabled. Using an external SSL library.") + return + } + log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") +} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go new file mode 100644 --- /dev/null +++ b/internal/boring/notboring.go @@ -0,0 +1,9 @@ +//go:build !boringcrypto +// +build !boringcrypto + +package boring + +// CheckBoring does nothing when the boringcrypto tag is not in the +// build. +func CheckBoring() { +} diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -13,13 +13,7 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.ReceivePack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.ReceivePack), response) request := &pb.SSHReceivePackRequest{ Repository: &response.Gitaly.Repo, @@ -30,8 +24,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -13,18 +13,12 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadArchive), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadArchive), response) request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -13,26 +13,20 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadPack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) if response.Gitaly.UseSidechannel { - gc.DialSidechannel = true request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) @@ -44,8 +38,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -97,15 +97,18 @@ Env: env, } + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - err := cmd.Execute(ctx) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -13,6 +13,7 @@ yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -31,6 +32,7 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` GracePeriodSeconds uint64 `yaml:"grace_period"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` @@ -86,6 +88,8 @@ httpClient *client.HttpClient httpClientErr error httpClientOnce sync.Once + + GitalyClient gitaly.Client } // The defaults to apply before parsing the config file(s). @@ -102,6 +106,7 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + LoginGraceTimeSeconds: 60, GracePeriodSeconds: 10, ReadinessProbe: "/start", LivenessProbe: "/health", @@ -113,6 +118,10 @@ } ) +func (sc *ServerConfig) LoginGraceTime() time.Duration { + return time.Duration(sc.LoginGraceTimeSeconds) * time.Second +} + func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:6] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -48,8 +48,11 @@ "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", "gitlab_shell_sshd_concurrent_limited_sessions_total", - "gitlab_shell_sshd_connection_duration_seconds", "gitlab_shell_sshd_in_flight_connections", + "gitlab_shell_sshd_session_duration_seconds", + "gitlab_shell_sshd_session_established_duration_seconds", + "gitlab_sli:shell_sshd_sessions:errors_total", + "gitlab_sli:shell_sshd_sessions:total", } require.Equal(t, expectedMetricNames, actualNames) diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly.go @@ -0,0 +1,133 @@ +package gitaly + +import ( + "context" + "fmt" + "sync" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "google.golang.org/grpc" + + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" + "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + "gitlab.com/gitlab-org/labkit/correlation" + grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" + grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +type Command struct { + ServiceName string + Address string + Token string + DialSidechannel bool +} + +type connectionsCache struct { + sync.RWMutex + + connections map[Command]*grpc.ClientConn +} + +type Client struct { + SidechannelRegistry *gitalyclient.SidechannelRegistry + + cache connectionsCache +} + +func (c *Client) InitSidechannelRegistry(ctx context.Context) { + c.SidechannelRegistry = gitalyclient.NewSidechannelRegistry(log.ContextLogger(ctx)) +} + +func (c *Client) GetConnection(ctx context.Context, cmd Command) (*grpc.ClientConn, error) { + c.cache.RLock() + conn := c.cache.connections[cmd] + c.cache.RUnlock() + + if conn != nil { + return conn, nil + } + + c.cache.Lock() + defer c.cache.Unlock() + + if conn := c.cache.connections[cmd]; conn != nil { + return conn, nil + } + + conn, err := c.newConnection(ctx, cmd) + if err != nil { + return nil, err + } + + if c.cache.connections == nil { + c.cache.connections = make(map[Command]*grpc.ClientConn) + } + + c.cache.connections[cmd] = conn + + return conn, nil +} + +func (c *Client) newConnection(ctx context.Context, cmd Command) (conn *grpc.ClientConn, err error) { + defer func() { + label := "ok" + if err != nil { + label = "fail" + } + metrics.GitalyConnectionsTotal.WithLabelValues(label).Inc() + }() + + if cmd.Address == "" { + return nil, fmt.Errorf("no gitaly_address given") + } + + serviceName := correlation.ExtractClientNameFromContext(ctx) + if serviceName == "" { + serviceName = "gitlab-shell-unknown" + + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + } + + serviceName = fmt.Sprintf("%s-%s", serviceName, cmd.ServiceName) + + connOpts := client.DefaultDialOpts + connOpts = append( + connOpts, + grpc.WithStreamInterceptor( + grpc_middleware.ChainStreamClient( + grpctracing.StreamClientTracingInterceptor(), + grpc_prometheus.StreamClientInterceptor, + grpccorrelation.StreamClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + + grpc.WithUnaryInterceptor( + grpc_middleware.ChainUnaryClient( + grpctracing.UnaryClientTracingInterceptor(), + grpc_prometheus.UnaryClientInterceptor, + grpccorrelation.UnaryClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + ) + + if cmd.Token != "" { + connOpts = append(connOpts, + grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cmd.Token)), + ) + } + + if cmd.DialSidechannel { + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) + } + + return client.DialContext(ctx, cmd.Address, connOpts) +} diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly_test.go @@ -0,0 +1,53 @@ +package gitaly + +import ( + "context" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +func TestPrometheusMetrics(t *testing.T) { + metrics.GitalyConnectionsTotal.Reset() + + c := &Client{} + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + c.newConnection(context.Background(), cmd) + c.newConnection(context.Background(), cmd) + + require.Equal(t, 1, testutil.CollectAndCount(metrics.GitalyConnectionsTotal)) + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 0, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) + + cmd = Command{Address: ""} + c.newConnection(context.Background(), cmd) + + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 1, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) +} + +func TestCachedConnections(t *testing.T) { + c := &Client{} + + require.Len(t, c.cache.connections, 0) + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + + conn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + + newConn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + require.Equal(t, conn, newConn) + + cmd = Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9998"} + _, err = c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 2) +} diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -6,56 +6,57 @@ "strconv" "strings" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/labkit/correlation" - grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" - grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" ) // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string - DialSidechannel bool + Config *config.Config + Response *accessverifier.Response + Command gitaly.Command +} + +func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { + gc := gitaly.Command{ + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, + DialSidechannel: response.Gitaly.UseSidechannel, + } + + return &GitalyCommand{Config: cfg, Response: response, Command: gc} } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) - conn, err := getConn(ctx, gc, registry) + // We leave the connection open for future reuse + conn, err := gc.getConn(ctx) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") return err } - defer conn.Close() - childCtx := withOutgoingMetadata(ctx, gc.Features) + childCtx := withOutgoingMetadata(ctx, gc.Response.Gitaly.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn, registry) + exitStatus, err := handler(childCtx, conn) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -72,35 +73,35 @@ // PrepareContext wraps a given context with a correlation ID and logs the command to // be run. -func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) (context.Context, context.CancelFunc) { +func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, env sshenv.Env) (context.Context, context.CancelFunc) { ctx, cancel := context.WithCancel(ctx) - gc.LogExecution(ctx, repository, response, env) + gc.LogExecution(ctx, repository, env) md, ok := metadata.FromOutgoingContext(ctx) if !ok { md = metadata.New(nil) } - md.Append("key_id", strconv.Itoa(response.KeyId)) - md.Append("key_type", response.KeyType) - md.Append("user_id", response.UserId) - md.Append("username", response.Username) + md.Append("key_id", strconv.Itoa(gc.Response.KeyId)) + md.Append("key_type", gc.Response.KeyType) + md.Append("user_id", gc.Response.UserId) + md.Append("username", gc.Response.Username) md.Append("remote_ip", env.RemoteAddr) ctx = metadata.NewOutgoingContext(ctx, md) return ctx, cancel } -func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { +func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, env sshenv.Env) { fields := log.Fields{ - "command": gc.ServiceName, + "command": gc.Command.ServiceName, "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, - "user_id": response.UserId, - "username": response.Username, + "user_id": gc.Response.UserId, + "username": gc.Response.Username, "git_protocol": env.GitProtocolVersion, "remote_ip": env.RemoteAddr, - "gl_key_type": response.KeyType, - "gl_key_id": response.KeyId, + "gl_key_type": gc.Response.KeyType, + "gl_key_id": gc.Response.KeyId, } log.WithContextFields(ctx, fields).Info("executing git command") @@ -118,53 +119,6 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { - if gc.Address == "" { - return nil, fmt.Errorf("no gitaly_address given") - } - - serviceName := correlation.ExtractClientNameFromContext(ctx) - if serviceName == "" { - serviceName = "gitlab-shell-unknown" - - log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") - } - - serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) - - connOpts := client.DefaultDialOpts - connOpts = append( - connOpts, - grpc.WithStreamInterceptor( - grpc_middleware.ChainStreamClient( - grpctracing.StreamClientTracingInterceptor(), - grpc_prometheus.StreamClientInterceptor, - grpccorrelation.StreamClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - - grpc.WithUnaryInterceptor( - grpc_middleware.ChainUnaryClient( - grpctracing.UnaryClientTracingInterceptor(), - grpc_prometheus.UnaryClientInterceptor, - grpccorrelation.UnaryClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - ) - - if gc.Token != "" { - connOpts = append(connOpts, - grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(gc.Token)), - ) - } - - if gc.DialSidechannel { - return client.DialSidechannel(ctx, gc.Address, registry, connOpts) - } - - return client.DialContext(ctx, gc.Address, connOpts) +func (gc *GitalyCommand) getConn(ctx context.Context) (*grpc.ClientConn, error) { + return gc.Config.GitalyClient.GetConnection(ctx, gc.Command) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,15 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -28,10 +28,13 @@ } func TestRunGitalyCommand(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.NoError(t, err) @@ -41,6 +44,32 @@ require.Equal(t, err, expectedErr) } +func TestCachingOfGitalyConnections(t *testing.T) { + ctx := context.Background() + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + response := &accessverifier.Response{ + Username: "user", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Token: "token", + UseSidechannel: true, + }, + } + + cmd := NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + + conn, err := cmd.getConn(ctx) + require.NoError(t, err) + + // Reuses connection for different users + response.Username = "another-user" + cmd = NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + newConn, err := cmd.getConn(ctx) + require.NoError(t, err) + require.Equal(t, conn, newConn) +} + func TestMissingGitalyAddress(t *testing.T) { cmd := GitalyCommand{Config: &config.Config{}} @@ -49,10 +78,13 @@ } func TestUnavailableGitalyErr(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) @@ -68,15 +100,20 @@ }{ { name: "gitaly_feature_flags", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - Features: map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "other-ff": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Features: map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "other-ff": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + }, + }, }, - }, + ), want: map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", @@ -87,7 +124,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) @@ -117,10 +154,19 @@ }{ { name: "client_identity", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - }, + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + KeyId: 1, + KeyType: "key", + UserId: "6", + Username: "jane.doe", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + }, + }, + ), env: sshenv.Env{ GitProtocolVersion: "protocol", IsSSHConnection: true, @@ -134,12 +180,6 @@ GlRepository: "project-26", GlProjectPath: "group/private", }, - response: &accessverifier.Response{ - KeyId: 1, - KeyType: "key", - UserId: "6", - Username: "jane.doe", - }, want: map[string]string{ "key_id": "1", "key_type": "key", @@ -153,7 +193,7 @@ t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.response, tt.env) + ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.env) defer cancel() md, exists := metadata.FromOutgoingContext(ctx) diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -22,6 +22,14 @@ return inFmt } +func logLevel(inLevel string) string { + if inLevel == "" { + return "info" + } + + return inLevel +} + func logFile(inFile string) string { if inFile == "" { return "stderr" @@ -35,7 +43,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), - log.WithLogLevel(cfg.LogLevel), + log.WithLogLevel(logLevel(cfg.LogLevel)), } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -30,9 +30,11 @@ tmpFile.Close() data, err := os.ReadFile(tmpFile.Name()) + dataStr := string(data) require.NoError(t, err) - require.Contains(t, string(data), `msg":"this is a test"`) - require.NotContains(t, string(data), `msg:":"debug log message"`) + require.Contains(t, dataStr, `"msg":"this is a test"`) + require.NotContains(t, dataStr, `"msg":"debug log message"`) + require.NotContains(t, dataStr, `"msg":"unknown log level`) } func TestConfigureWithDebugLogLevel(t *testing.T) { diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -9,36 +9,51 @@ ) const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" - httpSubsystem = "http" + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" + gitalySubsystem = "gitaly" httpInFlightRequestsMetricName = "in_flight_requests" httpRequestsTotalMetricName = "requests_total" httpRequestDurationSecondsMetricName = "request_duration_seconds" - sshdConnectionsInFlightName = "in_flight_connections" - sshdConnectionDuration = "connection_duration_seconds" - sshdHitMaxSessions = "concurrent_limited_sessions_total" + sshdConnectionsInFlightName = "in_flight_connections" + sshdHitMaxSessionsName = "concurrent_limited_sessions_total" + sshdSessionDurationSecondsName = "session_duration_seconds" + sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + + sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" + sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" + + gitalyConnectionsTotalName = "connections_total" ) var ( - SshdConnectionDuration = promauto.NewHistogram( + SshdSessionDuration = promauto.NewHistogram( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdConnectionDuration, + Name: sshdSessionDurationSecondsName, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ + 5.0, /* 5s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + }, + }, + ) + + SshdSessionEstablishedDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdSessionEstablishedDurationSecondsName, + Help: "A histogram of latencies until session established to gitlab-shell sshd.", + Buckets: []float64{ + 0.5, /* 5ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ }, }, ) @@ -56,11 +71,35 @@ prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdHitMaxSessions, + Name: sshdHitMaxSessionsName, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) + SliSshdSessionsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsTotalName, + Help: "Number of SSH sessions that have been established", + }, + ) + + SliSshdSessionsErrorsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsErrorsTotalName, + Help: "Number of SSH sessions that have failed", + }, + ) + + GitalyConnectionsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: gitalySubsystem, + Name: gitalyConnectionsTotalName, + Help: "Number of Gitaly connections that have been established", + }, + []string{"status"}, + ) + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,7 +2,6 @@ import ( "context" - "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" @@ -13,7 +12,6 @@ ) type connection struct { - begin time.Time concurrentSessions *semaphore.Weighted remoteAddr string } @@ -22,7 +20,6 @@ func newConnection(maxSessions int64, remoteAddr string) *connection { return &connection{ - begin: time.Now(), concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, } @@ -31,11 +28,6 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) - metrics.SshdConnectionsInFlight.Inc() - defer metrics.SshdConnectionsInFlight.Dec() - - defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) - for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,6 +22,7 @@ channel ssh.Channel gitlabKeyId string remoteAddr string + success bool // State managed by the session execCmd string @@ -182,6 +183,8 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} + s.success = status == 0 + s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -99,6 +99,7 @@ expectedExecCmd string sentRequestName string sentRequestPayload []byte + success bool }{ { desc: "invalid payload", @@ -111,6 +112,7 @@ expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + success: true, }, } @@ -130,6 +132,7 @@ require.Equal(t, false, s.handleExec(context.Background(), r)) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + require.Equal(t, tc.success, s.success) }) } } @@ -141,6 +144,7 @@ errMsg string gitlabKeyId string expectedExitCode uint32 + success bool }{ { desc: "fails to parse command", diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,6 +12,7 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -145,6 +146,20 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + success := false + + metrics.SshdConnectionsInFlight.Inc() + started := time.Now() + defer func() { + metrics.SshdConnectionsInFlight.Dec() + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + + metrics.SliSshdSessionsTotal.Inc() + if !success { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + }() + remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() @@ -164,7 +179,7 @@ ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) + sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) if err != nil { ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return @@ -172,8 +187,12 @@ go ssh.DiscardRequests(reqs) + var establishSessionDuration float64 conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + establishSessionDuration = time.Since(started).Seconds() + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) + session := &session{ cfg: s.Config, channel: channel, @@ -182,9 +201,28 @@ } session.handle(ctx, requests) + + success = session.success }) - ctxlog.Info("server: handleConn: done") + ctxlog.WithFields(log.Fields{ + "duration_s": time.Since(started).Seconds(), + "establish_session_duration_s": establishSessionDuration, + }).Info("server: handleConn: done") +} + +func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { + timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { + nconn.Close() + }) + defer func() { + // If time.Stop() equals false, that means that AfterFunc has been executed + if !timer.Stop() { + err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) + } + }() + + return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) } func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" "net/http/httptest" "os" @@ -134,6 +135,33 @@ require.Nil(t, s.Shutdown()) } +func TestLoginGraceTime(t *testing.T) { + s := setupServer(t) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Verify that the server shutdowns instantly without waiting for any connection to execute + // That means that the server doesn't have any connections to wait for + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -183,6 +211,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.LoginGraceTimeSeconds = 1 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1654097568 -7200 # Wed Jun 01 17:32:48 2022 +0200 # Branch heptapod # Node ID e35ff18d0d7035d511f8454909ca5ccc10bbb3fd # Parent b2dc62c22d14ce793d1e9ddee673350d2ea6d651 Heptapod CI: resync with upstream - using `matrix` - 'race' tests run on Go 1.18 diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -38,22 +38,18 @@ script: - make verify test -go:1.16: +tests: extends: .test - image: golang:1.16 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.17: - extends: .test - image: golang:1.17 + image: golang:${GO_VERSION} + parallel: + matrix: + - GO_VERSION: ["1.16", "1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' race: extends: .test - image: golang:1.17 + image: golang:1.18 script: - make test_golang_race # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1654097653 -7200 # Wed Jun 01 17:34:13 2022 +0200 # Branch heptapod # Node ID bbf4eff5db1a60372d6a9828b15464d5207c1fbf # Parent e35ff18d0d7035d511f8454909ca5ccc10bbb3fd Heptapod CI: bumped Gitaly version Upstream just uses "master", but they are by definition working on a version closer to the bleeding edge than we are. diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -31,7 +31,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.5.2 + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.10.1 # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1655107575 -7200 # Mon Jun 13 10:06:15 2022 +0200 # Branch heptapod # Node ID 57a0260a6fb85a23d5d983b8bf04030cc1b79768 # Parent bbf4eff5db1a60372d6a9828b15464d5207c1fbf Added tag heptapod-13.25.0 for changeset bbf4eff5db1a diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -39,3 +39,4 @@ 7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 eaa400f46c97a398037f0a72a5a30836f31a3586 heptapod-13.24.0 +bbf4eff5db1a60372d6a9828b15464d5207c1fbf heptapod-13.25.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1657204193 -7200 # Thu Jul 07 16:29:53 2022 +0200 # Branch heptapod-stable # Node ID 2ab8e6717d3b7798734e1bac9d079c41f52d5b0a # Parent 3b031eaaaf7b158306134942e70b00abf2182cd0 # Parent 57a0260a6fb85a23d5d983b8bf04030cc1b79768 heptapod#685: making 0.32 the new stable diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,9 @@ - template: Security/SAST.gitlab-ci.yml - template: Security/Dependency-Scanning.gitlab-ci.yml - template: Security/Secret-Detection.gitlab-ci.yml + - project: 'gitlab-org/quality/pipeline-common' + file: + - '/ci/danger-review.yml' variables: DOCKER_VERSION: "20.10.3" @@ -52,23 +55,19 @@ script: - make verify test -go:1.16: +tests: extends: .test - image: golang:1.16 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.17: - extends: .test - image: golang:1.17 + image: golang:${GO_VERSION} + parallel: + matrix: + - GO_VERSION: ["1.16", "1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' race: extends: .test - image: golang:1.17 + image: golang:1.18 script: - make test_golang_race diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -39,3 +39,4 @@ 7f259a883e58759e4734cb0f38449379bb36aca6 heptapod-13.22.0 61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 eaa400f46c97a398037f0a72a5a30836f31a3586 heptapod-13.24.0 +bbf4eff5db1a60372d6a9828b15464d5207c1fbf heptapod-13.25.0 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.7 +golang 1.17.8 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,25 @@ +v13.25.1 + +- Upgrade golang to 1.17.8 !591 +- Add additional metrics to gitlab-sshd !593 +- Add support for FIPS encryption !597 + +v13.25.0 + +- Fix connections duration metrics !588 +- ci: start integrating go 1.18 into the CI pipelines !587 +- Abort long-running unauthenticated SSH connections !582 + +v13.24.2 + +- Bump gitaly client !584 + +v13.24.1 + +- Default to info level for an empty log-level !579 +- Update Gitaly dependency to v14.9.0-rc1 !578 +- Reuse Gitaly connections and sidechannel !575 + v13.24.0 - Upgrade golang to 1.17.7 !576 diff --git a/Dangerfile b/Dangerfile new file mode 100644 --- /dev/null +++ b/Dangerfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'gitlab-dangerfiles' + +Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| + gitlab_dangerfiles.import_plugins + + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) +end diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,7 @@ group :development, :test do gem 'rspec', '~> 3.8.0' end + +group :development, :danger do + gem 'gitlab-dangerfiles', '~> 3.0.0' +end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,89 @@ GEM remote: https://rubygems.org/ specs: + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) + claide (1.1.0) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + colored2 (3.1.2) + cork (0.3.0) + colored2 (~> 3.1) + danger (8.5.0) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (>= 0.9.0, < 2.0) + faraday-http-cache (~> 2.0) + git (~> 1.7) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + no_proxy_fix + octokit (~> 4.7) + terminal-table (>= 1, < 4) + danger-gitlab (8.0.0) + danger + gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) + faraday (1.10.0) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-http-cache (2.2.0) + faraday (>= 0.8) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.3) + multipart-post (>= 1.2, < 3) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + git (1.10.2) + rchardet (~> 1.8) + gitlab (4.18.0) + httparty (~> 0.18) + terminal-table (>= 1.5.1) + gitlab-dangerfiles (3.0.0) + danger (>= 8.4.5) + danger-gitlab (>= 8.0.0) + rake + httparty (0.20.0) + mime-types (~> 3.0) + multi_xml (>= 0.5.2) + kramdown (2.3.2) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2022.0105) + multi_xml (0.6.0) + multipart-post (2.1.1) + nap (1.1.0) + no_proxy_fix (0.1.2) + octokit (4.22.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + open4 (1.3.4) + public_suffix (4.0.6) + rake (13.0.6) + rchardet (1.8.0) + rexml (3.2.5) rspec (3.8.0) rspec-core (~> 3.8.0) rspec-expectations (~> 3.8.0) @@ -15,11 +97,19 @@ diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) + ruby2_keywords (0.0.5) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.1.0) PLATFORMS ruby DEPENDENCIES + gitlab-dangerfiles (~> 3.0.0) rspec (~> 3.8.0) BUNDLED WITH diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 13.25.0 + +- Jump to upstream GitLab Shell v13.25.1 (GitLab 14.10 series) + ## 13.24.0 - Jump to upstream GitLab Shell v13.24.0 (GitLab 14.9 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.24.0 +13.25.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -1,8 +1,14 @@ .PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install +FIPS_MODE ?= 0 GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver + +ifeq (${FIPS_MODE}, 1) + BUILD_TAGS += boringcrypto +endif + GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod PREFIX ?= /usr/local diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.24.0 +13.25.1 diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,6 +11,7 @@ "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -68,9 +69,12 @@ ctx, finished := command.Setup(executable.Name, config) defer finished() + config.GitalyClient.InitSidechannelRegistry(ctx) + cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") + boring.CheckBoring() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -69,6 +69,8 @@ ctx, finished := command.Setup("gitlab-sshd", cfg) defer finished() + cfg.GitalyClient.InitSidechannelRegistry(ctx) + server, err := sshd.NewServer(cfg) if err != nil { log.WithError(err).Fatal("Failed to start GitLab built-in sshd") diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -94,6 +94,14 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + grace_period: 10 + # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". + readiness_probe: "/start" + # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". + liveness_probe: "/health" + # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. + login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ github.com/pires/go-proxyproto v0.6.1 github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 + gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 gitlab.com/gitlab-org/labkit v1.12.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= 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/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= @@ -583,7 +585,7 @@ github.com/lib/pq v1.10.2/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/v32 v32.1.6/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= +github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= @@ -865,8 +867,8 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490 h1:NzcVF6tscgsW890MQfVAhMVnAhXeohPaUGOTuFfIJXs= -gitlab.com/gitlab-org/gitaly/v14 v14.6.0-rc1.0.20220121102056-2e398afa0490/go.mod h1:taZCYTkDDPh8LCetkdOEx/x+mkvNgGc9GIGlWkXivk0= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= +gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -31,29 +31,25 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.5.2 + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.10.1 # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly script: - make verify test -go:1.16: +tests: extends: .test - image: golang:1.16 - after_script: - - make coverage - coverage: '/\d+.\d+%/' - -go:1.17: - extends: .test - image: golang:1.17 + image: golang:${GO_VERSION} + parallel: + matrix: + - GO_VERSION: ["1.16", "1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' race: extends: .test - image: golang:1.17 + image: golang:1.18 script: - make test_golang_race diff --git a/internal/boring/boring.go b/internal/boring/boring.go new file mode 100644 --- /dev/null +++ b/internal/boring/boring.go @@ -0,0 +1,23 @@ +//go:build boringcrypto +// +build boringcrypto + +package boring + +import ( + "crypto/boring" + + "gitlab.com/gitlab-org/labkit/log" +) + +// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go +// compiler in https://github.com/golang-fips/go, this requires that: +// +// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). +// 2. A system OpenSSL can be dynamically loaded via ldopen(). +func CheckBoring() { + if boring.Enabled() { + log.Info("FIPS mode is enabled. Using an external SSL library.") + return + } + log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") +} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go new file mode 100644 --- /dev/null +++ b/internal/boring/notboring.go @@ -0,0 +1,9 @@ +//go:build !boringcrypto +// +build !boringcrypto + +package boring + +// CheckBoring does nothing when the boringcrypto tag is not in the +// build. +func CheckBoring() { +} diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -13,13 +13,7 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.ReceivePack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.ReceivePack), response) request := &pb.SSHReceivePackRequest{ Repository: &response.Gitaly.Repo, @@ -30,8 +24,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -13,18 +13,12 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadArchive), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadArchive), response) request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo} - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -13,26 +13,20 @@ ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { - gc := &handler.GitalyCommand{ - Config: c.Config, - ServiceName: string(commandargs.UploadPack), - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - Features: response.Gitaly.Features, - } + gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) if response.Gitaly.UseSidechannel { - gc.DialSidechannel = true request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) @@ -44,8 +38,8 @@ GitConfigOptions: response.GitConfigOptions, } - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, response, c.Args.Env) + return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() rw := c.ReadWriter diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -97,15 +97,18 @@ Env: env, } + ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") + ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") + + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - err := cmd.Execute(ctx) require.NoError(t, err) diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -13,6 +13,7 @@ yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -31,6 +32,7 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` GracePeriodSeconds uint64 `yaml:"grace_period"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` @@ -86,6 +88,8 @@ httpClient *client.HttpClient httpClientErr error httpClientOnce sync.Once + + GitalyClient gitaly.Client } // The defaults to apply before parsing the config file(s). @@ -102,6 +106,7 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, + LoginGraceTimeSeconds: 60, GracePeriodSeconds: 10, ReadinessProbe: "/start", LivenessProbe: "/health", @@ -113,6 +118,10 @@ } ) +func (sc *ServerConfig) LoginGraceTime() time.Duration { + return time.Duration(sc.LoginGraceTimeSeconds) * time.Second +} + func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:6] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -48,8 +48,11 @@ "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", "gitlab_shell_sshd_concurrent_limited_sessions_total", - "gitlab_shell_sshd_connection_duration_seconds", "gitlab_shell_sshd_in_flight_connections", + "gitlab_shell_sshd_session_duration_seconds", + "gitlab_shell_sshd_session_established_duration_seconds", + "gitlab_sli:shell_sshd_sessions:errors_total", + "gitlab_sli:shell_sshd_sessions:total", } require.Equal(t, expectedMetricNames, actualNames) diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly.go @@ -0,0 +1,133 @@ +package gitaly + +import ( + "context" + "fmt" + "sync" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "google.golang.org/grpc" + + gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" + "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + "gitlab.com/gitlab-org/labkit/correlation" + grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" + "gitlab.com/gitlab-org/labkit/log" + grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +type Command struct { + ServiceName string + Address string + Token string + DialSidechannel bool +} + +type connectionsCache struct { + sync.RWMutex + + connections map[Command]*grpc.ClientConn +} + +type Client struct { + SidechannelRegistry *gitalyclient.SidechannelRegistry + + cache connectionsCache +} + +func (c *Client) InitSidechannelRegistry(ctx context.Context) { + c.SidechannelRegistry = gitalyclient.NewSidechannelRegistry(log.ContextLogger(ctx)) +} + +func (c *Client) GetConnection(ctx context.Context, cmd Command) (*grpc.ClientConn, error) { + c.cache.RLock() + conn := c.cache.connections[cmd] + c.cache.RUnlock() + + if conn != nil { + return conn, nil + } + + c.cache.Lock() + defer c.cache.Unlock() + + if conn := c.cache.connections[cmd]; conn != nil { + return conn, nil + } + + conn, err := c.newConnection(ctx, cmd) + if err != nil { + return nil, err + } + + if c.cache.connections == nil { + c.cache.connections = make(map[Command]*grpc.ClientConn) + } + + c.cache.connections[cmd] = conn + + return conn, nil +} + +func (c *Client) newConnection(ctx context.Context, cmd Command) (conn *grpc.ClientConn, err error) { + defer func() { + label := "ok" + if err != nil { + label = "fail" + } + metrics.GitalyConnectionsTotal.WithLabelValues(label).Inc() + }() + + if cmd.Address == "" { + return nil, fmt.Errorf("no gitaly_address given") + } + + serviceName := correlation.ExtractClientNameFromContext(ctx) + if serviceName == "" { + serviceName = "gitlab-shell-unknown" + + log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") + } + + serviceName = fmt.Sprintf("%s-%s", serviceName, cmd.ServiceName) + + connOpts := client.DefaultDialOpts + connOpts = append( + connOpts, + grpc.WithStreamInterceptor( + grpc_middleware.ChainStreamClient( + grpctracing.StreamClientTracingInterceptor(), + grpc_prometheus.StreamClientInterceptor, + grpccorrelation.StreamClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + + grpc.WithUnaryInterceptor( + grpc_middleware.ChainUnaryClient( + grpctracing.UnaryClientTracingInterceptor(), + grpc_prometheus.UnaryClientInterceptor, + grpccorrelation.UnaryClientCorrelationInterceptor( + grpccorrelation.WithClientName(serviceName), + ), + ), + ), + ) + + if cmd.Token != "" { + connOpts = append(connOpts, + grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(cmd.Token)), + ) + } + + if cmd.DialSidechannel { + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) + } + + return client.DialContext(ctx, cmd.Address, connOpts) +} diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go new file mode 100644 --- /dev/null +++ b/internal/gitaly/gitaly_test.go @@ -0,0 +1,53 @@ +package gitaly + +import ( + "context" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" +) + +func TestPrometheusMetrics(t *testing.T) { + metrics.GitalyConnectionsTotal.Reset() + + c := &Client{} + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + c.newConnection(context.Background(), cmd) + c.newConnection(context.Background(), cmd) + + require.Equal(t, 1, testutil.CollectAndCount(metrics.GitalyConnectionsTotal)) + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 0, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) + + cmd = Command{Address: ""} + c.newConnection(context.Background(), cmd) + + require.InDelta(t, 2, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("ok")), 0.1) + require.InDelta(t, 1, testutil.ToFloat64(metrics.GitalyConnectionsTotal.WithLabelValues("fail")), 0.1) +} + +func TestCachedConnections(t *testing.T) { + c := &Client{} + + require.Len(t, c.cache.connections, 0) + + cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} + + conn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + + newConn, err := c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 1) + require.Equal(t, conn, newConn) + + cmd = Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9998"} + _, err = c.GetConnection(context.Background(), cmd) + require.NoError(t, err) + require.Len(t, c.cache.connections, 2) +} diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -6,56 +6,57 @@ "strconv" "strings" - grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" - grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/labkit/correlation" - grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" - grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" ) // GitalyHandlerFunc implementations are responsible for making // an appropriate Gitaly call using the provided client and context // and returning an error from the Gitaly call. -type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) +type GitalyHandlerFunc func(ctx context.Context, client *grpc.ClientConn) (int32, error) type GitalyCommand struct { - Config *config.Config - ServiceName string - Address string - Token string - Features map[string]string - DialSidechannel bool + Config *config.Config + Response *accessverifier.Response + Command gitaly.Command +} + +func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { + gc := gitaly.Command{ + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, + DialSidechannel: response.Gitaly.UseSidechannel, + } + + return &GitalyCommand{Config: cfg, Response: response, Command: gc} } // RunGitalyCommand provides a bootstrap for Gitaly commands executed // through GitLab-Shell. It ensures that logging, tracing and other // common concerns are configured before executing the `handler`. func (gc *GitalyCommand) RunGitalyCommand(ctx context.Context, handler GitalyHandlerFunc) error { - registry := client.NewSidechannelRegistry(log.ContextLogger(ctx)) - conn, err := getConn(ctx, gc, registry) + // We leave the connection open for future reuse + conn, err := gc.getConn(ctx) if err != nil { log.ContextLogger(ctx).WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Failed to get connection to execute Git command") return err } - defer conn.Close() - childCtx := withOutgoingMetadata(ctx, gc.Features) + childCtx := withOutgoingMetadata(ctx, gc.Response.Gitaly.Features) ctxlog := log.ContextLogger(childCtx) - exitStatus, err := handler(childCtx, conn, registry) + exitStatus, err := handler(childCtx, conn) if err != nil { if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { @@ -72,35 +73,35 @@ // PrepareContext wraps a given context with a correlation ID and logs the command to // be run. -func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) (context.Context, context.CancelFunc) { +func (gc *GitalyCommand) PrepareContext(ctx context.Context, repository *pb.Repository, env sshenv.Env) (context.Context, context.CancelFunc) { ctx, cancel := context.WithCancel(ctx) - gc.LogExecution(ctx, repository, response, env) + gc.LogExecution(ctx, repository, env) md, ok := metadata.FromOutgoingContext(ctx) if !ok { md = metadata.New(nil) } - md.Append("key_id", strconv.Itoa(response.KeyId)) - md.Append("key_type", response.KeyType) - md.Append("user_id", response.UserId) - md.Append("username", response.Username) + md.Append("key_id", strconv.Itoa(gc.Response.KeyId)) + md.Append("key_type", gc.Response.KeyType) + md.Append("user_id", gc.Response.UserId) + md.Append("username", gc.Response.Username) md.Append("remote_ip", env.RemoteAddr) ctx = metadata.NewOutgoingContext(ctx, md) return ctx, cancel } -func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, response *accessverifier.Response, env sshenv.Env) { +func (gc *GitalyCommand) LogExecution(ctx context.Context, repository *pb.Repository, env sshenv.Env) { fields := log.Fields{ - "command": gc.ServiceName, + "command": gc.Command.ServiceName, "gl_project_path": repository.GlProjectPath, "gl_repository": repository.GlRepository, - "user_id": response.UserId, - "username": response.Username, + "user_id": gc.Response.UserId, + "username": gc.Response.Username, "git_protocol": env.GitProtocolVersion, "remote_ip": env.RemoteAddr, - "gl_key_type": response.KeyType, - "gl_key_id": response.KeyId, + "gl_key_type": gc.Response.KeyType, + "gl_key_id": gc.Response.KeyId, } log.WithContextFields(ctx, fields).Info("executing git command") @@ -118,53 +119,6 @@ return metadata.NewOutgoingContext(ctx, md) } -func getConn(ctx context.Context, gc *GitalyCommand, registry *client.SidechannelRegistry) (*grpc.ClientConn, error) { - if gc.Address == "" { - return nil, fmt.Errorf("no gitaly_address given") - } - - serviceName := correlation.ExtractClientNameFromContext(ctx) - if serviceName == "" { - serviceName = "gitlab-shell-unknown" - - log.WithContextFields(ctx, log.Fields{"service_name": serviceName}).Warn("No gRPC service name specified, defaulting to gitlab-shell-unknown") - } - - serviceName = fmt.Sprintf("%s-%s", serviceName, gc.ServiceName) - - connOpts := client.DefaultDialOpts - connOpts = append( - connOpts, - grpc.WithStreamInterceptor( - grpc_middleware.ChainStreamClient( - grpctracing.StreamClientTracingInterceptor(), - grpc_prometheus.StreamClientInterceptor, - grpccorrelation.StreamClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - - grpc.WithUnaryInterceptor( - grpc_middleware.ChainUnaryClient( - grpctracing.UnaryClientTracingInterceptor(), - grpc_prometheus.UnaryClientInterceptor, - grpccorrelation.UnaryClientCorrelationInterceptor( - grpccorrelation.WithClientName(serviceName), - ), - ), - ), - ) - - if gc.Token != "" { - connOpts = append(connOpts, - grpc.WithPerRPCCredentials(gitalyauth.RPCCredentialsV2(gc.Token)), - ) - } - - if gc.DialSidechannel { - return client.DialSidechannel(ctx, gc.Address, registry, connOpts) - } - - return client.DialContext(ctx, gc.Address, connOpts) +func (gc *GitalyCommand) getConn(ctx context.Context) (*grpc.ClientConn, error) { + return gc.Config.GitalyClient.GetConnection(ctx, gc.Command) } diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,15 +11,15 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) -func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn, *client.SidechannelRegistry) (int32, error) { - return func(ctx context.Context, client *grpc.ClientConn, registry *client.SidechannelRegistry) (int32, error) { +func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { + return func(ctx context.Context, client *grpc.ClientConn) (int32, error) { require.NotNil(t, ctx) require.NotNil(t, client) @@ -28,10 +28,13 @@ } func TestRunGitalyCommand(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.NoError(t, err) @@ -41,6 +44,32 @@ require.Equal(t, err, expectedErr) } +func TestCachingOfGitalyConnections(t *testing.T) { + ctx := context.Background() + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(ctx) + response := &accessverifier.Response{ + Username: "user", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Token: "token", + UseSidechannel: true, + }, + } + + cmd := NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + + conn, err := cmd.getConn(ctx) + require.NoError(t, err) + + // Reuses connection for different users + response.Username = "another-user" + cmd = NewGitalyCommand(cfg, string(commandargs.UploadPack), response) + newConn, err := cmd.getConn(ctx) + require.NoError(t, err) + require.Equal(t, conn, newConn) +} + func TestMissingGitalyAddress(t *testing.T) { cmd := GitalyCommand{Config: &config.Config{}} @@ -49,10 +78,13 @@ } func TestUnavailableGitalyErr(t *testing.T) { - cmd := GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - } + cmd := NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, + }, + ) expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) @@ -68,15 +100,20 @@ }{ { name: "gitaly_feature_flags", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - Features: map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "other-ff": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + Features: map[string]string{ + "gitaly-feature-cache_invalidator": "true", + "other-ff": "true", + "gitaly-feature-inforef_uploadpack_cache": "false", + }, + }, }, - }, + ), want: map[string]string{ "gitaly-feature-cache_invalidator": "true", "gitaly-feature-inforef_uploadpack_cache": "false", @@ -87,7 +124,7 @@ t.Run(tt.name, func(t *testing.T) { cmd := tt.gc - err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn, _ *client.SidechannelRegistry) (int32, error) { + err := cmd.RunGitalyCommand(context.Background(), func(ctx context.Context, _ *grpc.ClientConn) (int32, error) { md, exists := metadata.FromOutgoingContext(ctx) require.True(t, exists) require.Equal(t, len(tt.want), md.Len()) @@ -117,10 +154,19 @@ }{ { name: "client_identity", - gc: &GitalyCommand{ - Config: &config.Config{}, - Address: "tcp://localhost:9999", - }, + gc: NewGitalyCommand( + &config.Config{}, + string(commandargs.UploadPack), + &accessverifier.Response{ + KeyId: 1, + KeyType: "key", + UserId: "6", + Username: "jane.doe", + Gitaly: accessverifier.Gitaly{ + Address: "tcp://localhost:9999", + }, + }, + ), env: sshenv.Env{ GitProtocolVersion: "protocol", IsSSHConnection: true, @@ -134,12 +180,6 @@ GlRepository: "project-26", GlProjectPath: "group/private", }, - response: &accessverifier.Response{ - KeyId: 1, - KeyType: "key", - UserId: "6", - Username: "jane.doe", - }, want: map[string]string{ "key_id": "1", "key_type": "key", @@ -153,7 +193,7 @@ t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.response, tt.env) + ctx, cancel := tt.gc.PrepareContext(ctx, tt.repo, tt.env) defer cancel() md, exists := metadata.FromOutgoingContext(ctx) diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -22,6 +22,14 @@ return inFmt } +func logLevel(inLevel string) string { + if inLevel == "" { + return "info" + } + + return inLevel +} + func logFile(inFile string) string { if inFile == "" { return "stderr" @@ -35,7 +43,7 @@ log.WithFormatter(logFmt(cfg.LogFormat)), log.WithOutputName(logFile(cfg.LogFile)), log.WithTimezone(time.UTC), - log.WithLogLevel(cfg.LogLevel), + log.WithLogLevel(logLevel(cfg.LogLevel)), } } diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -30,9 +30,11 @@ tmpFile.Close() data, err := os.ReadFile(tmpFile.Name()) + dataStr := string(data) require.NoError(t, err) - require.Contains(t, string(data), `msg":"this is a test"`) - require.NotContains(t, string(data), `msg:":"debug log message"`) + require.Contains(t, dataStr, `"msg":"this is a test"`) + require.NotContains(t, dataStr, `"msg":"debug log message"`) + require.NotContains(t, dataStr, `"msg":"unknown log level`) } func TestConfigureWithDebugLogLevel(t *testing.T) { diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -9,36 +9,51 @@ ) const ( - namespace = "gitlab_shell" - sshdSubsystem = "sshd" - httpSubsystem = "http" + namespace = "gitlab_shell" + sshdSubsystem = "sshd" + httpSubsystem = "http" + gitalySubsystem = "gitaly" httpInFlightRequestsMetricName = "in_flight_requests" httpRequestsTotalMetricName = "requests_total" httpRequestDurationSecondsMetricName = "request_duration_seconds" - sshdConnectionsInFlightName = "in_flight_connections" - sshdConnectionDuration = "connection_duration_seconds" - sshdHitMaxSessions = "concurrent_limited_sessions_total" + sshdConnectionsInFlightName = "in_flight_connections" + sshdHitMaxSessionsName = "concurrent_limited_sessions_total" + sshdSessionDurationSecondsName = "session_duration_seconds" + sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + + sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" + sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" + + gitalyConnectionsTotalName = "connections_total" ) var ( - SshdConnectionDuration = promauto.NewHistogram( + SshdSessionDuration = promauto.NewHistogram( prometheus.HistogramOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdConnectionDuration, + Name: sshdSessionDurationSecondsName, Help: "A histogram of latencies for connections to gitlab-shell sshd.", Buckets: []float64{ - 0.005, /* 5ms */ - 0.025, /* 25ms */ - 0.1, /* 100ms */ - 0.5, /* 500ms */ - 1.0, /* 1s */ - 10.0, /* 10s */ - 30.0, /* 30s */ - 60.0, /* 1m */ - 300.0, /* 5m */ + 5.0, /* 5s */ + 30.0, /* 30s */ + 60.0, /* 1m */ + }, + }, + ) + + SshdSessionEstablishedDuration = promauto.NewHistogram( + prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdSessionEstablishedDurationSecondsName, + Help: "A histogram of latencies until session established to gitlab-shell sshd.", + Buckets: []float64{ + 0.5, /* 5ms */ + 1.0, /* 1s */ + 5.0, /* 5s */ }, }, ) @@ -56,11 +71,35 @@ prometheus.CounterOpts{ Namespace: namespace, Subsystem: sshdSubsystem, - Name: sshdHitMaxSessions, + Name: sshdHitMaxSessionsName, Help: "The number of times the concurrent sessions limit was hit in gitlab-shell sshd.", }, ) + SliSshdSessionsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsTotalName, + Help: "Number of SSH sessions that have been established", + }, + ) + + SliSshdSessionsErrorsTotal = promauto.NewCounter( + prometheus.CounterOpts{ + Name: sliSshdSessionsErrorsTotalName, + Help: "Number of SSH sessions that have failed", + }, + ) + + GitalyConnectionsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: gitalySubsystem, + Name: gitalyConnectionsTotalName, + Help: "Number of Gitaly connections that have been established", + }, + []string{"status"}, + ) + // The metrics and the buckets size are similar to the ones we have for handlers in Labkit // When the MR: https://gitlab.com/gitlab-org/labkit/-/merge_requests/150 is merged, // these metrics can be refactored out of Gitlab Shell code by using the helper function from Labkit diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,7 +2,6 @@ import ( "context" - "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" @@ -13,7 +12,6 @@ ) type connection struct { - begin time.Time concurrentSessions *semaphore.Weighted remoteAddr string } @@ -22,7 +20,6 @@ func newConnection(maxSessions int64, remoteAddr string) *connection { return &connection{ - begin: time.Now(), concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, } @@ -31,11 +28,6 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) - metrics.SshdConnectionsInFlight.Inc() - defer metrics.SshdConnectionsInFlight.Dec() - - defer metrics.SshdConnectionDuration.Observe(time.Since(c.begin).Seconds()) - for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,6 +22,7 @@ channel ssh.Channel gitlabKeyId string remoteAddr string + success bool // State managed by the session execCmd string @@ -182,6 +183,8 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} + s.success = status == 0 + s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -99,6 +99,7 @@ expectedExecCmd string sentRequestName string sentRequestPayload []byte + success bool }{ { desc: "invalid payload", @@ -111,6 +112,7 @@ expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), + success: true, }, } @@ -130,6 +132,7 @@ require.Equal(t, false, s.handleExec(context.Background(), r)) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) + require.Equal(t, tc.success, s.success) }) } } @@ -141,6 +144,7 @@ errMsg string gitlabKeyId string expectedExitCode uint32 + success bool }{ { desc: "fails to parse command", diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,6 +12,7 @@ "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -145,6 +146,20 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + success := false + + metrics.SshdConnectionsInFlight.Inc() + started := time.Now() + defer func() { + metrics.SshdConnectionsInFlight.Dec() + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + + metrics.SliSshdSessionsTotal.Inc() + if !success { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + }() + remoteAddr := nconn.RemoteAddr().String() defer s.wg.Done() @@ -164,7 +179,7 @@ ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) + sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) if err != nil { ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return @@ -172,8 +187,12 @@ go ssh.DiscardRequests(reqs) + var establishSessionDuration float64 conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + establishSessionDuration = time.Since(started).Seconds() + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) + session := &session{ cfg: s.Config, channel: channel, @@ -182,9 +201,28 @@ } session.handle(ctx, requests) + + success = session.success }) - ctxlog.Info("server: handleConn: done") + ctxlog.WithFields(log.Fields{ + "duration_s": time.Since(started).Seconds(), + "establish_session_duration_s": establishSessionDuration, + }).Info("server: handleConn: done") +} + +func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { + timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { + nconn.Close() + }) + defer func() { + // If time.Stop() equals false, that means that AfterFunc has been executed + if !timer.Stop() { + err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) + } + }() + + return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) } func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" "net/http/httptest" "os" @@ -134,6 +135,33 @@ require.Nil(t, s.Shutdown()) } +func TestLoginGraceTime(t *testing.T) { + s := setupServer(t) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Verify that the server shutdowns instantly without waiting for any connection to execute + // That means that the server doesn't have any connections to wait for + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -183,6 +211,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.LoginGraceTimeSeconds = 1 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652658086 -14400 # Mon May 16 03:41:26 2022 +0400 # Node ID b09a5bfed30e6b24b54b4233aa8b34a409288b52 # Parent 95f105751282580f695ff4bec8577de261720bbd Remove deprecated bundler-audit It's been removed in: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86704 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -92,9 +92,6 @@ gemnasium-dependency_scanning: rules: *workflow_rules -bundler-audit-dependency_scanning: - rules: *workflow_rules - # Secret Detection secret_detection: rules: *workflow_rules # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652687897 0 # Mon May 16 07:58:17 2022 +0000 # Node ID 69a1d91856762023270fdc879e015f95444acb2a # Parent 95f105751282580f695ff4bec8577de261720bbd # Parent b09a5bfed30e6b24b54b4233aa8b34a409288b52 Merge branch 'id-fix-ci-pipeline' into 'main' Remove deprecated bundler-audit See merge request gitlab-org/gitlab-shell!626 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -92,9 +92,6 @@ gemnasium-dependency_scanning: rules: *workflow_rules -bundler-audit-dependency_scanning: - rules: *workflow_rules - # Secret Detection secret_detection: rules: *workflow_rules # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652649472 -14400 # Mon May 16 01:17:52 2022 +0400 # Node ID abc89bd8192dce763944a2f6dd61371c08d75db6 # Parent 69a1d91856762023270fdc879e015f95444acb2a Return error from session handler diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -22,7 +22,7 @@ sconn *ssh.ServerConn } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) +type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { return &connection{ @@ -76,7 +76,12 @@ } }() - handler(ctx, channel, requests) + metrics.SliSshdSessionsTotal.Inc() + err := handler(ctx, channel, requests) + if err != nil { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + ctxlog.Info("connection: handle: done") }() } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -55,9 +55,14 @@ ssh.Conn sentRequestName string + waitErr error mu sync.Mutex } +func (f *fakeConn) Wait() error { + return f.waitErr +} + func (f *fakeConn) SentRequestName() string { f.mu.Lock() defer f.mu.Unlock() @@ -90,7 +95,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -128,8 +133,9 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test + return nil }) }() @@ -142,9 +148,10 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) + return nil }) require.True(t, channelHandled) @@ -160,8 +167,9 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true + return nil }) }() diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,7 +22,6 @@ channel ssh.Channel gitlabKeyId string remoteAddr string - success bool // State managed by the session execCmd string @@ -42,11 +41,12 @@ ExitStatus uint32 } -func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { +func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) error { ctxlog := log.ContextLogger(ctx) ctxlog.Debug("session: handle: entering request loop") + var err error for req := range requests { sessionLog := ctxlog.WithFields(log.Fields{ "bytesize": len(req.Payload), @@ -58,12 +58,14 @@ var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(ctx, req) + shouldContinue, err = s.handleEnv(ctx, req) case "exec": - shouldContinue = s.handleExec(ctx, req) + shouldContinue, err = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(ctx, s.handleShell(ctx, req)) + var status uint32 + status, err = s.handleShell(ctx, req) + s.exit(ctx, status) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -84,15 +86,17 @@ } ctxlog.Debug("session: handle: exiting request loop") + + return err } -func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error) { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") - return false + return false, err } switch envRequest.Name { @@ -113,23 +117,24 @@ ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, ).Debug("session: handleEnv: processed") - return true + return true, nil } -func (s *session) handleExec(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleExec(ctx context.Context, req *ssh.Request) (bool, error) { var execRequest execRequest if err := ssh.Unmarshal(req.Payload, &execRequest); err != nil { - return false + return false, err } s.execCmd = execRequest.Command - s.exit(ctx, s.handleShell(ctx, req)) + status, err := s.handleShell(ctx, req) + s.exit(ctx, status) - return false + return false, err } -func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { +func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, error) { ctxlog := log.ContextLogger(ctx) if req.WantReply { @@ -157,7 +162,7 @@ s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) } s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) - return 128 + return 128, err } cmdName := reflect.TypeOf(cmd).String() @@ -165,12 +170,12 @@ if err := cmd.Execute(ctx); err != nil { s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) - return 1 + return 1, err } ctxlog.Info("session: handleShell: command executed successfully") - return 0 + return 0, nil } func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { @@ -183,8 +188,6 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} - s.success = status == 0 - s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -3,6 +3,7 @@ import ( "bytes" "context" + "errors" "io" "net/http" "testing" @@ -60,22 +61,26 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedProtocolVersion string expectedResult bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Name of type envRequest"), expectedProtocolVersion: "1", expectedResult: false, }, { desc: "valid payload", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "2", expectedResult: true, }, { desc: "valid payload with forbidden env var", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "1", expectedResult: true, }, @@ -86,8 +91,11 @@ s := &session{gitProtocolVersion: "1"} r := &ssh.Request{Payload: tc.payload} - require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) - require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + shouldContinue, err := s.handleEnv(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResult, shouldContinue) + require.Equal(t, tc.expectedProtocolVersion, s.gitProtocolVersion) }) } } @@ -96,23 +104,24 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedExecCmd string sentRequestName string sentRequestPayload []byte - success bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Command of type execRequest"), expectedExecCmd: "", sentRequestName: "", }, { desc: "valid payload", payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedErr: nil, expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), - success: true, }, } @@ -129,47 +138,53 @@ } r := &ssh.Request{Payload: tc.payload} - require.Equal(t, false, s.handleExec(context.Background(), r)) + shouldContinue, err := s.handleExec(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, false, shouldContinue) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) - require.Equal(t, tc.success, s.success) }) } } func TestHandleShell(t *testing.T) { testCases := []struct { - desc string - cmd string - errMsg string - gitlabKeyId string - expectedExitCode uint32 - success bool + desc string + cmd string + errMsg string + gitlabKeyId string + expectedErrString string + expectedExitCode uint32 }{ { - desc: "fails to parse command", - cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + gitlabKeyId: "root", + expectedErrString: "Invalid SSH command: invalid command line string", + expectedExitCode: 128, }, { - desc: "specified command is unknown", - cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedErrString: "Disallowed command", + expectedExitCode: 128, }, { - desc: "fails to parse command", - cmd: "discover", - gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", - expectedExitCode: 1, + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedErrString: "Failed to get username: who='' is invalid", + expectedExitCode: 1, }, { - desc: "fails to parse command", - cmd: "discover", - errMsg: "", - gitlabKeyId: "root", - expectedExitCode: 0, + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedErrString: "", + expectedExitCode: 0, }, } @@ -186,7 +201,13 @@ } r := &ssh.Request{} - require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + exitCode, err := s.handleShell(context.Background(), r) + + if tc.expectedErrString != "" { + require.Equal(t, tc.expectedErrString, err.Error()) + } + + require.Equal(t, tc.expectedExitCode, exitCode) require.Equal(t, tc.errMsg, out.String()) }) } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -181,7 +181,7 @@ started := time.Now() var establishSessionDuration float64 conn := newConnection(s.Config, remoteAddr, sconn) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { establishSessionDuration = time.Since(started).Seconds() metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) @@ -192,11 +192,7 @@ remoteAddr: remoteAddr, } - metrics.SliSshdSessionsTotal.Inc() - session.handle(ctx, requests) - if !session.success { - metrics.SliSshdSessionsErrorsTotal.Inc() - } + return session.handle(ctx, requests) }) reason := sconn.Wait() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652650327 -14400 # Mon May 16 01:32:07 2022 +0400 # Node ID af39d7ea02da4bdd77c83b08b60e3efbeae2f810 # Parent abc89bd8192dce763944a2f6dd61371c08d75db6 Wait until all Gitaly sessions are executed If they haven't been executed within a timeout, we unblock the execution. Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/563 We have an issue when a lot of git clones operations get canceled. It was assumed that some clients close the connection just after all the data has been received from Git server. If there was a network delay and gitlab-sshd hadn't managed to gracefully close the connection, context get canceled and Gitaly cancels the execution and returns the error. Let's wait for a perion to allow Gitaly to gracefully complete the operation diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -15,19 +15,25 @@ const KeepAliveMsg = "keepalive@openssh.com" +var EOFTimeout = 10 * time.Second + type connection struct { cfg *config.Config concurrentSessions *semaphore.Weighted remoteAddr string sconn *ssh.ServerConn + maxSessions int64 } type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { + maxSessions := cfg.Server.ConcurrentSessionsLimit + return &connection{ cfg: cfg, - concurrentSessions: semaphore.NewWeighted(cfg.Server.ConcurrentSessionsLimit), + maxSessions: maxSessions, + concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, sconn: sconn, } @@ -85,6 +91,14 @@ ctxlog.Info("connection: handle: done") }() } + + // When a connection has been prematurely closed we block execution until all concurrent sessions are released + // in order to allow Gitaly complete the operations and close all the channels gracefully. + // If it didn't happen within timeout, we unblock the execution + // Related issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/563 + ctx, cancel := context.WithTimeout(ctx, EOFTimeout) + defer cancel() + c.concurrentSessions.Acquire(ctx, c.maxSessions) } func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -55,14 +55,9 @@ ssh.Conn sentRequestName string - waitErr error mu sync.Mutex } -func (f *fakeConn) Wait() error { - return f.waitErr -} - func (f *fakeConn) SentRequestName() string { f.mu.Lock() defer f.mu.Unlock() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652650600 -14400 # Mon May 16 01:36:40 2022 +0400 # Node ID 7a17aa4c8548a037a05e4f60d2d0095bc1a46485 # Parent af39d7ea02da4bdd77c83b08b60e3efbeae2f810 Log canceled requests into separate metrics When a request get canceled we don't want to consider it an error diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:9] { + for _, m := range ms[0:10] { actualNames = append(actualNames, m.GetName()) } @@ -47,6 +47,7 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -22,6 +22,7 @@ sshdHitMaxSessionsName = "concurrent_limited_sessions_total" sshdSessionDurationSecondsName = "session_duration_seconds" sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + sshdCanceledSessionsName = "canceled_sessions" sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" @@ -76,6 +77,15 @@ }, ) + SshdCanceledSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdCanceledSessionsName, + Help: "The number of canceled gitlab-sshd sessions.", + }, + ) + SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -6,6 +6,8 @@ "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -85,7 +87,11 @@ metrics.SliSshdSessionsTotal.Inc() err := handler(ctx, channel, requests) if err != nil { - metrics.SliSshdSessionsErrorsTotal.Inc() + if grpcstatus.Convert(err).Code() == grpccodes.Canceled { + metrics.SshdCanceledSessions.Inc() + } else { + metrics.SliSshdSessionsErrorsTotal.Inc() + } } ctxlog.Info("connection: handle: done") diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -7,10 +7,14 @@ "testing" "time" + "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) type rejectCall struct { @@ -189,3 +193,33 @@ require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) } + +func TestSessionsMetrics(t *testing.T) { + // Unfortunately, there is no working way to reset Counter (not CounterVec) + // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index + initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) + initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) + initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) + + newChannel := &fakeNewChannel{channelType: "session"} + + conn, chans := setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return errors.New("custom error") + }) + + require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return grpcstatus.Error(grpccodes.Canceled, "error") + }) + + require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) +} # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1652764543 0 # Tue May 17 05:15:43 2022 +0000 # Node ID 6604d04ecf6592621356721508f7337b190fd602 # Parent 69a1d91856762023270fdc879e015f95444acb2a # Parent 7a17aa4c8548a037a05e4f60d2d0095bc1a46485 Merge branch 'id-wait-until-gitaly-execution' into 'main' Wait until all Gitaly sessions are executed See merge request gitlab-org/gitlab-shell!624 diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:9] { + for _, m := range ms[0:10] { actualNames = append(actualNames, m.GetName()) } @@ -47,6 +47,7 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -22,6 +22,7 @@ sshdHitMaxSessionsName = "concurrent_limited_sessions_total" sshdSessionDurationSecondsName = "session_duration_seconds" sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + sshdCanceledSessionsName = "canceled_sessions" sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" @@ -76,6 +77,15 @@ }, ) + SshdCanceledSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdCanceledSessionsName, + Help: "The number of canceled gitlab-sshd sessions.", + }, + ) + SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -6,6 +6,8 @@ "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -15,19 +17,25 @@ const KeepAliveMsg = "keepalive@openssh.com" +var EOFTimeout = 10 * time.Second + type connection struct { cfg *config.Config concurrentSessions *semaphore.Weighted remoteAddr string sconn *ssh.ServerConn + maxSessions int64 } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) +type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { + maxSessions := cfg.Server.ConcurrentSessionsLimit + return &connection{ cfg: cfg, - concurrentSessions: semaphore.NewWeighted(cfg.Server.ConcurrentSessionsLimit), + maxSessions: maxSessions, + concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, sconn: sconn, } @@ -76,10 +84,27 @@ } }() - handler(ctx, channel, requests) + metrics.SliSshdSessionsTotal.Inc() + err := handler(ctx, channel, requests) + if err != nil { + if grpcstatus.Convert(err).Code() == grpccodes.Canceled { + metrics.SshdCanceledSessions.Inc() + } else { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + } + ctxlog.Info("connection: handle: done") }() } + + // When a connection has been prematurely closed we block execution until all concurrent sessions are released + // in order to allow Gitaly complete the operations and close all the channels gracefully. + // If it didn't happen within timeout, we unblock the execution + // Related issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/563 + ctx, cancel := context.WithTimeout(ctx, EOFTimeout) + defer cancel() + c.concurrentSessions.Acquire(ctx, c.maxSessions) } func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -7,10 +7,14 @@ "testing" "time" + "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) type rejectCall struct { @@ -90,7 +94,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -128,8 +132,9 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test + return nil }) }() @@ -142,9 +147,10 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) + return nil }) require.True(t, channelHandled) @@ -160,8 +166,9 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true + return nil }) }() @@ -186,3 +193,33 @@ require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) } + +func TestSessionsMetrics(t *testing.T) { + // Unfortunately, there is no working way to reset Counter (not CounterVec) + // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index + initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) + initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) + initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) + + newChannel := &fakeNewChannel{channelType: "session"} + + conn, chans := setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return errors.New("custom error") + }) + + require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return grpcstatus.Error(grpccodes.Canceled, "error") + }) + + require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) +} diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,7 +22,6 @@ channel ssh.Channel gitlabKeyId string remoteAddr string - success bool // State managed by the session execCmd string @@ -42,11 +41,12 @@ ExitStatus uint32 } -func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { +func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) error { ctxlog := log.ContextLogger(ctx) ctxlog.Debug("session: handle: entering request loop") + var err error for req := range requests { sessionLog := ctxlog.WithFields(log.Fields{ "bytesize": len(req.Payload), @@ -58,12 +58,14 @@ var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(ctx, req) + shouldContinue, err = s.handleEnv(ctx, req) case "exec": - shouldContinue = s.handleExec(ctx, req) + shouldContinue, err = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(ctx, s.handleShell(ctx, req)) + var status uint32 + status, err = s.handleShell(ctx, req) + s.exit(ctx, status) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -84,15 +86,17 @@ } ctxlog.Debug("session: handle: exiting request loop") + + return err } -func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error) { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") - return false + return false, err } switch envRequest.Name { @@ -113,23 +117,24 @@ ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, ).Debug("session: handleEnv: processed") - return true + return true, nil } -func (s *session) handleExec(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleExec(ctx context.Context, req *ssh.Request) (bool, error) { var execRequest execRequest if err := ssh.Unmarshal(req.Payload, &execRequest); err != nil { - return false + return false, err } s.execCmd = execRequest.Command - s.exit(ctx, s.handleShell(ctx, req)) + status, err := s.handleShell(ctx, req) + s.exit(ctx, status) - return false + return false, err } -func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { +func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, error) { ctxlog := log.ContextLogger(ctx) if req.WantReply { @@ -157,7 +162,7 @@ s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) } s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) - return 128 + return 128, err } cmdName := reflect.TypeOf(cmd).String() @@ -165,12 +170,12 @@ if err := cmd.Execute(ctx); err != nil { s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) - return 1 + return 1, err } ctxlog.Info("session: handleShell: command executed successfully") - return 0 + return 0, nil } func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { @@ -183,8 +188,6 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} - s.success = status == 0 - s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -3,6 +3,7 @@ import ( "bytes" "context" + "errors" "io" "net/http" "testing" @@ -60,22 +61,26 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedProtocolVersion string expectedResult bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Name of type envRequest"), expectedProtocolVersion: "1", expectedResult: false, }, { desc: "valid payload", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "2", expectedResult: true, }, { desc: "valid payload with forbidden env var", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "1", expectedResult: true, }, @@ -86,8 +91,11 @@ s := &session{gitProtocolVersion: "1"} r := &ssh.Request{Payload: tc.payload} - require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) - require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + shouldContinue, err := s.handleEnv(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResult, shouldContinue) + require.Equal(t, tc.expectedProtocolVersion, s.gitProtocolVersion) }) } } @@ -96,23 +104,24 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedExecCmd string sentRequestName string sentRequestPayload []byte - success bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Command of type execRequest"), expectedExecCmd: "", sentRequestName: "", }, { desc: "valid payload", payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedErr: nil, expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), - success: true, }, } @@ -129,47 +138,53 @@ } r := &ssh.Request{Payload: tc.payload} - require.Equal(t, false, s.handleExec(context.Background(), r)) + shouldContinue, err := s.handleExec(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, false, shouldContinue) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) - require.Equal(t, tc.success, s.success) }) } } func TestHandleShell(t *testing.T) { testCases := []struct { - desc string - cmd string - errMsg string - gitlabKeyId string - expectedExitCode uint32 - success bool + desc string + cmd string + errMsg string + gitlabKeyId string + expectedErrString string + expectedExitCode uint32 }{ { - desc: "fails to parse command", - cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + gitlabKeyId: "root", + expectedErrString: "Invalid SSH command: invalid command line string", + expectedExitCode: 128, }, { - desc: "specified command is unknown", - cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedErrString: "Disallowed command", + expectedExitCode: 128, }, { - desc: "fails to parse command", - cmd: "discover", - gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", - expectedExitCode: 1, + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedErrString: "Failed to get username: who='' is invalid", + expectedExitCode: 1, }, { - desc: "fails to parse command", - cmd: "discover", - errMsg: "", - gitlabKeyId: "root", - expectedExitCode: 0, + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedErrString: "", + expectedExitCode: 0, }, } @@ -186,7 +201,13 @@ } r := &ssh.Request{} - require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + exitCode, err := s.handleShell(context.Background(), r) + + if tc.expectedErrString != "" { + require.Equal(t, tc.expectedErrString, err.Error()) + } + + require.Equal(t, tc.expectedExitCode, exitCode) require.Equal(t, tc.errMsg, out.String()) }) } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -181,7 +181,7 @@ started := time.Now() var establishSessionDuration float64 conn := newConnection(s.Config, remoteAddr, sconn) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { establishSessionDuration = time.Since(started).Seconds() metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) @@ -192,11 +192,7 @@ remoteAddr: remoteAddr, } - metrics.SliSshdSessionsTotal.Inc() - session.handle(ctx, requests) - if !session.success { - metrics.SliSshdSessionsErrorsTotal.Inc() - } + return session.handle(ctx, requests) }) reason := sconn.Wait() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652764523 -14400 # Tue May 17 09:15:23 2022 +0400 # Node ID 55cc92a5c0c755a56eb60915b61866be19953812 # Parent 6604d04ecf6592621356721508f7337b190fd602 Release v14.3.0 - Remove deprecated bundler-audit !626 - Wait until all Gitaly sessions are executed !624 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.3.0 + +- Remove deprecated bundler-audit !626 +- Wait until all Gitaly sessions are executed !624 + v14.2.0 - Implement ClientKeepAlive option !622 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.2.0 +14.3.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652765061 0 # Tue May 17 05:24:21 2022 +0000 # Node ID c7cb78872f0da7b8083d01a00da0f1c478ee42e3 # Parent 6604d04ecf6592621356721508f7337b190fd602 # Parent 55cc92a5c0c755a56eb60915b61866be19953812 Merge branch 'id-release-14-3-0' into 'main' Release v14.3.0 See merge request gitlab-org/gitlab-shell!627 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.3.0 + +- Remove deprecated bundler-audit !626 +- Wait until all Gitaly sessions are executed !624 + v14.2.0 - Implement ClientKeepAlive option !622 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.2.0 +14.3.0 # HG changeset patch # User Costel Maxim <cmaxim@gitlab.com> # Date 1652798396 0 # Tue May 17 14:39:56 2022 +0000 # Node ID 7dfcbf548920a0081247253cea142b54b81ce42f # Parent c7cb78872f0da7b8083d01a00da0f1c478ee42e3 Resolve "Dependency update DOCKER_VERSION: 20.10.15" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ - '/ci/danger-review.yml' variables: - DOCKER_VERSION: "20.10.3" + DOCKER_VERSION: "20.10.15" workflow: rules: &workflow_rules # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652798397 0 # Tue May 17 14:39:57 2022 +0000 # Node ID e5060a36dafed0a2fb0fcdd3bd084f6cacd8c393 # Parent c7cb78872f0da7b8083d01a00da0f1c478ee42e3 # Parent 7dfcbf548920a0081247253cea142b54b81ce42f Merge branch '571-dependency-update-docker_version-20-10-15' into 'main' Resolve "Dependency update DOCKER_VERSION: 20.10.15" Closes #571 See merge request gitlab-org/gitlab-shell!628 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ - '/ci/danger-review.yml' variables: - DOCKER_VERSION: "20.10.3" + DOCKER_VERSION: "20.10.15" workflow: rules: &workflow_rules # HG changeset patch # User Sean Carroll <scarroll@gitlab.com> # Date 1652866142 -7200 # Wed May 18 11:29:02 2022 +0200 # Node ID 6ba21e8902c1b95e8fcc9f2b732e28365fb26044 # Parent e5060a36dafed0a2fb0fcdd3bd084f6cacd8c393 Git ignore .DS_Store diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ tags tmp/* vendor +.DS_Store # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652869843 0 # Wed May 18 10:30:43 2022 +0000 # Node ID 0e062368747082f13655ddebf21c03968e7d8727 # Parent e5060a36dafed0a2fb0fcdd3bd084f6cacd8c393 # Parent 6ba21e8902c1b95e8fcc9f2b732e28365fb26044 Merge branch 'ds-store' into 'main' Git ignore .DS_Store See merge request gitlab-org/gitlab-shell!629 diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ tags tmp/* vendor +.DS_Store # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652881192 -14400 # Wed May 18 17:39:52 2022 +0400 # Node ID f8a45bbc6d510998d0caf3c58d9ca4ca97394acc # Parent c7cb78872f0da7b8083d01a00da0f1c478ee42e3 Exclude API errors from error rate When API isn't responsible or the resource is not accessible (returns 404 or 403), then we shouldn't consider it as an error on gitlab-sshd side diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -37,6 +37,14 @@ userAgent string } +type ApiError struct { + Msg string +} + +func (e *ApiError) Error() string { + return e.Msg +} + func NewGitlabNetClient( user, password, @@ -101,9 +109,9 @@ parsedResponse := &ErrorResponse{} if err := json.NewDecoder(resp.Body).Decode(parsedResponse); err != nil { - return fmt.Errorf("Internal API error (%v)", resp.StatusCode) + return &ApiError{fmt.Sprintf("Internal API error (%v)", resp.StatusCode)} } else { - return fmt.Errorf(parsedResponse.Message) + return &ApiError{parsedResponse.Message} } } @@ -157,7 +165,7 @@ if err != nil { logger.WithError(err).Error("Internal API unreachable") - return nil, fmt.Errorf("Internal API unreachable") + return nil, &ApiError{"Internal API unreachable"} } if response != nil { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "time" "golang.org/x/crypto/ssh" @@ -9,6 +10,7 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -90,7 +92,10 @@ if grpcstatus.Convert(err).Code() == grpccodes.Canceled { metrics.SshdCanceledSessions.Inc() } else { - metrics.SliSshdSessionsErrorsTotal.Inc() + var apiError *client.ApiError + if !errors.As(err, &apiError) { + metrics.SliSshdSessionsErrorsTotal.Inc() + } } } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -13,6 +13,7 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -222,4 +223,14 @@ require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return &client.ApiError{"api error"} + }) + + require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) } # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652883067 0 # Wed May 18 14:11:07 2022 +0000 # Node ID db75b36effa4d6e4da4430be795b9d6eec9c2869 # Parent 0e062368747082f13655ddebf21c03968e7d8727 # Parent f8a45bbc6d510998d0caf3c58d9ca4ca97394acc Merge branch 'id-ignore-api-errors' into 'main' Exclude API errors from error rate See merge request gitlab-org/gitlab-shell!630 diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -37,6 +37,14 @@ userAgent string } +type ApiError struct { + Msg string +} + +func (e *ApiError) Error() string { + return e.Msg +} + func NewGitlabNetClient( user, password, @@ -101,9 +109,9 @@ parsedResponse := &ErrorResponse{} if err := json.NewDecoder(resp.Body).Decode(parsedResponse); err != nil { - return fmt.Errorf("Internal API error (%v)", resp.StatusCode) + return &ApiError{fmt.Sprintf("Internal API error (%v)", resp.StatusCode)} } else { - return fmt.Errorf(parsedResponse.Message) + return &ApiError{parsedResponse.Message} } } @@ -157,7 +165,7 @@ if err != nil { logger.WithError(err).Error("Internal API unreachable") - return nil, fmt.Errorf("Internal API unreachable") + return nil, &ApiError{"Internal API unreachable"} } if response != nil { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "time" "golang.org/x/crypto/ssh" @@ -9,6 +10,7 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -90,7 +92,10 @@ if grpcstatus.Convert(err).Code() == grpccodes.Canceled { metrics.SshdCanceledSessions.Inc() } else { - metrics.SliSshdSessionsErrorsTotal.Inc() + var apiError *client.ApiError + if !errors.As(err, &apiError) { + metrics.SliSshdSessionsErrorsTotal.Inc() + } } } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -13,6 +13,7 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -222,4 +223,14 @@ require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return &client.ApiError{"api error"} + }) + + require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652883182 -14400 # Wed May 18 18:13:02 2022 +0400 # Node ID 866b7fbfc6ca08f99d852bbc742a275489c683d9 # Parent db75b36effa4d6e4da4430be795b9d6eec9c2869 Release v14.3.1 - Exclude API errors from error rate !630 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.3.1 + +- Exclude API errors from error rate !630 + v14.3.0 - Remove deprecated bundler-audit !626 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.3.0 +14.3.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652884757 0 # Wed May 18 14:39:17 2022 +0000 # Node ID 0ea5c918a3bf8342b43bb8ec5e616bec564f41f4 # Parent db75b36effa4d6e4da4430be795b9d6eec9c2869 # Parent 866b7fbfc6ca08f99d852bbc742a275489c683d9 Merge branch 'id-release-14-3-1' into 'main' Release v14.3.1 See merge request gitlab-org/gitlab-shell!631 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.3.1 + +- Exclude API errors from error rate !630 + v14.3.0 - Remove deprecated bundler-audit !626 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.3.0 +14.3.1 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652907213 25200 # Wed May 18 13:53:33 2022 -0700 # Node ID 4c592bff8162f6bdd2dbfb4ae0624c81a8b221d6 # Parent 0ea5c918a3bf8342b43bb8ec5e616bec564f41f4 Update gitlab-org/golang-crypto module version This update pulls in: 1. https://gitlab.com/gitlab-org/golang-crypto/-/merge_requests/3, which syncs the module with upstream master and supports the new `curve25519-sha256@libssh.org` kex name. 2. https://gitlab.com/gitlab-org/golang-crypto/-/merge_requests/4, which adds: * MACs: hmac-sha2-512-etm@openssh.com, hmac-sha2-512 * Cipher: aes256-gcm@openssh.com Relates to https://gitlab.com/gitlab-org/gitlab-shell/-/issues/575 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -81,4 +81,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) -replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -888,8 +888,8 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac h1:qNUzqBTbEGGjF5Fp0NWz3rNmqamwchxM+QKUZYeOS1c= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652908785 0 # Wed May 18 21:19:45 2022 +0000 # Node ID 2a2ce010683a031623595b8ed3e740653d7f2057 # Parent 0ea5c918a3bf8342b43bb8ec5e616bec564f41f4 # Parent 4c592bff8162f6bdd2dbfb4ae0624c81a8b221d6 Merge branch 'sh-update-crypto-ver' into 'main' Update gitlab-org/golang-crypto module version See merge request gitlab-org/gitlab-shell!632 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -81,4 +81,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) -replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -888,8 +888,8 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac h1:qNUzqBTbEGGjF5Fp0NWz3rNmqamwchxM+QKUZYeOS1c= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652910576 -14400 # Thu May 19 01:49:36 2022 +0400 # Node ID 30df69d888ae6cdfff2057f321b437f8e36b5383 # Parent 2a2ce010683a031623595b8ed3e740653d7f2057 Allow configuring SSH server algorithms MACs, Ciphers and KEX algorithms now can be configured If the values are empty, reasonable defaults are used diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -84,6 +84,12 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" + # Specifies the available message authentication code algorithms that are used for protecting data integrity + macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] + # Specifies the available Key Exchange algorithms + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] + # Specified the ciphers allowed + ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -32,6 +32,9 @@ ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` + MACs []string `yaml:"macs"` + KexAlgorithms []string `yaml:"kex_algorithms"` + Ciphers []string `yaml:"ciphers"` } type HttpSettingsConfig struct { diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -16,6 +16,14 @@ "gitlab.com/gitlab-org/labkit/log" ) +var supportedMACs = []string{ + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1", +} + type serverConfig struct { cfg *config.Config hostKeys []ssh.Signer @@ -86,6 +94,20 @@ }, } + if len(s.cfg.Server.MACs) > 0 { + sshCfg.MACs = s.cfg.Server.MACs + } else { + sshCfg.MACs = supportedMACs + } + + if len(s.cfg.Server.KexAlgorithms) > 0 { + sshCfg.KeyExchanges = s.cfg.Server.KexAlgorithms + } + + if len(s.cfg.Server.Ciphers) > 0 { + sshCfg.Ciphers = s.cfg.Server.Ciphers + } + for _, key := range s.hostKeys { sshCfg.AddHostKey(key) } diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -80,6 +80,67 @@ } } +func TestDefaultAlgorithms(t *testing.T) { + srvCfg := &serverConfig{cfg: &config.Config{}} + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + require.Nil(t, sshServerConfig.KeyExchanges) + require.Nil(t, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + + defaultKeyExchanges := []string{ + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha256", + "diffie-hellman-group14-sha1", + } + require.Equal(t, defaultKeyExchanges, sshServerConfig.KeyExchanges) + + defaultCiphers := []string{ + "aes128-gcm@openssh.com", + "chacha20-poly1305@openssh.com", + "aes256-gcm@openssh.com", + "aes128-ctr", + "aes192-ctr", + "aes256-ctr", + } + require.Equal(t, defaultCiphers, sshServerConfig.Ciphers) +} + +func TestCustomAlgorithms(t *testing.T) { + customMACs := []string{"hmac-sha2-512-etm@openssh.com"} + customKexAlgos := []string{"curve25519-sha256"} + customCiphers := []string{"aes256-gcm@openssh.com"} + + srvCfg := &serverConfig{ + cfg: &config.Config{ + Server: config.ServerConfig{ + MACs: customMACs, + KexAlgorithms: customKexAlgos, + Ciphers: customCiphers, + }, + }, + } + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) +} + func rsaPublicKey(t *testing.T) ssh.PublicKey { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652914523 0 # Wed May 18 22:55:23 2022 +0000 # Node ID 94ce2390d9e30cc09306a560ef89d55b376e410a # Parent 2a2ce010683a031623595b8ed3e740653d7f2057 # Parent 30df69d888ae6cdfff2057f321b437f8e36b5383 Merge branch 'id-configure-algorithms' into 'main' Allow configuring SSH server algorithms See merge request gitlab-org/gitlab-shell!633 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -84,6 +84,12 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" + # Specifies the available message authentication code algorithms that are used for protecting data integrity + macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] + # Specifies the available Key Exchange algorithms + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] + # Specified the ciphers allowed + ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -32,6 +32,9 @@ ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` + MACs []string `yaml:"macs"` + KexAlgorithms []string `yaml:"kex_algorithms"` + Ciphers []string `yaml:"ciphers"` } type HttpSettingsConfig struct { diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -16,6 +16,14 @@ "gitlab.com/gitlab-org/labkit/log" ) +var supportedMACs = []string{ + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1", +} + type serverConfig struct { cfg *config.Config hostKeys []ssh.Signer @@ -86,6 +94,20 @@ }, } + if len(s.cfg.Server.MACs) > 0 { + sshCfg.MACs = s.cfg.Server.MACs + } else { + sshCfg.MACs = supportedMACs + } + + if len(s.cfg.Server.KexAlgorithms) > 0 { + sshCfg.KeyExchanges = s.cfg.Server.KexAlgorithms + } + + if len(s.cfg.Server.Ciphers) > 0 { + sshCfg.Ciphers = s.cfg.Server.Ciphers + } + for _, key := range s.hostKeys { sshCfg.AddHostKey(key) } diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -80,6 +80,67 @@ } } +func TestDefaultAlgorithms(t *testing.T) { + srvCfg := &serverConfig{cfg: &config.Config{}} + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + require.Nil(t, sshServerConfig.KeyExchanges) + require.Nil(t, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + + defaultKeyExchanges := []string{ + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha256", + "diffie-hellman-group14-sha1", + } + require.Equal(t, defaultKeyExchanges, sshServerConfig.KeyExchanges) + + defaultCiphers := []string{ + "aes128-gcm@openssh.com", + "chacha20-poly1305@openssh.com", + "aes256-gcm@openssh.com", + "aes128-ctr", + "aes192-ctr", + "aes256-ctr", + } + require.Equal(t, defaultCiphers, sshServerConfig.Ciphers) +} + +func TestCustomAlgorithms(t *testing.T) { + customMACs := []string{"hmac-sha2-512-etm@openssh.com"} + customKexAlgos := []string{"curve25519-sha256"} + customCiphers := []string{"aes256-gcm@openssh.com"} + + srvCfg := &serverConfig{ + cfg: &config.Config{ + Server: config.ServerConfig{ + MACs: customMACs, + KexAlgorithms: customKexAlgos, + Ciphers: customCiphers, + }, + }, + } + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) +} + func rsaPublicKey(t *testing.T) ssh.PublicKey { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652914696 -14400 # Thu May 19 02:58:16 2022 +0400 # Node ID b76642ca4efcde8a23116aed75a56594c1504dd9 # Parent 94ce2390d9e30cc09306a560ef89d55b376e410a Release 14.4.0 - Allow configuring SSH server algorithms !633 - Update gitlab-org/golang-crypto module version !632 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.4.0 + +- Allow configuring SSH server algorithms !633 +- Update gitlab-org/golang-crypto module version !632 + v14.3.1 - Exclude API errors from error rate !630 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.3.1 +14.4.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652915139 0 # Wed May 18 23:05:39 2022 +0000 # Node ID b5a0002e1a3887d92469d212c04d461bda32c6ef # Parent 94ce2390d9e30cc09306a560ef89d55b376e410a # Parent b76642ca4efcde8a23116aed75a56594c1504dd9 Merge branch 'id-release-14-4-0' into 'main' Release 14.4.0 See merge request gitlab-org/gitlab-shell!634 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.4.0 + +- Allow configuring SSH server algorithms !633 +- Update gitlab-org/golang-crypto module version !632 + v14.3.1 - Exclude API errors from error rate !630 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.3.1 +14.4.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652951065 -14400 # Thu May 19 13:04:25 2022 +0400 # Node ID 3a4948692b5d655284883e7d173f4b2a7174f683 # Parent b5a0002e1a3887d92469d212c04d461bda32c6ef Allow specifying formatted durations in config - If an integer is specified, we assume that these are seconds - A duration of format "500ms", "10s", "1m", etc... accepted diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -99,11 +99,12 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + gracePeriod := time.Duration(cfg.Server.GracePeriod) + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": gracePeriod.Seconds(), "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() - <-time.After(cfg.Server.GracePeriod()) + <-time.After(gracePeriod) cancel() diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,20 +21,22 @@ defaultSecretFileName = ".gitlab_shell_secret" ) +type yamlDuration time.Duration + type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - ProxyPolicy string `yaml:"proxy_policy,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` - MACs []string `yaml:"macs"` - KexAlgorithms []string `yaml:"kex_algorithms"` - Ciphers []string `yaml:"ciphers"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveInterval yamlDuration `yaml:"client_alive_interval,omitempty"` + GracePeriod yamlDuration `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` + MACs []string `yaml:"macs"` + KexAlgorithms []string `yaml:"kex_algorithms"` + Ciphers []string `yaml:"ciphers"` } type HttpSettingsConfig struct { @@ -79,13 +81,13 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ClientAliveIntervalSeconds: 15, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriod: yamlDuration(10 * time.Second), + ClientAliveInterval: yamlDuration(15 * time.Second), + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -94,12 +96,15 @@ } ) -func (sc *ServerConfig) ClientAliveInterval() time.Duration { - return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second -} +func (d *yamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { + var intDuration int + if err := unmarshal(&intDuration); err != nil { + return unmarshal((*time.Duration)(d)) + } -func (sc *ServerConfig) GracePeriod() time.Duration { - return time.Duration(sc.GracePeriodSeconds) * time.Second + *d = yamlDuration(time.Duration(intDuration) * time.Second) + + return nil } func (c *Config) ApplyGlobalState() { diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -3,7 +3,9 @@ import ( "os" "testing" + "time" + yaml "gopkg.in/yaml.v2" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -58,3 +60,39 @@ require.Equal(t, expectedMetricNames, actualNames) } + +func TestNewFromDir(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + cfg, err := NewFromDir(testhelper.TestRoot) + require.NoError(t, err) + + require.Equal(t, 10 * time.Second, time.Duration(cfg.Server.GracePeriod)) + require.Equal(t, 1 * time.Minute, time.Duration(cfg.Server.ClientAliveInterval)) +} + +func TestYAMLDuration(t *testing.T) { + testCases := []struct{ + desc string + data string + duration time.Duration + }{ + {"seconds assumed by default", "duration: 10", 10 * time.Second}, + {"milliseconds are parsed", "duration: 500ms", 500 * time.Millisecond}, + {"minutes are parsed", "duration: 1m", 1 * time.Minute}, + } + + type durationCfg struct { + Duration yamlDuration `yaml:"duration"` + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + var cfg durationCfg + err := yaml.Unmarshal([]byte(tc.data), &cfg) + require.NoError(t, err) + + require.Equal(t, tc.duration, time.Duration(cfg.Duration)) + }) + } +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -46,8 +46,8 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) - if c.cfg.Server.ClientAliveIntervalSeconds > 0 { - ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) + if c.cfg.Server.ClientAliveInterval > 0 { + ticker := time.NewTicker(time.Duration(c.cfg.Server.ClientAliveInterval)) defer ticker.Stop() go c.sendKeepAliveMsg(ctx, ticker) } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -80,7 +80,7 @@ } func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum}} conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) chans := make(chan ssh.NewChannel, 1) diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -265,7 +265,6 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) diff --git a/internal/testhelper/testdata/testroot/config.yml b/internal/testhelper/testdata/testroot/config.yml --- a/internal/testhelper/testdata/testroot/config.yml +++ b/internal/testhelper/testdata/testroot/config.yml @@ -0,0 +1,3 @@ +sshd: + grace_period: 10 + client_alive_interval: 1m # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1652951414 -14400 # Thu May 19 13:10:14 2022 +0400 # Node ID 615e6c9ba39d727a4f4941c36a00aa83011bacd6 # Parent 3a4948692b5d655284883e7d173f4b2a7174f683 Make ProxyHeaderTimeout configurable Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/576 ProxyHeaderTimeout must be small to avoid DoS risk Let's make the value configurable and 500ms by default diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -80,6 +80,8 @@ client_alive_interval: 15 # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. grace_period: 10 + # A short timeout to decide to abort the connection if the protocol header is not seen within it. Defaults to 500ms + proxy_header_timeout: 500ms # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -31,6 +31,7 @@ ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` ClientAliveInterval yamlDuration `yaml:"client_alive_interval,omitempty"` GracePeriod yamlDuration `yaml:"grace_period"` + ProxyHeaderTimeout yamlDuration `yaml:"proxy_header_timeout"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` @@ -86,6 +87,7 @@ ConcurrentSessionsLimit: 10, GracePeriod: yamlDuration(10 * time.Second), ClientAliveInterval: yamlDuration(15 * time.Second), + ProxyHeaderTimeout: yamlDuration(500 * time.Millisecond), ReadinessProbe: "/start", LivenessProbe: "/health", HostKeyFiles: []string{ diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -5,9 +5,9 @@ "testing" "time" - yaml "gopkg.in/yaml.v2" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" + yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" @@ -67,14 +67,15 @@ cfg, err := NewFromDir(testhelper.TestRoot) require.NoError(t, err) - require.Equal(t, 10 * time.Second, time.Duration(cfg.Server.GracePeriod)) - require.Equal(t, 1 * time.Minute, time.Duration(cfg.Server.ClientAliveInterval)) + require.Equal(t, 10*time.Second, time.Duration(cfg.Server.GracePeriod)) + require.Equal(t, 1*time.Minute, time.Duration(cfg.Server.ClientAliveInterval)) + require.Equal(t, 500*time.Millisecond, time.Duration(cfg.Server.ProxyHeaderTimeout)) } func TestYAMLDuration(t *testing.T) { - testCases := []struct{ - desc string - data string + testCases := []struct { + desc string + data string duration time.Duration }{ {"seconds assumed by default", "duration: 10", 10 * time.Second}, diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -26,7 +26,6 @@ StatusReady StatusOnShutdown StatusClosed - ProxyHeaderTimeout = 90 * time.Second ) type Server struct { @@ -97,7 +96,7 @@ sshListener = &proxyproto.Listener{ Listener: sshListener, Policy: s.requirePolicy, - ReadHeaderTimeout: ProxyHeaderTimeout, + ReadHeaderTimeout: time.Duration(s.Config.Server.ProxyHeaderTimeout), } log.ContextLogger(ctx).Info("Proxy protocol is enabled") diff --git a/internal/testhelper/testdata/testroot/config.yml b/internal/testhelper/testdata/testroot/config.yml --- a/internal/testhelper/testdata/testroot/config.yml +++ b/internal/testhelper/testdata/testroot/config.yml @@ -1,3 +1,4 @@ sshd: grace_period: 10 client_alive_interval: 1m + proxy_header_timeout: 500ms # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652972660 0 # Thu May 19 15:04:20 2022 +0000 # Node ID 615b574a746d29556dfca756724aa990c7a3cc50 # Parent b5a0002e1a3887d92469d212c04d461bda32c6ef # Parent 615e6c9ba39d727a4f4941c36a00aa83011bacd6 Merge branch 'id-fix-proxy-header-timeout' into 'main' Make ProxyHeaderTimeout configurable See merge request gitlab-org/gitlab-shell!635 diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -99,11 +99,12 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + gracePeriod := time.Duration(cfg.Server.GracePeriod) + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": gracePeriod.Seconds(), "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() - <-time.After(cfg.Server.GracePeriod()) + <-time.After(gracePeriod) cancel() diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -80,6 +80,8 @@ client_alive_interval: 15 # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. grace_period: 10 + # A short timeout to decide to abort the connection if the protocol header is not seen within it. Defaults to 500ms + proxy_header_timeout: 500ms # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,20 +21,23 @@ defaultSecretFileName = ".gitlab_shell_secret" ) +type yamlDuration time.Duration + type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - ProxyPolicy string `yaml:"proxy_policy,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` - MACs []string `yaml:"macs"` - KexAlgorithms []string `yaml:"kex_algorithms"` - Ciphers []string `yaml:"ciphers"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveInterval yamlDuration `yaml:"client_alive_interval,omitempty"` + GracePeriod yamlDuration `yaml:"grace_period"` + ProxyHeaderTimeout yamlDuration `yaml:"proxy_header_timeout"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` + MACs []string `yaml:"macs"` + KexAlgorithms []string `yaml:"kex_algorithms"` + Ciphers []string `yaml:"ciphers"` } type HttpSettingsConfig struct { @@ -79,13 +82,14 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ClientAliveIntervalSeconds: 15, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriod: yamlDuration(10 * time.Second), + ClientAliveInterval: yamlDuration(15 * time.Second), + ProxyHeaderTimeout: yamlDuration(500 * time.Millisecond), + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -94,12 +98,15 @@ } ) -func (sc *ServerConfig) ClientAliveInterval() time.Duration { - return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second -} +func (d *yamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { + var intDuration int + if err := unmarshal(&intDuration); err != nil { + return unmarshal((*time.Duration)(d)) + } -func (sc *ServerConfig) GracePeriod() time.Duration { - return time.Duration(sc.GracePeriodSeconds) * time.Second + *d = yamlDuration(time.Duration(intDuration) * time.Second) + + return nil } func (c *Config) ApplyGlobalState() { diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -3,9 +3,11 @@ import ( "os" "testing" + "time" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" + yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" @@ -58,3 +60,40 @@ require.Equal(t, expectedMetricNames, actualNames) } + +func TestNewFromDir(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + cfg, err := NewFromDir(testhelper.TestRoot) + require.NoError(t, err) + + require.Equal(t, 10*time.Second, time.Duration(cfg.Server.GracePeriod)) + require.Equal(t, 1*time.Minute, time.Duration(cfg.Server.ClientAliveInterval)) + require.Equal(t, 500*time.Millisecond, time.Duration(cfg.Server.ProxyHeaderTimeout)) +} + +func TestYAMLDuration(t *testing.T) { + testCases := []struct { + desc string + data string + duration time.Duration + }{ + {"seconds assumed by default", "duration: 10", 10 * time.Second}, + {"milliseconds are parsed", "duration: 500ms", 500 * time.Millisecond}, + {"minutes are parsed", "duration: 1m", 1 * time.Minute}, + } + + type durationCfg struct { + Duration yamlDuration `yaml:"duration"` + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + var cfg durationCfg + err := yaml.Unmarshal([]byte(tc.data), &cfg) + require.NoError(t, err) + + require.Equal(t, tc.duration, time.Duration(cfg.Duration)) + }) + } +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -46,8 +46,8 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) - if c.cfg.Server.ClientAliveIntervalSeconds > 0 { - ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) + if c.cfg.Server.ClientAliveInterval > 0 { + ticker := time.NewTicker(time.Duration(c.cfg.Server.ClientAliveInterval)) defer ticker.Stop() go c.sendKeepAliveMsg(ctx, ticker) } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -80,7 +80,7 @@ } func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum}} conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) chans := make(chan ssh.NewChannel, 1) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -26,7 +26,6 @@ StatusReady StatusOnShutdown StatusClosed - ProxyHeaderTimeout = 90 * time.Second ) type Server struct { @@ -97,7 +96,7 @@ sshListener = &proxyproto.Listener{ Listener: sshListener, Policy: s.requirePolicy, - ReadHeaderTimeout: ProxyHeaderTimeout, + ReadHeaderTimeout: time.Duration(s.Config.Server.ProxyHeaderTimeout), } log.ContextLogger(ctx).Info("Proxy protocol is enabled") diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -265,7 +265,6 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) diff --git a/internal/testhelper/testdata/testroot/config.yml b/internal/testhelper/testdata/testroot/config.yml --- a/internal/testhelper/testdata/testroot/config.yml +++ b/internal/testhelper/testdata/testroot/config.yml @@ -0,0 +1,4 @@ +sshd: + grace_period: 10 + client_alive_interval: 1m + proxy_header_timeout: 500ms # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652984464 25200 # Thu May 19 11:21:04 2022 -0700 # Node ID 49a5f84c0ebe727653990d66163f182d1b3468dc # Parent 615b574a746d29556dfca756724aa990c7a3cc50 Release 14.5.0 - Make ProxyHeaderTimeout configurable !635 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.5.0 + +- Make ProxyHeaderTimeout configurable !635 + v14.4.0 - Allow configuring SSH server algorithms !633 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.4.0 +14.5.0 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1652984905 0 # Thu May 19 18:28:25 2022 +0000 # Node ID c1e06d31b6ef53cea0f58afa656b99c22fd38743 # Parent 615b574a746d29556dfca756724aa990c7a3cc50 # Parent 49a5f84c0ebe727653990d66163f182d1b3468dc Merge branch 'sh-release-14.5.0' into 'main' Release 14.5.0 See merge request gitlab-org/gitlab-shell!636 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.5.0 + +- Make ProxyHeaderTimeout configurable !635 + v14.4.0 - Allow configuring SSH server algorithms !633 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.4.0 +14.5.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653065479 -14400 # Fri May 20 20:51:19 2022 +0400 # Node ID 20969ab322f10de98b2225800ec8d3c9e244bd3c # Parent c1e06d31b6ef53cea0f58afa656b99c22fd38743 Narrow supported kex algorithms We don't support diffie-hellman-group14-sha1 via OpenSSH currently Let's avoid introducing it in gitlab-sshd because it's using weak hashing algorithm diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -89,7 +89,7 @@ # Specifies the available message authentication code algorithms that are used for protecting data integrity macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] # Specifies the available Key Exchange algorithms - kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256] # Specified the ciphers allowed ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -16,13 +16,24 @@ "gitlab.com/gitlab-org/labkit/log" ) -var supportedMACs = []string{ - "hmac-sha2-256-etm@openssh.com", - "hmac-sha2-512-etm@openssh.com", - "hmac-sha2-256", - "hmac-sha2-512", - "hmac-sha1", -} +var ( + supportedMACs = []string{ + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1", + } + + supportedKeyExchanges = []string{ + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha256", + } +) type serverConfig struct { cfg *config.Config @@ -102,6 +113,8 @@ if len(s.cfg.Server.KexAlgorithms) > 0 { sshCfg.KeyExchanges = s.cfg.Server.KexAlgorithms + } else { + sshCfg.KeyExchanges = supportedKeyExchanges } if len(s.cfg.Server.Ciphers) > 0 { diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -85,23 +85,13 @@ sshServerConfig := srvCfg.get(context.Background()) require.Equal(t, supportedMACs, sshServerConfig.MACs) - require.Nil(t, sshServerConfig.KeyExchanges) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) require.Nil(t, sshServerConfig.Ciphers) sshServerConfig.SetDefaults() require.Equal(t, supportedMACs, sshServerConfig.MACs) - - defaultKeyExchanges := []string{ - "curve25519-sha256", - "curve25519-sha256@libssh.org", - "ecdh-sha2-nistp256", - "ecdh-sha2-nistp384", - "ecdh-sha2-nistp521", - "diffie-hellman-group14-sha256", - "diffie-hellman-group14-sha1", - } - require.Equal(t, defaultKeyExchanges, sshServerConfig.KeyExchanges) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) defaultCiphers := []string{ "aes128-gcm@openssh.com", # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653066024 0 # Fri May 20 17:00:24 2022 +0000 # Node ID 8f6f9f16dc098a781d4b98a6b91b8a2c78037d50 # Parent c1e06d31b6ef53cea0f58afa656b99c22fd38743 # Parent 20969ab322f10de98b2225800ec8d3c9e244bd3c Merge branch 'id-set-supported-kex-algos' into 'main' Narrow supported kex algorithms See merge request gitlab-org/gitlab-shell!638 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -89,7 +89,7 @@ # Specifies the available message authentication code algorithms that are used for protecting data integrity macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] # Specifies the available Key Exchange algorithms - kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256] # Specified the ciphers allowed ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -16,13 +16,24 @@ "gitlab.com/gitlab-org/labkit/log" ) -var supportedMACs = []string{ - "hmac-sha2-256-etm@openssh.com", - "hmac-sha2-512-etm@openssh.com", - "hmac-sha2-256", - "hmac-sha2-512", - "hmac-sha1", -} +var ( + supportedMACs = []string{ + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1", + } + + supportedKeyExchanges = []string{ + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha256", + } +) type serverConfig struct { cfg *config.Config @@ -102,6 +113,8 @@ if len(s.cfg.Server.KexAlgorithms) > 0 { sshCfg.KeyExchanges = s.cfg.Server.KexAlgorithms + } else { + sshCfg.KeyExchanges = supportedKeyExchanges } if len(s.cfg.Server.Ciphers) > 0 { diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -85,23 +85,13 @@ sshServerConfig := srvCfg.get(context.Background()) require.Equal(t, supportedMACs, sshServerConfig.MACs) - require.Nil(t, sshServerConfig.KeyExchanges) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) require.Nil(t, sshServerConfig.Ciphers) sshServerConfig.SetDefaults() require.Equal(t, supportedMACs, sshServerConfig.MACs) - - defaultKeyExchanges := []string{ - "curve25519-sha256", - "curve25519-sha256@libssh.org", - "ecdh-sha2-nistp256", - "ecdh-sha2-nistp384", - "ecdh-sha2-nistp521", - "diffie-hellman-group14-sha256", - "diffie-hellman-group14-sha1", - } - require.Equal(t, defaultKeyExchanges, sshServerConfig.KeyExchanges) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) defaultCiphers := []string{ "aes128-gcm@openssh.com", # HG changeset patch # User Hendrik Meyer <t4cc0re@gitlab.com> # Date 1653104624 0 # Sat May 21 03:43:44 2022 +0000 # Node ID 3f5e048b2ab5bb122761a7d63d834e0a60880355 # Parent 8f6f9f16dc098a781d4b98a6b91b8a2c78037d50 Introduce a GitLab-SSHD server version during handshake diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -103,6 +103,7 @@ }, }, nil }, + ServerVersion: "SSH-2.0-GitLab-SSHD", } if len(s.cfg.Server.MACs) > 0 { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653104624 0 # Sat May 21 03:43:44 2022 +0000 # Node ID 236ca48fc6332d2da46c34134fc09d773d352196 # Parent 8f6f9f16dc098a781d4b98a6b91b8a2c78037d50 # Parent 3f5e048b2ab5bb122761a7d63d834e0a60880355 Merge branch 'T4cC0re-main-patch-11870' into 'main' Introduce a GitLab-SSHD server version during handshake See merge request gitlab-org/gitlab-shell!640 diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -103,6 +103,7 @@ }, }, nil }, + ServerVersion: "SSH-2.0-GitLab-SSHD", } if len(s.cfg.Server.MACs) > 0 { # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653085917 25200 # Fri May 20 15:31:57 2022 -0700 # Node ID e6c3ba396f7cf96434e60197f1443e62fe8cb80f # Parent 8f6f9f16dc098a781d4b98a6b91b8a2c78037d50 Downgrade host key mismatch messages from warning to debug In production, we often see SSH key scans requesting host key algorithms that we don't support, such as `sk-ssh-ed25519@openssh.com` or `sk-ecdsa-sha2-nistp256@openssh.com`. These messages might be useful if someone forgets to configure a host key that should be supported, but most of the time they are noise. This commit downgrades these messages to DEBUG. Relates to https://gitlab.com/gitlab-org/gitlab-shell/-/issues/581 Changelog: changed diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.1 + github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 gitlab.com/gitlab-org/labkit v1.14.0 @@ -59,7 +60,6 @@ github.com/prometheus/procfs v0.7.3 // indirect github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect github.com/shirou/gopsutil/v3 v3.21.2 // indirect - github.com/sirupsen/logrus v1.8.1 // 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 diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,6 +10,7 @@ "time" "github.com/pires/go-proxyproto" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -38,6 +39,18 @@ serverConfig *serverConfig } +func logSSHInitError(ctxlog *logrus.Entry, err error) { + msg := "server: handleConn: failed to initialize SSH connection" + + logger := ctxlog.WithError(err) + + if strings.Contains(err.Error(), "no common algorithm for host key") { + logger.Debug(msg) + } else { + logger.Warn(msg) + } +} + func NewServer(cfg *config.Config) (*Server, error) { serverConfig, err := newServerConfig(cfg) if err != nil { @@ -172,7 +185,7 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") + logSSHInitError(ctxlog, err) return } go ssh.DiscardRequests(reqs) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653086772 25200 # Fri May 20 15:46:12 2022 -0700 # Node ID f6c346f0e4fcc9e178042f0a02cc349339dd9eba # Parent e6c3ba396f7cf96434e60197f1443e62fe8cb80f Downgrade handleConn start message to debug This message doesn't provide that much value, so let's just drop it. diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -181,7 +181,7 @@ } }() - ctxlog.Info("server: handleConn: start") + ctxlog.Debug("server: handleConn: start") sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653109080 0 # Sat May 21 04:58:00 2022 +0000 # Node ID f32f24a0e5383a503775155b9fc08d7dc3b8b887 # Parent 236ca48fc6332d2da46c34134fc09d773d352196 # Parent f6c346f0e4fcc9e178042f0a02cc349339dd9eba Merge branch 'sh-downgrade-host-key-errors' into 'main' Downgrade host key mismatch messages from warning to debug See merge request gitlab-org/gitlab-shell!639 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.1 + github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 gitlab.com/gitlab-org/labkit v1.14.0 @@ -59,7 +60,6 @@ github.com/prometheus/procfs v0.7.3 // indirect github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect github.com/shirou/gopsutil/v3 v3.21.2 // indirect - github.com/sirupsen/logrus v1.8.1 // 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 diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,6 +10,7 @@ "time" "github.com/pires/go-proxyproto" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -38,6 +39,18 @@ serverConfig *serverConfig } +func logSSHInitError(ctxlog *logrus.Entry, err error) { + msg := "server: handleConn: failed to initialize SSH connection" + + logger := ctxlog.WithError(err) + + if strings.Contains(err.Error(), "no common algorithm for host key") { + logger.Debug(msg) + } else { + logger.Warn(msg) + } +} + func NewServer(cfg *config.Config) (*Server, error) { serverConfig, err := newServerConfig(cfg) if err != nil { @@ -168,11 +181,11 @@ } }() - ctxlog.Info("server: handleConn: start") + ctxlog.Debug("server: handleConn: start") sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") + logSSHInitError(ctxlog, err) return } go ssh.DiscardRequests(reqs) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653108915 -14400 # Sat May 21 08:55:15 2022 +0400 # Node ID 3b1e131ec2437c044518d368bda770f2f0185e0f # Parent f32f24a0e5383a503775155b9fc08d7dc3b8b887 Display constistently in gitlab-sshd and gitlab-shell - Use console package to format the errors in gitlab-sshd - Suppress internal Gitaly errors in client output diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -58,13 +58,11 @@ exitStatus, err := handler(childCtx, conn) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { - ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") - return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + if grpcstatus.Code(err) == grpccodes.Unavailable { + return grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.") } - - ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") } return err diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -84,10 +84,8 @@ }, ) - expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") - err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) - - require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, grpcstatus.Error(grpccodes.Unavailable, "error"))) + require.Equal(t, err, grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.")) } func TestRunGitalyCommandMetadata(t *testing.T) { diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -8,11 +8,14 @@ "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -158,10 +161,12 @@ cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) if err != nil { - if !errors.Is(err, disallowedcommand.Error) { - s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) + if errors.Is(err, disallowedcommand.Error) { + s.toStderr(ctx, "ERROR: Unknown command: %v\n", s.execCmd) + } else { + s.toStderr(ctx, "ERROR: Failed to parse command: %v\n", err.Error()) } - s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) + return 128, err } @@ -169,7 +174,11 @@ ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") if err := cmd.Execute(ctx); err != nil { - s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) + grpcStatus := grpcstatus.Convert(err) + if grpcStatus.Code() != grpccodes.Internal { + s.toStderr(ctx, "ERROR: %v\n", grpcStatus.Message()) + } + return 1, err } @@ -181,7 +190,7 @@ func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { out := fmt.Sprintf(format, args...) log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") - fmt.Fprint(s.channel.Stderr(), out) + console.DisplayWarningMessage(out, s.channel.Stderr()) } func (s *session) exit(ctx context.Context, status uint32) { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -13,6 +13,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/console" ) type fakeChannel struct { @@ -160,14 +161,14 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + errMsg: "ERROR: Failed to parse command: Invalid SSH command: invalid command line string\n", gitlabKeyId: "root", expectedErrString: "Invalid SSH command: invalid command line string", expectedExitCode: 128, }, { desc: "specified command is unknown", cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", + errMsg: "ERROR: Unknown command: unknown-command\n", gitlabKeyId: "root", expectedErrString: "Disallowed command", expectedExitCode: 128, @@ -175,7 +176,7 @@ desc: "fails to parse command", cmd: "discover", gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + errMsg: "ERROR: Failed to get username: who='' is invalid\n", expectedErrString: "Failed to get username: who='' is invalid", expectedExitCode: 1, }, { @@ -208,7 +209,14 @@ } require.Equal(t, tc.expectedExitCode, exitCode) - require.Equal(t, tc.errMsg, out.String()) + + formattedErr := &bytes.Buffer{} + if tc.errMsg != "" { + console.DisplayWarningMessage(tc.errMsg, formattedErr) + require.Equal(t, formattedErr.String(), out.String()) + } else { + require.Equal(t, tc.errMsg, out.String()) + } }) } } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653071530 -14400 # Fri May 20 22:32:10 2022 +0400 # Node ID 1d9befdbb63d366fa604b030d2489075503c9517 # Parent 3b1e131ec2437c044518d368bda770f2f0185e0f Exclude Gitaly unavailable error from error rate When a user hits repository rate limit, Gitaly returns an error that the request can't be handled (Gitaly unavailable) We should avoid this error to avoid exceeding the error rate diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -41,7 +41,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:10] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -49,7 +49,6 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", - "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -77,15 +77,6 @@ }, ) - SshdCanceledSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: sshdCanceledSessionsName, - Help: "The number of canceled gitlab-sshd sessions.", - }, - ) - SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -89,14 +89,7 @@ metrics.SliSshdSessionsTotal.Inc() err := handler(ctx, channel, requests) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Canceled { - metrics.SshdCanceledSessions.Inc() - } else { - var apiError *client.ApiError - if !errors.As(err, &apiError) { - metrics.SliSshdSessionsErrorsTotal.Inc() - } - } + c.trackError(err) } ctxlog.Info("connection: handle: done") @@ -126,3 +119,17 @@ } } } + +func (c *connection) trackError(err error) { + var apiError *client.ApiError + if errors.As(err, &apiError) { + return + } + + grpcCode := grpcstatus.Code(err) + if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { + return + } + + metrics.SliSshdSessionsErrorsTotal.Inc() +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -200,7 +200,6 @@ // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) - initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) newChannel := &fakeNewChannel{channelType: "session"} @@ -212,17 +211,15 @@ require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) conn, chans = setup(1, newChannel) conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { close(chans) - return grpcstatus.Error(grpccodes.Canceled, "error") + return grpcstatus.Error(grpccodes.Canceled, "canceled") }) require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) conn, chans = setup(1, newChannel) conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { @@ -232,5 +229,13 @@ require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return grpcstatus.Error(grpccodes.Unavailable, "unavailable") + }) + + require.InDelta(t, initialSessionsTotal+4, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653109441 -14400 # Sat May 21 09:04:01 2022 +0400 # Node ID 0ef9f95f2356e122bac2b5c352ab26c302ae8a1e # Parent 1d9befdbb63d366fa604b030d2489075503c9517 Downgrade auth EOF messages from warning to debug The errors happen when a client closes a connection on handshake They can be ignored to avoid noise diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -44,7 +44,7 @@ logger := ctxlog.WithError(err) - if strings.Contains(err.Error(), "no common algorithm for host key") { + if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { logger.Debug(msg) } else { logger.Warn(msg) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653114095 0 # Sat May 21 06:21:35 2022 +0000 # Node ID 6547a3124efd00569abddf812d3ad9716d74843a # Parent f32f24a0e5383a503775155b9fc08d7dc3b8b887 # Parent 0ef9f95f2356e122bac2b5c352ab26c302ae8a1e Merge branch 'id-ignore-gitaly-unavailable-errors' into 'main' Exclude Gitaly unavailable error from error rate See merge request gitlab-org/gitlab-shell!641 diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -41,7 +41,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:10] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -49,7 +49,6 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", - "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -58,13 +58,11 @@ exitStatus, err := handler(childCtx, conn) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { - ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") - return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + if grpcstatus.Code(err) == grpccodes.Unavailable { + return grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.") } - - ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") } return err diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -84,10 +84,8 @@ }, ) - expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") - err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) - - require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, grpcstatus.Error(grpccodes.Unavailable, "error"))) + require.Equal(t, err, grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.")) } func TestRunGitalyCommandMetadata(t *testing.T) { diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -77,15 +77,6 @@ }, ) - SshdCanceledSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: sshdCanceledSessionsName, - Help: "The number of canceled gitlab-sshd sessions.", - }, - ) - SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -89,14 +89,7 @@ metrics.SliSshdSessionsTotal.Inc() err := handler(ctx, channel, requests) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Canceled { - metrics.SshdCanceledSessions.Inc() - } else { - var apiError *client.ApiError - if !errors.As(err, &apiError) { - metrics.SliSshdSessionsErrorsTotal.Inc() - } - } + c.trackError(err) } ctxlog.Info("connection: handle: done") @@ -126,3 +119,17 @@ } } } + +func (c *connection) trackError(err error) { + var apiError *client.ApiError + if errors.As(err, &apiError) { + return + } + + grpcCode := grpcstatus.Code(err) + if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { + return + } + + metrics.SliSshdSessionsErrorsTotal.Inc() +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -200,7 +200,6 @@ // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) - initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) newChannel := &fakeNewChannel{channelType: "session"} @@ -212,17 +211,15 @@ require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) conn, chans = setup(1, newChannel) conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { close(chans) - return grpcstatus.Error(grpccodes.Canceled, "error") + return grpcstatus.Error(grpccodes.Canceled, "canceled") }) require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) conn, chans = setup(1, newChannel) conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { @@ -232,5 +229,13 @@ require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return grpcstatus.Error(grpccodes.Unavailable, "unavailable") + }) + + require.InDelta(t, initialSessionsTotal+4, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -8,11 +8,14 @@ "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -158,10 +161,12 @@ cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) if err != nil { - if !errors.Is(err, disallowedcommand.Error) { - s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) + if errors.Is(err, disallowedcommand.Error) { + s.toStderr(ctx, "ERROR: Unknown command: %v\n", s.execCmd) + } else { + s.toStderr(ctx, "ERROR: Failed to parse command: %v\n", err.Error()) } - s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) + return 128, err } @@ -169,7 +174,11 @@ ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") if err := cmd.Execute(ctx); err != nil { - s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) + grpcStatus := grpcstatus.Convert(err) + if grpcStatus.Code() != grpccodes.Internal { + s.toStderr(ctx, "ERROR: %v\n", grpcStatus.Message()) + } + return 1, err } @@ -181,7 +190,7 @@ func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { out := fmt.Sprintf(format, args...) log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") - fmt.Fprint(s.channel.Stderr(), out) + console.DisplayWarningMessage(out, s.channel.Stderr()) } func (s *session) exit(ctx context.Context, status uint32) { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -13,6 +13,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/console" ) type fakeChannel struct { @@ -160,14 +161,14 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + errMsg: "ERROR: Failed to parse command: Invalid SSH command: invalid command line string\n", gitlabKeyId: "root", expectedErrString: "Invalid SSH command: invalid command line string", expectedExitCode: 128, }, { desc: "specified command is unknown", cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", + errMsg: "ERROR: Unknown command: unknown-command\n", gitlabKeyId: "root", expectedErrString: "Disallowed command", expectedExitCode: 128, @@ -175,7 +176,7 @@ desc: "fails to parse command", cmd: "discover", gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + errMsg: "ERROR: Failed to get username: who='' is invalid\n", expectedErrString: "Failed to get username: who='' is invalid", expectedExitCode: 1, }, { @@ -208,7 +209,14 @@ } require.Equal(t, tc.expectedExitCode, exitCode) - require.Equal(t, tc.errMsg, out.String()) + + formattedErr := &bytes.Buffer{} + if tc.errMsg != "" { + console.DisplayWarningMessage(tc.errMsg, formattedErr) + require.Equal(t, formattedErr.String(), out.String()) + } else { + require.Equal(t, tc.errMsg, out.String()) + } }) } } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -44,7 +44,7 @@ logger := ctxlog.WithError(err) - if strings.Contains(err.Error(), "no common algorithm for host key") { + if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { logger.Debug(msg) } else { logger.Warn(msg) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653114539 -14400 # Sat May 21 10:28:59 2022 +0400 # Node ID 1874de47d59cb1ac4bb37508a1a61ff98bd67177 # Parent 6547a3124efd00569abddf812d3ad9716d74843a Release 14.6.0 - Exclude Gitaly unavailable error from error rate !641 - Downgrade auth EOF messages from warning to debug !641 - Display constistently in gitlab-sshd and gitlab-shell !641 - Downgrade host key mismatch messages from warning to debug !639 - Introduce a GitLab-SSHD server version during handshake !640 - Narrow supported kex algorithms !638 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +v14.6.0 + +- Exclude Gitaly unavailable error from error rate !641 +- Downgrade auth EOF messages from warning to debug !641 +- Display constistently in gitlab-sshd and gitlab-shell !641 +- Downgrade host key mismatch messages from warning to debug !639 +- Introduce a GitLab-SSHD server version during handshake !640 +- Narrow supported kex algorithms !638 + v14.5.0 - Make ProxyHeaderTimeout configurable !635 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.5.0 +14.6.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653115022 0 # Sat May 21 06:37:02 2022 +0000 # Node ID 363bcf081e7da20b57c13161133c718c3aa63c4c # Parent 6547a3124efd00569abddf812d3ad9716d74843a # Parent 1874de47d59cb1ac4bb37508a1a61ff98bd67177 Merge branch 'id-release-14-6-0' into 'main' Release 14.6.0 See merge request gitlab-org/gitlab-shell!643 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +v14.6.0 + +- Exclude Gitaly unavailable error from error rate !641 +- Downgrade auth EOF messages from warning to debug !641 +- Display constistently in gitlab-sshd and gitlab-shell !641 +- Downgrade host key mismatch messages from warning to debug !639 +- Introduce a GitLab-SSHD server version during handshake !640 +- Narrow supported kex algorithms !638 + v14.5.0 - Make ProxyHeaderTimeout configurable !635 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.5.0 +14.6.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653294631 -14400 # Mon May 23 12:30:31 2022 +0400 # Node ID 0c4f65831e4a5e0456be9da50e55ae4b3069526a # Parent 363bcf081e7da20b57c13161133c718c3aa63c4c Return support for diffie-hellman-group14-sha1 It seems that a lot of users rely on this, let's return it and deprecated later to make the migration less disruptive diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -89,7 +89,7 @@ # Specifies the available message authentication code algorithms that are used for protecting data integrity macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] # Specifies the available Key Exchange algorithms - kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256] + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] # Specified the ciphers allowed ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -32,6 +32,7 @@ "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", + "diffie-hellman-group14-sha1", } ) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653295311 0 # Mon May 23 08:41:51 2022 +0000 # Node ID 1187698232fe6bb93f202d369f8e9c80d76e0d7f # Parent 363bcf081e7da20b57c13161133c718c3aa63c4c # Parent 0c4f65831e4a5e0456be9da50e55ae4b3069526a Merge branch 'id-revert-narrowing-kex-algos' into 'main' Return support for diffie-hellman-group14-sha1 See merge request gitlab-org/gitlab-shell!644 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -89,7 +89,7 @@ # Specifies the available message authentication code algorithms that are used for protecting data integrity macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] # Specifies the available Key Exchange algorithms - kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256] + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] # Specified the ciphers allowed ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -32,6 +32,7 @@ "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", + "diffie-hellman-group14-sha1", } ) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653295351 -14400 # Mon May 23 12:42:31 2022 +0400 # Node ID 47b689bfce2d6842187e2ceb197185082af8a8d5 # Parent 1187698232fe6bb93f202d369f8e9c80d76e0d7f Release v14.6.1 - Return support for diffie-hellman-group14-sha1 !644 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.6.1 + +- Return support for diffie-hellman-group14-sha1 !644 + v14.6.0 - Exclude Gitaly unavailable error from error rate !641 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.6.0 +14.6.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653295769 0 # Mon May 23 08:49:29 2022 +0000 # Node ID 7388be2b682515483bb91b68a351c5b0d2590c17 # Parent 1187698232fe6bb93f202d369f8e9c80d76e0d7f # Parent 47b689bfce2d6842187e2ceb197185082af8a8d5 Merge branch 'id-release-14-6-1' into 'main' Release v14.6.1 See merge request gitlab-org/gitlab-shell!645 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.6.1 + +- Return support for diffie-hellman-group14-sha1 !644 + v14.6.0 - Exclude Gitaly unavailable error from error rate !641 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.6.0 +14.6.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653310430 -14400 # Mon May 23 16:53:50 2022 +0400 # Node ID 929d42f39088c63cb672deec90e29e8266ae64cb # Parent 7388be2b682515483bb91b68a351c5b0d2590c17 Move connection init into connection.go diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -3,6 +3,8 @@ import ( "context" "errors" + "net" + "strings" "time" "golang.org/x/crypto/ssh" @@ -22,52 +24,91 @@ var EOFTimeout = 10 * time.Second type connection struct { - cfg *config.Config - concurrentSessions *semaphore.Weighted - remoteAddr string - sconn *ssh.ServerConn - maxSessions int64 + cfg *config.Config + concurrentSessions *semaphore.Weighted + nconn net.Conn + maxSessions int64 + remoteAddr string + started time.Time + establishSessionDuration float64 } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error +type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error -func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { +func newConnection(cfg *config.Config, nconn net.Conn) *connection { maxSessions := cfg.Server.ConcurrentSessionsLimit return &connection{ cfg: cfg, maxSessions: maxSessions, concurrentSessions: semaphore.NewWeighted(maxSessions), - remoteAddr: remoteAddr, - sconn: sconn, + nconn: nconn, + remoteAddr: nconn.RemoteAddr().String(), + started: time.Now(), } } -func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) +func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handler channelHandler) { + sconn, chans, err := c.initServerConn(ctx, srvCfg) + if err != nil { + return + } if c.cfg.Server.ClientAliveInterval > 0 { ticker := time.NewTicker(time.Duration(c.cfg.Server.ClientAliveInterval)) defer ticker.Stop() - go c.sendKeepAliveMsg(ctx, ticker) + go c.sendKeepAliveMsg(ctx, sconn, ticker) } + c.handleRequests(ctx, sconn, chans, handler) + + reason := sconn.Wait() + log.WithContextFields(ctx, log.Fields{ + "duration_s": time.Since(c.started).Seconds(), + "establish_session_duration_s": c.establishSessionDuration, + "reason": reason, + }).Info("server: handleConn: done") +} + +func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { + sconn, chans, reqs, err := ssh.NewServerConn(c.nconn, srvCfg) + if err != nil { + msg := "connection: initServerConn: failed to initialize SSH connection" + + logger := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}).WithError(err) + + if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { + logger.Debug(msg) + } else { + logger.Warn(msg) + } + + return nil, nil, err + } + go ssh.DiscardRequests(reqs) + + return sconn, chans, err +} + +func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { - ctxlog.Info("connection: handle: unknown channel type") + ctxlog.Info("connection: handleRequests: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { - ctxlog.Info("connection: handle: too many concurrent sessions") + ctxlog.Info("connection: handleRequests: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - ctxlog.WithError(err).Error("connection: handle: accepting channel failed") + ctxlog.WithError(err).Error("connection: handleRequests: accepting channel failed") c.concurrentSessions.Release(1) continue } @@ -76,6 +117,7 @@ defer func(started time.Time) { metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) }(time.Now()) + c.establishSessionDuration = time.Since(c.started).Seconds() defer c.concurrentSessions.Release(1) @@ -87,12 +129,12 @@ }() metrics.SliSshdSessionsTotal.Inc() - err := handler(ctx, channel, requests) + err := handler(sconn, channel, requests) if err != nil { c.trackError(err) } - ctxlog.Info("connection: handle: done") + ctxlog.Info("connection: handleRequests: done") }() } @@ -105,7 +147,7 @@ c.concurrentSessions.Acquire(ctx, c.maxSessions) } -func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { +func (c *connection) sendKeepAliveMsg(ctx context.Context, sconn *ssh.ServerConn, ticker *time.Ticker) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) for { @@ -113,9 +155,9 @@ case <-ctx.Done(): return case <-ticker.C: - ctxlog.Debug("session: handleShell: send keepalive message to a client") + ctxlog.Debug("connection: sendKeepAliveMsg: send keepalive message to a client") - c.sconn.SendRequest(KeepAliveMsg, true, nil) + sconn.SendRequest(KeepAliveMsg, true, nil) } } } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -10,6 +10,7 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" @@ -81,7 +82,7 @@ func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum}} - conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) + conn := &connection{cfg: cfg, concurrentSessions: semaphore.NewWeighted(sessionsNum)} chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -95,7 +96,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -113,7 +114,7 @@ conn, chans := setup(1, newChannel) go func() { - conn.handle(context.Background(), chans, nil) + conn.handleRequests(context.Background(), nil, chans, nil) }() rejectionData := <-rejectCh @@ -133,7 +134,7 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test return nil }) @@ -148,7 +149,7 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) return nil @@ -167,7 +168,7 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true return nil }) @@ -185,12 +186,11 @@ func TestClientAliveInterval(t *testing.T) { f := &fakeConn{} - conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) - ticker := time.NewTicker(time.Millisecond) defer ticker.Stop() - go conn.sendKeepAliveMsg(context.Background(), ticker) + conn := &connection{} + go conn.sendKeepAliveMsg(context.Background(), &ssh.ServerConn{f, nil}, ticker) require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) } @@ -204,7 +204,7 @@ newChannel := &fakeNewChannel{channelType: "session"} conn, chans := setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return errors.New("custom error") }) @@ -213,7 +213,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return grpcstatus.Error(grpccodes.Canceled, "canceled") }) @@ -222,7 +222,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return &client.ApiError{"api error"} }) @@ -231,7 +231,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return grpcstatus.Error(grpccodes.Unavailable, "unavailable") }) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,7 +10,6 @@ "time" "github.com/pires/go-proxyproto" - "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -39,18 +38,6 @@ serverConfig *serverConfig } -func logSSHInitError(ctxlog *logrus.Entry, err error) { - msg := "server: handleConn: failed to initialize SSH connection" - - logger := ctxlog.WithError(err) - - if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { - logger.Debug(msg) - } else { - logger.Warn(msg) - } -} - func NewServer(cfg *config.Config) (*Server, error) { serverConfig, err := newServerConfig(cfg) if err != nil { @@ -171,6 +158,7 @@ defer cancel() ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + ctxlog.Debug("server: handleConn: start") // Prevent a panic in a single connection from taking out the whole server defer func() { @@ -181,22 +169,8 @@ } }() - ctxlog.Debug("server: handleConn: start") - - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) - if err != nil { - logSSHInitError(ctxlog, err) - return - } - go ssh.DiscardRequests(reqs) - - started := time.Now() - var establishSessionDuration float64 - conn := newConnection(s.Config, remoteAddr, sconn) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { - establishSessionDuration = time.Since(started).Seconds() - metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) - + conn := newConnection(s.Config, nconn) + conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ cfg: s.Config, channel: channel, @@ -206,13 +180,6 @@ return session.handle(ctx, requests) }) - - reason := sconn.Wait() - ctxlog.WithFields(log.Fields{ - "duration_s": time.Since(started).Seconds(), - "establish_session_duration_s": establishSessionDuration, - "reason": reason, - }).Info("server: handleConn: done") } func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653311792 -14400 # Mon May 23 17:16:32 2022 +0400 # Node ID 57a182223f988ee89744efb35b0edcad7dfc691a # Parent 929d42f39088c63cb672deec90e29e8266ae64cb Close the connection when context is canceled When graceful shutdown timeout expires, the global context is canceled. All the operations dependent on it are canceled as well. Unfortunately, some of the operations doesn't respect the context. For example, SSH connection initialization. In this case, we need to manually close the connection. One of the options is to wait for ctx.Done() and close the connection diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -146,17 +146,19 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + defer s.wg.Done() + metrics.SshdConnectionsInFlight.Inc() defer metrics.SshdConnectionsInFlight.Dec() - remoteAddr := nconn.RemoteAddr().String() - - defer s.wg.Done() - defer nconn.Close() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() + go func() { + <-ctx.Done() + nconn.Close() // Close the connection when context is cancelled + }() + remoteAddr := nconn.RemoteAddr().String() ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) ctxlog.Debug("server: handleConn: start") diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -222,6 +222,35 @@ require.Nil(t, s.Shutdown()) } +func TestClosingHangedConnections(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + s := setupServerWithContext(t, nil, ctx) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + require.NoError(t, s.Shutdown()) + cancel() + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -231,6 +260,12 @@ func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() + return setupServerWithContext(t, cfg, context.Background()) +} + +func setupServerWithContext(t *testing.T, cfg *config.Config, ctx context.Context) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -270,7 +305,7 @@ s, err := NewServer(cfg) require.NoError(t, err) - go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + go func() { require.NoError(t, s.ListenAndServe(ctx)) }() t.Cleanup(func() { s.Shutdown() }) verifyStatus(t, s, StatusReady) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653325222 0 # Mon May 23 17:00:22 2022 +0000 # Node ID 58aa9e1be5d3b8b3764a6b9faec5ac47ee4d1070 # Parent 7388be2b682515483bb91b68a351c5b0d2590c17 # Parent 57a182223f988ee89744efb35b0edcad7dfc691a Merge branch 'id-login-grace-time' into 'main' Close the connection when context is canceled See merge request gitlab-org/gitlab-shell!646 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -3,6 +3,8 @@ import ( "context" "errors" + "net" + "strings" "time" "golang.org/x/crypto/ssh" @@ -22,52 +24,91 @@ var EOFTimeout = 10 * time.Second type connection struct { - cfg *config.Config - concurrentSessions *semaphore.Weighted - remoteAddr string - sconn *ssh.ServerConn - maxSessions int64 + cfg *config.Config + concurrentSessions *semaphore.Weighted + nconn net.Conn + maxSessions int64 + remoteAddr string + started time.Time + establishSessionDuration float64 } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error +type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error -func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { +func newConnection(cfg *config.Config, nconn net.Conn) *connection { maxSessions := cfg.Server.ConcurrentSessionsLimit return &connection{ cfg: cfg, maxSessions: maxSessions, concurrentSessions: semaphore.NewWeighted(maxSessions), - remoteAddr: remoteAddr, - sconn: sconn, + nconn: nconn, + remoteAddr: nconn.RemoteAddr().String(), + started: time.Now(), } } -func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) +func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handler channelHandler) { + sconn, chans, err := c.initServerConn(ctx, srvCfg) + if err != nil { + return + } if c.cfg.Server.ClientAliveInterval > 0 { ticker := time.NewTicker(time.Duration(c.cfg.Server.ClientAliveInterval)) defer ticker.Stop() - go c.sendKeepAliveMsg(ctx, ticker) + go c.sendKeepAliveMsg(ctx, sconn, ticker) } + c.handleRequests(ctx, sconn, chans, handler) + + reason := sconn.Wait() + log.WithContextFields(ctx, log.Fields{ + "duration_s": time.Since(c.started).Seconds(), + "establish_session_duration_s": c.establishSessionDuration, + "reason": reason, + }).Info("server: handleConn: done") +} + +func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { + sconn, chans, reqs, err := ssh.NewServerConn(c.nconn, srvCfg) + if err != nil { + msg := "connection: initServerConn: failed to initialize SSH connection" + + logger := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}).WithError(err) + + if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { + logger.Debug(msg) + } else { + logger.Warn(msg) + } + + return nil, nil, err + } + go ssh.DiscardRequests(reqs) + + return sconn, chans, err +} + +func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { - ctxlog.Info("connection: handle: unknown channel type") + ctxlog.Info("connection: handleRequests: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { - ctxlog.Info("connection: handle: too many concurrent sessions") + ctxlog.Info("connection: handleRequests: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - ctxlog.WithError(err).Error("connection: handle: accepting channel failed") + ctxlog.WithError(err).Error("connection: handleRequests: accepting channel failed") c.concurrentSessions.Release(1) continue } @@ -76,6 +117,7 @@ defer func(started time.Time) { metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) }(time.Now()) + c.establishSessionDuration = time.Since(c.started).Seconds() defer c.concurrentSessions.Release(1) @@ -87,12 +129,12 @@ }() metrics.SliSshdSessionsTotal.Inc() - err := handler(ctx, channel, requests) + err := handler(sconn, channel, requests) if err != nil { c.trackError(err) } - ctxlog.Info("connection: handle: done") + ctxlog.Info("connection: handleRequests: done") }() } @@ -105,7 +147,7 @@ c.concurrentSessions.Acquire(ctx, c.maxSessions) } -func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { +func (c *connection) sendKeepAliveMsg(ctx context.Context, sconn *ssh.ServerConn, ticker *time.Ticker) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) for { @@ -113,9 +155,9 @@ case <-ctx.Done(): return case <-ticker.C: - ctxlog.Debug("session: handleShell: send keepalive message to a client") + ctxlog.Debug("connection: sendKeepAliveMsg: send keepalive message to a client") - c.sconn.SendRequest(KeepAliveMsg, true, nil) + sconn.SendRequest(KeepAliveMsg, true, nil) } } } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -10,6 +10,7 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" @@ -81,7 +82,7 @@ func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum}} - conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) + conn := &connection{cfg: cfg, concurrentSessions: semaphore.NewWeighted(sessionsNum)} chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -95,7 +96,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -113,7 +114,7 @@ conn, chans := setup(1, newChannel) go func() { - conn.handle(context.Background(), chans, nil) + conn.handleRequests(context.Background(), nil, chans, nil) }() rejectionData := <-rejectCh @@ -133,7 +134,7 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test return nil }) @@ -148,7 +149,7 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) return nil @@ -167,7 +168,7 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true return nil }) @@ -185,12 +186,11 @@ func TestClientAliveInterval(t *testing.T) { f := &fakeConn{} - conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) - ticker := time.NewTicker(time.Millisecond) defer ticker.Stop() - go conn.sendKeepAliveMsg(context.Background(), ticker) + conn := &connection{} + go conn.sendKeepAliveMsg(context.Background(), &ssh.ServerConn{f, nil}, ticker) require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) } @@ -204,7 +204,7 @@ newChannel := &fakeNewChannel{channelType: "session"} conn, chans := setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return errors.New("custom error") }) @@ -213,7 +213,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return grpcstatus.Error(grpccodes.Canceled, "canceled") }) @@ -222,7 +222,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return &client.ApiError{"api error"} }) @@ -231,7 +231,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return grpcstatus.Error(grpccodes.Unavailable, "unavailable") }) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,7 +10,6 @@ "time" "github.com/pires/go-proxyproto" - "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -39,18 +38,6 @@ serverConfig *serverConfig } -func logSSHInitError(ctxlog *logrus.Entry, err error) { - msg := "server: handleConn: failed to initialize SSH connection" - - logger := ctxlog.WithError(err) - - if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { - logger.Debug(msg) - } else { - logger.Warn(msg) - } -} - func NewServer(cfg *config.Config) (*Server, error) { serverConfig, err := newServerConfig(cfg) if err != nil { @@ -159,18 +146,21 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + defer s.wg.Done() + metrics.SshdConnectionsInFlight.Inc() defer metrics.SshdConnectionsInFlight.Dec() - remoteAddr := nconn.RemoteAddr().String() - - defer s.wg.Done() - defer nconn.Close() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() + go func() { + <-ctx.Done() + nconn.Close() // Close the connection when context is cancelled + }() + remoteAddr := nconn.RemoteAddr().String() ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + ctxlog.Debug("server: handleConn: start") // Prevent a panic in a single connection from taking out the whole server defer func() { @@ -181,22 +171,8 @@ } }() - ctxlog.Debug("server: handleConn: start") - - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) - if err != nil { - logSSHInitError(ctxlog, err) - return - } - go ssh.DiscardRequests(reqs) - - started := time.Now() - var establishSessionDuration float64 - conn := newConnection(s.Config, remoteAddr, sconn) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { - establishSessionDuration = time.Since(started).Seconds() - metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) - + conn := newConnection(s.Config, nconn) + conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ cfg: s.Config, channel: channel, @@ -206,13 +182,6 @@ return session.handle(ctx, requests) }) - - reason := sconn.Wait() - ctxlog.WithFields(log.Fields{ - "duration_s": time.Since(started).Seconds(), - "establish_session_duration_s": establishSessionDuration, - "reason": reason, - }).Info("server: handleConn: done") } func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -222,6 +222,35 @@ require.Nil(t, s.Shutdown()) } +func TestClosingHangedConnections(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + s := setupServerWithContext(t, nil, ctx) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + require.NoError(t, s.Shutdown()) + cancel() + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -231,6 +260,12 @@ func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() + return setupServerWithContext(t, cfg, context.Background()) +} + +func setupServerWithContext(t *testing.T, cfg *config.Config, ctx context.Context) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -270,7 +305,7 @@ s, err := NewServer(cfg) require.NoError(t, err) - go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + go func() { require.NoError(t, s.ListenAndServe(ctx)) }() t.Cleanup(func() { s.Shutdown() }) verifyStatus(t, s, StatusReady) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653318594 -14400 # Mon May 23 19:09:54 2022 +0400 # Node ID 72603ad5e8b7a2bad70ed13870e6d63e24f88e95 # Parent 58aa9e1be5d3b8b3764a6b9faec5ac47ee4d1070 Abort long-running unauthenticated SSH connections The config option is basically a copy of LoginGraceTime OpenSSH option. If an SSH connection is hanging unauthenticated, after some period of time, the connection gets canceled. The value is configurable, the server waits for 60 seconds by default. diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -76,10 +76,12 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # Sets an interval after which server will send keepalive message to a client + # Sets an interval after which server will send keepalive message to a client. Defaults to 15s. client_alive_interval: 15 - # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + # The server waits for this time for the ongoing connections to complete before shutting down. Defaults to 10s. grace_period: 10 + # The server disconnects after this time if the user has not successfully logged in. Defaults to 60s. + login_grace_time: 60 # A short timeout to decide to abort the connection if the protocol header is not seen within it. Defaults to 500ms proxy_header_timeout: 500ms # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,7 +21,7 @@ defaultSecretFileName = ".gitlab_shell_secret" ) -type yamlDuration time.Duration +type YamlDuration time.Duration type ServerConfig struct { Listen string `yaml:"listen,omitempty"` @@ -29,9 +29,10 @@ ProxyPolicy string `yaml:"proxy_policy,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - ClientAliveInterval yamlDuration `yaml:"client_alive_interval,omitempty"` - GracePeriod yamlDuration `yaml:"grace_period"` - ProxyHeaderTimeout yamlDuration `yaml:"proxy_header_timeout"` + ClientAliveInterval YamlDuration `yaml:"client_alive_interval,omitempty"` + GracePeriod YamlDuration `yaml:"grace_period"` + ProxyHeaderTimeout YamlDuration `yaml:"proxy_header_timeout"` + LoginGraceTime YamlDuration `yaml:"login_grace_time"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` @@ -85,9 +86,10 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - GracePeriod: yamlDuration(10 * time.Second), - ClientAliveInterval: yamlDuration(15 * time.Second), - ProxyHeaderTimeout: yamlDuration(500 * time.Millisecond), + GracePeriod: YamlDuration(10 * time.Second), + ClientAliveInterval: YamlDuration(15 * time.Second), + ProxyHeaderTimeout: YamlDuration(500 * time.Millisecond), + LoginGraceTime: YamlDuration(60 * time.Second), ReadinessProbe: "/start", LivenessProbe: "/health", HostKeyFiles: []string{ @@ -98,13 +100,13 @@ } ) -func (d *yamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (d *YamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { var intDuration int if err := unmarshal(&intDuration); err != nil { return unmarshal((*time.Duration)(d)) } - *d = yamlDuration(time.Duration(intDuration) * time.Second) + *d = YamlDuration(time.Duration(intDuration) * time.Second) return nil } diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -83,7 +83,7 @@ } type durationCfg struct { - Duration yamlDuration `yaml:"duration"` + Duration YamlDuration `yaml:"duration"` } for _, tc := range testCases { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -71,10 +71,14 @@ } func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { + if c.cfg.Server.LoginGraceTime > 0 { + c.nconn.SetDeadline(time.Now().Add(time.Duration(c.cfg.Server.LoginGraceTime))) + defer c.nconn.SetDeadline(time.Time{}) + } + sconn, chans, reqs, err := ssh.NewServerConn(c.nconn, srvCfg) if err != nil { msg := "connection: initServerConn: failed to initialize SSH connection" - logger := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}).WithError(err) if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -251,6 +251,39 @@ verifyStatus(t, s, StatusClosed) } +func TestLoginGraceTime(t *testing.T) { + cfg := &config.Config{ + Server: config.ServerConfig{ + LoginGraceTime: config.YamlDuration(50 * time.Millisecond), + }, + } + s := setupServerWithConfig(t, cfg) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Shutdown the server and verify that it's closed + // If LoginGraceTime doesn't work, then the connection that runs infinitely, will stop it from closing. + // The close won't happen until the context is canceled like in TestClosingHangedConnections + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653329107 -14400 # Mon May 23 22:05:07 2022 +0400 # Node ID 6daa11cf78d408c6f80f47dc58cc0c0255a55d74 # Parent 72603ad5e8b7a2bad70ed13870e6d63e24f88e95 Add missing SshdSessionEstablishedDuration metrics diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -122,6 +122,7 @@ metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) }(time.Now()) c.establishSessionDuration = time.Since(c.started).Seconds() + metrics.SshdSessionEstablishedDuration.Observe(c.establishSessionDuration) defer c.concurrentSessions.Release(1) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653334249 0 # Mon May 23 19:30:49 2022 +0000 # Node ID c9b3de80460bdb418a34a53e4be6011c28f06546 # Parent 58aa9e1be5d3b8b3764a6b9faec5ac47ee4d1070 # Parent 6daa11cf78d408c6f80f47dc58cc0c0255a55d74 Merge branch 'id-login-grace-time-impl' into 'main' Abort long-running unauthenticated SSH connections See merge request gitlab-org/gitlab-shell!647 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -76,10 +76,12 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # Sets an interval after which server will send keepalive message to a client + # Sets an interval after which server will send keepalive message to a client. Defaults to 15s. client_alive_interval: 15 - # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + # The server waits for this time for the ongoing connections to complete before shutting down. Defaults to 10s. grace_period: 10 + # The server disconnects after this time if the user has not successfully logged in. Defaults to 60s. + login_grace_time: 60 # A short timeout to decide to abort the connection if the protocol header is not seen within it. Defaults to 500ms proxy_header_timeout: 500ms # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,7 +21,7 @@ defaultSecretFileName = ".gitlab_shell_secret" ) -type yamlDuration time.Duration +type YamlDuration time.Duration type ServerConfig struct { Listen string `yaml:"listen,omitempty"` @@ -29,9 +29,10 @@ ProxyPolicy string `yaml:"proxy_policy,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - ClientAliveInterval yamlDuration `yaml:"client_alive_interval,omitempty"` - GracePeriod yamlDuration `yaml:"grace_period"` - ProxyHeaderTimeout yamlDuration `yaml:"proxy_header_timeout"` + ClientAliveInterval YamlDuration `yaml:"client_alive_interval,omitempty"` + GracePeriod YamlDuration `yaml:"grace_period"` + ProxyHeaderTimeout YamlDuration `yaml:"proxy_header_timeout"` + LoginGraceTime YamlDuration `yaml:"login_grace_time"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` @@ -85,9 +86,10 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - GracePeriod: yamlDuration(10 * time.Second), - ClientAliveInterval: yamlDuration(15 * time.Second), - ProxyHeaderTimeout: yamlDuration(500 * time.Millisecond), + GracePeriod: YamlDuration(10 * time.Second), + ClientAliveInterval: YamlDuration(15 * time.Second), + ProxyHeaderTimeout: YamlDuration(500 * time.Millisecond), + LoginGraceTime: YamlDuration(60 * time.Second), ReadinessProbe: "/start", LivenessProbe: "/health", HostKeyFiles: []string{ @@ -98,13 +100,13 @@ } ) -func (d *yamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (d *YamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { var intDuration int if err := unmarshal(&intDuration); err != nil { return unmarshal((*time.Duration)(d)) } - *d = yamlDuration(time.Duration(intDuration) * time.Second) + *d = YamlDuration(time.Duration(intDuration) * time.Second) return nil } diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -83,7 +83,7 @@ } type durationCfg struct { - Duration yamlDuration `yaml:"duration"` + Duration YamlDuration `yaml:"duration"` } for _, tc := range testCases { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -71,10 +71,14 @@ } func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { + if c.cfg.Server.LoginGraceTime > 0 { + c.nconn.SetDeadline(time.Now().Add(time.Duration(c.cfg.Server.LoginGraceTime))) + defer c.nconn.SetDeadline(time.Time{}) + } + sconn, chans, reqs, err := ssh.NewServerConn(c.nconn, srvCfg) if err != nil { msg := "connection: initServerConn: failed to initialize SSH connection" - logger := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}).WithError(err) if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { @@ -118,6 +122,7 @@ metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) }(time.Now()) c.establishSessionDuration = time.Since(c.started).Seconds() + metrics.SshdSessionEstablishedDuration.Observe(c.establishSessionDuration) defer c.concurrentSessions.Release(1) diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -251,6 +251,39 @@ verifyStatus(t, s, StatusClosed) } +func TestLoginGraceTime(t *testing.T) { + cfg := &config.Config{ + Server: config.ServerConfig{ + LoginGraceTime: config.YamlDuration(50 * time.Millisecond), + }, + } + s := setupServerWithConfig(t, cfg) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Shutdown the server and verify that it's closed + // If LoginGraceTime doesn't work, then the connection that runs infinitely, will stop it from closing. + // The close won't happen until the context is canceled like in TestClosingHangedConnections + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653334375 25200 # Mon May 23 12:32:55 2022 -0700 # Node ID 2cebb1acbf5cbb82111a48cb8ecf89ffd38c5d16 # Parent c9b3de80460bdb418a34a53e4be6011c28f06546 Release v14.7.0 - Abort long-running unauthenticated SSH connections !647 - Close the connection when context is canceled !646 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.7.0 + +- Abort long-running unauthenticated SSH connections !647 +- Close the connection when context is canceled !646 + v14.6.1 - Return support for diffie-hellman-group14-sha1 !644 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.6.1 +14.7.0 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653334810 0 # Mon May 23 19:40:10 2022 +0000 # Node ID c54d0c6dfdb2076fb1a80dfd40886d8d98eb9a98 # Parent c9b3de80460bdb418a34a53e4be6011c28f06546 # Parent 2cebb1acbf5cbb82111a48cb8ecf89ffd38c5d16 Merge branch 'sh-release-14.7.0' into 'main' Release v14.7.0 See merge request gitlab-org/gitlab-shell!648 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.7.0 + +- Abort long-running unauthenticated SSH connections !647 +- Close the connection when context is canceled !646 + v14.6.1 - Return support for diffie-hellman-group14-sha1 !644 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.6.1 +14.7.0 # HG changeset patch # User Sean Carroll <scarroll@gitlab.com> # Date 1652865840 -7200 # Wed May 18 11:24:00 2022 +0200 # Node ID 798354f81cbc785a0af65eee9257a986664295dc # Parent 95f105751282580f695ff4bec8577de261720bbd Document gitlab-shell on GitLab SaaS diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -52,6 +52,44 @@ There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). +## GitLab SaaS + +A diagram of the flow of `gitlab-shell` on GitLab.com: + +```mermaid +graph LR + a2 --> b2 + a2 --> b3 + a2 --> b4 + b2 --> c1 + b3 --> c1 + b4 --> c1 + c2 --> d1 + c2 --> d2 + c2 --> d3 + d1 --> e1 + d2 --> e1 + d3 --> e1 + a1[Cloudflare] --> a2[TCP<br/> load balancer] + e1[Git] + + subgraph HAProxy Fleet + b2[HAProxy] + b3[HAProxy] + b4[HAProxy] + end + + subgraph GKE + c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods] + end + + subgraph Gitaly + d1[Gitaly] + d2[Gitaly] + d3[Gitaly] + end +``` + ## Releasing See [PROCESS.md](./PROCESS.md) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653385846 0 # Tue May 24 09:50:46 2022 +0000 # Node ID 86e1d0dc34802c5fd17f5f5248e69ec3bbdf1fc1 # Parent c54d0c6dfdb2076fb1a80dfd40886d8d98eb9a98 # Parent 798354f81cbc785a0af65eee9257a986664295dc Merge branch 'prod' into 'main' Document gitlab-shell on GitLab SaaS See merge request gitlab-org/gitlab-shell!625 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -52,6 +52,44 @@ There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). +## GitLab SaaS + +A diagram of the flow of `gitlab-shell` on GitLab.com: + +```mermaid +graph LR + a2 --> b2 + a2 --> b3 + a2 --> b4 + b2 --> c1 + b3 --> c1 + b4 --> c1 + c2 --> d1 + c2 --> d2 + c2 --> d3 + d1 --> e1 + d2 --> e1 + d3 --> e1 + a1[Cloudflare] --> a2[TCP<br/> load balancer] + e1[Git] + + subgraph HAProxy Fleet + b2[HAProxy] + b3[HAProxy] + b4[HAProxy] + end + + subgraph GKE + c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods] + end + + subgraph Gitaly + d1[Gitaly] + d2[Gitaly] + d3[Gitaly] + end +``` + ## Releasing See [PROCESS.md](./PROCESS.md) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653431447 25200 # Tue May 24 15:30:47 2022 -0700 # Node ID 6a3edabded6c36eb3818e27c0817a62b252da147 # Parent 86e1d0dc34802c5fd17f5f5248e69ec3bbdf1fc1 Log gitlab-sshd session level indicator errors In production, we saw gitlab-sshd error metrics rise, but it was not clear why. We now log a message every time we encounter a session error that affects the service level indicator counter. diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -7,6 +7,7 @@ "strings" "time" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" @@ -136,7 +137,7 @@ metrics.SliSshdSessionsTotal.Inc() err := handler(sconn, channel, requests) if err != nil { - c.trackError(err) + c.trackError(ctxlog, err) } ctxlog.Info("connection: handleRequests: done") @@ -167,7 +168,7 @@ } } -func (c *connection) trackError(err error) { +func (c *connection) trackError(ctxlog *logrus.Entry, err error) { var apiError *client.ApiError if errors.As(err, &apiError) { return @@ -179,4 +180,5 @@ } metrics.SliSshdSessionsErrorsTotal.Inc() + ctxlog.WithError(err).Warn("connection: session error") } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653447596 0 # Wed May 25 02:59:56 2022 +0000 # Node ID 07b38ad716c3a4de5f8d3c411704fa03e3710120 # Parent 86e1d0dc34802c5fd17f5f5248e69ec3bbdf1fc1 # Parent 6a3edabded6c36eb3818e27c0817a62b252da147 Merge branch 'sh-log-session-errors' into 'main' Log gitlab-sshd session level indicator errors See merge request gitlab-org/gitlab-shell!650 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -7,6 +7,7 @@ "strings" "time" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" @@ -136,7 +137,7 @@ metrics.SliSshdSessionsTotal.Inc() err := handler(sconn, channel, requests) if err != nil { - c.trackError(err) + c.trackError(ctxlog, err) } ctxlog.Info("connection: handleRequests: done") @@ -167,7 +168,7 @@ } } -func (c *connection) trackError(err error) { +func (c *connection) trackError(ctxlog *logrus.Entry, err error) { var apiError *client.ApiError if errors.As(err, &apiError) { return @@ -179,4 +180,5 @@ } metrics.SliSshdSessionsErrorsTotal.Inc() + ctxlog.WithError(err).Warn("connection: session error") } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653448632 -14400 # Wed May 25 07:17:12 2022 +0400 # Node ID e3ba7fb0b513299d331e32126b7a477fd6c867fc # Parent 86e1d0dc34802c5fd17f5f5248e69ec3bbdf1fc1 Improve establish session duration metrics Before we took into account the time a user takes to authenticate Now it only measures the time between a connection established and a command started to being executed It's still can be controlled by a user, but it's something we can measure and restrict if necessary diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -24,13 +24,11 @@ var EOFTimeout = 10 * time.Second type connection struct { - cfg *config.Config - concurrentSessions *semaphore.Weighted - nconn net.Conn - maxSessions int64 - remoteAddr string - started time.Time - establishSessionDuration float64 + cfg *config.Config + concurrentSessions *semaphore.Weighted + nconn net.Conn + maxSessions int64 + remoteAddr string } type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error @@ -44,7 +42,6 @@ concurrentSessions: semaphore.NewWeighted(maxSessions), nconn: nconn, remoteAddr: nconn.RemoteAddr().String(), - started: time.Now(), } } @@ -63,11 +60,7 @@ c.handleRequests(ctx, sconn, chans, handler) reason := sconn.Wait() - log.WithContextFields(ctx, log.Fields{ - "duration_s": time.Since(c.started).Seconds(), - "establish_session_duration_s": c.establishSessionDuration, - "reason": reason, - }).Info("server: handleConn: done") + log.WithContextFields(ctx, log.Fields{"reason": reason}).Info("server: handleConn: done") } func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { @@ -119,10 +112,10 @@ go func() { defer func(started time.Time) { - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + duration := time.Since(started).Seconds() + metrics.SshdSessionDuration.Observe(duration) + ctxlog.WithFields(log.Fields{"duration_s": duration}).Info("connection: handleRequests: done") }(time.Now()) - c.establishSessionDuration = time.Since(c.started).Seconds() - metrics.SshdSessionEstablishedDuration.Observe(c.establishSessionDuration) defer c.concurrentSessions.Release(1) @@ -138,8 +131,6 @@ if err != nil { c.trackError(err) } - - ctxlog.Info("connection: handleRequests: done") }() } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -5,6 +5,7 @@ "errors" "fmt" "reflect" + "time" "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" @@ -16,6 +17,7 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -29,6 +31,7 @@ // State managed by the session execCmd string gitProtocolVersion string + started time.Time } type execRequest struct { @@ -171,7 +174,12 @@ } cmdName := reflect.TypeOf(cmd).String() - ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + + establishSessionDuration := time.Since(s.started).Seconds() + ctxlog.WithFields(log.Fields{ + "env": env, "command": cmdName, "established_session_duration_s": establishSessionDuration, + }).Info("session: handleShell: executing command") + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) if err := cmd.Execute(ctx); err != nil { grpcStatus := grpcstatus.Convert(err) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -171,6 +171,7 @@ } }() + started := time.Now() conn := newConnection(s.Config, nconn) conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ @@ -178,6 +179,7 @@ channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, + started: started, } return session.handle(ctx, requests) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653457980 0 # Wed May 25 05:53:00 2022 +0000 # Node ID 74d8627ee0a7594386438c942c27f5f1e217b1fc # Parent 07b38ad716c3a4de5f8d3c411704fa03e3710120 # Parent e3ba7fb0b513299d331e32126b7a477fd6c867fc Merge branch 'id-session-duration' into 'main' Improve establish session duration metrics See merge request gitlab-org/gitlab-shell!651 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -25,13 +25,11 @@ var EOFTimeout = 10 * time.Second type connection struct { - cfg *config.Config - concurrentSessions *semaphore.Weighted - nconn net.Conn - maxSessions int64 - remoteAddr string - started time.Time - establishSessionDuration float64 + cfg *config.Config + concurrentSessions *semaphore.Weighted + nconn net.Conn + maxSessions int64 + remoteAddr string } type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error @@ -45,7 +43,6 @@ concurrentSessions: semaphore.NewWeighted(maxSessions), nconn: nconn, remoteAddr: nconn.RemoteAddr().String(), - started: time.Now(), } } @@ -64,11 +61,7 @@ c.handleRequests(ctx, sconn, chans, handler) reason := sconn.Wait() - log.WithContextFields(ctx, log.Fields{ - "duration_s": time.Since(c.started).Seconds(), - "establish_session_duration_s": c.establishSessionDuration, - "reason": reason, - }).Info("server: handleConn: done") + log.WithContextFields(ctx, log.Fields{"reason": reason}).Info("server: handleConn: done") } func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { @@ -120,10 +113,10 @@ go func() { defer func(started time.Time) { - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + duration := time.Since(started).Seconds() + metrics.SshdSessionDuration.Observe(duration) + ctxlog.WithFields(log.Fields{"duration_s": duration}).Info("connection: handleRequests: done") }(time.Now()) - c.establishSessionDuration = time.Since(c.started).Seconds() - metrics.SshdSessionEstablishedDuration.Observe(c.establishSessionDuration) defer c.concurrentSessions.Release(1) @@ -139,8 +132,6 @@ if err != nil { c.trackError(ctxlog, err) } - - ctxlog.Info("connection: handleRequests: done") }() } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -5,6 +5,7 @@ "errors" "fmt" "reflect" + "time" "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" @@ -16,6 +17,7 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -29,6 +31,7 @@ // State managed by the session execCmd string gitProtocolVersion string + started time.Time } type execRequest struct { @@ -171,7 +174,12 @@ } cmdName := reflect.TypeOf(cmd).String() - ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + + establishSessionDuration := time.Since(s.started).Seconds() + ctxlog.WithFields(log.Fields{ + "env": env, "command": cmdName, "established_session_duration_s": establishSessionDuration, + }).Info("session: handleShell: executing command") + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) if err := cmd.Execute(ctx); err != nil { grpcStatus := grpcstatus.Convert(err) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -171,6 +171,7 @@ } }() + started := time.Now() conn := newConnection(s.Config, nconn) conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ @@ -178,6 +179,7 @@ channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, + started: started, } return session.handle(ctx, requests) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653458300 -14400 # Wed May 25 09:58:20 2022 +0400 # Node ID 8946ad1922582f61ba1733dacb96488c4dcb1ed5 # Parent 74d8627ee0a7594386438c942c27f5f1e217b1fc Calculate session start after the connection is established diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -171,7 +171,6 @@ } }() - started := time.Now() conn := newConnection(s.Config, nconn) conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ @@ -179,7 +178,7 @@ channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, - started: started, + started: time.Now(), } return session.handle(ctx, requests) # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1653460729 0 # Wed May 25 06:38:49 2022 +0000 # Node ID 4984af77b5c3df66b168e5c0087f4cd60f615561 # Parent 74d8627ee0a7594386438c942c27f5f1e217b1fc # Parent 8946ad1922582f61ba1733dacb96488c4dcb1ed5 Merge branch 'id-calculate-started-just-before-session-handling' into 'main' Calculate session start after the connection is established See merge request gitlab-org/gitlab-shell!653 diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -171,7 +171,6 @@ } }() - started := time.Now() conn := newConnection(s.Config, nconn) conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ @@ -179,7 +178,7 @@ channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, - started: started, + started: time.Now(), } return session.handle(ctx, requests) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653458005 -14400 # Wed May 25 09:53:25 2022 +0400 # Node ID b602f160745449f796a881587617e23563ccbf10 # Parent 4984af77b5c3df66b168e5c0087f4cd60f615561 Release 14.7.1 - Log gitlab-sshd session level indicator errors !650 - Improve establish session duration metrics !651 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.7.1 + +- Log gitlab-sshd session level indicator errors !650 +- Improve establish session duration metrics !651 + v14.7.0 - Abort long-running unauthenticated SSH connections !647 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.0 +14.7.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1653461319 0 # Wed May 25 06:48:39 2022 +0000 # Node ID 4d1b81301352f36de1c3c11f5a68dd5cf48afab4 # Parent 4984af77b5c3df66b168e5c0087f4cd60f615561 # Parent b602f160745449f796a881587617e23563ccbf10 Merge branch 'id-release-14-7-1' into 'main' Release 14.7.1 See merge request gitlab-org/gitlab-shell!652 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.7.1 + +- Log gitlab-sshd session level indicator errors !650 +- Improve establish session duration metrics !651 + v14.7.0 - Abort long-running unauthenticated SSH connections !647 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.0 +14.7.1 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1654057997 -14400 # Wed Jun 01 08:33:17 2022 +0400 # Node ID 5ee2cc7cd7fbb191a859820e0e90243755abf41f # Parent 4d1b81301352f36de1c3c11f5a68dd5cf48afab4 Exclude disallowed command from error rate diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -14,6 +14,7 @@ grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -165,6 +166,10 @@ return } + if errors.Is(err, disallowedcommand.Error) { + return + } + grpcCode := grpcstatus.Code(err) if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { return diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -15,6 +15,7 @@ grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -212,30 +213,24 @@ require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return grpcstatus.Error(grpccodes.Canceled, "canceled") - }) - - require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + for i, ignoredError := range []struct { + desc string + err error + }{ + {"canceled requests", grpcstatus.Error(grpccodes.Canceled, "canceled")}, + {"unavailable Gitaly", grpcstatus.Error(grpccodes.Unavailable, "unavailable")}, + {"api error", &client.ApiError{"api error"}}, + {"disallowed command", disallowedcommand.Error}, + } { + t.Run(ignoredError.desc, func(t *testing.T) { + conn, chans = setup(1, newChannel) + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return ignoredError.err + }) - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return &client.ApiError{"api error"} - }) - - require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return grpcstatus.Error(grpccodes.Unavailable, "unavailable") - }) - - require.InDelta(t, initialSessionsTotal+4, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + }) + } } # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1654491072 0 # Mon Jun 06 04:51:12 2022 +0000 # Node ID 6176a3759da53856c0f46f41d3179f503a7ccea7 # Parent 4d1b81301352f36de1c3c11f5a68dd5cf48afab4 # Parent 5ee2cc7cd7fbb191a859820e0e90243755abf41f Merge branch 'id-ignore-disallowed-cmd-err' into 'main' Exclude disallowed command from error rate See merge request gitlab-org/gitlab-shell!654 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -14,6 +14,7 @@ grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -165,6 +166,10 @@ return } + if errors.Is(err, disallowedcommand.Error) { + return + } + grpcCode := grpcstatus.Code(err) if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { return diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -15,6 +15,7 @@ grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -212,30 +213,24 @@ require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return grpcstatus.Error(grpccodes.Canceled, "canceled") - }) - - require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + for i, ignoredError := range []struct { + desc string + err error + }{ + {"canceled requests", grpcstatus.Error(grpccodes.Canceled, "canceled")}, + {"unavailable Gitaly", grpcstatus.Error(grpccodes.Unavailable, "unavailable")}, + {"api error", &client.ApiError{"api error"}}, + {"disallowed command", disallowedcommand.Error}, + } { + t.Run(ignoredError.desc, func(t *testing.T) { + conn, chans = setup(1, newChannel) + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return ignoredError.err + }) - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return &client.ApiError{"api error"} - }) - - require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return grpcstatus.Error(grpccodes.Unavailable, "unavailable") - }) - - require.InDelta(t, initialSessionsTotal+4, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + }) + } } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1654504723 -14400 # Mon Jun 06 12:38:43 2022 +0400 # Node ID 7d60e21882ecf8a085f61c540ba5fbdfb159b130 # Parent 6176a3759da53856c0f46f41d3179f503a7ccea7 Release 14.7.2 - Exclude disallowed command from error rate diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.7.2 + +- Exclude disallowed command from error rate !654 + v14.7.1 - Log gitlab-sshd session level indicator errors !650 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.1 +14.7.2 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1654505161 0 # Mon Jun 06 08:46:01 2022 +0000 # Node ID 02577e13cefa3ad7eda5a8f640694cd857246a8d # Parent 6176a3759da53856c0f46f41d3179f503a7ccea7 # Parent 7d60e21882ecf8a085f61c540ba5fbdfb159b130 Merge branch 'id-release-14-7-2' into 'main' Release 14.7.2 See merge request gitlab-org/gitlab-shell!655 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.7.2 + +- Exclude disallowed command from error rate !654 + v14.7.1 - Log gitlab-sshd session level indicator errors !650 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.1 +14.7.2 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1654535340 25200 # Mon Jun 06 10:09:00 2022 -0700 # Node ID c592da0f9a7e25a4213aa564acbdad38c1fd6acf # Parent 02577e13cefa3ad7eda5a8f640694cd857246a8d Ignore "not our ref" errors from gitlab-sshd error metrics If a client requests a ref that cannot be found in the repository, previously gitlab-sshd would record it as part of its service level indicator metric. This is really an application error between the client and the Git repository, so we exclude it from our metrics. Relates to https://gitlab.com/gitlab-com/gl-infra/reliability/-/issues/15848 Changelog: fixed diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -21,7 +21,10 @@ "gitlab.com/gitlab-org/labkit/log" ) -const KeepAliveMsg = "keepalive@openssh.com" +const ( + KeepAliveMsg = "keepalive@openssh.com" + NotOurRefError = `exit status 128, stderr: "fatal: git upload-pack: not our ref ` +) var EOFTimeout = 10 * time.Second @@ -173,6 +176,8 @@ grpcCode := grpcstatus.Code(err) if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { return + } else if grpcCode == grpccodes.Internal && strings.Contains(err.Error(), NotOurRefError) { + return } metrics.SliSshdSessionsErrorsTotal.Inc() diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -221,6 +221,7 @@ {"unavailable Gitaly", grpcstatus.Error(grpccodes.Unavailable, "unavailable")}, {"api error", &client.ApiError{"api error"}}, {"disallowed command", disallowedcommand.Error}, + {"not our ref", grpcstatus.Error(grpccodes.Internal, `rpc error: code = Internal desc = cmd wait: exit status 128, stderr: "fatal: git upload-pack: not our ref 9106d18f6a1b8022f6517f479696f3e3ea5e68c1"`)}, } { t.Run(ignoredError.desc, func(t *testing.T) { conn, chans = setup(1, newChannel) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1654537263 0 # Mon Jun 06 17:41:03 2022 +0000 # Node ID 2045af844a92d01d7feb031315da05df45186949 # Parent 02577e13cefa3ad7eda5a8f640694cd857246a8d # Parent c592da0f9a7e25a4213aa564acbdad38c1fd6acf Merge branch 'sh-ignore-not-our-ref-errors' into 'main' Ignore "not our ref" errors from gitlab-sshd error metrics See merge request gitlab-org/gitlab-shell!656 diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -21,7 +21,10 @@ "gitlab.com/gitlab-org/labkit/log" ) -const KeepAliveMsg = "keepalive@openssh.com" +const ( + KeepAliveMsg = "keepalive@openssh.com" + NotOurRefError = `exit status 128, stderr: "fatal: git upload-pack: not our ref ` +) var EOFTimeout = 10 * time.Second @@ -173,6 +176,8 @@ grpcCode := grpcstatus.Code(err) if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { return + } else if grpcCode == grpccodes.Internal && strings.Contains(err.Error(), NotOurRefError) { + return } metrics.SliSshdSessionsErrorsTotal.Inc() diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -221,6 +221,7 @@ {"unavailable Gitaly", grpcstatus.Error(grpccodes.Unavailable, "unavailable")}, {"api error", &client.ApiError{"api error"}}, {"disallowed command", disallowedcommand.Error}, + {"not our ref", grpcstatus.Error(grpccodes.Internal, `rpc error: code = Internal desc = cmd wait: exit status 128, stderr: "fatal: git upload-pack: not our ref 9106d18f6a1b8022f6517f479696f3e3ea5e68c1"`)}, } { t.Run(ignoredError.desc, func(t *testing.T) { conn, chans = setup(1, newChannel) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1654537499 -14400 # Mon Jun 06 21:44:59 2022 +0400 # Node ID a2a739e3f554ecf529f321a4d7b32d178f578be7 # Parent 2045af844a92d01d7feb031315da05df45186949 Release v14.7.3 - Ignore "not our ref" errors from gitlab-sshd error metrics diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.7.3 + +- Ignore "not our ref" errors from gitlab-sshd error metrics !656 + v14.7.2 - Exclude disallowed command from error rate !654 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.2 +14.7.3 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1654538412 0 # Mon Jun 06 18:00:12 2022 +0000 # Node ID caa03cf8351fe1ec3bc901200e04d13123011ac0 # Parent 2045af844a92d01d7feb031315da05df45186949 # Parent a2a739e3f554ecf529f321a4d7b32d178f578be7 Merge branch 'id-release-14-7-3' into 'main' Release v14.7.3 See merge request gitlab-org/gitlab-shell!657 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.7.3 + +- Ignore "not our ref" errors from gitlab-sshd error metrics !656 + v14.7.2 - Exclude disallowed command from error rate !654 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.2 +14.7.3 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1654590701 25200 # Tue Jun 07 01:31:41 2022 -0700 # Node ID 815d4e96d450647f3d7ac1e08ebe19e44c57f172 # Parent 02577e13cefa3ad7eda5a8f640694cd857246a8d Upgrade Gemfile.lock to use bundler to v2.3.15 This is just to minimize the versions of bundler used for development. The GDK runs `support/bundle-install` in this directory to obtain the version of bundler needed. This relates to https://gitlab.com/gitlab-org/gitlab/-/issues/364373. diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,4 +113,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.3.6 + 2.3.15 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1654600872 0 # Tue Jun 07 11:21:12 2022 +0000 # Node ID 4493ab240bbec0f36c1379d187f9f82e09f58f83 # Parent caa03cf8351fe1ec3bc901200e04d13123011ac0 # Parent 815d4e96d450647f3d7ac1e08ebe19e44c57f172 Merge branch 'sh-upgrade-bundler-version' into 'main' Upgrade Gemfile.lock to use bundler to v2.3.15 See merge request gitlab-org/gitlab-shell!658 diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,4 +113,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.3.6 + 2.3.15 # HG changeset patch # User Alejandro RodrÃÂguez <alejorro70@gmail.com> # Date 1654869688 -7200 # Fri Jun 10 16:01:28 2022 +0200 # Node ID 20c30f8a78288a1a9f505105757d86297b21f193 # Parent 4493ab240bbec0f36c1379d187f9f82e09f58f83 Set BUNDLE_FROZEN to true To follow rubygems' security adisory https://github.com/rubygems/rubygems.org/security/advisories/GHSA-hccv-rwq6-vh79: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ variables: DOCKER_VERSION: "20.10.15" + BUNDLE_FROZEN: "true" workflow: rules: &workflow_rules # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1655196892 0 # Tue Jun 14 08:54:52 2022 +0000 # Node ID d4ceca3bc914146fc28c8b239f2ea96eaa31a1b1 # Parent 4493ab240bbec0f36c1379d187f9f82e09f58f83 # Parent 20c30f8a78288a1a9f505105757d86297b21f193 Merge branch 'freeze-bundle' into 'main' Set BUNDLE_FROZEN to true Closes #562 See merge request gitlab-org/gitlab-shell!659 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ variables: DOCKER_VERSION: "20.10.15" + BUNDLE_FROZEN: "true" workflow: rules: &workflow_rules # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1655248838 25200 # Tue Jun 14 16:20:38 2022 -0700 # Node ID 613c8ffa93c6dc492503e2ebd1cc7b500059dcf4 # Parent d4ceca3bc914146fc28c8b239f2ea96eaa31a1b1 gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent When we put gitlab-sshd in production, we noticed a number of clients using RSA keys would fail to login. The server would report: ``` ssh: signature "ssh-rsa" not compatible with selected algorithm "rsa-sha2-512" ``` This is reproducible on Ubuntu 18.04, which ships gpg-agent v2.2.4 and OpenSSH v7.6. That version of gpg-agent does not support `rsa-sha2-256` or `rsa-sha2-512`, but OpenSSH does. As a result, OpenSSH specifies `rsa-sha-512` as the public key algorithm to use in the user authentication request message, but gpg-agent includes an `ssh-rsa` signature. OpenSSH servers tolerates this discrepancy, but the Go implementation fails because it expects a strict match. This commit pulls in https://gitlab.com/gitlab-org/golang-crypto/-/merge_requests/9 to fix the problem. Relates to: 1. https://github.com/golang/go/issues/53391 2. https://gitlab.com/gitlab-org/gitlab-shell/-/issues/587 Changelog: fixed diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -81,4 +81,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) -replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -888,8 +888,8 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac h1:qNUzqBTbEGGjF5Fp0NWz3rNmqamwchxM+QKUZYeOS1c= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1655363387 0 # Thu Jun 16 07:09:47 2022 +0000 # Node ID 0a35bc7598fe9d46f27ce99bb9641f29e7772ab6 # Parent d4ceca3bc914146fc28c8b239f2ea96eaa31a1b1 # Parent 613c8ffa93c6dc492503e2ebd1cc7b500059dcf4 Merge branch 'sh-update-crypto-lib' into 'main' gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent See merge request gitlab-org/gitlab-shell!662 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -81,4 +81,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) -replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -888,8 +888,8 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac h1:qNUzqBTbEGGjF5Fp0NWz3rNmqamwchxM+QKUZYeOS1c= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1655363436 -7200 # Thu Jun 16 09:10:36 2022 +0200 # Node ID c310139f96439ddba4192f3d2839d7f7c9609626 # Parent 0a35bc7598fe9d46f27ce99bb9641f29e7772ab6 Release v14.7.4 - Update crypto module to fix RSA keys with old gpg-agent diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.7.4 + +- gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent !662 + v14.7.3 - Ignore "not our ref" errors from gitlab-sshd error metrics !656 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.3 +14.7.4 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1655364199 0 # Thu Jun 16 07:23:19 2022 +0000 # Node ID d27c5af605da53832cae29fa0f9a200c1447047b # Parent 0a35bc7598fe9d46f27ce99bb9641f29e7772ab6 # Parent c310139f96439ddba4192f3d2839d7f7c9609626 Merge branch 'id-release-14-7-4' into 'main' Release v14.7.4 See merge request gitlab-org/gitlab-shell!663 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.7.4 + +- gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent !662 + v14.7.3 - Ignore "not our ref" errors from gitlab-sshd error metrics !656 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.3 +14.7.4 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1656001706 25200 # Thu Jun 23 09:28:26 2022 -0700 # Node ID d65758fc2f6f6035f0fafbfe537bfb6c3676a785 # Parent d27c5af605da53832cae29fa0f9a200c1447047b Fix make install copying the wrong binaries While testing https://gitlab.com/gitlab-org/build/CNG/-/merge_requests/1062, we found `make install` was not copying the right binaries, such as `gitlab-shell-authorized-keys-check`. This might have originally been written with a single binary in mind (https://gitlab.com/gitlab-org/gitlab-shell/-/issues/207). Changelog: fixed diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ mkdir -p $(DESTDIR)$(PREFIX)/bin/ install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd - + install -m755 bin/gitlab-shell-authorized-keys-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell-authorized-principals-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-sshd $(DESTDIR)$(PREFIX)/bin/gitlab-sshd # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1656002841 0 # Thu Jun 23 16:47:21 2022 +0000 # Node ID 0093de29bc5020319e5d6ef4a9be0f4b09b46a1e # Parent d27c5af605da53832cae29fa0f9a200c1447047b # Parent d65758fc2f6f6035f0fafbfe537bfb6c3676a785 Merge branch 'fix-make-install' into 'main' Fix make install copying the wrong binaries See merge request gitlab-org/gitlab-shell!664 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ mkdir -p $(DESTDIR)$(PREFIX)/bin/ install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd - + install -m755 bin/gitlab-shell-authorized-keys-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell-authorized-principals-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-sshd $(DESTDIR)$(PREFIX)/bin/gitlab-sshd # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1654983745 25200 # Sat Jun 11 14:42:25 2022 -0700 # Node ID c1924280df1446887110459c5ad1aeb05f9efb1b # Parent 0093de29bc5020319e5d6ef4a9be0f4b09b46a1e gitlab-sshd: Add support for configuring host certificates This adds support for specifying host certificates via the `host_cert_files` option and advertises the signed key to the client. This acts similarly to OpenSSH's `HostCertificate` parameter: gitlab-sshd attempts to match a host key to its certificate, and then substitutes the matching host key with a certificate signed by a trusted certificate authority's key. This is the first requirement to supporting SSH certificates. This will enable the client to trust the server if both trust a common certificate authority. The `TrustedUserCAKeys` option will need to be supported later for the server to trust all user keys signed by this certificate authority. Relates to https://gitlab.com/gitlab-org/gitlab-shell/-/issues/495 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -99,3 +99,7 @@ - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key + host_key_certs: + - /run/secrets/ssh-hostkeys/ssh_host_rsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key-cert.pub diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -36,6 +36,7 @@ ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` + HostCertFiles []string `yaml:"host_cert_files,omitempty"` MACs []string `yaml:"macs"` KexAlgorithms []string `yaml:"kex_algorithms"` Ciphers []string `yaml:"ciphers"` diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -39,17 +39,14 @@ type serverConfig struct { cfg *config.Config hostKeys []ssh.Signer + hostKeyToCertMap map[string]*ssh.Certificate authorizedKeysClient *authorizedkeys.Client } -func newServerConfig(cfg *config.Config) (*serverConfig, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) - if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) - } +func parseHostKeys(keyFiles []string) []ssh.Signer { + var hostKeys []ssh.Signer - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { + for _, filename := range keyFiles { keyRaw, err := os.ReadFile(filename) if err != nil { log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") @@ -63,11 +60,70 @@ hostKeys = append(hostKeys, key) } + + return hostKeys +} + +func parseHostCerts(hostKeys []ssh.Signer, certFiles []string) map[string]*ssh.Certificate { + keyToCertMap := map[string]*ssh.Certificate{} + hostKeyIndex := make(map[string]int) + + for index, hostKey := range hostKeys { + hostKeyIndex[string(hostKey.PublicKey().Marshal())] = index + } + + for _, filename := range certFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to read host certificate") + continue + } + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to parse host certificate") + continue + } + + cert, ok := publicKey.(*ssh.Certificate) + if !ok { + log.WithFields(log.Fields{"filename": filename}).Warn("failed to decode host certificate") + continue + } + + hostRawKey := string(cert.Key.Marshal()) + index, found := hostKeyIndex[hostRawKey] + if found { + keyToCertMap[hostRawKey] = cert + + certSigner, err := ssh.NewCertSigner(cert, hostKeys[index]) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("the host certificate doesn't match the host private key") + continue + } + + hostKeys[index] = certSigner + } else { + log.WithFields(log.Fields{"filename": filename}).Warnf("no matching private key for certificate %s", filename) + } + } + + return keyToCertMap +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + hostKeys := parseHostKeys(cfg.Server.HostKeyFiles) if len(hostKeys) == 0 { return nil, fmt.Errorf("No host keys could be loaded, aborting") } - return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + hostKeyToCertMap := parseHostCerts(hostKeys, cfg.Server.HostCertFiles) + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys, hostKeyToCertMap: hostKeyToCertMap}, nil } func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -5,6 +5,7 @@ "crypto/dsa" "crypto/rand" "crypto/rsa" + "os" "path" "testing" @@ -22,6 +23,45 @@ require.Equal(t, "No host keys could be loaded, aborting", err.Error()) } +func TestHostKeyAndCerts(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + }, + HostCertFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/valid/server2-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + require.Len(t, cfg.hostKeys, 1) + require.Len(t, cfg.hostKeyToCertMap, 1) + + // Check that the entry is pointing to the server's public key + data, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server.pub")) + require.NoError(t, err) + + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(data) + require.NoError(t, err) + require.NotNil(t, publicKey) + cert, ok := cfg.hostKeyToCertMap[string(publicKey.Marshal())] + require.True(t, ok) + require.NotNil(t, cert) + require.Equal(t, cert, cfg.hostKeys[0].PublicKey()) +} + func TestFailedAuthorizedKeysClient(t *testing.T) { _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) diff --git a/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql not_a_valid_cert.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca b/internal/testhelper/testdata/testroot/certs/valid/ca new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV ++IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfw +FoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj +4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4 +NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqI +cXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfX +KGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCf +EG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAAFkA5fIlIOXyJSAAAAB3NzaC1yc2 +EAAAGBANyFATfNPwSRubrfVNt/BcCBgHzGUKDl2GxbYkGaPlPnHWxiZRBoFfiE6Bje/GCc +qZGyvDYqbTDDoFmfHrugwiTDcYz2+3t12Bq5hz3qCuWfYqBEg8NEEpMQyH8BaC0p8dPnol +0td/MqRDYC0/4TjJfn5q6AO+Gab5LyKSvkaAKNapVglrQOzcoJEJFkYJ5wI+I5AyqvWk9Y +hxmvZ0GC7k7X4l95d+f6DjjCRaw4O22+RB5wbCnsA6AMXajW8aeFv7EMlBeDWzhSxs0Wrw +OnjUXzsfVF3HctL/flIAprvdp24j5jQaPcGNw/aa8FwFnrUzNQd2Qg5NYaiHF0YOqTQTQv +Xthbm3IbPU3Ky2maa+JIBb03pBnKH9ZtqMyU1ZXCCZSacveZqdbl8MUz231yhj7yruza6E +dmr5ACH8EY+RP/B8K4Ax9q/+LkT2nUQsfYZt/ByNZ+kuGK67Ji/X3y1ukgnxBunO/lEQ0K +9fFavWMsTJrtPRCu1ZQw19CTNFGp+QAAAAMBAAEAAAGACHnYRSPPc0aCpAsngNRODUss/B +7HRJfxDKEqkqjyElmEyQCzL8FAbu/019fiTXhYEDCViWNyFPi/9hHmpYGVVMJqX+eyXNl3 +t/c/moKfbpoEuXJIuj2olRyFCFSug2XkVKfHlttDjAYo3waWzWJE+iXAuR5WruI3vacvK+ ++4i7iRyzIOONeE02orx9ra19wplO1qEL7ysrANaVBToLH+pOspWVAa6sCywT2+XdM/fYVd +qunZTncy4Hj5NJ8mZLEATfJKnT2v7C47fBjN+ylqpyTImBZxSfVyjrljcQXb9ExjAhVTjv +tBuZdB1NPnok9cycwpg6aGXuZX2mSQWROhHM/r80kUzfxJpRDs/AqMWRZYC2k/kCKbXg7S +1cuAwJ2SiH5jslekhbB8bCU3rL2SgUV4oZsqh5fb6ZsytXarbzX/8Kcmb4KGsjZ7wBD6Yu +sJ05TkzC/HkOT3xTXwyzZpEldKucLClnY3Boq8pkO1EoUD8uPJNgSgukH9W5SleaIxAAAA +wEzXR8Av4SxsgWW2pPVtQaeKhUKrid21RuPF5/7c4PZ4GlnhL3Fod4PwdD8yPjuIuI7s6/ +9HRxzi+vr616/BXMagGWPSZEQMaX6I/L5CSratN2Dk1jSYcH501GseILr+kIcZhe7HoEf2 +xbr8ByF88DXpeSdimIqMeVYTPGWac7oSf3Y5WHi9FUuJ4BEccu8bLIXWkGMK6yi/zJo1RQ +u4aMzdMyzat0C2aeAm40HABdUv350K/H20Voj7zfhmlXvQ7wAAAMEA8a1oEPFL1+cAqfUD +Jbx+KWyw/1kFBIpU93rk2qfJR593nMLebAk0l9qfhbvlN6GTNcGETjzGK1bHaD9G14c2IT +bFcIoKmah6LygIlMGwdTMSWPPrczeIhMy6H0rJ2lDa208+nLwKqlFlMDYNpycL2Q1ZynnB +fYqfRiUSDJcs+2jfTX0gA17NuSwqp6j/JlMm45tN3GK1neIVH+4PBazBXqZTzdfCfqJ9r5 +TWJw2i6CsSlCDAtO3uo+Pyj327RbNtAAAAwQDplpqK2+0+QiQB+LUeT0hfWp5/HmXJjfgm +u+xIICJKPqOYwDvBWEHHssv7YS70dFJrbENJ66NZfdv+foDbQXrr10odbIntk9QoO4CS1g +zd63kolFCLhbwkYos45CjJIPuzNDeiYIgsLEOQwnjHbp3HxAIywxtUPKj80YmfoogeidiD +JNMwRoJfqlNziW1PDq0r8Zhw2lbyGZPI218ox7tsJ94BS4MFJfgASwO9qcDsaYz23sS8uQ +BBbY6cCknC7T0AAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca.pub b/internal/testhelper/testdata/testroot/certs/valid/ca.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDchQE3zT8Ekbm631TbfwXAgYB8xlCg5dhsW2JBmj5T5x1sYmUQaBX4hOgY3vxgnKmRsrw2Km0ww6BZnx67oMIkw3GM9vt7ddgauYc96grln2KgRIPDRBKTEMh/AWgtKfHT56JdLXfzKkQ2AtP+E4yX5+augDvhmm+S8ikr5GgCjWqVYJa0Ds3KCRCRZGCecCPiOQMqr1pPWIcZr2dBgu5O1+JfeXfn+g44wkWsODttvkQecGwp7AOgDF2o1vGnhb+xDJQXg1s4UsbNFq8Dp41F87H1Rdx3LS/35SAKa73aduI+Y0Gj3BjcP2mvBcBZ61MzUHdkIOTWGohxdGDqk0E0L17YW5tyGz1NystpmmviSAW9N6QZyh/WbajMlNWVwgmUmnL3manW5fDFM9t9coY+8q7s2uhHZq+QAh/BGPkT/wfCuAMfav/i5E9p1ELH2GbfwcjWfpLhiuuyYv198tbpIJ8Qbpzv5RENCvXxWr1jLEya7T0QrtWUMNfQkzRRqfk= test@test.example.org diff --git a/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgNGUtD+qw0Xj5NU2uj4+4LoCWPcvXP54F9Adw/hWN5LAAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yqlAAAAAAAAAAAAAAACAAAABnNlcnZlcgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGAapK5VzLDoRe88tnLORrH8VxLegTWPKGdn0k5Ye8tS5XUgd0N98gU669y4ErDNf0kPxlz40bjsfisEEtJ/N7m14IskCepScfZRh8w6QgPxbTOhmrc89xooqBUE50y5FU9hIIbzUrnEP+Dfu4IiFPToAguCa+KoAKiOX7lBQqEugV6uOWVZ2erPopEv+OiMLD8hXsuKKjQ+TomHZ/IjuXsFdXH7Vcl0VsPaAcxyCtDU7nCTJSTUoUZtMtwwpulp0e/zNmFrEn2Binz4jRaUlk3FM2fdbotviDQYeOY3npmxaWUvvQ/eKn0/DzUTAKAGr2LDa2XWnPhj51BS1XkNaUlnupdYmZ2Sok0R4U3bfVwokteREvAltGbXQSDtZwLS5NEY6vIdDrxpn5QRf9vGjqnc7piXxye9gcLne4YDUi24IhGyHrnWKCC0HjF7tuUhCOVKrqRdmHxRGWX3PlS8Xn6HHEPWU+YZnfT1V2W7LAFcDMozQbs4GPGzZdR3f3vCOJ8 server.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server.pub b/internal/testhelper/testdata/testroot/certs/valid/server.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg3XO30wn4+lFxc5fLsanH4Pvu0OuKGHoR94zZjxx7qAEAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgokAAAAAAAAAAAAAAAIAAAAHc2VydmVyMgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGANOKG8Tq7kp9B5+CQEyb+mEatJOoQRV+4rpemWlfEw6TuVwQN2wSXc6XKBHzSG4NRnFkwk6GgiPLQEf4lBBKA8VYQnDKuhrHJlU4DFCRPw/aceHfCwNOruyJmuf91W3yEO/kYAd6EhkQiW/K3ky7BuXCqR34T2fBZSCeYhNcXWxhEMLoAuj0kEdX+YMNBmiPtinPE13KMFGyIVBm/ojgSZa8j4WnhDcK0cWv0OSGTgJF6q3hENCWRz2E1HroKUiABOy5Nca6gPVAi4OTd7gwER8eh9MngVHYorAJ3N9HjUh640SbL3zCC8f/lqIztqsHY0u3olsQ0gLXpFain+430HeyJlmVlsDZgQKRb90Mm1viSCKvHGpmVDYMimE9y0DCQS1i0yRGF1uSIPtuQ0NCbhS/HPKsT3nYgGCEuoB8aGOu3aGB/tmUkYXW+pwXRKqw0f/zX088XWYWvA+AR4hmmr6DDMnf/4EHgJp3xHTEwOBHCVj69xvlOawBNlL2X0b2p server2.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.key b/internal/testhelper/testdata/testroot/certs/valid/server2.key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.key @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEAyuDL6ZomdHC0uPqd2BMHAsKOJFWyT0xHoiDLqBCOyid8qgIyibp7 +OlaZwumkYLty5rjOLgR3IpkIuNeQpQTpuPrRYlbFTXAJLAPkLlPK0xAusT7PestWP6gvv1 +kJ+vriqdfnwLKVrC6YoN1V0k36vmAHMWX03Tv+nJNJB1b8V9PemHuw9JnatpVmxsEgZQG8 +1NcF/2Z7+YS2Q+A0htXCIwPb0P3yfacHJWYktKkNVV3aCFALy/bUwCo9veVRk9jTBhmGUA +ENL17TNWBzjAGeF6Dy9aFRY1RGaC0Q+fGug6XuIWPECnul9cO81Na6+b1WK8+zE1Guac7F +EjnlE3N5MiiaxMVZKC8gYGEKvKlvZGJPzsfcx8EwCsPb8IiLNjMHup5cSe3MOM8pDLMTyu +M/R5G2aExVst6YbjxarP1kKArx0yjY1j2m+1AGpnjOg59DfNwRdtbQkzFo5EQr7WVRiBme +2OHAIojdDj80Fg2rCfyClQ0YLmSUZ95IBwjGAoKJAAAFkBOZmjETmZoxAAAAB3NzaC1yc2 +EAAAGBAMrgy+maJnRwtLj6ndgTBwLCjiRVsk9MR6Igy6gQjsonfKoCMom6ezpWmcLppGC7 +cua4zi4EdyKZCLjXkKUE6bj60WJWxU1wCSwD5C5TytMQLrE+z3rLVj+oL79ZCfr64qnX58 +CylawumKDdVdJN+r5gBzFl9N07/pyTSQdW/FfT3ph7sPSZ2raVZsbBIGUBvNTXBf9me/mE +tkPgNIbVwiMD29D98n2nByVmJLSpDVVd2ghQC8v21MAqPb3lUZPY0wYZhlABDS9e0zVgc4 +wBnheg8vWhUWNURmgtEPnxroOl7iFjxAp7pfXDvNTWuvm9VivPsxNRrmnOxRI55RNzeTIo +msTFWSgvIGBhCrypb2RiT87H3MfBMArD2/CIizYzB7qeXEntzDjPKQyzE8rjP0eRtmhMVb +LemG48Wqz9ZCgK8dMo2NY9pvtQBqZ4zoOfQ3zcEXbW0JMxaOREK+1lUYgZntjhwCKI3Q4/ +NBYNqwn8gpUNGC5klGfeSAcIxgKCiQAAAAMBAAEAAAGAUxojzMt85wNns8HMuD6LB6FkEh +QcVwka6plecrhdlQb5tLXzt6DwayQgFcwYrhr6ZPHcWtMvbbeb8AM017OcfU4YSJzccuzq +hOIPLL7b/PrK9YWR/W2fJbIh5NJ3GRx9ji7HWpKMZpwrnvEq/1s705GIQL7Pv3Ocxsw6BM +ynzt4VdwZrpLYE9fdawx1GxLkifViat1Rmgf3PnxwOyBB1Vlx1RTVQiBHMBpDBhlMdCBPK +hM8tFd5EpXZoFgoCEXqlssIptaf0zUZAgeES31GwNrP7+n6SlL+xZxbs7ykWKjA1ibYDTE +fLIojOQCOgnIFaDFbbgUiqxoYg1SAr2SRPOjopc5EXSt5kfCdQk3I5MKoSm2INNuwBqprI +/BL0Do3VowAQkxjXJUWit9RR0wS7FiA54WJqOrfU+2ChRooVUvtt0i/0y9tJMr6+PJYawZ +uLwQ4DXs3UNVFKdopyh+zcLht+1xIZO6VrMteXejVhcz8UnRQE7leCdOvCYbBX87eRAAAA +wFX+Q0Cp8SD3Pf607nq0GNYgY+vQR/zqqTnIlYt3kKt0jP6TuvkOUnaANOt29W17LxIR1U +tZxFfyktrT4/RiVRP+QWvdLS32IN3mpCPt+J0oKujlSWrUT0SJgd7ZLePJIOscjuFqW72M +dNV7aCNIisc2QgJbp5EwCNTFxQmdqryk9Pd80kWSSAwWQ5A6jXSrLEAdaFTa9kF/o3DGNe +E/6HOTnt7BFvdE1hetYFnUTR1vqjD21Pi3d5rnePYUOGI1nAAAAMEA9fDwdHOCjosfA1ri +pWZDYYkR5JaxrCFZC5h2LcYL01aCutISH07Z5gmnAVM+CfHkihck9wiGDJuJNTo1mYR1pg +aFgoIFg8LjZzBConlSnHTPYkIYHvYFaE9T4PIS8yjlHjaDn59P06nHRNa5W/4vvhGK8eEn +hpBCQ68huqMZyCH9az6BYR1TasHY7GMbIuMXpswXt9tWRzXpuvQq0BFThNelviTw3JNFhC +cdR2+2wMCErnT0w1Y9fd+8SIHL3OdVAAAAwQDTLPokbpKxlOQOdKMGgn0CZnhiAiLMKp6k +ZQmqNjVEdiOkLWvmoBYMxW93n6uCpyc7p9R+++xXWvfIH7o4fCpiIcMKQtd7Ikp4s4uC6q +xP0QOtGui5wac/iBgd0QB7ZlRh0WNIRS0ej5sn3wHz7es5eq1F/auGhxR6i5N0EhB/qI72 +lFgWtRJsIxi0tm424K6XWEjjj7fe7k9qQ712BVOvvhZp1OK/qfsOl6lj7VPXtcVPr9+6Aw +MsHc/xbLoyRmUAAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.pub b/internal/testhelper/testdata/testroot/certs/valid/server2.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgok= # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1656518256 0 # Wed Jun 29 15:57:36 2022 +0000 # Node ID 95477d444999b8feb935a8a64f458119bb6931a6 # Parent 0093de29bc5020319e5d6ef4a9be0f4b09b46a1e # Parent c1924280df1446887110459c5ad1aeb05f9efb1b Merge branch 'sh-sshd-add-host-cert-support' into 'main' gitlab-sshd: Add support for configuring host certificates See merge request gitlab-org/gitlab-shell!661 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -99,3 +99,7 @@ - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key + host_key_certs: + - /run/secrets/ssh-hostkeys/ssh_host_rsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key-cert.pub diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -36,6 +36,7 @@ ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` + HostCertFiles []string `yaml:"host_cert_files,omitempty"` MACs []string `yaml:"macs"` KexAlgorithms []string `yaml:"kex_algorithms"` Ciphers []string `yaml:"ciphers"` diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -39,17 +39,14 @@ type serverConfig struct { cfg *config.Config hostKeys []ssh.Signer + hostKeyToCertMap map[string]*ssh.Certificate authorizedKeysClient *authorizedkeys.Client } -func newServerConfig(cfg *config.Config) (*serverConfig, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) - if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) - } +func parseHostKeys(keyFiles []string) []ssh.Signer { + var hostKeys []ssh.Signer - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { + for _, filename := range keyFiles { keyRaw, err := os.ReadFile(filename) if err != nil { log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") @@ -63,11 +60,70 @@ hostKeys = append(hostKeys, key) } + + return hostKeys +} + +func parseHostCerts(hostKeys []ssh.Signer, certFiles []string) map[string]*ssh.Certificate { + keyToCertMap := map[string]*ssh.Certificate{} + hostKeyIndex := make(map[string]int) + + for index, hostKey := range hostKeys { + hostKeyIndex[string(hostKey.PublicKey().Marshal())] = index + } + + for _, filename := range certFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to read host certificate") + continue + } + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to parse host certificate") + continue + } + + cert, ok := publicKey.(*ssh.Certificate) + if !ok { + log.WithFields(log.Fields{"filename": filename}).Warn("failed to decode host certificate") + continue + } + + hostRawKey := string(cert.Key.Marshal()) + index, found := hostKeyIndex[hostRawKey] + if found { + keyToCertMap[hostRawKey] = cert + + certSigner, err := ssh.NewCertSigner(cert, hostKeys[index]) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("the host certificate doesn't match the host private key") + continue + } + + hostKeys[index] = certSigner + } else { + log.WithFields(log.Fields{"filename": filename}).Warnf("no matching private key for certificate %s", filename) + } + } + + return keyToCertMap +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + hostKeys := parseHostKeys(cfg.Server.HostKeyFiles) if len(hostKeys) == 0 { return nil, fmt.Errorf("No host keys could be loaded, aborting") } - return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + hostKeyToCertMap := parseHostCerts(hostKeys, cfg.Server.HostCertFiles) + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys, hostKeyToCertMap: hostKeyToCertMap}, nil } func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -5,6 +5,7 @@ "crypto/dsa" "crypto/rand" "crypto/rsa" + "os" "path" "testing" @@ -22,6 +23,45 @@ require.Equal(t, "No host keys could be loaded, aborting", err.Error()) } +func TestHostKeyAndCerts(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + }, + HostCertFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/valid/server2-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + require.Len(t, cfg.hostKeys, 1) + require.Len(t, cfg.hostKeyToCertMap, 1) + + // Check that the entry is pointing to the server's public key + data, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server.pub")) + require.NoError(t, err) + + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(data) + require.NoError(t, err) + require.NotNil(t, publicKey) + cert, ok := cfg.hostKeyToCertMap[string(publicKey.Marshal())] + require.True(t, ok) + require.NotNil(t, cert) + require.Equal(t, cert, cfg.hostKeys[0].PublicKey()) +} + func TestFailedAuthorizedKeysClient(t *testing.T) { _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) diff --git a/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql not_a_valid_cert.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca b/internal/testhelper/testdata/testroot/certs/valid/ca new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV ++IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfw +FoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj +4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4 +NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqI +cXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfX +KGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCf +EG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAAFkA5fIlIOXyJSAAAAB3NzaC1yc2 +EAAAGBANyFATfNPwSRubrfVNt/BcCBgHzGUKDl2GxbYkGaPlPnHWxiZRBoFfiE6Bje/GCc +qZGyvDYqbTDDoFmfHrugwiTDcYz2+3t12Bq5hz3qCuWfYqBEg8NEEpMQyH8BaC0p8dPnol +0td/MqRDYC0/4TjJfn5q6AO+Gab5LyKSvkaAKNapVglrQOzcoJEJFkYJ5wI+I5AyqvWk9Y +hxmvZ0GC7k7X4l95d+f6DjjCRaw4O22+RB5wbCnsA6AMXajW8aeFv7EMlBeDWzhSxs0Wrw +OnjUXzsfVF3HctL/flIAprvdp24j5jQaPcGNw/aa8FwFnrUzNQd2Qg5NYaiHF0YOqTQTQv +Xthbm3IbPU3Ky2maa+JIBb03pBnKH9ZtqMyU1ZXCCZSacveZqdbl8MUz231yhj7yruza6E +dmr5ACH8EY+RP/B8K4Ax9q/+LkT2nUQsfYZt/ByNZ+kuGK67Ji/X3y1ukgnxBunO/lEQ0K +9fFavWMsTJrtPRCu1ZQw19CTNFGp+QAAAAMBAAEAAAGACHnYRSPPc0aCpAsngNRODUss/B +7HRJfxDKEqkqjyElmEyQCzL8FAbu/019fiTXhYEDCViWNyFPi/9hHmpYGVVMJqX+eyXNl3 +t/c/moKfbpoEuXJIuj2olRyFCFSug2XkVKfHlttDjAYo3waWzWJE+iXAuR5WruI3vacvK+ ++4i7iRyzIOONeE02orx9ra19wplO1qEL7ysrANaVBToLH+pOspWVAa6sCywT2+XdM/fYVd +qunZTncy4Hj5NJ8mZLEATfJKnT2v7C47fBjN+ylqpyTImBZxSfVyjrljcQXb9ExjAhVTjv +tBuZdB1NPnok9cycwpg6aGXuZX2mSQWROhHM/r80kUzfxJpRDs/AqMWRZYC2k/kCKbXg7S +1cuAwJ2SiH5jslekhbB8bCU3rL2SgUV4oZsqh5fb6ZsytXarbzX/8Kcmb4KGsjZ7wBD6Yu +sJ05TkzC/HkOT3xTXwyzZpEldKucLClnY3Boq8pkO1EoUD8uPJNgSgukH9W5SleaIxAAAA +wEzXR8Av4SxsgWW2pPVtQaeKhUKrid21RuPF5/7c4PZ4GlnhL3Fod4PwdD8yPjuIuI7s6/ +9HRxzi+vr616/BXMagGWPSZEQMaX6I/L5CSratN2Dk1jSYcH501GseILr+kIcZhe7HoEf2 +xbr8ByF88DXpeSdimIqMeVYTPGWac7oSf3Y5WHi9FUuJ4BEccu8bLIXWkGMK6yi/zJo1RQ +u4aMzdMyzat0C2aeAm40HABdUv350K/H20Voj7zfhmlXvQ7wAAAMEA8a1oEPFL1+cAqfUD +Jbx+KWyw/1kFBIpU93rk2qfJR593nMLebAk0l9qfhbvlN6GTNcGETjzGK1bHaD9G14c2IT +bFcIoKmah6LygIlMGwdTMSWPPrczeIhMy6H0rJ2lDa208+nLwKqlFlMDYNpycL2Q1ZynnB +fYqfRiUSDJcs+2jfTX0gA17NuSwqp6j/JlMm45tN3GK1neIVH+4PBazBXqZTzdfCfqJ9r5 +TWJw2i6CsSlCDAtO3uo+Pyj327RbNtAAAAwQDplpqK2+0+QiQB+LUeT0hfWp5/HmXJjfgm +u+xIICJKPqOYwDvBWEHHssv7YS70dFJrbENJ66NZfdv+foDbQXrr10odbIntk9QoO4CS1g +zd63kolFCLhbwkYos45CjJIPuzNDeiYIgsLEOQwnjHbp3HxAIywxtUPKj80YmfoogeidiD +JNMwRoJfqlNziW1PDq0r8Zhw2lbyGZPI218ox7tsJ94BS4MFJfgASwO9qcDsaYz23sS8uQ +BBbY6cCknC7T0AAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca.pub b/internal/testhelper/testdata/testroot/certs/valid/ca.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDchQE3zT8Ekbm631TbfwXAgYB8xlCg5dhsW2JBmj5T5x1sYmUQaBX4hOgY3vxgnKmRsrw2Km0ww6BZnx67oMIkw3GM9vt7ddgauYc96grln2KgRIPDRBKTEMh/AWgtKfHT56JdLXfzKkQ2AtP+E4yX5+augDvhmm+S8ikr5GgCjWqVYJa0Ds3KCRCRZGCecCPiOQMqr1pPWIcZr2dBgu5O1+JfeXfn+g44wkWsODttvkQecGwp7AOgDF2o1vGnhb+xDJQXg1s4UsbNFq8Dp41F87H1Rdx3LS/35SAKa73aduI+Y0Gj3BjcP2mvBcBZ61MzUHdkIOTWGohxdGDqk0E0L17YW5tyGz1NystpmmviSAW9N6QZyh/WbajMlNWVwgmUmnL3manW5fDFM9t9coY+8q7s2uhHZq+QAh/BGPkT/wfCuAMfav/i5E9p1ELH2GbfwcjWfpLhiuuyYv198tbpIJ8Qbpzv5RENCvXxWr1jLEya7T0QrtWUMNfQkzRRqfk= test@test.example.org diff --git a/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgNGUtD+qw0Xj5NU2uj4+4LoCWPcvXP54F9Adw/hWN5LAAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yqlAAAAAAAAAAAAAAACAAAABnNlcnZlcgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGAapK5VzLDoRe88tnLORrH8VxLegTWPKGdn0k5Ye8tS5XUgd0N98gU669y4ErDNf0kPxlz40bjsfisEEtJ/N7m14IskCepScfZRh8w6QgPxbTOhmrc89xooqBUE50y5FU9hIIbzUrnEP+Dfu4IiFPToAguCa+KoAKiOX7lBQqEugV6uOWVZ2erPopEv+OiMLD8hXsuKKjQ+TomHZ/IjuXsFdXH7Vcl0VsPaAcxyCtDU7nCTJSTUoUZtMtwwpulp0e/zNmFrEn2Binz4jRaUlk3FM2fdbotviDQYeOY3npmxaWUvvQ/eKn0/DzUTAKAGr2LDa2XWnPhj51BS1XkNaUlnupdYmZ2Sok0R4U3bfVwokteREvAltGbXQSDtZwLS5NEY6vIdDrxpn5QRf9vGjqnc7piXxye9gcLne4YDUi24IhGyHrnWKCC0HjF7tuUhCOVKrqRdmHxRGWX3PlS8Xn6HHEPWU+YZnfT1V2W7LAFcDMozQbs4GPGzZdR3f3vCOJ8 server.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server.pub b/internal/testhelper/testdata/testroot/certs/valid/server.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg3XO30wn4+lFxc5fLsanH4Pvu0OuKGHoR94zZjxx7qAEAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgokAAAAAAAAAAAAAAAIAAAAHc2VydmVyMgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGANOKG8Tq7kp9B5+CQEyb+mEatJOoQRV+4rpemWlfEw6TuVwQN2wSXc6XKBHzSG4NRnFkwk6GgiPLQEf4lBBKA8VYQnDKuhrHJlU4DFCRPw/aceHfCwNOruyJmuf91W3yEO/kYAd6EhkQiW/K3ky7BuXCqR34T2fBZSCeYhNcXWxhEMLoAuj0kEdX+YMNBmiPtinPE13KMFGyIVBm/ojgSZa8j4WnhDcK0cWv0OSGTgJF6q3hENCWRz2E1HroKUiABOy5Nca6gPVAi4OTd7gwER8eh9MngVHYorAJ3N9HjUh640SbL3zCC8f/lqIztqsHY0u3olsQ0gLXpFain+430HeyJlmVlsDZgQKRb90Mm1viSCKvHGpmVDYMimE9y0DCQS1i0yRGF1uSIPtuQ0NCbhS/HPKsT3nYgGCEuoB8aGOu3aGB/tmUkYXW+pwXRKqw0f/zX088XWYWvA+AR4hmmr6DDMnf/4EHgJp3xHTEwOBHCVj69xvlOawBNlL2X0b2p server2.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.key b/internal/testhelper/testdata/testroot/certs/valid/server2.key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.key @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEAyuDL6ZomdHC0uPqd2BMHAsKOJFWyT0xHoiDLqBCOyid8qgIyibp7 +OlaZwumkYLty5rjOLgR3IpkIuNeQpQTpuPrRYlbFTXAJLAPkLlPK0xAusT7PestWP6gvv1 +kJ+vriqdfnwLKVrC6YoN1V0k36vmAHMWX03Tv+nJNJB1b8V9PemHuw9JnatpVmxsEgZQG8 +1NcF/2Z7+YS2Q+A0htXCIwPb0P3yfacHJWYktKkNVV3aCFALy/bUwCo9veVRk9jTBhmGUA +ENL17TNWBzjAGeF6Dy9aFRY1RGaC0Q+fGug6XuIWPECnul9cO81Na6+b1WK8+zE1Guac7F +EjnlE3N5MiiaxMVZKC8gYGEKvKlvZGJPzsfcx8EwCsPb8IiLNjMHup5cSe3MOM8pDLMTyu +M/R5G2aExVst6YbjxarP1kKArx0yjY1j2m+1AGpnjOg59DfNwRdtbQkzFo5EQr7WVRiBme +2OHAIojdDj80Fg2rCfyClQ0YLmSUZ95IBwjGAoKJAAAFkBOZmjETmZoxAAAAB3NzaC1yc2 +EAAAGBAMrgy+maJnRwtLj6ndgTBwLCjiRVsk9MR6Igy6gQjsonfKoCMom6ezpWmcLppGC7 +cua4zi4EdyKZCLjXkKUE6bj60WJWxU1wCSwD5C5TytMQLrE+z3rLVj+oL79ZCfr64qnX58 +CylawumKDdVdJN+r5gBzFl9N07/pyTSQdW/FfT3ph7sPSZ2raVZsbBIGUBvNTXBf9me/mE +tkPgNIbVwiMD29D98n2nByVmJLSpDVVd2ghQC8v21MAqPb3lUZPY0wYZhlABDS9e0zVgc4 +wBnheg8vWhUWNURmgtEPnxroOl7iFjxAp7pfXDvNTWuvm9VivPsxNRrmnOxRI55RNzeTIo +msTFWSgvIGBhCrypb2RiT87H3MfBMArD2/CIizYzB7qeXEntzDjPKQyzE8rjP0eRtmhMVb +LemG48Wqz9ZCgK8dMo2NY9pvtQBqZ4zoOfQ3zcEXbW0JMxaOREK+1lUYgZntjhwCKI3Q4/ +NBYNqwn8gpUNGC5klGfeSAcIxgKCiQAAAAMBAAEAAAGAUxojzMt85wNns8HMuD6LB6FkEh +QcVwka6plecrhdlQb5tLXzt6DwayQgFcwYrhr6ZPHcWtMvbbeb8AM017OcfU4YSJzccuzq +hOIPLL7b/PrK9YWR/W2fJbIh5NJ3GRx9ji7HWpKMZpwrnvEq/1s705GIQL7Pv3Ocxsw6BM +ynzt4VdwZrpLYE9fdawx1GxLkifViat1Rmgf3PnxwOyBB1Vlx1RTVQiBHMBpDBhlMdCBPK +hM8tFd5EpXZoFgoCEXqlssIptaf0zUZAgeES31GwNrP7+n6SlL+xZxbs7ykWKjA1ibYDTE +fLIojOQCOgnIFaDFbbgUiqxoYg1SAr2SRPOjopc5EXSt5kfCdQk3I5MKoSm2INNuwBqprI +/BL0Do3VowAQkxjXJUWit9RR0wS7FiA54WJqOrfU+2ChRooVUvtt0i/0y9tJMr6+PJYawZ +uLwQ4DXs3UNVFKdopyh+zcLht+1xIZO6VrMteXejVhcz8UnRQE7leCdOvCYbBX87eRAAAA +wFX+Q0Cp8SD3Pf607nq0GNYgY+vQR/zqqTnIlYt3kKt0jP6TuvkOUnaANOt29W17LxIR1U +tZxFfyktrT4/RiVRP+QWvdLS32IN3mpCPt+J0oKujlSWrUT0SJgd7ZLePJIOscjuFqW72M +dNV7aCNIisc2QgJbp5EwCNTFxQmdqryk9Pd80kWSSAwWQ5A6jXSrLEAdaFTa9kF/o3DGNe +E/6HOTnt7BFvdE1hetYFnUTR1vqjD21Pi3d5rnePYUOGI1nAAAAMEA9fDwdHOCjosfA1ri +pWZDYYkR5JaxrCFZC5h2LcYL01aCutISH07Z5gmnAVM+CfHkihck9wiGDJuJNTo1mYR1pg +aFgoIFg8LjZzBConlSnHTPYkIYHvYFaE9T4PIS8yjlHjaDn59P06nHRNa5W/4vvhGK8eEn +hpBCQ68huqMZyCH9az6BYR1TasHY7GMbIuMXpswXt9tWRzXpuvQq0BFThNelviTw3JNFhC +cdR2+2wMCErnT0w1Y9fd+8SIHL3OdVAAAAwQDTLPokbpKxlOQOdKMGgn0CZnhiAiLMKp6k +ZQmqNjVEdiOkLWvmoBYMxW93n6uCpyc7p9R+++xXWvfIH7o4fCpiIcMKQtd7Ikp4s4uC6q +xP0QOtGui5wac/iBgd0QB7ZlRh0WNIRS0ej5sn3wHz7es5eq1F/auGhxR6i5N0EhB/qI72 +lFgWtRJsIxi0tm424K6XWEjjj7fe7k9qQ712BVOvvhZp1OK/qfsOl6lj7VPXtcVPr9+6Aw +MsHc/xbLoyRmUAAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.pub b/internal/testhelper/testdata/testroot/certs/valid/server2.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgok= # HG changeset patch # User Alejandro RodrÃÂguez <alejorro70@gmail.com> # Date 1656617851 -7200 # Thu Jun 30 21:37:31 2022 +0200 # Node ID 6ea212dfc5cb500d23b7d98fe904c07bae53e992 # Parent 95477d444999b8feb935a8a64f458119bb6931a6 Pass original IP from PROXY requests to internal API calls diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -76,6 +76,7 @@ testErrorMessage(t, client) testAuthenticationHeader(t, client) testJWTAuthenticationHeader(t, client) + testXForwardedForHeader(t, client) }) } } @@ -221,6 +222,21 @@ }) } +func testXForwardedForHeader(t *testing.T, client *GitlabNetClient) { + t.Run("X-Forwarded-For Header inserted if original address in context", func(t *testing.T) { + ctx := context.WithValue(context.Background(), OriginalRemoteIPContextKey{}, "196.7.0.238") + response, err := client.Get(ctx, "/x_forwarded_for") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + require.Equal(t, "196.7.0.238", string(responseBody)) + }) +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { @@ -257,6 +273,12 @@ }, }, { + Path: "/api/v4/internal/x_forwarded_for", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get("X-Forwarded-For")) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -41,6 +41,9 @@ Msg string } +// To use as the key in a Context to set an X-Forwarded-For header in a request +type OriginalRemoteIPContextKey struct{} + func (e *ApiError) Error() string { return e.Msg } @@ -150,6 +153,11 @@ } request.Header.Set(apiSecretHeaderName, tokenString) + originalRemoteIP, ok := ctx.Value(OriginalRemoteIPContextKey{}).(string) + if ok { + request.Header.Add("X-Forwarded-For", originalRemoteIP) + } + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,7 +3,6 @@ import ( "context" "fmt" - "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -86,7 +85,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = parseIP(args.Env.RemoteAddr) + request.CheckIp = gitlabnet.ParseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -117,18 +116,3 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } - -func parseIP(remoteAddr string) string { - // The remoteAddr field can be filled by: - // 1. An IP address via the SSH_CONNECTION environment variable - // 2. A host:port combination via the PROXY protocol - ip, _, err := net.SplitHostPort(remoteAddr) - - // If we don't have a port or can't parse this address for some reason, - // just return the original string. - if err != nil { - return remoteAddr - } - - return ip -} diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -3,6 +3,7 @@ import ( "encoding/json" "fmt" + "net" "net/http" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -34,3 +35,18 @@ return nil } + +func ParseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,7 +12,9 @@ "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" @@ -145,13 +147,26 @@ return s.status } +func contextWithValues(parent context.Context, nconn net.Conn) context.Context { + ctx := correlation.ContextWithCorrelation(parent, correlation.SafeRandomID()) + + // If we're dealing with a PROXY connection, register the original requester's IP + mconn, ok := nconn.(*proxyproto.Conn) + if ok { + ip := gitlabnet.ParseIP(mconn.Raw().RemoteAddr().String()) + ctx = context.WithValue(ctx, client.OriginalRemoteIPContextKey{}, ip) + } + + return ctx +} + func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { defer s.wg.Done() metrics.SshdConnectionsInFlight.Inc() defer metrics.SshdConnectionsInFlight.Dec() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) + ctx, cancel := context.WithCancel(contextWithValues(ctx, nconn)) defer cancel() go func() { <-ctx.Done() diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -27,6 +27,7 @@ var ( correlationId = "" + xForwardedFor = "" ) func TestListenAndServe(t *testing.T) { @@ -63,6 +64,10 @@ }, DestinationAddr: target, } + xForwardedFor = "127.0.0.1" + defer func() { + xForwardedFor = "" // Cleanup for other test cases + }() testCases := []struct { desc string @@ -132,9 +137,9 @@ require.NoError(t, err) } - sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + sshConn, sshChans, sshRequs, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) if sshConn != nil { - sshConn.Close() + defer sshConn.Close() } if tc.isRejected { @@ -142,6 +147,10 @@ require.Regexp(t, "ssh: handshake failed", err.Error()) } else { require.NoError(t, err) + client := ssh.NewClient(sshConn, sshChans, sshRequs) + defer client.Close() + + holdSession(t, client) } }) } @@ -306,6 +315,7 @@ correlationId = r.Header.Get("X-Request-Id") require.NotEmpty(t, correlationId) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "key": "key"}`) }, @@ -313,6 +323,7 @@ Path: "/api/v4/internal/discover", Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) }, # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1656673379 0 # Fri Jul 01 11:02:59 2022 +0000 # Node ID f780371e985f8a3e77a11e55731aae89cdee03a5 # Parent 95477d444999b8feb935a8a64f458119bb6931a6 # Parent 6ea212dfc5cb500d23b7d98fe904c07bae53e992 Merge branch 'sshd-forwarded-for' into 'main' Pass original IP from PROXY requests to internal API calls See merge request gitlab-org/gitlab-shell!665 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -76,6 +76,7 @@ testErrorMessage(t, client) testAuthenticationHeader(t, client) testJWTAuthenticationHeader(t, client) + testXForwardedForHeader(t, client) }) } } @@ -221,6 +222,21 @@ }) } +func testXForwardedForHeader(t *testing.T, client *GitlabNetClient) { + t.Run("X-Forwarded-For Header inserted if original address in context", func(t *testing.T) { + ctx := context.WithValue(context.Background(), OriginalRemoteIPContextKey{}, "196.7.0.238") + response, err := client.Get(ctx, "/x_forwarded_for") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + require.Equal(t, "196.7.0.238", string(responseBody)) + }) +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { @@ -257,6 +273,12 @@ }, }, { + Path: "/api/v4/internal/x_forwarded_for", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get("X-Forwarded-For")) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -41,6 +41,9 @@ Msg string } +// To use as the key in a Context to set an X-Forwarded-For header in a request +type OriginalRemoteIPContextKey struct{} + func (e *ApiError) Error() string { return e.Msg } @@ -150,6 +153,11 @@ } request.Header.Set(apiSecretHeaderName, tokenString) + originalRemoteIP, ok := ctx.Value(OriginalRemoteIPContextKey{}).(string) + if ok { + request.Header.Add("X-Forwarded-For", originalRemoteIP) + } + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,7 +3,6 @@ import ( "context" "fmt" - "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -86,7 +85,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = parseIP(args.Env.RemoteAddr) + request.CheckIp = gitlabnet.ParseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -117,18 +116,3 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } - -func parseIP(remoteAddr string) string { - // The remoteAddr field can be filled by: - // 1. An IP address via the SSH_CONNECTION environment variable - // 2. A host:port combination via the PROXY protocol - ip, _, err := net.SplitHostPort(remoteAddr) - - // If we don't have a port or can't parse this address for some reason, - // just return the original string. - if err != nil { - return remoteAddr - } - - return ip -} diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -3,6 +3,7 @@ import ( "encoding/json" "fmt" + "net" "net/http" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -34,3 +35,18 @@ return nil } + +func ParseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,7 +12,9 @@ "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" @@ -145,13 +147,26 @@ return s.status } +func contextWithValues(parent context.Context, nconn net.Conn) context.Context { + ctx := correlation.ContextWithCorrelation(parent, correlation.SafeRandomID()) + + // If we're dealing with a PROXY connection, register the original requester's IP + mconn, ok := nconn.(*proxyproto.Conn) + if ok { + ip := gitlabnet.ParseIP(mconn.Raw().RemoteAddr().String()) + ctx = context.WithValue(ctx, client.OriginalRemoteIPContextKey{}, ip) + } + + return ctx +} + func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { defer s.wg.Done() metrics.SshdConnectionsInFlight.Inc() defer metrics.SshdConnectionsInFlight.Dec() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) + ctx, cancel := context.WithCancel(contextWithValues(ctx, nconn)) defer cancel() go func() { <-ctx.Done() diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -27,6 +27,7 @@ var ( correlationId = "" + xForwardedFor = "" ) func TestListenAndServe(t *testing.T) { @@ -63,6 +64,10 @@ }, DestinationAddr: target, } + xForwardedFor = "127.0.0.1" + defer func() { + xForwardedFor = "" // Cleanup for other test cases + }() testCases := []struct { desc string @@ -132,9 +137,9 @@ require.NoError(t, err) } - sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + sshConn, sshChans, sshRequs, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) if sshConn != nil { - sshConn.Close() + defer sshConn.Close() } if tc.isRejected { @@ -142,6 +147,10 @@ require.Regexp(t, "ssh: handshake failed", err.Error()) } else { require.NoError(t, err) + client := ssh.NewClient(sshConn, sshChans, sshRequs) + defer client.Close() + + holdSession(t, client) } }) } @@ -306,6 +315,7 @@ correlationId = r.Header.Get("X-Request-Id") require.NotEmpty(t, correlationId) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "key": "key"}`) }, @@ -313,6 +323,7 @@ Path: "/api/v4/internal/discover", Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) }, # HG changeset patch # User Patrick Steinhardt <psteinhardt@gitlab.com> # Date 1657003434 -7200 # Tue Jul 05 08:43:54 2022 +0200 # Node ID 91f2a74d0d6cef9515a7c46e39f039aff8b12fe3 # Parent f780371e985f8a3e77a11e55731aae89cdee03a5 go: Bump major version to v14 While gitlab-shell currently has a major version of v14, the module path it exposes is not using that major version like it is required by the Go standard. This makes it impossible for dependents to import gitlab-shell as a dependency without using a commit as version. Fix this by changing the module path of gitlab-shell to instead be `gitlab.com/gitlab-org/gitlab-shell/v14` and adjust all imports accordingly. Changelog: fixed diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -15,8 +15,8 @@ "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -11,7 +11,7 @@ "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func TestReadTimeout(t *testing.T) { diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -9,8 +9,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) //go:generate openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 -out ../internal/testhelper/testdata/testroot/certs/client/server.crt -keyout ../internal/testhelper/testdata/testroot/certs/client/key.pem -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=GitLab-Shell/CN=localhost" diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -14,7 +14,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go --- a/cmd/check/command/command.go +++ b/cmd/check/command/command.go @@ -1,11 +1,11 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go --- a/cmd/check/command/command_test.go +++ b/cmd/check/command/command_test.go @@ -4,11 +4,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" - checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go --- a/cmd/gitlab-shell/command/command.go +++ b/cmd/gitlab-shell/command/command.go @@ -1,20 +1,20 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -5,20 +5,20 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,14 +11,14 @@ "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -24,7 +24,7 @@ "github.com/stretchr/testify/require" gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -8,10 +8,10 @@ "syscall" "time" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshd" "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module gitlab.com/gitlab-org/gitlab-shell +module gitlab.com/gitlab-org/gitlab-shell/v14 go 1.17 diff --git a/internal/command/authorizedkeys/authorized_keys.go b/internal/command/authorizedkeys/authorized_keys.go --- a/internal/command/authorizedkeys/authorized_keys.go +++ b/internal/command/authorizedkeys/authorized_keys.go @@ -5,11 +5,11 @@ "fmt" "strconv" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedkeys/authorized_keys_test.go b/internal/command/authorizedkeys/authorized_keys_test.go --- a/internal/command/authorizedkeys/authorized_keys_test.go +++ b/internal/command/authorizedkeys/authorized_keys_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/authorizedprincipals/authorized_principals.go b/internal/command/authorizedprincipals/authorized_principals.go --- a/internal/command/authorizedprincipals/authorized_principals.go +++ b/internal/command/authorizedprincipals/authorized_principals.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedprincipals/authorized_principals_test.go b/internal/command/authorizedprincipals/authorized_principals_test.go --- a/internal/command/authorizedprincipals/authorized_principals_test.go +++ b/internal/command/authorizedprincipals/authorized_principals_test.go @@ -7,9 +7,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestExecute(t *testing.T) { diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,7 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -6,7 +6,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" ) diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -6,7 +6,7 @@ "strings" "github.com/mattn/go-shellwords" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) const ( diff --git a/internal/command/discover/discover.go b/internal/command/discover/discover.go --- a/internal/command/discover/discover.go +++ b/internal/command/discover/discover.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Command struct { diff --git a/internal/command/discover/discover_test.go b/internal/command/discover/discover_test.go --- a/internal/command/discover/discover_test.go +++ b/internal/command/discover/discover_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/healthcheck/healthcheck.go b/internal/command/healthcheck/healthcheck.go --- a/internal/command/healthcheck/healthcheck.go +++ b/internal/command/healthcheck/healthcheck.go @@ -4,9 +4,9 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/healthcheck/healthcheck_test.go b/internal/command/healthcheck/healthcheck_test.go --- a/internal/command/healthcheck/healthcheck_test.go +++ b/internal/command/healthcheck/healthcheck_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -8,12 +8,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" ) const ( diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -10,13 +10,13 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestFailedRequests(t *testing.T) { diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -10,10 +10,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) const ( diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) var ( diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { diff --git a/internal/command/receivepack/receivepack.go b/internal/command/receivepack/receivepack.go --- a/internal/command/receivepack/receivepack.go +++ b/internal/command/receivepack/receivepack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/receivepack/receivepack_test.go b/internal/command/receivepack/receivepack_test.go --- a/internal/command/receivepack/receivepack_test.go +++ b/internal/command/receivepack/receivepack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/shared/accessverifier/accessverifier.go b/internal/command/shared/accessverifier/accessverifier.go --- a/internal/command/shared/accessverifier/accessverifier.go +++ b/internal/command/shared/accessverifier/accessverifier.go @@ -4,11 +4,11 @@ "context" "errors" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) type Response = accessverifier.Response diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) var ( diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -9,12 +9,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/pktline" ) type Request struct { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) func TestExecuteEOFSent(t *testing.T) { diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -8,10 +8,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) const readerLimit = 1024 diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) var ( diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -7,10 +7,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) type Command struct { diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) func setup(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadArchive(t *testing.T) { diff --git a/internal/command/uploadarchive/uploadarchive.go b/internal/command/uploadarchive/uploadarchive.go --- a/internal/command/uploadarchive/uploadarchive.go +++ b/internal/command/uploadarchive/uploadarchive.go @@ -3,11 +3,11 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadarchive/uploadarchive_test.go b/internal/command/uploadarchive/uploadarchive_test.go --- a/internal/command/uploadarchive/uploadarchive_test.go +++ b/internal/command/uploadarchive/uploadarchive_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadPack(t *testing.T) { diff --git a/internal/command/uploadpack/uploadpack.go b/internal/command/uploadpack/uploadpack.go --- a/internal/command/uploadpack/uploadpack.go +++ b/internal/command/uploadpack/uploadpack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadpack/uploadpack_test.go b/internal/command/uploadpack/uploadpack_test.go --- a/internal/command/uploadpack/uploadpack_test.go +++ b/internal/command/uploadpack/uploadpack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -11,9 +11,9 @@ yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) const ( diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -9,8 +9,8 @@ "github.com/stretchr/testify/require" yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestConfigApplyGlobalState(t *testing.T) { diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -4,7 +4,7 @@ "errors" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "github.com/stretchr/testify/require" ) diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -17,7 +17,7 @@ "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type Command struct { diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -7,7 +7,7 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) func TestPrometheusMetrics(t *testing.T) { diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -6,10 +6,10 @@ "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/internal/gitlabnet/authorizedkeys/client.go b/internal/gitlabnet/authorizedkeys/client.go --- a/internal/gitlabnet/authorizedkeys/client.go +++ b/internal/gitlabnet/authorizedkeys/client.go @@ -5,9 +5,9 @@ "fmt" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/authorizedkeys/client_test.go b/internal/gitlabnet/authorizedkeys/client_test.go --- a/internal/gitlabnet/authorizedkeys/client_test.go +++ b/internal/gitlabnet/authorizedkeys/client_test.go @@ -7,9 +7,9 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -6,9 +6,9 @@ "net" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/discover/client.go b/internal/gitlabnet/discover/client.go --- a/internal/gitlabnet/discover/client.go +++ b/internal/gitlabnet/discover/client.go @@ -6,10 +6,10 @@ "net/http" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/discover/client_test.go b/internal/gitlabnet/discover/client_test.go --- a/internal/gitlabnet/discover/client_test.go +++ b/internal/gitlabnet/discover/client_test.go @@ -8,11 +8,11 @@ "net/url" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/healthcheck/client.go b/internal/gitlabnet/healthcheck/client.go --- a/internal/gitlabnet/healthcheck/client.go +++ b/internal/gitlabnet/healthcheck/client.go @@ -5,9 +5,9 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/healthcheck/client_test.go b/internal/gitlabnet/healthcheck/client_test.go --- a/internal/gitlabnet/healthcheck/client_test.go +++ b/internal/gitlabnet/healthcheck/client_test.go @@ -6,8 +6,8 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "github.com/stretchr/testify/require" ) diff --git a/internal/gitlabnet/lfsauthenticate/client.go b/internal/gitlabnet/lfsauthenticate/client.go --- a/internal/gitlabnet/lfsauthenticate/client.go +++ b/internal/gitlabnet/lfsauthenticate/client.go @@ -6,10 +6,10 @@ "net/http" "strings" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -9,9 +9,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) const ( diff --git a/internal/gitlabnet/personalaccesstoken/client.go b/internal/gitlabnet/personalaccesstoken/client.go --- a/internal/gitlabnet/personalaccesstoken/client.go +++ b/internal/gitlabnet/personalaccesstoken/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorrecover/client.go b/internal/gitlabnet/twofactorrecover/client.go --- a/internal/gitlabnet/twofactorrecover/client.go +++ b/internal/gitlabnet/twofactorrecover/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -7,13 +7,13 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func initialize(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -11,10 +11,10 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -12,10 +12,10 @@ grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { diff --git a/internal/keyline/key_line.go b/internal/keyline/key_line.go --- a/internal/keyline/key_line.go +++ b/internal/keyline/key_line.go @@ -7,8 +7,8 @@ "regexp" "strings" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" ) var ( diff --git a/internal/keyline/key_line_test.go b/internal/keyline/key_line_test.go --- a/internal/keyline/key_line_test.go +++ b/internal/keyline/key_line_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestFailingNewPublicKeyLine(t *testing.T) { diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -9,7 +9,7 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func logFmt(inFmt string) string { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -8,7 +8,7 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestConfigure(t *testing.T) { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -13,10 +13,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -14,10 +14,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type rejectCall struct { diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -10,8 +10,8 @@ "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -12,8 +12,8 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewServerConfigWithoutHosts(t *testing.T) { diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -12,13 +12,13 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) type session struct { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -11,9 +11,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" ) type fakeChannel struct { diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,10 +12,10 @@ "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -15,9 +15,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) const ( diff --git a/internal/sshenv/sshenv_test.go b/internal/sshenv/sshenv_test.go --- a/internal/sshenv/sshenv_test.go +++ b/internal/sshenv/sshenv_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewFromEnv(t *testing.T) { diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -7,7 +7,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func BuildDisallowedByApiHandlers(t *testing.T) []testserver.TestRequestHandler { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1657012810 0 # Tue Jul 05 09:20:10 2022 +0000 # Node ID 7fc6cf9719ad6dee23d206e5d3152971d1c1525c # Parent f780371e985f8a3e77a11e55731aae89cdee03a5 # Parent 91f2a74d0d6cef9515a7c46e39f039aff8b12fe3 Merge branch 'pks-go-module-path-version' into 'main' go: Bump major version to v14 Closes #593 See merge request gitlab-org/gitlab-shell!666 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -15,8 +15,8 @@ "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -11,7 +11,7 @@ "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func TestReadTimeout(t *testing.T) { diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -9,8 +9,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) //go:generate openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 -out ../internal/testhelper/testdata/testroot/certs/client/server.crt -keyout ../internal/testhelper/testdata/testroot/certs/client/key.pem -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=GitLab-Shell/CN=localhost" diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -14,7 +14,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go --- a/cmd/check/command/command.go +++ b/cmd/check/command/command.go @@ -1,11 +1,11 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go --- a/cmd/check/command/command_test.go +++ b/cmd/check/command/command_test.go @@ -4,11 +4,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" - checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go --- a/cmd/gitlab-shell/command/command.go +++ b/cmd/gitlab-shell/command/command.go @@ -1,20 +1,20 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -5,20 +5,20 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,14 +11,14 @@ "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -24,7 +24,7 @@ "github.com/stretchr/testify/require" gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -8,10 +8,10 @@ "syscall" "time" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshd" "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module gitlab.com/gitlab-org/gitlab-shell +module gitlab.com/gitlab-org/gitlab-shell/v14 go 1.17 diff --git a/internal/command/authorizedkeys/authorized_keys.go b/internal/command/authorizedkeys/authorized_keys.go --- a/internal/command/authorizedkeys/authorized_keys.go +++ b/internal/command/authorizedkeys/authorized_keys.go @@ -5,11 +5,11 @@ "fmt" "strconv" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedkeys/authorized_keys_test.go b/internal/command/authorizedkeys/authorized_keys_test.go --- a/internal/command/authorizedkeys/authorized_keys_test.go +++ b/internal/command/authorizedkeys/authorized_keys_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/authorizedprincipals/authorized_principals.go b/internal/command/authorizedprincipals/authorized_principals.go --- a/internal/command/authorizedprincipals/authorized_principals.go +++ b/internal/command/authorizedprincipals/authorized_principals.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedprincipals/authorized_principals_test.go b/internal/command/authorizedprincipals/authorized_principals_test.go --- a/internal/command/authorizedprincipals/authorized_principals_test.go +++ b/internal/command/authorizedprincipals/authorized_principals_test.go @@ -7,9 +7,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestExecute(t *testing.T) { diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,7 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -6,7 +6,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" ) diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -6,7 +6,7 @@ "strings" "github.com/mattn/go-shellwords" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) const ( diff --git a/internal/command/discover/discover.go b/internal/command/discover/discover.go --- a/internal/command/discover/discover.go +++ b/internal/command/discover/discover.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Command struct { diff --git a/internal/command/discover/discover_test.go b/internal/command/discover/discover_test.go --- a/internal/command/discover/discover_test.go +++ b/internal/command/discover/discover_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/healthcheck/healthcheck.go b/internal/command/healthcheck/healthcheck.go --- a/internal/command/healthcheck/healthcheck.go +++ b/internal/command/healthcheck/healthcheck.go @@ -4,9 +4,9 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/healthcheck/healthcheck_test.go b/internal/command/healthcheck/healthcheck_test.go --- a/internal/command/healthcheck/healthcheck_test.go +++ b/internal/command/healthcheck/healthcheck_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -8,12 +8,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" ) const ( diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -10,13 +10,13 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestFailedRequests(t *testing.T) { diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -10,10 +10,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) const ( diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) var ( diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { diff --git a/internal/command/receivepack/receivepack.go b/internal/command/receivepack/receivepack.go --- a/internal/command/receivepack/receivepack.go +++ b/internal/command/receivepack/receivepack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/receivepack/receivepack_test.go b/internal/command/receivepack/receivepack_test.go --- a/internal/command/receivepack/receivepack_test.go +++ b/internal/command/receivepack/receivepack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/shared/accessverifier/accessverifier.go b/internal/command/shared/accessverifier/accessverifier.go --- a/internal/command/shared/accessverifier/accessverifier.go +++ b/internal/command/shared/accessverifier/accessverifier.go @@ -4,11 +4,11 @@ "context" "errors" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) type Response = accessverifier.Response diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) var ( diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -9,12 +9,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/pktline" ) type Request struct { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) func TestExecuteEOFSent(t *testing.T) { diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -8,10 +8,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) const readerLimit = 1024 diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) var ( diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -7,10 +7,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) type Command struct { diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) func setup(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadArchive(t *testing.T) { diff --git a/internal/command/uploadarchive/uploadarchive.go b/internal/command/uploadarchive/uploadarchive.go --- a/internal/command/uploadarchive/uploadarchive.go +++ b/internal/command/uploadarchive/uploadarchive.go @@ -3,11 +3,11 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadarchive/uploadarchive_test.go b/internal/command/uploadarchive/uploadarchive_test.go --- a/internal/command/uploadarchive/uploadarchive_test.go +++ b/internal/command/uploadarchive/uploadarchive_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadPack(t *testing.T) { diff --git a/internal/command/uploadpack/uploadpack.go b/internal/command/uploadpack/uploadpack.go --- a/internal/command/uploadpack/uploadpack.go +++ b/internal/command/uploadpack/uploadpack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadpack/uploadpack_test.go b/internal/command/uploadpack/uploadpack_test.go --- a/internal/command/uploadpack/uploadpack_test.go +++ b/internal/command/uploadpack/uploadpack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -11,9 +11,9 @@ yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) const ( diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -9,8 +9,8 @@ "github.com/stretchr/testify/require" yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestConfigApplyGlobalState(t *testing.T) { diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -4,7 +4,7 @@ "errors" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "github.com/stretchr/testify/require" ) diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -17,7 +17,7 @@ "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type Command struct { diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -7,7 +7,7 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) func TestPrometheusMetrics(t *testing.T) { diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -6,10 +6,10 @@ "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/internal/gitlabnet/authorizedkeys/client.go b/internal/gitlabnet/authorizedkeys/client.go --- a/internal/gitlabnet/authorizedkeys/client.go +++ b/internal/gitlabnet/authorizedkeys/client.go @@ -5,9 +5,9 @@ "fmt" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/authorizedkeys/client_test.go b/internal/gitlabnet/authorizedkeys/client_test.go --- a/internal/gitlabnet/authorizedkeys/client_test.go +++ b/internal/gitlabnet/authorizedkeys/client_test.go @@ -7,9 +7,9 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -6,9 +6,9 @@ "net" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/discover/client.go b/internal/gitlabnet/discover/client.go --- a/internal/gitlabnet/discover/client.go +++ b/internal/gitlabnet/discover/client.go @@ -6,10 +6,10 @@ "net/http" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/discover/client_test.go b/internal/gitlabnet/discover/client_test.go --- a/internal/gitlabnet/discover/client_test.go +++ b/internal/gitlabnet/discover/client_test.go @@ -8,11 +8,11 @@ "net/url" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/healthcheck/client.go b/internal/gitlabnet/healthcheck/client.go --- a/internal/gitlabnet/healthcheck/client.go +++ b/internal/gitlabnet/healthcheck/client.go @@ -5,9 +5,9 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/healthcheck/client_test.go b/internal/gitlabnet/healthcheck/client_test.go --- a/internal/gitlabnet/healthcheck/client_test.go +++ b/internal/gitlabnet/healthcheck/client_test.go @@ -6,8 +6,8 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "github.com/stretchr/testify/require" ) diff --git a/internal/gitlabnet/lfsauthenticate/client.go b/internal/gitlabnet/lfsauthenticate/client.go --- a/internal/gitlabnet/lfsauthenticate/client.go +++ b/internal/gitlabnet/lfsauthenticate/client.go @@ -6,10 +6,10 @@ "net/http" "strings" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -9,9 +9,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) const ( diff --git a/internal/gitlabnet/personalaccesstoken/client.go b/internal/gitlabnet/personalaccesstoken/client.go --- a/internal/gitlabnet/personalaccesstoken/client.go +++ b/internal/gitlabnet/personalaccesstoken/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorrecover/client.go b/internal/gitlabnet/twofactorrecover/client.go --- a/internal/gitlabnet/twofactorrecover/client.go +++ b/internal/gitlabnet/twofactorrecover/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -7,13 +7,13 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func initialize(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -11,10 +11,10 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -12,10 +12,10 @@ grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { diff --git a/internal/keyline/key_line.go b/internal/keyline/key_line.go --- a/internal/keyline/key_line.go +++ b/internal/keyline/key_line.go @@ -7,8 +7,8 @@ "regexp" "strings" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" ) var ( diff --git a/internal/keyline/key_line_test.go b/internal/keyline/key_line_test.go --- a/internal/keyline/key_line_test.go +++ b/internal/keyline/key_line_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestFailingNewPublicKeyLine(t *testing.T) { diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -9,7 +9,7 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func logFmt(inFmt string) string { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -8,7 +8,7 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestConfigure(t *testing.T) { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -13,10 +13,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -14,10 +14,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type rejectCall struct { diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -10,8 +10,8 @@ "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -12,8 +12,8 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewServerConfigWithoutHosts(t *testing.T) { diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -12,13 +12,13 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) type session struct { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -11,9 +11,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" ) type fakeChannel struct { diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,10 +12,10 @@ "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -15,9 +15,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) const ( diff --git a/internal/sshenv/sshenv_test.go b/internal/sshenv/sshenv_test.go --- a/internal/sshenv/sshenv_test.go +++ b/internal/sshenv/sshenv_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewFromEnv(t *testing.T) { diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -7,7 +7,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func BuildDisallowedByApiHandlers(t *testing.T) []testserver.TestRequestHandler { # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1657013300 -7200 # Tue Jul 05 11:28:20 2022 +0200 # Node ID bed6fee616ab7f5565041e304c98f7fa7a4b8e97 # Parent 7fc6cf9719ad6dee23d206e5d3152971d1c1525c Release v14.8.0 - go: Bump major version to v14 !666 - Pass original IP from PROXY requests to internal API calls !665 - Fix make install copying the wrong binaries !664 - gitlab-sshd: Add support for configuring host certificates !661 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +v14.8.0 + +- go: Bump major version to v14 !666 +- Pass original IP from PROXY requests to internal API calls !665 +- Fix make install copying the wrong binaries !664 +- gitlab-sshd: Add support for configuring host certificates !661 + v14.7.4 - gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent !662 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.4 +14.8.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1657013923 0 # Tue Jul 05 09:38:43 2022 +0000 # Node ID 8bb84a6ad6dd3ed5e3ff025513b3604cf83b9e3b # Parent 7fc6cf9719ad6dee23d206e5d3152971d1c1525c # Parent bed6fee616ab7f5565041e304c98f7fa7a4b8e97 Merge branch 'id-release-14-8' into 'main' Release v14.8.0 See merge request gitlab-org/gitlab-shell!667 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +v14.8.0 + +- go: Bump major version to v14 !666 +- Pass original IP from PROXY requests to internal API calls !665 +- Fix make install copying the wrong binaries !664 +- gitlab-sshd: Add support for configuring host certificates !661 + v14.7.4 - gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent !662 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.4 +14.8.0 # HG changeset patch # User Alejandro RodrÃÂguez <alejorro70@gmail.com> # Date 1657734467 -7200 # Wed Jul 13 19:47:47 2022 +0200 # Node ID 71b98021ef29ebd9a3d7800a490e87189f68d043 # Parent 8bb84a6ad6dd3ed5e3ff025513b3604cf83b9e3b Update LabKit library to v1.16.0 * include original address in correlation CIDR checks ([ae96001](https://gitlab.com/gitlab-org/labkit/commit/ae9600163a6f5fa2ad06676a00b310af36573df4)) * run make recipes in parallel during backward compat check ([efa9c71](https://gitlab.com/gitlab-org/labkit/commit/efa9c71e13ef2bfe4415278e6b1e5c5ee8cc8022)) See https://gitlab.com/gitlab-org/labkit/-/releases/v1.16.0 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.14.0 + gitlab.com/gitlab-org/labkit v1.16.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -887,6 +887,7 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -895,8 +896,8 @@ 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.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= +gitlab.com/gitlab-org/labkit v1.16.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= # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1657749660 0 # Wed Jul 13 22:01:00 2022 +0000 # Node ID e86c7d77a163f0d1926b6ee63c9e5e8b1dc55e19 # Parent 8bb84a6ad6dd3ed5e3ff025513b3604cf83b9e3b # Parent 71b98021ef29ebd9a3d7800a490e87189f68d043 Merge branch 'vendor-v1.16.0' into 'main' Update LabKit library to v1.16.0 See merge request gitlab-org/gitlab-shell!668 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.14.0 + gitlab.com/gitlab-org/labkit v1.16.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -887,6 +887,7 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -895,8 +896,8 @@ 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.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= +gitlab.com/gitlab-org/labkit v1.16.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= # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1657830895 25200 # Thu Jul 14 13:34:55 2022 -0700 # Node ID b584562b76540fbfc054a976a2ae46e2ef39f77c # Parent e86c7d77a163f0d1926b6ee63c9e5e8b1dc55e19 Release v14.9.0 - Update LabKit library to v1.16.0 !668 (https://gitlab.com/gitlab-org/labkit/-/releases/v1.16.0) diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.9.0 + +- Update LabKit library to v1.16.0 !668 + v14.8.0 - go: Bump major version to v14 !666 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.8.0 +14.9.0 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1657861769 0 # Fri Jul 15 05:09:29 2022 +0000 # Node ID 00502e780098673e6e130e33b80b04710dca7ad5 # Parent e86c7d77a163f0d1926b6ee63c9e5e8b1dc55e19 # Parent b584562b76540fbfc054a976a2ae46e2ef39f77c Merge branch 'sh-release-14.9.0' into 'main' Release v14.9.0 See merge request gitlab-org/gitlab-shell!669 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.9.0 + +- Update LabKit library to v1.16.0 !668 + v14.8.0 - go: Bump major version to v14 !666 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.8.0 +14.9.0 # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1657861711 25200 # Thu Jul 14 22:08:31 2022 -0700 # Node ID 3c492987c9aa2edeb461f99e211d77241a127718 # Parent e86c7d77a163f0d1926b6ee63c9e5e8b1dc55e19 Fix flaky race test `ignoredError.err` was being used in a Goroutine handler, but the value of `ignoredError` changes with each test case. To avoid a race, make a local copy of the error before each Goroutine runs. Closes https://gitlab.com/gitlab-org/gitlab-shell/-/issues/590 diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -225,9 +225,10 @@ } { t.Run(ignoredError.desc, func(t *testing.T) { conn, chans = setup(1, newChannel) + ignored := ignoredError.err conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) - return ignoredError.err + return ignored }) require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1657862126 0 # Fri Jul 15 05:15:26 2022 +0000 # Node ID 7517f48a5d24f1415f58523c3e2ee1ec72bd437a # Parent 00502e780098673e6e130e33b80b04710dca7ad5 # Parent 3c492987c9aa2edeb461f99e211d77241a127718 Merge branch 'sh-fix-flaky-race-test' into 'main' Fix flaky race test Closes #590 See merge request gitlab-org/gitlab-shell!670 diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -225,9 +225,10 @@ } { t.Run(ignoredError.desc, func(t *testing.T) { conn, chans = setup(1, newChannel) + ignored := ignoredError.err conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) - return ignoredError.err + return ignored }) require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) # HG changeset patch # User kmcknight <kmcknight@gitlab.com> # Date 1614302245 28800 # Thu Feb 25 17:17:25 2021 -0800 # Node ID fcbdf9e966ae00e60daa009adfba0ee3ecc70a5d # Parent 7517f48a5d24f1415f58523c3e2ee1ec72bd437a Implement Push Auth support for 2FA verification When `2fa_verify` command is executed: - A user is asked to enter OTP - A blocking call for push auth is performed Then: - If the push auth request fails, the user is still able to enter OTP - If OTP is invalid, the `2fa_verify` command ends the execution - If OTP is valid or push auth request succeeded, then the user is successfully authenticated - If 30 seconds passed while no OTP or Push have been provided, then the `2fa_verify` command ends the execution diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -4,6 +4,7 @@ "context" "fmt" "io" + "time" "gitlab.com/gitlab-org/labkit/log" @@ -15,23 +16,96 @@ type Command struct { Config *config.Config + Client *twofactorverify.Client Args *commandargs.Shell ReadWriter *readwriter.ReadWriter } +type Result struct { + Error error + Status string + Success bool +} + func (c *Command) Execute(ctx context.Context) error { ctxlog := log.ContextLogger(ctx) - ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP(ctx) - ctxlog.Info("twofactorverify: execute: verifying entered OTP") - err := c.verifyOTP(ctx, otp) + // config.GetHTTPClient isn't thread-safe so save Client in struct for concurrency + // workaround until #518 is fixed + var err error + c.Client, err = twofactorverify.NewClient(c.Config) + if err != nil { ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } - ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") + // Create timeout context + // TODO: make timeout configurable + const ctxTimeout = 30 + timeoutCtx, cancelTimeout := context.WithTimeout(ctx, ctxTimeout*time.Second) + defer cancelTimeout() + + // Background push notification with timeout + pushauth := make(chan Result) + go func() { + defer close(pushauth) + ctxlog.Info("twofactorverify: execute: waiting for push auth") + status, success, err := c.pushAuth(timeoutCtx) + ctxlog.WithError(err).Info("twofactorverify: execute: push auth verified") + + select { + case <-timeoutCtx.Done(): // push cancelled by manual OTP + // skip writing to channel + ctxlog.Info("twofactorverify: execute: push auth cancelled") + default: + pushauth <- Result{Error: err, Status: status, Success: success} + } + }() + + // Also allow manual OTP entry while waiting for push, with same timeout as push + verify := make(chan Result) + go func() { + defer close(verify) + ctxlog.Info("twofactorverify: execute: waiting for user input") + answer := "" + answer = c.getOTP(timeoutCtx) + ctxlog.Info("twofactorverify: execute: user input received") + + select { + case <-timeoutCtx.Done(): // manual OTP cancelled by push + // skip writing to channel + ctxlog.Info("twofactorverify: execute: verify cancelled") + default: + ctxlog.Info("twofactorverify: execute: verifying entered OTP") + status, success, err := c.verifyOTP(timeoutCtx, answer) + ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") + verify <- Result{Error: err, Status: status, Success: success} + } + }() + + for { + select { + case res := <-verify: + if res.Status == "" { + // channel closed; don't print anything + } else { + fmt.Fprint(c.ReadWriter.Out, res.Status) + return nil + } + case res := <-pushauth: + if res.Status == "" { + // channel closed; don't print anything + } else { + fmt.Fprint(c.ReadWriter.Out, res.Status) + return nil + } + case <-timeoutCtx.Done(): // push timed out + fmt.Fprint(c.ReadWriter.Out, "\nOTP verification timed out\n") + return nil + } + } + return nil } @@ -49,18 +123,38 @@ return answer } -func (c *Command) verifyOTP(ctx context.Context, otp string) error { - client, err := twofactorverify.NewClient(c.Config) - if err != nil { - return err +func (c *Command) verifyOTP(ctx context.Context, otp string) (status string, success bool, err error) { + reason := "" + + success, reason, err = c.Client.VerifyOTP(ctx, c.Args, otp) + if success { + status = fmt.Sprintf("\nOTP validation successful. Git operations are now allowed.\n") + } else { + if err != nil { + status = fmt.Sprintf("\nOTP validation failed.\n%v\n", err) + } else { + status = fmt.Sprintf("\nOTP validation failed.\n%v\n", reason) + } } - err = client.VerifyOTP(ctx, c.Args, otp) - if err == nil { - fmt.Fprint(c.ReadWriter.Out, "\nOTP validation successful. Git operations are now allowed.\n") + err = nil + + return +} + +func (c *Command) pushAuth(ctx context.Context) (status string, success bool, err error) { + reason := "" + + success, reason, err = c.Client.PushAuth(ctx, c.Args) + if success { + status = fmt.Sprintf("\nPush OTP validation successful. Git operations are now allowed.\n") } else { - fmt.Fprintf(c.ReadWriter.Out, "\nOTP validation failed.\n%v\n", err) + if err != nil { + status = fmt.Sprintf("\nPush OTP validation failed.\n%v\n", err) + } else { + status = fmt.Sprintf("\nPush OTP validation failed.\n%v\n", reason) + } } - return nil + return } diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go deleted file mode 100644 --- a/internal/command/twofactorverify/twofactorverify_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package twofactorverify - -import ( - "bytes" - "context" - "encoding/json" - "io" - "net/http" - "testing" - - "github.com/stretchr/testify/require" - - "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" -) - -func setup(t *testing.T) []testserver.TestRequestHandler { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/two_factor_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *twofactorverify.RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - switch requestBody.KeyId { - case "1": - body := map[string]interface{}{ - "success": true, - } - json.NewEncoder(w).Encode(body) - case "error": - body := map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "broken": - w.WriteHeader(http.StatusInternalServerError) - } - }, - }, - } - - return requests -} - -const ( - question = "OTP: \n" - errorHeader = "OTP validation failed.\n" -) - -func TestExecute(t *testing.T) { - requests := setup(t) - - url := testserver.StartSocketHttpServer(t, requests) - - testCases := []struct { - desc string - arguments *commandargs.Shell - answer string - expectedOutput string - }{ - { - desc: "With a known key id", - arguments: &commandargs.Shell{GitlabKeyId: "1"}, - answer: "123456\n", - expectedOutput: question + - "OTP validation successful. Git operations are now allowed.\n", - }, - { - desc: "With bad response", - arguments: &commandargs.Shell{GitlabKeyId: "-1"}, - answer: "123456\n", - expectedOutput: question + errorHeader + "Parsing failed\n", - }, - { - desc: "With API returns an error", - arguments: &commandargs.Shell{GitlabKeyId: "error"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "error message\n", - }, - { - desc: "With API fails", - arguments: &commandargs.Shell{GitlabKeyId: "broken"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "Internal API error (500)\n", - }, - { - desc: "With missing arguments", - arguments: &commandargs.Shell{}, - answer: "yes\n", - expectedOutput: question + errorHeader + "who='' is invalid\n", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - output := &bytes.Buffer{} - input := bytes.NewBufferString(tc.answer) - - cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, - Args: tc.arguments, - ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, - } - - err := cmd.Execute(context.Background()) - - require.NoError(t, err) - require.Equal(t, tc.expectedOutput, output.String()) - }) - } -} diff --git a/internal/command/twofactorverify/twofactorverifymanual_test.go b/internal/command/twofactorverify/twofactorverifymanual_test.go new file mode 100644 --- /dev/null +++ b/internal/command/twofactorverify/twofactorverifymanual_test.go @@ -0,0 +1,154 @@ +package twofactorverify + +import ( + "bytes" + "context" + "encoding/json" + "io" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" +) + +func setupManual(t *testing.T) []testserver.TestRequestHandler { + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + var body map[string]interface{} + switch requestBody.KeyId { + case "1": + body = map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "error": + body = map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "broken": + w.WriteHeader(http.StatusInternalServerError) + } + }, + }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + time.Sleep(5 * time.Second) + + var body map[string]interface{} + switch requestBody.KeyId { + case "1": + body = map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "error": + body = map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "broken": + w.WriteHeader(http.StatusInternalServerError) + default: + body = map[string]interface{}{ + "success": true, + "message": "default message", + } + json.NewEncoder(w).Encode(body) + } + }, + }, + } + + return requests +} + +const ( + manualQuestion = "OTP: \n" + manualErrorHeader = "OTP validation failed.\n" +) + +func TestExecuteManual(t *testing.T) { + requests := setupManual(t) + + url := testserver.StartSocketHttpServer(t, requests) + + testCases := []struct { + desc string + arguments *commandargs.Shell + answer string + expectedOutput string + }{ + { + desc: "With a known key id", + arguments: &commandargs.Shell{GitlabKeyId: "1"}, + answer: "123456\n", + expectedOutput: manualQuestion + "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "With bad response", + arguments: &commandargs.Shell{GitlabKeyId: "-1"}, + answer: "123456\n", + expectedOutput: manualQuestion + manualErrorHeader + "Parsing failed\n", + }, + { + desc: "With API returns an error", + arguments: &commandargs.Shell{GitlabKeyId: "error"}, + answer: "yes\n", + expectedOutput: manualQuestion + manualErrorHeader + "error message\n", + }, + { + desc: "With API fails", + arguments: &commandargs.Shell{GitlabKeyId: "broken"}, + answer: "yes\n", + expectedOutput: manualQuestion + manualErrorHeader + "Internal API error (500)\n", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + output := &bytes.Buffer{} + + input := bytes.NewBufferString(tc.answer) + + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: tc.arguments, + ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, + } + + err := cmd.Execute(context.Background()) + + require.NoError(t, err) + require.Equal(t, tc.expectedOutput, output.String()) + }) + } +} diff --git a/internal/command/twofactorverify/twofactorverifypush_test.go b/internal/command/twofactorverify/twofactorverifypush_test.go new file mode 100644 --- /dev/null +++ b/internal/command/twofactorverify/twofactorverifypush_test.go @@ -0,0 +1,144 @@ +package twofactorverify + +import ( + "bytes" + "context" + "encoding/json" + "io" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" +) + +func setupPush(t *testing.T) []testserver.TestRequestHandler { + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + var body map[string]interface{} + switch requestBody.KeyId { + case "1": + body = map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "error": + body = map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "broken": + w.WriteHeader(http.StatusInternalServerError) + } + }, + }, + { + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + time.Sleep(20 * time.Second) + + var body map[string]interface{} + switch requestBody.KeyId { + case "1": + body = map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "error": + body = map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "broken": + w.WriteHeader(http.StatusInternalServerError) + } + }, + }, + } + + return requests +} + +const ( + pushQuestion = "OTP: \n" + pushErrorHeader = "Push OTP validation failed.\n" +) + +func TestExecutePush(t *testing.T) { + requests := setupPush(t) + + url := testserver.StartSocketHttpServer(t, requests) + + testCases := []struct { + desc string + arguments *commandargs.Shell + answer string + expectedOutput string + }{ + { + desc: "When push is provided", + arguments: &commandargs.Shell{GitlabKeyId: "1"}, + answer: "", + expectedOutput: pushQuestion + "Push OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "With API returns an error", + arguments: &commandargs.Shell{GitlabKeyId: "error"}, + answer: "", + expectedOutput: pushQuestion + pushErrorHeader + "error message\n", + }, + { + desc: "With API fails", + arguments: &commandargs.Shell{GitlabKeyId: "broken"}, + answer: "", + expectedOutput: pushQuestion + pushErrorHeader + "Internal API error (500)\n", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + output := &bytes.Buffer{} + + var input io.Reader + // make input wait for push auth tests + input, _ = io.Pipe() + + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: tc.arguments, + ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, + } + + err := cmd.Execute(context.Background()) + + require.NoError(t, err) + require.Equal(t, tc.expectedOutput, output.String()) + }) + } +} diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -2,7 +2,6 @@ import ( "context" - "errors" "fmt" "net/http" @@ -38,32 +37,48 @@ return &Client{config: config, client: client}, nil } -func (c *Client) VerifyOTP(ctx context.Context, args *commandargs.Shell, otp string) error { +func (c *Client) VerifyOTP(ctx context.Context, args *commandargs.Shell, otp string) (bool, string, error) { requestBody, err := c.getRequestBody(ctx, args, otp) if err != nil { - return err + return false, "", err } - response, err := c.client.Post(ctx, "/two_factor_otp_check", requestBody) + response, err := c.client.Post(ctx, "/two_factor_manual_otp_check", requestBody) if err != nil { - return err + return false, "", err } defer response.Body.Close() return parse(response) } -func parse(hr *http.Response) error { +func (c *Client) PushAuth(ctx context.Context, args *commandargs.Shell) (bool, string, error) { + // enable push auth in internal rest api + requestBody, err := c.getRequestBody(ctx, args, "") + if err != nil { + return false, "", err + } + + response, err := c.client.Post(ctx, "/two_factor_push_otp_check", requestBody) + if err != nil { + return false, "", err + } + defer response.Body.Close() + + return parse(response) +} + +func parse(hr *http.Response) (bool, string, error) { response := &Response{} if err := gitlabnet.ParseJSON(hr, response); err != nil { - return err + return false, "", err } if !response.Success { - return errors.New(response.Message) + return false, response.Message, nil } - return nil + return true, response.Message, nil } func (c *Client) getRequestBody(ctx context.Context, args *commandargs.Shell, otp string) (*RequestBody, error) { diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go deleted file mode 100644 --- a/internal/gitlabnet/twofactorverify/client_test.go +++ /dev/null @@ -1,151 +0,0 @@ -package twofactorverify - -import ( - "context" - "encoding/json" - "io" - "net/http" - "testing" - - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/v14/client" - "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" -) - -func initialize(t *testing.T) []testserver.TestRequestHandler { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/two_factor_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - switch requestBody.KeyId { - case "0": - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "1": - body := map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "2": - w.WriteHeader(http.StatusForbidden) - body := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) - } - - if requestBody.UserId == 1 { - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - } - }, - }, - { - Path: "/api/v4/internal/discover", - Handler: func(w http.ResponseWriter, r *http.Request) { - body := &discover.Response{ - UserId: 1, - Username: "jane-doe", - Name: "Jane Doe", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - }, - }, - } - - return requests -} - -const ( - otpAttempt = "123456" -) - -func TestVerifyOTPByKeyId(t *testing.T) { - client := setup(t) - - args := &commandargs.Shell{GitlabKeyId: "0"} - err := client.VerifyOTP(context.Background(), args, otpAttempt) - require.NoError(t, err) -} - -func TestVerifyOTPByUsername(t *testing.T) { - client := setup(t) - - args := &commandargs.Shell{GitlabUsername: "jane-doe"} - err := client.VerifyOTP(context.Background(), args, otpAttempt) - require.NoError(t, err) -} - -func TestErrorMessage(t *testing.T) { - client := setup(t) - - args := &commandargs.Shell{GitlabKeyId: "1"} - err := client.VerifyOTP(context.Background(), args, otpAttempt) - require.Equal(t, "error message", err.Error()) -} - -func TestErrorResponses(t *testing.T) { - client := setup(t) - - testCases := []struct { - desc string - fakeId string - expectedError string - }{ - { - desc: "A response with an error message", - fakeId: "2", - expectedError: "Not allowed!", - }, - { - desc: "A response with bad JSON", - fakeId: "3", - expectedError: "Parsing failed", - }, - { - desc: "An error response without message", - fakeId: "4", - expectedError: "Internal API error (403)", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - args := &commandargs.Shell{GitlabKeyId: tc.fakeId} - err := client.VerifyOTP(context.Background(), args, otpAttempt) - - require.EqualError(t, err, tc.expectedError) - }) - } -} - -func setup(t *testing.T) *Client { - requests := initialize(t) - url := testserver.StartSocketHttpServer(t, requests) - - client, err := NewClient(&config.Config{GitlabUrl: url}) - require.NoError(t, err) - - return client -} diff --git a/internal/gitlabnet/twofactorverify/clientmanual_test.go b/internal/gitlabnet/twofactorverify/clientmanual_test.go new file mode 100644 --- /dev/null +++ b/internal/gitlabnet/twofactorverify/clientmanual_test.go @@ -0,0 +1,151 @@ +package twofactorverify + +import ( + "context" + "encoding/json" + "io" + "net/http" + "testing" + + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" +) + +func initializeManual(t *testing.T) []testserver.TestRequestHandler { + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "0": + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "1": + body := map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "2": + w.WriteHeader(http.StatusForbidden) + body := &client.ErrorResponse{ + Message: "Not allowed!", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "3": + w.Write([]byte("{ \"message\": \"broken json!\"")) + case "4": + w.WriteHeader(http.StatusForbidden) + } + + if requestBody.UserId == 1 { + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + } + }, + }, + { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + body := &discover.Response{ + UserId: 1, + Username: "jane-doe", + Name: "Jane Doe", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + }, + }, + } + + return requests +} + +const ( + manualOtpAttempt = "123456" +) + +func TestVerifyOTPByKeyId(t *testing.T) { + client := setupManual(t) + + args := &commandargs.Shell{GitlabKeyId: "0"} + _, _, err := client.VerifyOTP(context.Background(), args, manualOtpAttempt) + require.NoError(t, err) +} + +func TestVerifyOTPByUsername(t *testing.T) { + client := setupManual(t) + + args := &commandargs.Shell{GitlabUsername: "jane-doe"} + _, _, err := client.VerifyOTP(context.Background(), args, manualOtpAttempt) + require.NoError(t, err) +} + +func TestErrorMessage(t *testing.T) { + client := setupManual(t) + + args := &commandargs.Shell{GitlabKeyId: "1"} + _, reason, _ := client.VerifyOTP(context.Background(), args, manualOtpAttempt) + require.Equal(t, "error message", reason) +} + +func TestErrorResponses(t *testing.T) { + client := setupManual(t) + + testCases := []struct { + desc string + fakeId string + expectedError string + }{ + { + desc: "A response with an error message", + fakeId: "2", + expectedError: "Not allowed!", + }, + { + desc: "A response with bad JSON", + fakeId: "3", + expectedError: "Parsing failed", + }, + { + desc: "An error response without message", + fakeId: "4", + expectedError: "Internal API error (403)", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + args := &commandargs.Shell{GitlabKeyId: tc.fakeId} + _, _, err := client.VerifyOTP(context.Background(), args, manualOtpAttempt) + + require.EqualError(t, err, tc.expectedError) + }) + } +} + +func setupManual(t *testing.T) *Client { + requests := initializeManual(t) + url := testserver.StartSocketHttpServer(t, requests) + + client, err := NewClient(&config.Config{GitlabUrl: url}) + require.NoError(t, err) + + return client +} diff --git a/internal/gitlabnet/twofactorverify/clientpush_test.go b/internal/gitlabnet/twofactorverify/clientpush_test.go new file mode 100644 --- /dev/null +++ b/internal/gitlabnet/twofactorverify/clientpush_test.go @@ -0,0 +1,139 @@ +package twofactorverify + +import ( + "context" + "encoding/json" + "io" + "net/http" + "testing" + + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" +) + +func initializePush(t *testing.T) []testserver.TestRequestHandler { + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "0": + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "1": + body := map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "2": + w.WriteHeader(http.StatusForbidden) + body := &client.ErrorResponse{ + Message: "Not allowed!", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "3": + w.Write([]byte("{ \"message\": \"broken json!\"")) + case "4": + w.WriteHeader(http.StatusForbidden) + } + + if requestBody.UserId == 1 { + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + } + }, + }, + { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + body := &discover.Response{ + UserId: 1, + Username: "jane-doe", + Name: "Jane Doe", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + }, + }, + } + + return requests +} + +func TestVerifyPush(t *testing.T) { + client := setupPush(t) + + args := &commandargs.Shell{GitlabKeyId: "0"} + _, _, err := client.PushAuth(context.Background(), args) + require.NoError(t, err) +} + +func TestErrorMessagePush(t *testing.T) { + client := setupPush(t) + + args := &commandargs.Shell{GitlabKeyId: "1"} + _, reason, _ := client.PushAuth(context.Background(), args) + require.Equal(t, "error message", reason) +} + +func TestErrorResponsesPush(t *testing.T) { + client := setupPush(t) + + testCases := []struct { + desc string + fakeId string + expectedError string + }{ + { + desc: "A response with an error message", + fakeId: "2", + expectedError: "Not allowed!", + }, + { + desc: "A response with bad JSON", + fakeId: "3", + expectedError: "Parsing failed", + }, + { + desc: "An error response without message", + fakeId: "4", + expectedError: "Internal API error (403)", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + args := &commandargs.Shell{GitlabKeyId: tc.fakeId} + _, _, err := client.PushAuth(context.Background(), args) + + require.EqualError(t, err, tc.expectedError) + }) + } +} + +func setupPush(t *testing.T) *Client { + requests := initializePush(t) + url := testserver.StartSocketHttpServer(t, requests) + + client, err := NewClient(&config.Config{GitlabUrl: url}) + require.NoError(t, err) + + return client +} diff --git a/spec/gitlab_shell_two_factor_manual_verify_spec.rb b/spec/gitlab_shell_two_factor_manual_verify_spec.rb new file mode 100644 --- /dev/null +++ b/spec/gitlab_shell_two_factor_manual_verify_spec.rb @@ -0,0 +1,92 @@ +require_relative 'spec_helper' + +require 'open3' +require 'json' + +describe 'bin/gitlab-shell 2fa_verify manual' do + include_context 'gitlab shell' + + let(:env) do + { 'SSH_CONNECTION' => 'fake', + 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } + end + + before(:context) do + write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") + end + + def mock_server(server) + server.mount_proc('/api/v4/internal/two_factor_manual_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + key_id = params['key_id'] || params['user_id'].to_s + + if key_id == '100' + res.body = { success: true }.to_json + else + res.body = { success: false, message: 'boom!' }.to_json + end + end + + server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + key_id = params['key_id'] || params['user_id'].to_s + + sleep 5 # simulate Fortinet API timing + res.body = { success: false, message: 'boom!' }.to_json + end + + server.mount_proc('/api/v4/internal/discover') do |_, res| + res.status = 200 + res.content_type = 'application/json' + res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + end + end + + describe 'command' do + context 'when key is provided' do + let(:cmd) { "#{gitlab_shell_path} key-100" } + + it 'prints a successful verification message' do + verify_successful_verification!(cmd) + end + end + + context 'when username is provided' do + let(:cmd) { "#{gitlab_shell_path} username-someone" } + + it 'prints a successful verification message' do + verify_successful_verification!(cmd) + end + end + + context 'when API error occurs' do + let(:cmd) { "#{gitlab_shell_path} key-101" } + + it 'prints the error message' do + Open3.popen2(env, cmd) do |stdin, stdout| + expect(stdout.gets(5)).to eq('OTP: ') + + stdin.puts('123456') + + expect(stdout.flush.read).to eq("\nOTP validation failed.\nboom!\n") + end + end + end + end + + def verify_successful_verification!(cmd) + Open3.popen2(env, cmd) do |stdin, stdout| + expect(stdout.gets(5)).to eq('OTP: ') + + stdin.puts('123456') + + expect(stdout.flush.read).to eq("\nOTP validation successful. Git operations are now allowed.\n") + end + end +end diff --git a/spec/gitlab_shell_two_factor_push_verify_spec.rb b/spec/gitlab_shell_two_factor_push_verify_spec.rb new file mode 100644 --- /dev/null +++ b/spec/gitlab_shell_two_factor_push_verify_spec.rb @@ -0,0 +1,71 @@ +require_relative 'spec_helper' + +require 'open3' +require 'json' + +describe 'bin/gitlab-shell 2fa_verify push' do + include_context 'gitlab shell' + + let(:env) do + { 'SSH_CONNECTION' => 'fake', + 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } + end + + before(:context) do + write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") + end + + def mock_server(server) + server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + key_id = params['key_id'] || params['user_id'].to_s + + if key_id == '100' + res.body = { success: false }.to_json + elsif key_id == '102' + res.body = { success: true }.to_json + else + res.body = { success: false, message: 'boom!' }.to_json + end + end + + server.mount_proc('/api/v4/internal/discover') do |_, res| + res.status = 200 + res.content_type = 'application/json' + res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + end + end + + describe 'command' do + context 'when push is provided' do + let(:cmd) { "#{gitlab_shell_path} key-102" } + + it 'prints a successful push verification message' do + verify_successful_verification_push!(cmd) + end + end + + context 'when API error occurs' do + let(:cmd) { "#{gitlab_shell_path} key-101" } + + it 'prints the error message' do + Open3.popen2(env, cmd) do |stdin, stdout| + expect(stdout.gets(5)).to eq('OTP: ') + + expect(stdout.flush.read).to eq("\nPush OTP validation failed.\nboom!\n") + end + end + end + end + + def verify_successful_verification_push!(cmd) + Open3.popen2(env, cmd) do |stdin, stdout| + expect(stdout.gets(5)).to eq('OTP: ') + + expect(stdout.flush.read).to eq("\nPush OTP validation successful. Git operations are now allowed.\n") + end + end +end diff --git a/spec/gitlab_shell_two_factor_verify_spec.rb b/spec/gitlab_shell_two_factor_verify_spec.rb deleted file mode 100644 --- a/spec/gitlab_shell_two_factor_verify_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -require_relative 'spec_helper' - -require 'open3' -require 'json' - -describe 'bin/gitlab-shell 2fa_verify' do - include_context 'gitlab shell' - - let(:env) do - { 'SSH_CONNECTION' => 'fake', - 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } - end - - before(:context) do - write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") - end - - def mock_server(server) - server.mount_proc('/api/v4/internal/two_factor_otp_check') do |req, res| - res.content_type = 'application/json' - res.status = 200 - - params = JSON.parse(req.body) - key_id = params['key_id'] || params['user_id'].to_s - - if key_id == '100' - res.body = { success: true }.to_json - else - res.body = { success: false, message: 'boom!' }.to_json - end - end - - server.mount_proc('/api/v4/internal/discover') do |_, res| - res.status = 200 - res.content_type = 'application/json' - res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json - end - end - - describe 'command' do - context 'when key is provided' do - let(:cmd) { "#{gitlab_shell_path} key-100" } - - it 'prints a successful verification message' do - verify_successful_verification!(cmd) - end - end - - context 'when username is provided' do - let(:cmd) { "#{gitlab_shell_path} username-someone" } - - it 'prints a successful verification message' do - verify_successful_verification!(cmd) - end - end - - context 'when API error occurs' do - let(:cmd) { "#{gitlab_shell_path} key-101" } - - it 'prints the error message' do - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') - - expect(stdout.flush.read).to eq("\nOTP validation failed.\nboom!\n") - end - end - end - end - - def verify_successful_verification!(cmd) - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') - - expect(stdout.flush.read).to eq("\nOTP validation successful. Git operations are now allowed.\n") - end - end -end # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1657977306 -7200 # Sat Jul 16 15:15:06 2022 +0200 # Node ID 3b8480785bad7d68dfac81978e90675bfbc81121 # Parent fcbdf9e966ae00e60daa009adfba0ee3ecc70a5d Simplify 2FA Push auth processing Use a single channel to handle both Push Auth and OTP results diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -14,105 +14,63 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) +const ( + timeout = 30 * time.Second + prompt = "OTP: " +) + type Command struct { Config *config.Config - Client *twofactorverify.Client Args *commandargs.Shell ReadWriter *readwriter.ReadWriter } -type Result struct { - Error error - Status string - Success bool -} - func (c *Command) Execute(ctx context.Context) error { - ctxlog := log.ContextLogger(ctx) - - // config.GetHTTPClient isn't thread-safe so save Client in struct for concurrency - // workaround until #518 is fixed - var err error - c.Client, err = twofactorverify.NewClient(c.Config) - + client, err := twofactorverify.NewClient(c.Config) if err != nil { - ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } - // Create timeout context - // TODO: make timeout configurable - const ctxTimeout = 30 - timeoutCtx, cancelTimeout := context.WithTimeout(ctx, ctxTimeout*time.Second) - defer cancelTimeout() + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() - // Background push notification with timeout - pushauth := make(chan Result) + fmt.Fprint(c.ReadWriter.Out, prompt) + + resultCh := make(chan string) go func() { - defer close(pushauth) - ctxlog.Info("twofactorverify: execute: waiting for push auth") - status, success, err := c.pushAuth(timeoutCtx) - ctxlog.WithError(err).Info("twofactorverify: execute: push auth verified") - - select { - case <-timeoutCtx.Done(): // push cancelled by manual OTP - // skip writing to channel - ctxlog.Info("twofactorverify: execute: push auth cancelled") - default: - pushauth <- Result{Error: err, Status: status, Success: success} + err := client.PushAuth(ctx, c.Args) + if err == nil { + resultCh <- "OTP has been validated by Push Authentication. Git operations are now allowed." } }() - // Also allow manual OTP entry while waiting for push, with same timeout as push - verify := make(chan Result) go func() { - defer close(verify) - ctxlog.Info("twofactorverify: execute: waiting for user input") - answer := "" - answer = c.getOTP(timeoutCtx) - ctxlog.Info("twofactorverify: execute: user input received") + answer, err := c.getOTP(ctx) + if err != nil { + resultCh <- formatErr(err) + } - select { - case <-timeoutCtx.Done(): // manual OTP cancelled by push - // skip writing to channel - ctxlog.Info("twofactorverify: execute: verify cancelled") - default: - ctxlog.Info("twofactorverify: execute: verifying entered OTP") - status, success, err := c.verifyOTP(timeoutCtx, answer) - ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") - verify <- Result{Error: err, Status: status, Success: success} + if err := client.VerifyOTP(ctx, c.Args, answer); err != nil { + resultCh <- formatErr(err) + } else { + resultCh <- "OTP validation successful. Git operations are now allowed." } }() - for { - select { - case res := <-verify: - if res.Status == "" { - // channel closed; don't print anything - } else { - fmt.Fprint(c.ReadWriter.Out, res.Status) - return nil - } - case res := <-pushauth: - if res.Status == "" { - // channel closed; don't print anything - } else { - fmt.Fprint(c.ReadWriter.Out, res.Status) - return nil - } - case <-timeoutCtx.Done(): // push timed out - fmt.Fprint(c.ReadWriter.Out, "\nOTP verification timed out\n") - return nil - } + var message string + select { + case message = <-resultCh: + case <-ctx.Done(): + message = formatErr(ctx.Err()) } + log.WithContextFields(ctx, log.Fields{"message": message}).Info("Two factor verify command finished") + fmt.Fprintf(c.ReadWriter.Out, "\n%v\n", message) + return nil } -func (c *Command) getOTP(ctx context.Context) string { - prompt := "OTP: " - fmt.Fprint(c.ReadWriter.Out, prompt) - +func (c *Command) getOTP(ctx context.Context) (string, error) { var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) @@ -120,41 +78,13 @@ log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") } - return answer -} - -func (c *Command) verifyOTP(ctx context.Context, otp string) (status string, success bool, err error) { - reason := "" - - success, reason, err = c.Client.VerifyOTP(ctx, c.Args, otp) - if success { - status = fmt.Sprintf("\nOTP validation successful. Git operations are now allowed.\n") - } else { - if err != nil { - status = fmt.Sprintf("\nOTP validation failed.\n%v\n", err) - } else { - status = fmt.Sprintf("\nOTP validation failed.\n%v\n", reason) - } + if answer == "" { + return "", fmt.Errorf("OTP cannot be blank.") } - err = nil - - return + return answer, nil } -func (c *Command) pushAuth(ctx context.Context) (status string, success bool, err error) { - reason := "" - - success, reason, err = c.Client.PushAuth(ctx, c.Args) - if success { - status = fmt.Sprintf("\nPush OTP validation successful. Git operations are now allowed.\n") - } else { - if err != nil { - status = fmt.Sprintf("\nPush OTP validation failed.\n%v\n", err) - } else { - status = fmt.Sprintf("\nPush OTP validation failed.\n%v\n", reason) - } - } - - return +func formatErr(err error) string { + return fmt.Sprintf("OTP validation failed: %v", err) } diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go new file mode 100644 --- /dev/null +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -0,0 +1,191 @@ +package twofactorverify + +import ( + "bytes" + "context" + "encoding/json" + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" +) + +type blockingReader struct{} + +func (*blockingReader) Read([]byte) (int, error) { + waitInfinitely := make(chan struct{}) + <-waitInfinitely + + return 0, nil +} + +func setup(t *testing.T) []testserver.TestRequestHandler { + waitInfinitely := make(chan struct{}) + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "verify_via_otp", "verify_via_otp_with_push_error": + body := map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "wait_infinitely": + <-waitInfinitely + case "error": + body := map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "broken": + w.WriteHeader(http.StatusInternalServerError) + } + }, + }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "verify_via_push": + body := map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "verify_via_otp_with_push_error": + w.WriteHeader(http.StatusInternalServerError) + default: + <-waitInfinitely + } + }, + }, + } + + return requests +} + +const errorHeader = "OTP validation failed: " + +func TestExecute(t *testing.T) { + requests := setup(t) + + url := testserver.StartSocketHttpServer(t, requests) + + testCases := []struct { + desc string + arguments *commandargs.Shell + input io.Reader + expectedOutput string + }{ + { + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp_with_push_error"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via push authentication", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_push"}, + input: &blockingReader{}, + expectedOutput: "OTP has been validated by Push Authentication. Git operations are now allowed.\n", + }, + { + desc: "With an empty OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + input: bytes.NewBufferString("\n"), + expectedOutput: errorHeader + "OTP cannot be blank.\n", + }, + { + desc: "With bad response", + arguments: &commandargs.Shell{GitlabKeyId: "-1"}, + expectedOutput: errorHeader + "Parsing failed\n", + }, + { + desc: "With API returns an error", + arguments: &commandargs.Shell{GitlabKeyId: "error"}, + expectedOutput: errorHeader + "error message\n", + }, + { + desc: "With API fails", + arguments: &commandargs.Shell{GitlabKeyId: "broken"}, + expectedOutput: errorHeader + "Internal API error (500)\n", + }, + { + desc: "With missing arguments", + arguments: &commandargs.Shell{}, + expectedOutput: errorHeader + "who='' is invalid\n", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + output := &bytes.Buffer{} + + input := tc.input + if input == nil { + input = bytes.NewBufferString("123456\n") + } + + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: tc.arguments, + ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, + } + + err := cmd.Execute(context.Background()) + + require.NoError(t, err) + require.Equal(t, prompt+"\n"+tc.expectedOutput, output.String()) + }) + } +} + +func TestCanceledContext(t *testing.T) { + requests := setup(t) + + output := &bytes.Buffer{} + + url := testserver.StartSocketHttpServer(t, requests) + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: &commandargs.Shell{GitlabKeyId: "wait_infinitely"}, + ReadWriter: &readwriter.ReadWriter{Out: output, In: &bytes.Buffer{}}, + } + + ctx, cancel := context.WithCancel(context.Background()) + + errCh := make(chan error) + go func() { errCh <- cmd.Execute(ctx) }() + cancel() + + require.NoError(t, <-errCh) + require.Equal(t, prompt+"\n"+errorHeader+"context canceled\n", output.String()) +} diff --git a/internal/command/twofactorverify/twofactorverifymanual_test.go b/internal/command/twofactorverify/twofactorverifymanual_test.go deleted file mode 100644 --- a/internal/command/twofactorverify/twofactorverifymanual_test.go +++ /dev/null @@ -1,154 +0,0 @@ -package twofactorverify - -import ( - "bytes" - "context" - "encoding/json" - "io" - "net/http" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" -) - -func setupManual(t *testing.T) []testserver.TestRequestHandler { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/two_factor_manual_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *twofactorverify.RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - var body map[string]interface{} - switch requestBody.KeyId { - case "1": - body = map[string]interface{}{ - "success": true, - } - json.NewEncoder(w).Encode(body) - case "error": - body = map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "broken": - w.WriteHeader(http.StatusInternalServerError) - } - }, - }, - { - Path: "/api/v4/internal/two_factor_push_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *twofactorverify.RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - time.Sleep(5 * time.Second) - - var body map[string]interface{} - switch requestBody.KeyId { - case "1": - body = map[string]interface{}{ - "success": true, - } - json.NewEncoder(w).Encode(body) - case "error": - body = map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "broken": - w.WriteHeader(http.StatusInternalServerError) - default: - body = map[string]interface{}{ - "success": true, - "message": "default message", - } - json.NewEncoder(w).Encode(body) - } - }, - }, - } - - return requests -} - -const ( - manualQuestion = "OTP: \n" - manualErrorHeader = "OTP validation failed.\n" -) - -func TestExecuteManual(t *testing.T) { - requests := setupManual(t) - - url := testserver.StartSocketHttpServer(t, requests) - - testCases := []struct { - desc string - arguments *commandargs.Shell - answer string - expectedOutput string - }{ - { - desc: "With a known key id", - arguments: &commandargs.Shell{GitlabKeyId: "1"}, - answer: "123456\n", - expectedOutput: manualQuestion + "OTP validation successful. Git operations are now allowed.\n", - }, - { - desc: "With bad response", - arguments: &commandargs.Shell{GitlabKeyId: "-1"}, - answer: "123456\n", - expectedOutput: manualQuestion + manualErrorHeader + "Parsing failed\n", - }, - { - desc: "With API returns an error", - arguments: &commandargs.Shell{GitlabKeyId: "error"}, - answer: "yes\n", - expectedOutput: manualQuestion + manualErrorHeader + "error message\n", - }, - { - desc: "With API fails", - arguments: &commandargs.Shell{GitlabKeyId: "broken"}, - answer: "yes\n", - expectedOutput: manualQuestion + manualErrorHeader + "Internal API error (500)\n", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - output := &bytes.Buffer{} - - input := bytes.NewBufferString(tc.answer) - - cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, - Args: tc.arguments, - ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, - } - - err := cmd.Execute(context.Background()) - - require.NoError(t, err) - require.Equal(t, tc.expectedOutput, output.String()) - }) - } -} diff --git a/internal/command/twofactorverify/twofactorverifypush_test.go b/internal/command/twofactorverify/twofactorverifypush_test.go deleted file mode 100644 --- a/internal/command/twofactorverify/twofactorverifypush_test.go +++ /dev/null @@ -1,144 +0,0 @@ -package twofactorverify - -import ( - "bytes" - "context" - "encoding/json" - "io" - "net/http" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" -) - -func setupPush(t *testing.T) []testserver.TestRequestHandler { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/two_factor_push_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *twofactorverify.RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - var body map[string]interface{} - switch requestBody.KeyId { - case "1": - body = map[string]interface{}{ - "success": true, - } - json.NewEncoder(w).Encode(body) - case "error": - body = map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "broken": - w.WriteHeader(http.StatusInternalServerError) - } - }, - }, - { - Path: "/api/v4/internal/two_factor_manual_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *twofactorverify.RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - time.Sleep(20 * time.Second) - - var body map[string]interface{} - switch requestBody.KeyId { - case "1": - body = map[string]interface{}{ - "success": true, - } - json.NewEncoder(w).Encode(body) - case "error": - body = map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "broken": - w.WriteHeader(http.StatusInternalServerError) - } - }, - }, - } - - return requests -} - -const ( - pushQuestion = "OTP: \n" - pushErrorHeader = "Push OTP validation failed.\n" -) - -func TestExecutePush(t *testing.T) { - requests := setupPush(t) - - url := testserver.StartSocketHttpServer(t, requests) - - testCases := []struct { - desc string - arguments *commandargs.Shell - answer string - expectedOutput string - }{ - { - desc: "When push is provided", - arguments: &commandargs.Shell{GitlabKeyId: "1"}, - answer: "", - expectedOutput: pushQuestion + "Push OTP validation successful. Git operations are now allowed.\n", - }, - { - desc: "With API returns an error", - arguments: &commandargs.Shell{GitlabKeyId: "error"}, - answer: "", - expectedOutput: pushQuestion + pushErrorHeader + "error message\n", - }, - { - desc: "With API fails", - arguments: &commandargs.Shell{GitlabKeyId: "broken"}, - answer: "", - expectedOutput: pushQuestion + pushErrorHeader + "Internal API error (500)\n", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - output := &bytes.Buffer{} - - var input io.Reader - // make input wait for push auth tests - input, _ = io.Pipe() - - cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, - Args: tc.arguments, - ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, - } - - err := cmd.Execute(context.Background()) - - require.NoError(t, err) - require.Equal(t, tc.expectedOutput, output.String()) - }) - } -} diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "fmt" "net/http" @@ -25,7 +26,7 @@ type RequestBody struct { KeyId string `json:"key_id,omitempty"` UserId int64 `json:"user_id,omitempty"` - OTPAttempt string `json:"otp_attempt"` + OTPAttempt string `json:"otp_attempt,omitempty"` } func NewClient(config *config.Config) (*Client, error) { @@ -37,48 +38,47 @@ return &Client{config: config, client: client}, nil } -func (c *Client) VerifyOTP(ctx context.Context, args *commandargs.Shell, otp string) (bool, string, error) { +func (c *Client) VerifyOTP(ctx context.Context, args *commandargs.Shell, otp string) error { requestBody, err := c.getRequestBody(ctx, args, otp) if err != nil { - return false, "", err + return err } response, err := c.client.Post(ctx, "/two_factor_manual_otp_check", requestBody) if err != nil { - return false, "", err + return err } defer response.Body.Close() return parse(response) } -func (c *Client) PushAuth(ctx context.Context, args *commandargs.Shell) (bool, string, error) { - // enable push auth in internal rest api +func (c *Client) PushAuth(ctx context.Context, args *commandargs.Shell) error { requestBody, err := c.getRequestBody(ctx, args, "") if err != nil { - return false, "", err + return err } response, err := c.client.Post(ctx, "/two_factor_push_otp_check", requestBody) if err != nil { - return false, "", err + return err } defer response.Body.Close() return parse(response) } -func parse(hr *http.Response) (bool, string, error) { +func parse(hr *http.Response) error { response := &Response{} if err := gitlabnet.ParseJSON(hr, response); err != nil { - return false, "", err + return err } if !response.Success { - return false, response.Message, nil + return errors.New(response.Message) } - return true, response.Message, nil + return nil } func (c *Client) getRequestBody(ctx context.Context, args *commandargs.Shell, otp string) (*RequestBody, error) { diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go new file mode 100644 --- /dev/null +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -0,0 +1,208 @@ +package twofactorverify + +import ( + "context" + "encoding/json" + "io" + "net/http" + "testing" + + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" +) + +func initialize(t *testing.T) []testserver.TestRequestHandler { + handler := func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "0": + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "1": + body := map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "2": + w.WriteHeader(http.StatusForbidden) + body := &client.ErrorResponse{ + Message: "Not allowed!", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "3": + w.Write([]byte("{ \"message\": \"broken json!\"")) + case "4": + w.WriteHeader(http.StatusForbidden) + } + + if requestBody.UserId == 1 { + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + } + } + + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: handler, + }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: handler, + }, + { + Path: "/api/v4/internal/discover", + Handler: func(w http.ResponseWriter, r *http.Request) { + body := &discover.Response{ + UserId: 1, + Username: "jane-doe", + Name: "Jane Doe", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + }, + }, + } + + return requests +} + +const ( + otpAttempt = "123456" +) + +func TestVerifyOTPByKeyId(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "0"} + err := client.VerifyOTP(context.Background(), args, otpAttempt) + require.NoError(t, err) +} + +func TestVerifyOTPByUsername(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabUsername: "jane-doe"} + err := client.VerifyOTP(context.Background(), args, otpAttempt) + require.NoError(t, err) +} + +func TestErrorMessage(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "1"} + err := client.VerifyOTP(context.Background(), args, otpAttempt) + require.Equal(t, "error message", err.Error()) +} + +func TestErrorResponses(t *testing.T) { + client := setup(t) + + testCases := []struct { + desc string + fakeId string + expectedError string + }{ + { + desc: "A response with an error message", + fakeId: "2", + expectedError: "Not allowed!", + }, + { + desc: "A response with bad JSON", + fakeId: "3", + expectedError: "Parsing failed", + }, + { + desc: "An error response without message", + fakeId: "4", + expectedError: "Internal API error (403)", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + args := &commandargs.Shell{GitlabKeyId: tc.fakeId} + err := client.VerifyOTP(context.Background(), args, otpAttempt) + + require.EqualError(t, err, tc.expectedError) + }) + } +} + +func TestVerifyPush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "0"} + err := client.PushAuth(context.Background(), args) + require.NoError(t, err) +} + +func TestErrorMessagePush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "1"} + err := client.PushAuth(context.Background(), args) + require.Equal(t, "error message", err.Error()) +} + +func TestErrorResponsesPush(t *testing.T) { + client := setup(t) + + testCases := []struct { + desc string + fakeId string + expectedError string + }{ + { + desc: "A response with an error message", + fakeId: "2", + expectedError: "Not allowed!", + }, + { + desc: "A response with bad JSON", + fakeId: "3", + expectedError: "Parsing failed", + }, + { + desc: "An error response without message", + fakeId: "4", + expectedError: "Internal API error (403)", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + args := &commandargs.Shell{GitlabKeyId: tc.fakeId} + err := client.PushAuth(context.Background(), args) + + require.EqualError(t, err, tc.expectedError) + }) + } +} + +func setup(t *testing.T) *Client { + requests := initialize(t) + url := testserver.StartSocketHttpServer(t, requests) + + client, err := NewClient(&config.Config{GitlabUrl: url}) + require.NoError(t, err) + + return client +} diff --git a/internal/gitlabnet/twofactorverify/clientmanual_test.go b/internal/gitlabnet/twofactorverify/clientmanual_test.go deleted file mode 100644 --- a/internal/gitlabnet/twofactorverify/clientmanual_test.go +++ /dev/null @@ -1,151 +0,0 @@ -package twofactorverify - -import ( - "context" - "encoding/json" - "io" - "net/http" - "testing" - - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/v14/client" - "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" -) - -func initializeManual(t *testing.T) []testserver.TestRequestHandler { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/two_factor_manual_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - switch requestBody.KeyId { - case "0": - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "1": - body := map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "2": - w.WriteHeader(http.StatusForbidden) - body := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) - } - - if requestBody.UserId == 1 { - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - } - }, - }, - { - Path: "/api/v4/internal/discover", - Handler: func(w http.ResponseWriter, r *http.Request) { - body := &discover.Response{ - UserId: 1, - Username: "jane-doe", - Name: "Jane Doe", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - }, - }, - } - - return requests -} - -const ( - manualOtpAttempt = "123456" -) - -func TestVerifyOTPByKeyId(t *testing.T) { - client := setupManual(t) - - args := &commandargs.Shell{GitlabKeyId: "0"} - _, _, err := client.VerifyOTP(context.Background(), args, manualOtpAttempt) - require.NoError(t, err) -} - -func TestVerifyOTPByUsername(t *testing.T) { - client := setupManual(t) - - args := &commandargs.Shell{GitlabUsername: "jane-doe"} - _, _, err := client.VerifyOTP(context.Background(), args, manualOtpAttempt) - require.NoError(t, err) -} - -func TestErrorMessage(t *testing.T) { - client := setupManual(t) - - args := &commandargs.Shell{GitlabKeyId: "1"} - _, reason, _ := client.VerifyOTP(context.Background(), args, manualOtpAttempt) - require.Equal(t, "error message", reason) -} - -func TestErrorResponses(t *testing.T) { - client := setupManual(t) - - testCases := []struct { - desc string - fakeId string - expectedError string - }{ - { - desc: "A response with an error message", - fakeId: "2", - expectedError: "Not allowed!", - }, - { - desc: "A response with bad JSON", - fakeId: "3", - expectedError: "Parsing failed", - }, - { - desc: "An error response without message", - fakeId: "4", - expectedError: "Internal API error (403)", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - args := &commandargs.Shell{GitlabKeyId: tc.fakeId} - _, _, err := client.VerifyOTP(context.Background(), args, manualOtpAttempt) - - require.EqualError(t, err, tc.expectedError) - }) - } -} - -func setupManual(t *testing.T) *Client { - requests := initializeManual(t) - url := testserver.StartSocketHttpServer(t, requests) - - client, err := NewClient(&config.Config{GitlabUrl: url}) - require.NoError(t, err) - - return client -} diff --git a/internal/gitlabnet/twofactorverify/clientpush_test.go b/internal/gitlabnet/twofactorverify/clientpush_test.go deleted file mode 100644 --- a/internal/gitlabnet/twofactorverify/clientpush_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package twofactorverify - -import ( - "context" - "encoding/json" - "io" - "net/http" - "testing" - - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" - - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/v14/client" - "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" -) - -func initializePush(t *testing.T) []testserver.TestRequestHandler { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/two_factor_push_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - switch requestBody.KeyId { - case "0": - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "1": - body := map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "2": - w.WriteHeader(http.StatusForbidden) - body := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) - } - - if requestBody.UserId == 1 { - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - } - }, - }, - { - Path: "/api/v4/internal/discover", - Handler: func(w http.ResponseWriter, r *http.Request) { - body := &discover.Response{ - UserId: 1, - Username: "jane-doe", - Name: "Jane Doe", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - }, - }, - } - - return requests -} - -func TestVerifyPush(t *testing.T) { - client := setupPush(t) - - args := &commandargs.Shell{GitlabKeyId: "0"} - _, _, err := client.PushAuth(context.Background(), args) - require.NoError(t, err) -} - -func TestErrorMessagePush(t *testing.T) { - client := setupPush(t) - - args := &commandargs.Shell{GitlabKeyId: "1"} - _, reason, _ := client.PushAuth(context.Background(), args) - require.Equal(t, "error message", reason) -} - -func TestErrorResponsesPush(t *testing.T) { - client := setupPush(t) - - testCases := []struct { - desc string - fakeId string - expectedError string - }{ - { - desc: "A response with an error message", - fakeId: "2", - expectedError: "Not allowed!", - }, - { - desc: "A response with bad JSON", - fakeId: "3", - expectedError: "Parsing failed", - }, - { - desc: "An error response without message", - fakeId: "4", - expectedError: "Internal API error (403)", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - args := &commandargs.Shell{GitlabKeyId: tc.fakeId} - _, _, err := client.PushAuth(context.Background(), args) - - require.EqualError(t, err, tc.expectedError) - }) - } -} - -func setupPush(t *testing.T) *Client { - requests := initializePush(t) - url := testserver.StartSocketHttpServer(t, requests) - - client, err := NewClient(&config.Config{GitlabUrl: url}) - require.NoError(t, err) - - return client -} diff --git a/spec/gitlab_shell_two_factor_manual_verify_spec.rb b/spec/gitlab_shell_two_factor_manual_verify_spec.rb deleted file mode 100644 --- a/spec/gitlab_shell_two_factor_manual_verify_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -require_relative 'spec_helper' - -require 'open3' -require 'json' - -describe 'bin/gitlab-shell 2fa_verify manual' do - include_context 'gitlab shell' - - let(:env) do - { 'SSH_CONNECTION' => 'fake', - 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } - end - - before(:context) do - write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") - end - - def mock_server(server) - server.mount_proc('/api/v4/internal/two_factor_manual_otp_check') do |req, res| - res.content_type = 'application/json' - res.status = 200 - - params = JSON.parse(req.body) - key_id = params['key_id'] || params['user_id'].to_s - - if key_id == '100' - res.body = { success: true }.to_json - else - res.body = { success: false, message: 'boom!' }.to_json - end - end - - server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| - res.content_type = 'application/json' - res.status = 200 - - params = JSON.parse(req.body) - key_id = params['key_id'] || params['user_id'].to_s - - sleep 5 # simulate Fortinet API timing - res.body = { success: false, message: 'boom!' }.to_json - end - - server.mount_proc('/api/v4/internal/discover') do |_, res| - res.status = 200 - res.content_type = 'application/json' - res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json - end - end - - describe 'command' do - context 'when key is provided' do - let(:cmd) { "#{gitlab_shell_path} key-100" } - - it 'prints a successful verification message' do - verify_successful_verification!(cmd) - end - end - - context 'when username is provided' do - let(:cmd) { "#{gitlab_shell_path} username-someone" } - - it 'prints a successful verification message' do - verify_successful_verification!(cmd) - end - end - - context 'when API error occurs' do - let(:cmd) { "#{gitlab_shell_path} key-101" } - - it 'prints the error message' do - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') - - expect(stdout.flush.read).to eq("\nOTP validation failed.\nboom!\n") - end - end - end - end - - def verify_successful_verification!(cmd) - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') - - expect(stdout.flush.read).to eq("\nOTP validation successful. Git operations are now allowed.\n") - end - end -end diff --git a/spec/gitlab_shell_two_factor_push_verify_spec.rb b/spec/gitlab_shell_two_factor_push_verify_spec.rb deleted file mode 100644 --- a/spec/gitlab_shell_two_factor_push_verify_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -require_relative 'spec_helper' - -require 'open3' -require 'json' - -describe 'bin/gitlab-shell 2fa_verify push' do - include_context 'gitlab shell' - - let(:env) do - { 'SSH_CONNECTION' => 'fake', - 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } - end - - before(:context) do - write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") - end - - def mock_server(server) - server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| - res.content_type = 'application/json' - res.status = 200 - - params = JSON.parse(req.body) - key_id = params['key_id'] || params['user_id'].to_s - - if key_id == '100' - res.body = { success: false }.to_json - elsif key_id == '102' - res.body = { success: true }.to_json - else - res.body = { success: false, message: 'boom!' }.to_json - end - end - - server.mount_proc('/api/v4/internal/discover') do |_, res| - res.status = 200 - res.content_type = 'application/json' - res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json - end - end - - describe 'command' do - context 'when push is provided' do - let(:cmd) { "#{gitlab_shell_path} key-102" } - - it 'prints a successful push verification message' do - verify_successful_verification_push!(cmd) - end - end - - context 'when API error occurs' do - let(:cmd) { "#{gitlab_shell_path} key-101" } - - it 'prints the error message' do - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - expect(stdout.flush.read).to eq("\nPush OTP validation failed.\nboom!\n") - end - end - end - end - - def verify_successful_verification_push!(cmd) - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - expect(stdout.flush.read).to eq("\nPush OTP validation successful. Git operations are now allowed.\n") - end - end -end diff --git a/spec/gitlab_shell_two_factor_verify_spec.rb b/spec/gitlab_shell_two_factor_verify_spec.rb new file mode 100644 --- /dev/null +++ b/spec/gitlab_shell_two_factor_verify_spec.rb @@ -0,0 +1,125 @@ +require_relative 'spec_helper' + +require 'open3' +require 'json' + +describe 'bin/gitlab-shell 2fa_verify' do + include_context 'gitlab shell' + + let(:env) do + { 'SSH_CONNECTION' => 'fake', + 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } + end + + let(:correct_otp) { '123456' } + + before(:context) do + write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") + end + + def mock_server(server) + server.mount_proc('/api/v4/internal/two_factor_manual_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + + res.body = if params['otp_attempt'] == correct_otp + { success: true }.to_json + else + { success: false, message: 'boom!' }.to_json + end + end + + server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + id = params['key_id'] || params['user_id'].to_s + + if id == '100' + res.body = { success: false, message: 'boom!' }.to_json + else + res.body = { success: true }.to_json + end + end + + server.mount_proc('/api/v4/internal/discover') do |req, res| + res.status = 200 + res.content_type = 'application/json' + + if req.query['username'] == 'someone' + res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + else + res.body = { id: 101, name: 'Another User', username: 'another' }.to_json + end + end + end + + describe 'entering OTP manually' do + let(:cmd) { "#{gitlab_shell_path} key-100" } + + context 'when key is provided' do + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) + end + end + + context 'when username is provided' do + let(:cmd) { "#{gitlab_shell_path} username-someone" } + + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) + end + end + + it 'shows an error when an invalid otp is provided' do + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + stdin.puts('000000') + + expect(stdout.flush.read).to eq("\nOTP validation failed: boom!\n") + end + end + end + + describe 'authorizing via push' do + context 'when key is provided' do + let(:cmd) { "#{gitlab_shell_path} key-101" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + + context 'when username is provided' do + let(:cmd) { "#{gitlab_shell_path} username-another" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + end + + def verify_successful_otp_verification!(cmd) + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + stdin.puts(correct_otp) + + expect(stdout.flush.read).to eq("\nOTP validation successful. Git operations are now allowed.\n") + end + end + + def verify_successful_push_verification!(cmd) + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + + expect(stdout.flush.read).to eq("\nOTP has been validated by Push Authentication. Git operations are now allowed.\n") + end + end + + def asks_for_otp(stdout) + expect(stdout.gets(5)).to eq('OTP: ') + end +end # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1658385082 0 # Thu Jul 21 06:31:22 2022 +0000 # Node ID 4f37a339e4318a318d334a4acd0b534c85769528 # Parent 7517f48a5d24f1415f58523c3e2ee1ec72bd437a # Parent 3b8480785bad7d68dfac81978e90675bfbc81121 Merge branch '506-twofactorverify-command-to-support-push-notification' into 'main' Implement Push Auth support for 2FA verification Closes #506 See merge request gitlab-org/gitlab-shell!454 diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -4,6 +4,7 @@ "context" "fmt" "io" + "time" "gitlab.com/gitlab-org/labkit/log" @@ -13,6 +14,11 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) +const ( + timeout = 30 * time.Second + prompt = "OTP: " +) + type Command struct { Config *config.Config Args *commandargs.Shell @@ -20,25 +26,51 @@ } func (c *Command) Execute(ctx context.Context) error { - ctxlog := log.ContextLogger(ctx) - ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP(ctx) - - ctxlog.Info("twofactorverify: execute: verifying entered OTP") - err := c.verifyOTP(ctx, otp) + client, err := twofactorverify.NewClient(c.Config) if err != nil { - ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } - ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + fmt.Fprint(c.ReadWriter.Out, prompt) + + resultCh := make(chan string) + go func() { + err := client.PushAuth(ctx, c.Args) + if err == nil { + resultCh <- "OTP has been validated by Push Authentication. Git operations are now allowed." + } + }() + + go func() { + answer, err := c.getOTP(ctx) + if err != nil { + resultCh <- formatErr(err) + } + + if err := client.VerifyOTP(ctx, c.Args, answer); err != nil { + resultCh <- formatErr(err) + } else { + resultCh <- "OTP validation successful. Git operations are now allowed." + } + }() + + var message string + select { + case message = <-resultCh: + case <-ctx.Done(): + message = formatErr(ctx.Err()) + } + + log.WithContextFields(ctx, log.Fields{"message": message}).Info("Two factor verify command finished") + fmt.Fprintf(c.ReadWriter.Out, "\n%v\n", message) + return nil } -func (c *Command) getOTP(ctx context.Context) string { - prompt := "OTP: " - fmt.Fprint(c.ReadWriter.Out, prompt) - +func (c *Command) getOTP(ctx context.Context) (string, error) { var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) @@ -46,21 +78,13 @@ log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") } - return answer -} - -func (c *Command) verifyOTP(ctx context.Context, otp string) error { - client, err := twofactorverify.NewClient(c.Config) - if err != nil { - return err + if answer == "" { + return "", fmt.Errorf("OTP cannot be blank.") } - err = client.VerifyOTP(ctx, c.Args, otp) - if err == nil { - fmt.Fprint(c.ReadWriter.Out, "\nOTP validation successful. Git operations are now allowed.\n") - } else { - fmt.Fprintf(c.ReadWriter.Out, "\nOTP validation failed.\n%v\n", err) - } + return answer, nil +} - return nil +func formatErr(err error) string { + return fmt.Sprintf("OTP validation failed: %v", err) } diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -17,10 +17,20 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) +type blockingReader struct{} + +func (*blockingReader) Read([]byte) (int, error) { + waitInfinitely := make(chan struct{}) + <-waitInfinitely + + return 0, nil +} + func setup(t *testing.T) []testserver.TestRequestHandler { + waitInfinitely := make(chan struct{}) requests := []testserver.TestRequestHandler{ { - Path: "/api/v4/internal/two_factor_otp_check", + Path: "/api/v4/internal/two_factor_manual_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { b, err := io.ReadAll(r.Body) defer r.Body.Close() @@ -31,11 +41,13 @@ require.NoError(t, json.Unmarshal(b, &requestBody)) switch requestBody.KeyId { - case "1": + case "verify_via_otp", "verify_via_otp_with_push_error": body := map[string]interface{}{ "success": true, } json.NewEncoder(w).Encode(body) + case "wait_infinitely": + <-waitInfinitely case "error": body := map[string]interface{}{ "success": false, @@ -47,15 +59,36 @@ } }, }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "verify_via_push": + body := map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "verify_via_otp_with_push_error": + w.WriteHeader(http.StatusInternalServerError) + default: + <-waitInfinitely + } + }, + }, } return requests } -const ( - question = "OTP: \n" - errorHeader = "OTP validation failed.\n" -) +const errorHeader = "OTP validation failed: " func TestExecute(t *testing.T) { requests := setup(t) @@ -65,46 +98,61 @@ testCases := []struct { desc string arguments *commandargs.Shell - answer string + input io.Reader expectedOutput string }{ { - desc: "With a known key id", - arguments: &commandargs.Shell{GitlabKeyId: "1"}, - answer: "123456\n", - expectedOutput: question + - "OTP validation successful. Git operations are now allowed.\n", + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp_with_push_error"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via push authentication", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_push"}, + input: &blockingReader{}, + expectedOutput: "OTP has been validated by Push Authentication. Git operations are now allowed.\n", + }, + { + desc: "With an empty OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + input: bytes.NewBufferString("\n"), + expectedOutput: errorHeader + "OTP cannot be blank.\n", }, { desc: "With bad response", arguments: &commandargs.Shell{GitlabKeyId: "-1"}, - answer: "123456\n", - expectedOutput: question + errorHeader + "Parsing failed\n", + expectedOutput: errorHeader + "Parsing failed\n", }, { desc: "With API returns an error", arguments: &commandargs.Shell{GitlabKeyId: "error"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "error message\n", + expectedOutput: errorHeader + "error message\n", }, { desc: "With API fails", arguments: &commandargs.Shell{GitlabKeyId: "broken"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "Internal API error (500)\n", + expectedOutput: errorHeader + "Internal API error (500)\n", }, { desc: "With missing arguments", arguments: &commandargs.Shell{}, - answer: "yes\n", - expectedOutput: question + errorHeader + "who='' is invalid\n", + expectedOutput: errorHeader + "who='' is invalid\n", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { output := &bytes.Buffer{} - input := bytes.NewBufferString(tc.answer) + + input := tc.input + if input == nil { + input = bytes.NewBufferString("123456\n") + } cmd := &Command{ Config: &config.Config{GitlabUrl: url}, @@ -115,7 +163,29 @@ err := cmd.Execute(context.Background()) require.NoError(t, err) - require.Equal(t, tc.expectedOutput, output.String()) + require.Equal(t, prompt+"\n"+tc.expectedOutput, output.String()) }) } } + +func TestCanceledContext(t *testing.T) { + requests := setup(t) + + output := &bytes.Buffer{} + + url := testserver.StartSocketHttpServer(t, requests) + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: &commandargs.Shell{GitlabKeyId: "wait_infinitely"}, + ReadWriter: &readwriter.ReadWriter{Out: output, In: &bytes.Buffer{}}, + } + + ctx, cancel := context.WithCancel(context.Background()) + + errCh := make(chan error) + go func() { errCh <- cmd.Execute(ctx) }() + cancel() + + require.NoError(t, <-errCh) + require.Equal(t, prompt+"\n"+errorHeader+"context canceled\n", output.String()) +} diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -26,7 +26,7 @@ type RequestBody struct { KeyId string `json:"key_id,omitempty"` UserId int64 `json:"user_id,omitempty"` - OTPAttempt string `json:"otp_attempt"` + OTPAttempt string `json:"otp_attempt,omitempty"` } func NewClient(config *config.Config) (*Client, error) { @@ -44,7 +44,22 @@ return err } - response, err := c.client.Post(ctx, "/two_factor_otp_check", requestBody) + response, err := c.client.Post(ctx, "/two_factor_manual_otp_check", requestBody) + if err != nil { + return err + } + defer response.Body.Close() + + return parse(response) +} + +func (c *Client) PushAuth(ctx context.Context, args *commandargs.Shell) error { + requestBody, err := c.getRequestBody(ctx, args, "") + if err != nil { + return err + } + + response, err := c.client.Post(ctx, "/two_factor_push_otp_check", requestBody) if err != nil { return err } diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -17,49 +17,55 @@ ) func initialize(t *testing.T) []testserver.TestRequestHandler { + handler := func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "0": + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "1": + body := map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "2": + w.WriteHeader(http.StatusForbidden) + body := &client.ErrorResponse{ + Message: "Not allowed!", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "3": + w.Write([]byte("{ \"message\": \"broken json!\"")) + case "4": + w.WriteHeader(http.StatusForbidden) + } + + if requestBody.UserId == 1 { + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + } + } + requests := []testserver.TestRequestHandler{ { - Path: "/api/v4/internal/two_factor_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - switch requestBody.KeyId { - case "0": - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "1": - body := map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "2": - w.WriteHeader(http.StatusForbidden) - body := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) - } - - if requestBody.UserId == 1 { - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - } - }, + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: handler, + }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: handler, }, { Path: "/api/v4/internal/discover", @@ -140,6 +146,57 @@ } } +func TestVerifyPush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "0"} + err := client.PushAuth(context.Background(), args) + require.NoError(t, err) +} + +func TestErrorMessagePush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "1"} + err := client.PushAuth(context.Background(), args) + require.Equal(t, "error message", err.Error()) +} + +func TestErrorResponsesPush(t *testing.T) { + client := setup(t) + + testCases := []struct { + desc string + fakeId string + expectedError string + }{ + { + desc: "A response with an error message", + fakeId: "2", + expectedError: "Not allowed!", + }, + { + desc: "A response with bad JSON", + fakeId: "3", + expectedError: "Parsing failed", + }, + { + desc: "An error response without message", + fakeId: "4", + expectedError: "Internal API error (403)", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + args := &commandargs.Shell{GitlabKeyId: tc.fakeId} + err := client.PushAuth(context.Background(), args) + + require.EqualError(t, err, tc.expectedError) + }) + } +} + func setup(t *testing.T) *Client { requests := initialize(t) url := testserver.StartSocketHttpServer(t, requests) diff --git a/spec/gitlab_shell_two_factor_verify_spec.rb b/spec/gitlab_shell_two_factor_verify_spec.rb --- a/spec/gitlab_shell_two_factor_verify_spec.rb +++ b/spec/gitlab_shell_two_factor_verify_spec.rb @@ -11,71 +11,115 @@ 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } end + let(:correct_otp) { '123456' } + before(:context) do write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") end def mock_server(server) - server.mount_proc('/api/v4/internal/two_factor_otp_check') do |req, res| + server.mount_proc('/api/v4/internal/two_factor_manual_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + + res.body = if params['otp_attempt'] == correct_otp + { success: true }.to_json + else + { success: false, message: 'boom!' }.to_json + end + end + + server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| res.content_type = 'application/json' res.status = 200 params = JSON.parse(req.body) - key_id = params['key_id'] || params['user_id'].to_s + id = params['key_id'] || params['user_id'].to_s - if key_id == '100' + if id == '100' + res.body = { success: false, message: 'boom!' }.to_json + else res.body = { success: true }.to_json - else - res.body = { success: false, message: 'boom!' }.to_json end end - server.mount_proc('/api/v4/internal/discover') do |_, res| + server.mount_proc('/api/v4/internal/discover') do |req, res| res.status = 200 res.content_type = 'application/json' - res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + + if req.query['username'] == 'someone' + res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + else + res.body = { id: 101, name: 'Another User', username: 'another' }.to_json + end end end - describe 'command' do + describe 'entering OTP manually' do + let(:cmd) { "#{gitlab_shell_path} key-100" } + context 'when key is provided' do - let(:cmd) { "#{gitlab_shell_path} key-100" } - - it 'prints a successful verification message' do - verify_successful_verification!(cmd) + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) end end context 'when username is provided' do let(:cmd) { "#{gitlab_shell_path} username-someone" } - it 'prints a successful verification message' do - verify_successful_verification!(cmd) + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) end end - context 'when API error occurs' do - let(:cmd) { "#{gitlab_shell_path} key-101" } + it 'shows an error when an invalid otp is provided' do + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + stdin.puts('000000') - it 'prints the error message' do - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') - - expect(stdout.flush.read).to eq("\nOTP validation failed.\nboom!\n") - end + expect(stdout.flush.read).to eq("\nOTP validation failed: boom!\n") end end end - def verify_successful_verification!(cmd) + describe 'authorizing via push' do + context 'when key is provided' do + let(:cmd) { "#{gitlab_shell_path} key-101" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + + context 'when username is provided' do + let(:cmd) { "#{gitlab_shell_path} username-another" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + end + + def verify_successful_otp_verification!(cmd) Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') + asks_for_otp(stdout) + stdin.puts(correct_otp) expect(stdout.flush.read).to eq("\nOTP validation successful. Git operations are now allowed.\n") end end + + def verify_successful_push_verification!(cmd) + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + + expect(stdout.flush.read).to eq("\nOTP has been validated by Push Authentication. Git operations are now allowed.\n") + end + end + + def asks_for_otp(stdout) + expect(stdout.gets(5)).to eq('OTP: ') + end end # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1658386193 -7200 # Thu Jul 21 08:49:53 2022 +0200 # Node ID f7211c6193a856706b586df38536047160ca4c53 # Parent 4f37a339e4318a318d334a4acd0b534c85769528 Release v14.10.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.10.0 + +- Implement Push Auth support for 2FA verification !454 + v14.9.0 - Update LabKit library to v1.16.0 !668 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.9.0 +14.10.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1658386603 0 # Thu Jul 21 06:56:43 2022 +0000 # Node ID 45813b7245308037d79785402e6ab9a6b99fd3a2 # Parent 4f37a339e4318a318d334a4acd0b534c85769528 # Parent f7211c6193a856706b586df38536047160ca4c53 Merge branch 'id-release-14-10-0' into 'main' Release v14.10.0 See merge request gitlab-org/gitlab-shell!671 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.10.0 + +- Implement Push Auth support for 2FA verification !454 + v14.9.0 - Update LabKit library to v1.16.0 !668 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.9.0 +14.10.0 # HG changeset patch # User Terri Chu <tchu@gitlab.com> # Date 1658865867 0 # Tue Jul 26 20:04:27 2022 +0000 # Node ID 03e2727fa2380c2653835b6863944646b7d7de9c # Parent 45813b7245308037d79785402e6ab9a6b99fd3a2 Add simple_roulette to Dangerfile diff --git a/Dangerfile b/Dangerfile --- a/Dangerfile +++ b/Dangerfile @@ -5,5 +5,5 @@ Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| gitlab_dangerfiles.import_plugins - gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages]) end # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1658979485 0 # Thu Jul 28 03:38:05 2022 +0000 # Node ID 7a403c86ddc5c76f20d2f07f247092aa2afe4837 # Parent 45813b7245308037d79785402e6ab9a6b99fd3a2 # Parent 03e2727fa2380c2653835b6863944646b7d7de9c Merge branch 'tchu-add-simple-roulette-to-dangerfile' into 'main' Add simple_roulette to Dangerfile See merge request gitlab-org/gitlab-shell!672 diff --git a/Dangerfile b/Dangerfile --- a/Dangerfile +++ b/Dangerfile @@ -5,5 +5,5 @@ Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| gitlab_dangerfiles.import_plugins - gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages]) end # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1659706663 -7200 # Fri Aug 05 15:37:43 2022 +0200 # Node ID 45c060eda1d3ae5ce3447bd7a325c65dda6ef66c # Parent 7a403c86ddc5c76f20d2f07f247092aa2afe4837 Fix failing TestGitReceivePackSuccess After https://gitlab.com/gitlab-org/gitaly/-/merge_requests/4766 has been introduced, the test started fail because we basically cancel the git-receive-pack after the output is received This commit gracefully closes the connection to make the test pass diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -387,12 +387,25 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-receive-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + err = session.Start(fmt.Sprintf("git-receive-pack %s", testRepo)) + require.NoError(t, err) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + stdin.Close() + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1659714270 0 # Fri Aug 05 15:44:30 2022 +0000 # Node ID 499500688649ae58968c3d8ea902845f38b1f360 # Parent 7a403c86ddc5c76f20d2f07f247092aa2afe4837 # Parent 45c060eda1d3ae5ce3447bd7a325c65dda6ef66c Merge branch 'id-fix-git-receive-pack-in-tests' into 'main' Fix failing TestGitReceivePackSuccess See merge request gitlab-org/gitlab-shell!675 diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -387,12 +387,25 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-receive-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + err = session.Start(fmt.Sprintf("git-receive-pack %s", testRepo)) + require.NoError(t, err) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + stdin.Close() + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") # HG changeset patch # User Carlos Yu <carlosy@indeed.com> # Date 1659714942 0 # Fri Aug 05 15:55:42 2022 +0000 # Node ID a301814a2bf83c73905f9ff6af1623b636d84d87 # Parent 7a403c86ddc5c76f20d2f07f247092aa2afe4837 Fixed extra slashes in API request paths generated for geo diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -77,6 +77,7 @@ testAuthenticationHeader(t, client) testJWTAuthenticationHeader(t, client) testXForwardedForHeader(t, client) + testHostWithTrailingSlash(t, client) }) } } @@ -237,6 +238,16 @@ }) } +func testHostWithTrailingSlash(t *testing.T, client *GitlabNetClient) { + oldHost := client.httpClient.Host + client.httpClient.Host = oldHost + "/" + + testSuccessfulGet(t, client) + testSuccessfulPost(t, client) + + client.httpClient.Host = oldHost +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -85,6 +85,10 @@ return path } +func appendPath(host string, path string) string { + return strings.TrimSuffix(host, "/") + "/" + strings.TrimPrefix(path, "/") +} + func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { @@ -96,7 +100,7 @@ jsonReader = bytes.NewReader(jsonData) } - request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) + request, err := http.NewRequestWithContext(ctx, method, appendPath(host, path), jsonReader) if err != nil { return nil, err } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1659714943 0 # Fri Aug 05 15:55:43 2022 +0000 # Node ID 2d47cb0b0251d461399adca678da9819011b2c04 # Parent 499500688649ae58968c3d8ea902845f38b1f360 # Parent a301814a2bf83c73905f9ff6af1623b636d84d87 Merge branch 'I-365101' into 'main' Fixed extra slashes in API request paths generated for geo See merge request gitlab-org/gitlab-shell!673 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -77,6 +77,7 @@ testAuthenticationHeader(t, client) testJWTAuthenticationHeader(t, client) testXForwardedForHeader(t, client) + testHostWithTrailingSlash(t, client) }) } } @@ -237,6 +238,16 @@ }) } +func testHostWithTrailingSlash(t *testing.T, client *GitlabNetClient) { + oldHost := client.httpClient.Host + client.httpClient.Host = oldHost + "/" + + testSuccessfulGet(t, client) + testSuccessfulPost(t, client) + + client.httpClient.Host = oldHost +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -85,6 +85,10 @@ return path } +func appendPath(host string, path string) string { + return strings.TrimSuffix(host, "/") + "/" + strings.TrimPrefix(path, "/") +} + func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { @@ -96,7 +100,7 @@ jsonReader = bytes.NewReader(jsonData) } - request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) + request, err := http.NewRequestWithContext(ctx, method, appendPath(host, path), jsonReader) if err != nil { return nil, err } # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1659707501 -7200 # Fri Aug 05 15:51:41 2022 +0200 # Node ID 8c20e6acc5d7a3192b2b124dfbfcf80728fd9a36 # Parent 499500688649ae58968c3d8ea902845f38b1f360 Update Gitaly to v15 This commit also excludes gitlab-shell from dependencies: Gitaly specifies Gitlab Shell as a dependency as well in order to use gitlabnet client to perform API endpoints to Gitlab Rails. As a result, Gitlab Shell requires Gitaly -> Gitaly requires an older version of Gitlab Shell -> that version requires an older version of Gitlab Shell, etc. Let's use exclude to break the chain earlier diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -10,8 +10,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -22,8 +22,8 @@ "github.com/mikesmitty/edkey" "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" - gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyClient "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,27 +10,29 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 - github.com/prometheus/client_golang v1.12.1 + github.com/prometheus/client_golang v1.12.2 github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 + github.com/stretchr/testify v1.8.0 + gitlab.com/gitlab-org/gitaly/v15 v15.2.0 gitlab.com/gitlab-org/labkit v1.16.0 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.40.0 + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f + google.golang.org/grpc v1.47.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.92.2 // indirect + 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 v0.1.0 // indirect - contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // indirect + cloud.google.com/go/trace v1.2.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.10 // 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/aws/aws-sdk-go v1.38.35 // indirect + github.com/aws/aws-sdk-go v1.43.31 // 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 @@ -41,12 +43,13 @@ github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.6 // indirect + github.com/google/go-cmp v0.5.8 // indirect github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect - github.com/google/uuid v1.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.0.5 // indirect - github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kr/text v0.2.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // indirect @@ -63,22 +66,28 @@ 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-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect go.opencensus.io v0.23.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/api v0.54.0 // indirect + google.golang.org/api v0.74.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de // indirect + google.golang.org/protobuf v1.28.0 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) +// Gitaly specifies Gitlab Shell as a dependency and causes older versions +// of Gitaly and Gitlab Shell to be included in go.sum. +// Let's exclude the older version of Gitlab Shell to break the chain in the beginning +exclude gitlab.com/gitlab-org/gitlab-shell/v14 v14.8.0 + replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,9 +1,6 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -22,104 +19,118 @@ 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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= -github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= -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/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.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +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/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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -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 v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= 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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +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/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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= @@ -128,40 +139,52 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +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 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +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/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= +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/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= +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/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= +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/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= +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/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= +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/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/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/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= +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= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -171,63 +194,54 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= -github.com/cloudflare/tableflip v0.0.0-20190329062924-8392f1641731/go.mod h1:erh4dYezoMVbIa52pi7i1Du7+cXOgqNuTamt10qvMoA= -github.com/cloudflare/tableflip v1.2.2 h1:WkhiowHlg0nZuH7Y2beLVIZDfxtSvKta1f22PEgUN7w= -github.com/cloudflare/tableflip v1.2.2/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= +github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw= +github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= 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-20211001041855-01bcc9b48dfe/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 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/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +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= +github.com/dpotapov/go-spnego v0.0.0-20210315154721-298b63a54430/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= +github.com/dpotapov/go-spnego v0.0.0-20220426193508-b7f82e4507db/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -235,41 +249,37 @@ 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/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= 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= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -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/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/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= -github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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= -github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= -github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/git-lfs/git-lfs/v3 v3.2.0/go.mod h1:GZZO3jw2Yn3/1KFV4nRoXUzH+yPzGypIdTeQpkzxEvQ= +github.com/git-lfs/gitobj/v2 v2.1.0/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8COmU45ncAxw= +github.com/git-lfs/go-netrc v0.0.0-20210914205454-f0c862dd687a/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= +github.com/git-lfs/pktline v0.0.0-20210330133718-06e9096e2825/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A= +github.com/git-lfs/wildmatch/v2 v2.0.1/go.mod h1:EVqonpk9mXbREP3N8UkwoWdrF249uHpCUo5CPXY81gw= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= +github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -284,7 +294,6 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -297,7 +306,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -309,30 +317,25 @@ github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -361,7 +364,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -377,11 +379,13 @@ 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/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= +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= @@ -390,6 +394,7 @@ 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/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= @@ -403,6 +408,7 @@ 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= @@ -411,69 +417,50 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -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/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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.3-0.20210213123510-be4c235f9d1c/go.mod h1:RXwzibsL7UhPcEmGyGvXKJ8kyJsOCOEaLgGce4igMFs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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/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/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= @@ -486,7 +473,8 @@ github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= 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/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= 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= @@ -500,39 +488,42 @@ github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= 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/pgtype v1.11.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/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= 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/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -541,34 +532,23 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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= @@ -582,29 +562,21 @@ 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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leonelquinteros/gotext v1.5.0/go.mod h1:OCiUVHuhP9LGFBQ1oAmdtNCHJCiHiQA8lf4nAifHkr0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= -github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -613,6 +585,7 @@ 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-ieproxy v0.0.3/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= @@ -621,59 +594,44 @@ 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/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= -github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -682,86 +640,58 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -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/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -774,19 +704,13 @@ github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= -github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= @@ -795,7 +719,6 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -804,58 +727,45 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -868,12 +778,10 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -881,28 +789,14 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= -gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/gitaly/v15 v15.2.0 h1:UCv8LhzG6dCaq2zFsQqDuFVqFua4KR0+DKyx7MFx7kA= +gitlab.com/gitlab-org/gitaly/v15 v15.2.0/go.mod h1:WjitFL44l9ovitGC4OvSuGwfeq0VpHUbHS6sDw13LV8= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= -gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= -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.15.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= gitlab.com/gitlab-org/labkit v1.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= gitlab.com/gitlab-org/labkit v1.16.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= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -917,20 +811,23 @@ 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +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.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y= 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= @@ -948,7 +845,6 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -960,7 +856,6 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -973,16 +868,13 @@ 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -995,7 +887,6 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1005,7 +896,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1023,13 +913,19 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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-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-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +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/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= +golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 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= @@ -1042,12 +938,16 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -1058,16 +958,14 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1083,27 +981,22 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-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= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1122,20 +1015,14 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1144,13 +1031,29 @@ 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/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +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= @@ -1161,18 +1064,16 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1194,11 +1095,9 @@ golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1213,6 +1112,7 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= @@ -1238,7 +1138,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1252,13 +1151,10 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -1277,31 +1173,41 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= 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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1341,12 +1247,9 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= 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= @@ -1355,19 +1258,43 @@ 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/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/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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1388,8 +1315,12 @@ 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/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -1403,10 +1334,9 @@ 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= -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= +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.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1416,28 +1346,17 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v2 v2.0.0/go.mod h1:vCwK9HeXksMeUmQ4SxDd1tRz4LejrKh3KRVjQWhjvZI= -gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= -gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1448,9 +1367,10 @@ 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= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1458,11 +1378,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -9,9 +9,9 @@ grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v15/client" "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -5,7 +5,7 @@ "fmt" "net/http" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -10,7 +10,7 @@ "testing" "github.com/stretchr/testify/require" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -16,7 +16,7 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,7 +11,7 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1660093449 0 # Wed Aug 10 01:04:09 2022 +0000 # Node ID 2a1bdd3f4889f2e86839bd8f44e6980e34ec599f # Parent 2d47cb0b0251d461399adca678da9819011b2c04 # Parent 8c20e6acc5d7a3192b2b124dfbfcf80728fd9a36 Merge branch 'id-update-gitaly-to-v15' into 'main' Update Gitaly to v15 See merge request gitlab-org/gitlab-shell!676 diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -10,8 +10,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -22,8 +22,8 @@ "github.com/mikesmitty/edkey" "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" - gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyClient "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,27 +10,29 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 - github.com/prometheus/client_golang v1.12.1 + github.com/prometheus/client_golang v1.12.2 github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 + github.com/stretchr/testify v1.8.0 + gitlab.com/gitlab-org/gitaly/v15 v15.2.0 gitlab.com/gitlab-org/labkit v1.16.0 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.40.0 + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f + google.golang.org/grpc v1.47.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.92.2 // indirect + 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 v0.1.0 // indirect - contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // indirect + cloud.google.com/go/trace v1.2.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.10 // 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/aws/aws-sdk-go v1.38.35 // indirect + github.com/aws/aws-sdk-go v1.43.31 // 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 @@ -41,12 +43,13 @@ github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.6 // indirect + github.com/google/go-cmp v0.5.8 // indirect github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect - github.com/google/uuid v1.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.0.5 // indirect - github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kr/text v0.2.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // indirect @@ -63,22 +66,28 @@ 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-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect go.opencensus.io v0.23.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/api v0.54.0 // indirect + google.golang.org/api v0.74.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de // indirect + google.golang.org/protobuf v1.28.0 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) +// Gitaly specifies Gitlab Shell as a dependency and causes older versions +// of Gitaly and Gitlab Shell to be included in go.sum. +// Let's exclude the older version of Gitlab Shell to break the chain in the beginning +exclude gitlab.com/gitlab-org/gitlab-shell/v14 v14.8.0 + replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,9 +1,6 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -22,104 +19,118 @@ 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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= -github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= -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/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.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +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/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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -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 v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= 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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +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/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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= @@ -128,40 +139,52 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +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 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +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/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= +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/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= +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/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= +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/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= +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/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= +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/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/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/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= +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= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -171,63 +194,54 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= -github.com/cloudflare/tableflip v0.0.0-20190329062924-8392f1641731/go.mod h1:erh4dYezoMVbIa52pi7i1Du7+cXOgqNuTamt10qvMoA= -github.com/cloudflare/tableflip v1.2.2 h1:WkhiowHlg0nZuH7Y2beLVIZDfxtSvKta1f22PEgUN7w= -github.com/cloudflare/tableflip v1.2.2/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= +github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw= +github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= 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-20211001041855-01bcc9b48dfe/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 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/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +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= +github.com/dpotapov/go-spnego v0.0.0-20210315154721-298b63a54430/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= +github.com/dpotapov/go-spnego v0.0.0-20220426193508-b7f82e4507db/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -235,41 +249,37 @@ 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/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= 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= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -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/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/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= -github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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= -github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= -github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/git-lfs/git-lfs/v3 v3.2.0/go.mod h1:GZZO3jw2Yn3/1KFV4nRoXUzH+yPzGypIdTeQpkzxEvQ= +github.com/git-lfs/gitobj/v2 v2.1.0/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8COmU45ncAxw= +github.com/git-lfs/go-netrc v0.0.0-20210914205454-f0c862dd687a/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= +github.com/git-lfs/pktline v0.0.0-20210330133718-06e9096e2825/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A= +github.com/git-lfs/wildmatch/v2 v2.0.1/go.mod h1:EVqonpk9mXbREP3N8UkwoWdrF249uHpCUo5CPXY81gw= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= +github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -284,7 +294,6 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -297,7 +306,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -309,30 +317,25 @@ github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -361,7 +364,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -377,11 +379,13 @@ 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/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= +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= @@ -390,6 +394,7 @@ 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/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= @@ -403,6 +408,7 @@ 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= @@ -411,69 +417,50 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -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/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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.3-0.20210213123510-be4c235f9d1c/go.mod h1:RXwzibsL7UhPcEmGyGvXKJ8kyJsOCOEaLgGce4igMFs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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/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/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= @@ -486,7 +473,8 @@ github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= 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/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= 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= @@ -500,39 +488,42 @@ github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= 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/pgtype v1.11.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/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= 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/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -541,34 +532,23 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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= @@ -582,29 +562,21 @@ 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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leonelquinteros/gotext v1.5.0/go.mod h1:OCiUVHuhP9LGFBQ1oAmdtNCHJCiHiQA8lf4nAifHkr0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= -github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -613,6 +585,7 @@ 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-ieproxy v0.0.3/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= @@ -621,59 +594,44 @@ 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/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= -github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -682,86 +640,58 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -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/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -774,19 +704,13 @@ github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= -github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= @@ -795,7 +719,6 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -804,58 +727,45 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -868,12 +778,10 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -881,28 +789,14 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= -gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/gitaly/v15 v15.2.0 h1:UCv8LhzG6dCaq2zFsQqDuFVqFua4KR0+DKyx7MFx7kA= +gitlab.com/gitlab-org/gitaly/v15 v15.2.0/go.mod h1:WjitFL44l9ovitGC4OvSuGwfeq0VpHUbHS6sDw13LV8= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= -gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= -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.15.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= gitlab.com/gitlab-org/labkit v1.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= gitlab.com/gitlab-org/labkit v1.16.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= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -917,20 +811,23 @@ 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +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.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y= 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= @@ -948,7 +845,6 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -960,7 +856,6 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -973,16 +868,13 @@ 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -995,7 +887,6 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1005,7 +896,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1023,13 +913,19 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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-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-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +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/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= +golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 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= @@ -1042,12 +938,16 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -1058,16 +958,14 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1083,27 +981,22 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-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= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1122,20 +1015,14 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1144,13 +1031,29 @@ 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/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +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= @@ -1161,18 +1064,16 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1194,11 +1095,9 @@ golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1213,6 +1112,7 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= @@ -1238,7 +1138,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1252,13 +1151,10 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -1277,31 +1173,41 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= 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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1341,12 +1247,9 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= 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= @@ -1355,19 +1258,43 @@ 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/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/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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1388,8 +1315,12 @@ 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/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -1403,10 +1334,9 @@ 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= -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= +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.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1416,28 +1346,17 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v2 v2.0.0/go.mod h1:vCwK9HeXksMeUmQ4SxDd1tRz4LejrKh3KRVjQWhjvZI= -gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= -gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1448,9 +1367,10 @@ 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= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1458,11 +1378,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -9,9 +9,9 @@ grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v15/client" "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -5,7 +5,7 @@ "fmt" "net/http" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -10,7 +10,7 @@ "testing" "github.com/stretchr/testify/require" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -16,7 +16,7 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,7 +11,7 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1660213275 -7200 # Thu Aug 11 12:21:15 2022 +0200 # Node ID cee9648a5338e046e2ecd8caf04ebf46ff9a10bc # Parent 2a1bdd3f4889f2e86839bd8f44e6980e34ec599f Release 14.11.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.11.0 + +- Update Gitaly to v15 !676 +- Fixed extra slashes in API request paths generated for geo !673 + v14.10.0 - Implement Push Auth support for 2FA verification !454 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.10.0 +14.11.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1660213681 0 # Thu Aug 11 10:28:01 2022 +0000 # Node ID 24d75d667bfd829693f80c59f4fccd9c395995a0 # Parent 2a1bdd3f4889f2e86839bd8f44e6980e34ec599f # Parent cee9648a5338e046e2ecd8caf04ebf46ff9a10bc Merge branch 'id-release-14-11-0' into 'main' Release 14.11.0 See merge request gitlab-org/gitlab-shell!677 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.11.0 + +- Update Gitaly to v15 !676 +- Fixed extra slashes in API request paths generated for geo !673 + v14.10.0 - Implement Push Auth support for 2FA verification !454 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.10.0 +14.11.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1660214019 -7200 # Thu Aug 11 12:33:39 2022 +0200 # Node ID c7e54c8e62b50aec0616b02ae5424c5c869e72cd # Parent 2a1bdd3f4889f2e86839bd8f44e6980e34ec599f Update gitlab-dangerfiles gem diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -5,5 +5,5 @@ end group :development, :danger do - gem 'gitlab-dangerfiles', '~> 3.0.0' + gem 'gitlab-dangerfiles', '~> 3.5.1' end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ colored2 (3.1.2) cork (0.3.0) colored2 (~> 3.1) - danger (8.5.0) + danger (8.6.1) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) @@ -28,7 +28,7 @@ danger gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) - faraday (1.10.0) + faraday (1.10.1) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -43,29 +43,29 @@ faraday-em_http (1.0.0) faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) - faraday-http-cache (2.2.0) + faraday-http-cache (2.4.1) faraday (>= 0.8) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - git (1.10.2) + git (1.11.0) rchardet (~> 1.8) - gitlab (4.18.0) - httparty (~> 0.18) + gitlab (4.19.0) + httparty (~> 0.20) terminal-table (>= 1.5.1) - gitlab-dangerfiles (3.0.0) + gitlab-dangerfiles (3.5.1) danger (>= 8.4.5) danger-gitlab (>= 8.0.0) rake httparty (0.20.0) mime-types (~> 3.0) multi_xml (>= 0.5.2) - kramdown (2.3.2) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) @@ -73,14 +73,14 @@ mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) multi_xml (0.6.0) - multipart-post (2.1.1) + multipart-post (2.2.3) nap (1.1.0) no_proxy_fix (0.1.2) - octokit (4.22.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) open4 (1.3.4) - public_suffix (4.0.6) + public_suffix (4.0.7) rake (13.0.6) rchardet (1.8.0) rexml (3.2.5) @@ -98,18 +98,18 @@ rspec-support (~> 3.8.0) rspec-support (3.8.0) ruby2_keywords (0.0.5) - sawyer (0.8.2) + sawyer (0.9.2) addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) + faraday (>= 0.17.3, < 3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - unicode-display_width (2.1.0) + unicode-display_width (2.2.0) PLATFORMS ruby DEPENDENCIES - gitlab-dangerfiles (~> 3.0.0) + gitlab-dangerfiles (~> 3.5.1) rspec (~> 3.8.0) BUNDLED WITH # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1660214492 0 # Thu Aug 11 10:41:32 2022 +0000 # Node ID da67507aa519217f382c8f8c4fdbcf947741cae3 # Parent 24d75d667bfd829693f80c59f4fccd9c395995a0 # Parent c7e54c8e62b50aec0616b02ae5424c5c869e72cd Merge branch 'id-update-danger-gem' into 'main' Update gitlab-dangerfiles gem See merge request gitlab-org/gitlab-shell!678 diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -5,5 +5,5 @@ end group :development, :danger do - gem 'gitlab-dangerfiles', '~> 3.0.0' + gem 'gitlab-dangerfiles', '~> 3.5.1' end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ colored2 (3.1.2) cork (0.3.0) colored2 (~> 3.1) - danger (8.5.0) + danger (8.6.1) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) @@ -28,7 +28,7 @@ danger gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) - faraday (1.10.0) + faraday (1.10.1) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -43,29 +43,29 @@ faraday-em_http (1.0.0) faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) - faraday-http-cache (2.2.0) + faraday-http-cache (2.4.1) faraday (>= 0.8) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - git (1.10.2) + git (1.11.0) rchardet (~> 1.8) - gitlab (4.18.0) - httparty (~> 0.18) + gitlab (4.19.0) + httparty (~> 0.20) terminal-table (>= 1.5.1) - gitlab-dangerfiles (3.0.0) + gitlab-dangerfiles (3.5.1) danger (>= 8.4.5) danger-gitlab (>= 8.0.0) rake httparty (0.20.0) mime-types (~> 3.0) multi_xml (>= 0.5.2) - kramdown (2.3.2) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) @@ -73,14 +73,14 @@ mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) multi_xml (0.6.0) - multipart-post (2.1.1) + multipart-post (2.2.3) nap (1.1.0) no_proxy_fix (0.1.2) - octokit (4.22.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) open4 (1.3.4) - public_suffix (4.0.6) + public_suffix (4.0.7) rake (13.0.6) rchardet (1.8.0) rexml (3.2.5) @@ -98,18 +98,18 @@ rspec-support (~> 3.8.0) rspec-support (3.8.0) ruby2_keywords (0.0.5) - sawyer (0.8.2) + sawyer (0.9.2) addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) + faraday (>= 0.17.3, < 3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - unicode-display_width (2.1.0) + unicode-display_width (2.2.0) PLATFORMS ruby DEPENDENCIES - gitlab-dangerfiles (~> 3.0.0) + gitlab-dangerfiles (~> 3.5.1) rspec (~> 3.8.0) BUNDLED WITH # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1660644259 -7200 # Tue Aug 16 12:04:19 2022 +0200 # Node ID 6082a294c6e49bfa043d3513880418798a96a444 # Parent da67507aa519217f382c8f8c4fdbcf947741cae3 Add Golang 1.19 to CI diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,7 +61,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18", "1.19"] after_script: - make coverage coverage: '/\d+.\d+%/' # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1660654815 0 # Tue Aug 16 13:00:15 2022 +0000 # Node ID 588a8deae1853c4812d941298db4d6faca3afc49 # Parent da67507aa519217f382c8f8c4fdbcf947741cae3 # Parent 6082a294c6e49bfa043d3513880418798a96a444 Merge branch 'id-test-against-1.19' into 'main' Run tests agains 1.19 Golang See merge request gitlab-org/gitlab-shell!680 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,7 +61,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18", "1.19"] after_script: - make coverage coverage: '/\d+.\d+%/' # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1661862904 -7200 # Tue Aug 30 14:35:04 2022 +0200 # Node ID df2c3f6bd21886d287c305c11b17fbb380e4da7e # Parent 588a8deae1853c4812d941298db4d6faca3afc49 Update Gitaly to 15.4.0-rc2 It has gitlab-shell dependency removed, so it makes sense to remove the exclusion of circular dependency diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,13 +11,13 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.2 - github.com/sirupsen/logrus v1.8.1 + github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.8.0 - gitlab.com/gitlab-org/gitaly/v15 v15.2.0 + gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 gitlab.com/gitlab-org/labkit v1.16.0 - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f - google.golang.org/grpc v1.47.0 + google.golang.org/grpc v1.48.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -47,7 +47,7 @@ github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/gax-go/v2 v2.2.0 // indirect - github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 // indirect @@ -72,22 +72,17 @@ go.uber.org/atomic v1.9.0 // indirect golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect - golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // 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 - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) -// Gitaly specifies Gitlab Shell as a dependency and causes older versions -// of Gitaly and Gitlab Shell to be included in go.sum. -// Let's exclude the older version of Gitlab Shell to break the chain in the beginning -exclude gitlab.com/gitlab-org/gitlab-shell/v14 v14.8.0 - replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -45,6 +45,7 @@ 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.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 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= @@ -122,12 +123,16 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20220810064516-de89276ce0f3/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -142,7 +147,9 @@ github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= @@ -182,6 +189,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -198,6 +207,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw= github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -215,16 +225,18 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +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/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= @@ -261,6 +273,7 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 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.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= @@ -291,6 +304,7 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -307,17 +321,17 @@ github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -439,23 +453,40 @@ 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.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -474,7 +505,7 @@ 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.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= +github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= 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= @@ -488,20 +519,20 @@ github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= 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.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= -github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.12.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.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= -github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= +github.com/jackc/pgx/v4 v4.17.0/go.mod h1:Gd6RmOhtFLTu8cp/Fhq4kP195KrshxYJH3oW8AWJ1pw= 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= @@ -535,6 +566,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= @@ -553,6 +585,8 @@ 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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -570,6 +604,7 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= @@ -578,6 +613,10 @@ github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -594,23 +633,34 @@ 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/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -629,8 +679,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -652,23 +700,28 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.3/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -693,20 +746,20 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= +github.com/rubenv/sql-migrate v1.1.2/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 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= @@ -723,19 +776,25 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -752,6 +811,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= @@ -787,15 +847,18 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/gitlab-org/gitaly/v15 v15.2.0 h1:UCv8LhzG6dCaq2zFsQqDuFVqFua4KR0+DKyx7MFx7kA= -gitlab.com/gitlab-org/gitaly/v15 v15.2.0/go.mod h1:WjitFL44l9ovitGC4OvSuGwfeq0VpHUbHS6sDw13LV8= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 h1:ngV/NWEMz4TRlnJFzBpatdXkEIDMHsU3YUzGdZU63qY= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2/go.mod h1:Rv/LoDU5I3cOP6KLUWFjC1eigcay2u8b8ZcsW86A0Xo= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -gitlab.com/gitlab-org/labkit v1.15.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= gitlab.com/gitlab-org/labkit v1.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= gitlab.com/gitlab-org/labkit v1.16.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -826,8 +889,9 @@ 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.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y= +gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= 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= @@ -872,7 +936,9 @@ 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= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -916,6 +982,7 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/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= @@ -938,6 +1005,7 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -965,6 +1033,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -975,7 +1044,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -983,6 +1051,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1031,6 +1100,7 @@ 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-20210809222454-d867a43fc93e/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= @@ -1049,8 +1119,8 @@ golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1094,10 +1164,10 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1139,6 +1209,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1173,6 +1244,7 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= @@ -1319,8 +1391,8 @@ 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/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -1335,8 +1407,9 @@ 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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1349,9 +1422,9 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1661926633 0 # Wed Aug 31 06:17:13 2022 +0000 # Node ID 2640fced7a7dd0d0a80a54598e441c666a60906d # Parent 588a8deae1853c4812d941298db4d6faca3afc49 # Parent df2c3f6bd21886d287c305c11b17fbb380e4da7e Merge branch 'id-bump-gitaly' into 'main' Update Gitaly to 15.4.0-rc2 See merge request gitlab-org/gitlab-shell!681 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,13 +11,13 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.2 - github.com/sirupsen/logrus v1.8.1 + github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.8.0 - gitlab.com/gitlab-org/gitaly/v15 v15.2.0 + gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 gitlab.com/gitlab-org/labkit v1.16.0 - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f - google.golang.org/grpc v1.47.0 + google.golang.org/grpc v1.48.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -47,7 +47,7 @@ github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/gax-go/v2 v2.2.0 // indirect - github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 // indirect @@ -72,22 +72,17 @@ go.uber.org/atomic v1.9.0 // indirect golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect - golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // 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 - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) -// Gitaly specifies Gitlab Shell as a dependency and causes older versions -// of Gitaly and Gitlab Shell to be included in go.sum. -// Let's exclude the older version of Gitlab Shell to break the chain in the beginning -exclude gitlab.com/gitlab-org/gitlab-shell/v14 v14.8.0 - replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -45,6 +45,7 @@ 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.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 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= @@ -122,12 +123,16 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20220810064516-de89276ce0f3/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -142,7 +147,9 @@ github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= @@ -182,6 +189,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -198,6 +207,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw= github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -215,16 +225,18 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +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/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= @@ -261,6 +273,7 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 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.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= @@ -291,6 +304,7 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -307,17 +321,17 @@ github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -439,23 +453,40 @@ 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.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -474,7 +505,7 @@ 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.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= +github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= 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= @@ -488,20 +519,20 @@ github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= 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.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= -github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.12.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.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= -github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= +github.com/jackc/pgx/v4 v4.17.0/go.mod h1:Gd6RmOhtFLTu8cp/Fhq4kP195KrshxYJH3oW8AWJ1pw= 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= @@ -535,6 +566,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= @@ -553,6 +585,8 @@ 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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -570,6 +604,7 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= @@ -578,6 +613,10 @@ github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -594,23 +633,34 @@ 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/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -629,8 +679,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -652,23 +700,28 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.3/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -693,20 +746,20 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= +github.com/rubenv/sql-migrate v1.1.2/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 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= @@ -723,19 +776,25 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -752,6 +811,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= @@ -787,15 +847,18 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/gitlab-org/gitaly/v15 v15.2.0 h1:UCv8LhzG6dCaq2zFsQqDuFVqFua4KR0+DKyx7MFx7kA= -gitlab.com/gitlab-org/gitaly/v15 v15.2.0/go.mod h1:WjitFL44l9ovitGC4OvSuGwfeq0VpHUbHS6sDw13LV8= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 h1:ngV/NWEMz4TRlnJFzBpatdXkEIDMHsU3YUzGdZU63qY= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2/go.mod h1:Rv/LoDU5I3cOP6KLUWFjC1eigcay2u8b8ZcsW86A0Xo= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -gitlab.com/gitlab-org/labkit v1.15.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= gitlab.com/gitlab-org/labkit v1.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= gitlab.com/gitlab-org/labkit v1.16.0/go.mod h1:bcxc4ZpAC+WyACgyKl7FcvT2XXAbl8CrzN6UY+w8cMc= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -826,8 +889,9 @@ 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.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y= +gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= 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= @@ -872,7 +936,9 @@ 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= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -916,6 +982,7 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/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= @@ -938,6 +1005,7 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -965,6 +1033,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -975,7 +1044,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -983,6 +1051,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1031,6 +1100,7 @@ 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-20210809222454-d867a43fc93e/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= @@ -1049,8 +1119,8 @@ golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1094,10 +1164,10 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1139,6 +1209,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1173,6 +1244,7 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= @@ -1319,8 +1391,8 @@ 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/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -1335,8 +1407,9 @@ 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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1349,9 +1422,9 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663174194 -7200 # Wed Sep 14 18:49:54 2022 +0200 # Branch heptapod # Node ID 2daff2db282c6fbf244ff5d8e2b386bc8253f60d # Parent 57a0260a6fb85a23d5d983b8bf04030cc1b79768 # Parent 7b17b1d00467952ade430e1753f00ff2b92a303c Merged upstream v14.0.0 into Heptapod Shell Used in intermediate upstream GitLab revisions between 14.10 and 15.0. Notes: - upstream drops Golang 1.16 from CI, we're doing the same - filled in Heptapod changelog diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,7 +60,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.16", "1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.8 +golang 1.17.9 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,17 @@ +v14.0.0 +- Always use Gitaly sidechannel connections !567 + +v13.26.0 + +- Add JWT token to GitLab Rails request !596 +- Drop go 1.16 support !601 +- Remove `self_signed_cert` option !602 + +v13.25.2 + +- Revert "Abort long-running unauthenticated SSH connections" !605 +- Bump Go to 1.17.9 for asdf users !600 + v13.25.1 - Upgrade golang to 1.17.8 !591 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.0.0 + +- Jump to upstream GitLab Shell v14.0.0 (pre-GitLab 15.0) + ## 13.25.0 - Jump to upstream GitLab Shell v13.25.1 (GitLab 14.10 series) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.1 +14.0.0 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -10,13 +10,19 @@ "path" "strings" "testing" + "time" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) +var ( + secret = []byte("sssh, it's a secret") +) + func TestClients(t *testing.T) { testhelper.PrepareTestRootDir(t) @@ -57,12 +63,10 @@ t.Run(tc.desc, func(t *testing.T) { url := tc.server(t, buildRequests(t, tc.relativeURLRoot)) - secret := "sssh, it's a secret" - - httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", secret, httpClient) + client, err := NewGitlabNetClient("", "", string(secret), httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -71,6 +75,7 @@ testMissing(t, client) testErrorMessage(t, client) testAuthenticationHeader(t, client) + testJWTAuthenticationHeader(t, client) }) } } @@ -160,7 +165,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -175,7 +180,44 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) + }) +} + +func testJWTAuthenticationHeader(t *testing.T, client *GitlabNetClient) { + verifyJWTToken := func(t *testing.T, response *http.Response) { + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + + claims := &jwt.RegisteredClaims{} + token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { + return secret, nil + }) + require.NoError(t, err) + require.True(t, token.Valid) + require.Equal(t, "gitlab-shell", claims.Issuer) + require.Equal(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) + require.Equal(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) + } + + t.Run("JWT authentication headers for GET", func(t *testing.T) { + response, err := client.Get(context.Background(), "/jwt_auth") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) + }) + + t.Run("JWT authentication headers for POST", func(t *testing.T) { + response, err := client.Post(context.Background(), "/jwt_auth", map[string]string{}) + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) }) } @@ -209,6 +251,12 @@ }, }, { + Path: "/api/v4/internal/jwt_auth", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get(apiSecretHeaderName)) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,13 +11,18 @@ "strings" "time" + "github.com/golang-jwt/jwt/v4" + "gitlab.com/gitlab-org/labkit/log" ) const ( - internalApiPath = "/api/v4/internal" - secretHeaderName = "Gitlab-Shared-Secret" - defaultUserAgent = "GitLab-Shell" + internalApiPath = "/api/v4/internal" + secretHeaderName = "Gitlab-Shared-Secret" + apiSecretHeaderName = "Gitlab-Shell-Api-Request" + defaultUserAgent = "GitLab-Shell" + jwtTTL = time.Minute + jwtIssuer = "gitlab-shell" ) type ErrorResponse struct { @@ -121,10 +126,22 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } + secretBytes := []byte(c.secret) - encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) + encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) request.Header.Set(secretHeaderName, encodedSecret) + claims := jwt.RegisteredClaims{ + Issuer: jwtIssuer, + IssuedAt: jwt.NewNumericDate(time.Now()), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), + } + tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) + if err != nil { + return nil, err + } + request.Header.Set(apiSecretHeaderName, tokenString) + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -14,7 +14,6 @@ "time" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -70,17 +69,8 @@ return nil } -// Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 -func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { - c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) - if err != nil { - log.WithError(err).Error("new http client with opts") - } - return c -} - // NewHTTPClientWithOpts builds an HTTP client using the provided options -func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { +func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { var transport *http.Transport var host string var err error @@ -103,7 +93,7 @@ opt(hcc) } - transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) + transport, host, err = buildHttpsTransport(*hcc, gitlabURL) if err != nil { return nil, err } @@ -140,7 +130,7 @@ return transport, host } -func buildHttpsTransport(hcc httpClientCfg, selfSignedCert bool, gitlabURL string) (*http.Transport, string, error) { +func buildHttpsTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport, string, error) { certPool, err := x509.SystemCertPool() if err != nil { @@ -162,12 +152,8 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, - // The self_signed_cert config setting is deprecated - // The field and its usage is going to be removed in - // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 - InsecureSkipVerify: selfSignedCert, - MinVersion: tls.VersionTLS12, + RootCAs: certPool, + MinVersion: tls.VersionTLS12, } if hcc.HaveCertAndKey() { diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,7 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", expectedSeconds, nil) require.NoError(t, err) require.NotNil(t, client) @@ -123,7 +123,7 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", 1, nil) require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -18,7 +18,6 @@ testCases := []struct { desc string caFile, caPath string - selfSigned bool clientCAPath, clientCertPath, clientKeyPath string // used for TLS client certs }{ { @@ -31,9 +30,8 @@ caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { - desc: "Invalid cert with self signed cert option enabled", - caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), - selfSigned: true, + desc: "Invalid cert with self signed cert option enabled", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Client certs with CA", @@ -48,7 +46,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath) require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") @@ -95,7 +93,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "") if tc.expectedCaFileNotFound { require.Error(t, err) require.ErrorIs(t, err, ErrCafileNotFound) @@ -109,7 +107,7 @@ } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string) (*GitlabNetClient, error) { testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ @@ -130,7 +128,7 @@ opts = append(opts, WithClientCert(clientCertPath, clientKeyPath)) } - httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) + httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, 1, opts) if err != nil { return nil, err } diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -43,11 +43,6 @@ # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs # -# The self_signed_cert option is deprecated -# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible -# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed -# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 - self_signed_cert: false # File used as authorized_keys for gitlab user auth_file: "/home/git/.ssh/authorized_keys" @@ -100,8 +95,6 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" - # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. - login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,8 +1,9 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.16 +go 1.17 require ( + github.com/golang-jwt/jwt/v4 v4.4.1 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mattn/go-shellwords v1.0.11 @@ -19,4 +20,65 @@ gopkg.in/yaml.v2 v2.4.0 ) +require ( + cloud.google.com/go v0.92.2 // indirect + cloud.google.com/go/profiler v0.1.0 // indirect + cloud.google.com/go/trace v0.1.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // 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/aws/aws-sdk-go v1.38.35 // 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/cespare/xxhash/v2 v2.1.1 // indirect + github.com/client9/reopen v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // 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/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect + github.com/google/uuid v1.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/jmespath/go-jmespath v0.4.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // 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.26.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect + github.com/shirou/gopsutil/v3 v3.21.2 // indirect + github.com/sirupsen/logrus v1.8.1 // 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.7.0 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect + golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/api v0.54.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) + replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -316,6 +316,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/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/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -43,7 +43,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.16", "1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/internal/boring/boring.go b/internal/boring/boring.go --- a/internal/boring/boring.go +++ b/internal/boring/boring.go @@ -19,5 +19,5 @@ log.Info("FIPS mode is enabled. Using an external SSL library.") return } - log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") + log.Info("gitlab-shell was compiled with FIPS mode, but an external SSL library was not enabled.") } diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -57,8 +57,10 @@ args.GitlabKeyId = tc.keyId } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -41,8 +41,10 @@ Env: env, } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -15,24 +15,7 @@ func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) - if response.Gitaly.UseSidechannel { - request := &pb.SSHUploadPackWithSidechannelRequest{ - Repository: &response.Gitaly.Repo, - GitProtocol: c.Args.Env.GitProtocolVersion, - GitConfigOptions: response.GitConfigOptions, - } - - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) - defer cancel() - - registry := c.Config.GitalyClient.SidechannelRegistry - rw := c.ReadWriter - return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) - }) - } - - request := &pb.SSHUploadPackRequest{ + request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, @@ -42,7 +25,8 @@ ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter - return client.UploadPack(ctx, conn, rw.In, rw.Out, rw.ErrOut, request) + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -41,62 +41,6 @@ Env: env, } - cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, - Args: args, - ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, - } - - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - - err := cmd.Execute(ctx) - require.NoError(t, err) - - require.Equal(t, "UploadPack: "+repo, output.String()) - - for k, v := range map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", - "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", - "key_id": "123", - "user_id": "1", - "remote_ip": "127.0.0.1", - "key_type": "key", - } { - actual := testServer.ReceivedMD[k] - require.Len(t, actual, 1) - require.Equal(t, v, actual[0]) - } - require.Empty(t, testServer.ReceivedMD["some-other-ff"]) - require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") -} - -func TestUploadPack_withSidechannel(t *testing.T) { - gitalyAddress, testServer := testserver.StartGitalyServer(t) - - requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) - url := testserver.StartHttpServer(t, requests) - - output := &bytes.Buffer{} - input := &bytes.Buffer{} - - userId := "1" - repo := "group/repo" - - env := sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: "git-upload-pack " + repo, - RemoteAddr: "127.0.0.1", - } - - args := &commandargs.Shell{ - GitlabKeyId: userId, - CommandType: commandargs.UploadPack, - SshArgs: []string{"git-upload-pack", repo}, - Env: env, - } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -32,7 +32,6 @@ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` GracePeriodSeconds uint64 `yaml:"grace_period"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` @@ -45,7 +44,6 @@ ReadTimeoutSeconds uint64 `yaml:"read_timeout"` CaFile string `yaml:"ca_file"` CaPath string `yaml:"ca_path"` - SelfSignedCert bool `yaml:"self_signed_cert"` } type MercurialConfig struct { @@ -106,7 +104,6 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - LoginGraceTimeSeconds: 60, GracePeriodSeconds: 10, ReadinessProbe: "/start", LivenessProbe: "/health", @@ -118,10 +115,6 @@ } ) -func (sc *ServerConfig) LoginGraceTime() time.Duration { - return time.Duration(sc.LoginGraceTimeSeconds) * time.Second -} - func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } @@ -139,7 +132,6 @@ c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, - c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, nil, ) diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -21,10 +21,9 @@ ) type Command struct { - ServiceName string - Address string - Token string - DialSidechannel bool + ServiceName string + Address string + Token string } type connectionsCache struct { @@ -125,9 +124,5 @@ ) } - if cmd.DialSidechannel { - return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) - } - - return client.DialContext(ctx, cmd.Address, connOpts) + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) } diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -13,7 +13,7 @@ func TestPrometheusMetrics(t *testing.T) { metrics.GitalyConnectionsTotal.Reset() - c := &Client{} + c := newClient() cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} c.newConnection(context.Background(), cmd) @@ -31,7 +31,7 @@ } func TestCachedConnections(t *testing.T) { - c := &Client{} + c := newClient() require.Len(t, c.cache.connections, 0) @@ -51,3 +51,9 @@ require.NoError(t, err) require.Len(t, c.cache.connections, 2) } + +func newClient() *Client { + c := &Client{} + c.InitSidechannelRegistry(context.Background()) + return c +} diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -32,11 +32,10 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` - UseSidechannel bool `json:"use_sidechannel"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` } type CustomPayloadData struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -86,41 +86,6 @@ } } -func TestSidechannelFlag(t *testing.T) { - okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} - client := setup(t, - map[string]testResponse{"first": okResponse}, - map[string]testResponse{"1": okResponse}, - ) - - testCases := []struct { - desc string - args *commandargs.Shell - who string - }{ - { - desc: "Provide key id within the request", - args: &commandargs.Shell{GitlabKeyId: "1"}, - who: "key-1", - }, { - desc: "Provide username within the request", - args: &commandargs.Shell{GitlabUsername: "first"}, - who: "user-1", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) - require.NoError(t, err) - - response := buildExpectedResponse(tc.who) - response.Gitaly.UseSidechannel = true - require.Equal(t, response, result) - }) - } -} - func TestGeoPushGetCustomAction(t *testing.T) { client := setup(t, map[string]testResponse{ "custom": { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -33,10 +33,9 @@ func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { gc := gitaly.Command{ - ServiceName: serviceName, - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - DialSidechannel: response.Gitaly.UseSidechannel, + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, } return &GitalyCommand{Config: cfg, Response: response, Command: gc} diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -29,7 +29,7 @@ func TestRunGitalyCommand(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -46,14 +46,12 @@ func TestCachingOfGitalyConnections(t *testing.T) { ctx := context.Background() - cfg := &config.Config{} - cfg.GitalyClient.InitSidechannelRegistry(ctx) + cfg := newConfig() response := &accessverifier.Response{ Username: "user", Gitaly: accessverifier.Gitaly{ - Address: "tcp://localhost:9999", - Token: "token", - UseSidechannel: true, + Address: "tcp://localhost:9999", + Token: "token", }, } @@ -71,7 +69,7 @@ } func TestMissingGitalyAddress(t *testing.T) { - cmd := GitalyCommand{Config: &config.Config{}} + cmd := GitalyCommand{Config: newConfig()} err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.EqualError(t, err, "no gitaly_address given") @@ -79,7 +77,7 @@ func TestUnavailableGitalyErr(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -101,7 +99,7 @@ { name: "gitaly_feature_flags", gc: NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{ @@ -209,3 +207,9 @@ }) } } + +func newConfig() *config.Config { + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) + return cfg +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -32,7 +32,7 @@ Config *config.Config status status - statusMu sync.Mutex + statusMu sync.RWMutex wg sync.WaitGroup listener net.Listener serverConfig *serverConfig @@ -139,8 +139,8 @@ } func (s *Server) getStatus() status { - s.statusMu.Lock() - defer s.statusMu.Unlock() + s.statusMu.RLock() + defer s.statusMu.RUnlock() return s.status } @@ -179,12 +179,11 @@ ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") return } - go ssh.DiscardRequests(reqs) var establishSessionDuration float64 @@ -211,20 +210,6 @@ }).Info("server: handleConn: done") } -func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { - timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { - nconn.Close() - }) - defer func() { - // If time.Stop() equals false, that means that AfterFunc has been executed - if !timer.Stop() { - err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) - } - }() - - return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) -} - func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,7 +3,6 @@ import ( "context" "fmt" - "net" "net/http" "net/http/httptest" "os" @@ -135,33 +134,6 @@ require.Nil(t, s.Shutdown()) } -func TestLoginGraceTime(t *testing.T) { - s := setupServer(t) - - unauthenticatedRequestStatus := make(chan string) - completed := make(chan bool) - - clientCfg := clientConfig(t) - clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { - unauthenticatedRequestStatus <- "authentication-started" - <-completed // Wait infinitely - - return nil - } - - go func() { - // Start an SSH connection that never ends - ssh.Dial("tcp", serverUrl, clientCfg) - }() - - require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) - - // Verify that the server shutdowns instantly without waiting for any connection to execute - // That means that the server doesn't have any connections to wait for - require.NoError(t, s.Shutdown()) - verifyStatus(t, s, StatusClosed) -} - func setupServer(t *testing.T) *Server { t.Helper() @@ -211,7 +183,6 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.LoginGraceTimeSeconds = 1 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -81,14 +81,6 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) -} - -func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) -} - -func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -116,9 +108,6 @@ }, }, } - if useSidechannel { - body["gitaly"].(map[string]interface{})["use_sidechannel"] = true - } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json deleted file mode 100644 --- a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "status": true, - "gl_repository": "project-26", - "gl_project_path": "group/private", - "gl_id": "user-1", - "gl_username": "root", - "git_config_options": ["option"], - "gitaly": { - "repository": { - "storage_name": "default", - "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", - "git_object_directory": "path/to/git_object_directory", - "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], - "gl_repository": "project-26", - "gl_project_path": "group/private" - }, - "address": "unix:gitaly.socket", - "token": "token", - "use_sidechannel": true - }, - "git_protocol": "protocol", - "gl_console_messages": ["console", "message"] -} # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663175854 -7200 # Wed Sep 14 19:17:34 2022 +0200 # Branch heptapod # Node ID df16c7bb5675b839c8b7cac2252379e32850a7ab # Parent 2daff2db282c6fbf244ff5d8e2b386bc8253f60d build: restored build time information This is displayed by `gitlab-shell -version` Was inadvertently removed in 500ed5c3c7f5 (no mention of it in changeset description) diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -13,6 +13,8 @@ ## 14.0.0 - Jump to upstream GitLab Shell v14.0.0 (pre-GitLab 15.0) +- `gitlab-shell -version` now displays the build time as expected + instead of an empty string, giving a trailing dash (e.g., `hpd-13-25-`). ## 13.25.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ FIPS_MODE ?= 0 GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) +BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver ifeq (${FIPS_MODE}, 1) # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663176041 -7200 # Wed Sep 14 19:20:41 2022 +0200 # Branch heptapod # Node ID 0f10343a01bb4a060a4ff3f8531d81dbeffe67a9 # Parent df16c7bb5675b839c8b7cac2252379e32850a7ab Added tag heptapod-14.0.0 for changeset df16c7bb5675 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -40,3 +40,4 @@ 61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 eaa400f46c97a398037f0a72a5a30836f31a3586 heptapod-13.24.0 bbf4eff5db1a60372d6a9828b15464d5207c1fbf heptapod-13.25.0 +df16c7bb5675b839c8b7cac2252379e32850a7ab heptapod-14.0.0 # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663179966 -7200 # Wed Sep 14 20:26:06 2022 +0200 # Branch heptapod # Node ID 98d781e90b1bb472b9c37ad5fbdbed541e1457c5 # Parent 0f10343a01bb4a060a4ff3f8531d81dbeffe67a9 # Parent 95f105751282580f695ff4bec8577de261720bbd Merged upstream v14.2.0 into Heptapod Shell diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,4 +1,4 @@ -* @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao +* @ashmckenzie @igor.drozdov @patrickbajao [Documentation] *.md @aqualls diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,21 @@ +v14.2.0 + +- Implement ClientKeepAlive option !622 +- build: bump go-proxyproto to 0.6.2 !610 + +v14.1.1 + +- Log the error that happens on sconn.Wait() !613 + +v14.1.0 + +- Make PROXY policy configurable !619 +- Exclude authentication errors from apdex !611 +- Fix check_ip argument when gitlab-sshd used with PROXY protocol !616 +- Use labkit for FIPS check !607 + v14.0.0 + - Always use Gitaly sidechannel connections !567 v13.26.0 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.2.0 + +- Jump to upstream GitLab Shell v14.2.0 (pre-GitLab 15.0) + ## 14.0.0 - Jump to upstream GitLab Shell v14.0.0 (pre-GitLab 15.0) diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -7,7 +7,11 @@ BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver ifeq (${FIPS_MODE}, 1) - BUILD_TAGS += boringcrypto + # boringcrypto tag is added automatically by golang-fips compiler + BUILD_TAGS += fips + # If the golang-fips compiler is built with CGO_ENABLED=0, this needs to be + # explicitly switched on. + export CGO_ENABLED=1 endif GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.0.0 +14.2.0 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -196,8 +196,8 @@ require.NoError(t, err) require.True(t, token.Valid) require.Equal(t, "gitlab-shell", claims.Issuer) - require.Equal(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) - require.Equal(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) + require.WithinDuration(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) + require.WithinDuration(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) } t.Run("JWT authentication headers for GET", func(t *testing.T) { diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -8,10 +8,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -74,7 +74,7 @@ cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") - boring.CheckBoring() + fips.Check() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -85,10 +85,15 @@ # Set to true if gitlab-sshd is being fronted by a load balancer that implements # the PROXY protocol. proxy_protocol: false + # Proxy protocol policy ("use", "require", "reject", "ignore"), "use" is the default value + # Values: https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + proxy_policy: "use" # Address which the server listens on HTTP for monitoring/health checks. Defaults to localhost:9122. web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # Sets an interval after which server will send keepalive message to a client + client_alive_interval: 15 # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. grace_period: 10 # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -9,12 +9,12 @@ github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.1 - github.com/prometheus/client_golang v1.11.0 + github.com/pires/go-proxyproto v0.6.2 + github.com/prometheus/client_golang v1.12.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.12.0 - golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 + gitlab.com/gitlab-org/labkit v1.14.0 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 @@ -33,7 +33,7 @@ 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/cespare/xxhash/v2 v2.1.1 // 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/go-ole/go-ole v1.2.4 // indirect @@ -55,8 +55,8 @@ 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.26.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect github.com/shirou/gopsutil/v3 v3.21.2 // indirect github.com/sirupsen/logrus v1.8.1 // indirect @@ -69,8 +69,8 @@ go.uber.org/atomic v1.7.0 // indirect golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect - golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect - golang.org/x/text v0.3.6 // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/api v0.54.0 // indirect diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -165,8 +165,9 @@ github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -255,12 +256,13 @@ github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= -github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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.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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= @@ -294,6 +296,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -316,6 +319,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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.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= @@ -531,6 +536,7 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= @@ -577,6 +583,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -603,6 +610,8 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= @@ -611,6 +620,7 @@ 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/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= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -641,6 +651,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= @@ -706,8 +717,8 @@ 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/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= -github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= +github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= @@ -723,8 +734,9 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -737,15 +749,17 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -846,6 +860,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= @@ -880,8 +895,8 @@ 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.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= -gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= +gitlab.com/gitlab-org/labkit v1.14.0 h1:LSrvHgybidPyH8fHnsy1GBghrLR4kFObFrtZwUfCgAI= +gitlab.com/gitlab-org/labkit v1.14.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= @@ -1010,6 +1025,8 @@ golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1111,6 +1128,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1125,8 +1143,11 @@ 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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +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-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1136,12 +1157,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/boring/boring.go b/internal/boring/boring.go deleted file mode 100644 --- a/internal/boring/boring.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build boringcrypto -// +build boringcrypto - -package boring - -import ( - "crypto/boring" - - "gitlab.com/gitlab-org/labkit/log" -) - -// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go -// compiler in https://github.com/golang-fips/go, this requires that: -// -// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). -// 2. A system OpenSSL can be dynamically loaded via ldopen(). -func CheckBoring() { - if boring.Enabled() { - log.Info("FIPS mode is enabled. Using an external SSL library.") - return - } - log.Info("gitlab-shell was compiled with FIPS mode, but an external SSL library was not enabled.") -} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go deleted file mode 100644 --- a/internal/boring/notboring.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !boringcrypto -// +build !boringcrypto - -package boring - -// CheckBoring does nothing when the boringcrypto tag is not in the -// build. -func CheckBoring() { -} diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -28,14 +28,16 @@ ) type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` } type HttpSettingsConfig struct { @@ -101,12 +103,13 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, + ClientAliveIntervalSeconds: 15, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -115,6 +118,10 @@ } ) +func (sc *ServerConfig) ClientAliveInterval() time.Duration { + return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second +} + func (sc *ServerConfig) GracePeriod() time.Duration { return time.Duration(sc.GracePeriodSeconds) * time.Second } diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -85,7 +86,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = args.Env.RemoteAddr + request.CheckIp = parseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -116,3 +117,18 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } + +func parseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -14,6 +14,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -180,6 +181,51 @@ } } +func TestCheckIP(t *testing.T) { + testCases := []struct { + desc string + remoteAddr string + expectedCheckIp string + }{ + { + desc: "IPv4 address", + remoteAddr: "18.245.0.42", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 address", + remoteAddr: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Host and port", + remoteAddr: "18.245.0.42:6345", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 host and port", + remoteAddr: "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Bad remote addr", + remoteAddr: "[127.0", + expectedCheckIp: "[127.0", + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + client := setupWithApiInspector(t, + func(r *Request) { + require.Equal(t, tc.expectedCheckIp, r.CheckIp) + }) + + sshEnv := sshenv.Env{RemoteAddr: tc.remoteAddr} + client.Verify(context.Background(), &commandargs.Shell{Env: sshEnv}, uploadPackAction, repo) + }) + } +} + type testResponse struct { body []byte status int @@ -225,3 +271,29 @@ return client } + +func setupWithApiInspector(t *testing.T, inspector func(*Request)) *Client { + t.Helper() + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/allowed", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + require.NoError(t, err) + + var requestBody *Request + err = json.Unmarshal(b, &requestBody) + require.NoError(t, err) + + inspector(requestBody) + }, + }, + } + + url := testserver.StartSocketHttpServer(t, requests) + + client, err := NewClient(&config.Config{GitlabUrl: url}) + require.NoError(t, err) + + return client +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,32 +2,46 @@ import ( "context" + "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) +const KeepAliveMsg = "keepalive@openssh.com" + type connection struct { + cfg *config.Config concurrentSessions *semaphore.Weighted remoteAddr string + sconn *ssh.ServerConn } type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) -func newConnection(maxSessions int64, remoteAddr string) *connection { +func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { return &connection{ - concurrentSessions: semaphore.NewWeighted(maxSessions), + cfg: cfg, + concurrentSessions: semaphore.NewWeighted(cfg.Server.ConcurrentSessionsLimit), remoteAddr: remoteAddr, + sconn: sconn, } } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + if c.cfg.Server.ClientAliveIntervalSeconds > 0 { + ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) + defer ticker.Stop() + go c.sendKeepAliveMsg(ctx, ticker) + } + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { @@ -49,6 +63,10 @@ } go func() { + defer func(started time.Time) { + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + }(time.Now()) + defer c.concurrentSessions.Release(1) // Prevent a panic in a single session from taking out the whole server @@ -63,3 +81,18 @@ }() } } + +func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + ctxlog.Debug("session: handleShell: send keepalive message to a client") + + c.sconn.SendRequest(KeepAliveMsg, true, nil) + } + } +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -3,10 +3,14 @@ import ( "context" "errors" + "sync" "testing" + "time" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) type rejectCall struct { @@ -47,8 +51,32 @@ return f.extraData } +type fakeConn struct { + ssh.Conn + + sentRequestName string + mu sync.Mutex +} + +func (f *fakeConn) SentRequestName() string { + f.mu.Lock() + defer f.mu.Unlock() + + return f.sentRequestName +} + +func (f *fakeConn) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) { + f.mu.Lock() + defer f.mu.Unlock() + + f.sentRequestName = name + + return true, nil, nil +} + func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - conn := newConnection(sessionsNum, "127.0.0.1:50000") + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} + conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -145,3 +173,16 @@ require.False(t, channelHandled) } + +func TestClientAliveInterval(t *testing.T) { + f := &fakeConn{} + + conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) + + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + + go conn.sendKeepAliveMsg(context.Background(), ticker) + + require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) +} diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -5,6 +5,7 @@ "fmt" "net" "net/http" + "strings" "sync" "time" @@ -95,7 +96,7 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, - Policy: unconditionalRequirePolicy, + Policy: s.requirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } @@ -146,19 +147,8 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { - success := false - metrics.SshdConnectionsInFlight.Inc() - started := time.Now() - defer func() { - metrics.SshdConnectionsInFlight.Dec() - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) - - metrics.SliSshdSessionsTotal.Inc() - if !success { - metrics.SliSshdSessionsErrorsTotal.Inc() - } - }() + defer metrics.SshdConnectionsInFlight.Dec() remoteAddr := nconn.RemoteAddr().String() @@ -174,6 +164,8 @@ defer func() { if err := recover(); err != nil { ctxlog.Warn("panic handling session") + + metrics.SliSshdSessionsErrorsTotal.Inc() } }() @@ -181,13 +173,14 @@ sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") + ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") return } go ssh.DiscardRequests(reqs) + started := time.Now() var establishSessionDuration float64 - conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) + conn := newConnection(s.Config, remoteAddr, sconn) conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { establishSessionDuration = time.Since(started).Seconds() metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) @@ -199,17 +192,32 @@ remoteAddr: remoteAddr, } + metrics.SliSshdSessionsTotal.Inc() session.handle(ctx, requests) - - success = session.success + if !session.success { + metrics.SliSshdSessionsErrorsTotal.Inc() + } }) + reason := sconn.Wait() ctxlog.WithFields(log.Fields{ "duration_s": time.Since(started).Seconds(), "establish_session_duration_s": establishSessionDuration, + "reason": reason, }).Info("server: handleConn: done") } -func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { - return proxyproto.REQUIRE, nil +func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { + // Set the Policy value based on config + // Values are taken from https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + switch strings.ToLower(s.Config.Server.ProxyPolicy) { + case "require": + return proxyproto.REQUIRE, nil + case "ignore": + return proxyproto.IGNORE, nil + case "reject": + return proxyproto.REJECT, nil + default: + return proxyproto.USE, nil + } } diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" "net/http/httptest" "os" @@ -10,6 +11,7 @@ "testing" "time" + "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" @@ -48,15 +50,101 @@ } func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { - setupServerWithProxyProtocolEnabled(t) + target, err := net.ResolveTCPAddr("tcp", serverUrl) + require.NoError(t, err) - client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) - if client != nil { - client.Close() + header := &proxyproto.Header{ + Version: 2, + Command: proxyproto.PROXY, + TransportProtocol: proxyproto.TCPv4, + SourceAddr: &net.TCPAddr{ + IP: net.ParseIP("10.1.1.1"), + Port: 1000, + }, + DestinationAddr: target, } - require.Error(t, err, "Expected plain SSH request to be failed") - require.Regexp(t, "ssh: handshake failed", err.Error()) + testCases := []struct { + desc string + proxyPolicy string + header *proxyproto.Header + isRejected bool + }{ + { + desc: "USE (default) without a header", + proxyPolicy: "", + header: nil, + isRejected: false, + }, + { + desc: "USE (default) with a header", + proxyPolicy: "", + header: header, + isRejected: false, + }, + { + desc: "REQUIRE without a header", + proxyPolicy: "require", + header: nil, + isRejected: true, + }, + { + desc: "REQUIRE with a header", + proxyPolicy: "require", + header: header, + isRejected: false, + }, + { + desc: "REJECT without a header", + proxyPolicy: "reject", + header: nil, + isRejected: false, + }, + { + desc: "REJECT with a header", + proxyPolicy: "reject", + header: header, + isRejected: true, + }, + { + desc: "IGNORE without a header", + proxyPolicy: "ignore", + header: nil, + isRejected: false, + }, + { + desc: "IGNORE with a header", + proxyPolicy: "ignore", + header: header, + isRejected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true, ProxyPolicy: tc.proxyPolicy}}) + + conn, err := net.DialTCP("tcp", nil, target) + require.NoError(t, err) + + if tc.header != nil { + _, err := header.WriteTo(conn) + require.NoError(t, err) + } + + sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + if sshConn != nil { + sshConn.Close() + } + + if tc.isRejected { + require.Error(t, err, "Expected plain SSH request to be failed") + require.Regexp(t, "ssh: handshake failed", err.Error()) + } else { + require.NoError(t, err) + } + }) + } } func TestCorrelationId(t *testing.T) { @@ -140,12 +228,6 @@ return setupServerWithConfig(t, nil) } -func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { - t.Helper() - - return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) -} - func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() @@ -183,6 +265,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 + cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663180178 -7200 # Wed Sep 14 20:29:38 2022 +0200 # Branch heptapod # Node ID 60be5fae5a4266a3ed4eb3508b4731b1f821d8cf # Parent 98d781e90b1bb472b9c37ad5fbdbed541e1457c5 Added tag heptapod-14.2.0 for changeset 98d781e90b1b diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -41,3 +41,4 @@ eaa400f46c97a398037f0a72a5a30836f31a3586 heptapod-13.24.0 bbf4eff5db1a60372d6a9828b15464d5207c1fbf heptapod-13.25.0 df16c7bb5675b839c8b7cac2252379e32850a7ab heptapod-14.0.0 +98d781e90b1bb472b9c37ad5fbdbed541e1457c5 heptapod-14.2.0 # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663180324 -7200 # Wed Sep 14 20:32:04 2022 +0200 # Branch heptapod # Node ID 7e62e4be19def9c1f1773e326480a9429210bb8d # Parent 60be5fae5a4266a3ed4eb3508b4731b1f821d8cf # Parent c7cb78872f0da7b8083d01a00da0f1c478ee42e3 Merged upstream v14.3.0 into Heptapod Shell diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -92,9 +92,6 @@ gemnasium-dependency_scanning: rules: *workflow_rules -bundler-audit-dependency_scanning: - rules: *workflow_rules - # Secret Detection secret_detection: rules: *workflow_rules diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.3.0 + +- Remove deprecated bundler-audit !626 +- Wait until all Gitaly sessions are executed !624 + v14.2.0 - Implement ClientKeepAlive option !622 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.3.0 + +- Bump to upstream GitLab Shell v14.3.0 (GitLab 15.0 series) + ## 14.2.0 - Jump to upstream GitLab Shell v14.2.0 (pre-GitLab 15.0) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.2.0 +14.3.0 diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:9] { + for _, m := range ms[0:10] { actualNames = append(actualNames, m.GetName()) } @@ -47,6 +47,7 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -22,6 +22,7 @@ sshdHitMaxSessionsName = "concurrent_limited_sessions_total" sshdSessionDurationSecondsName = "session_duration_seconds" sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + sshdCanceledSessionsName = "canceled_sessions" sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" @@ -76,6 +77,15 @@ }, ) + SshdCanceledSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdCanceledSessionsName, + Help: "The number of canceled gitlab-sshd sessions.", + }, + ) + SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -6,6 +6,8 @@ "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -15,19 +17,25 @@ const KeepAliveMsg = "keepalive@openssh.com" +var EOFTimeout = 10 * time.Second + type connection struct { cfg *config.Config concurrentSessions *semaphore.Weighted remoteAddr string sconn *ssh.ServerConn + maxSessions int64 } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) +type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { + maxSessions := cfg.Server.ConcurrentSessionsLimit + return &connection{ cfg: cfg, - concurrentSessions: semaphore.NewWeighted(cfg.Server.ConcurrentSessionsLimit), + maxSessions: maxSessions, + concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, sconn: sconn, } @@ -76,10 +84,27 @@ } }() - handler(ctx, channel, requests) + metrics.SliSshdSessionsTotal.Inc() + err := handler(ctx, channel, requests) + if err != nil { + if grpcstatus.Convert(err).Code() == grpccodes.Canceled { + metrics.SshdCanceledSessions.Inc() + } else { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + } + ctxlog.Info("connection: handle: done") }() } + + // When a connection has been prematurely closed we block execution until all concurrent sessions are released + // in order to allow Gitaly complete the operations and close all the channels gracefully. + // If it didn't happen within timeout, we unblock the execution + // Related issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/563 + ctx, cancel := context.WithTimeout(ctx, EOFTimeout) + defer cancel() + c.concurrentSessions.Acquire(ctx, c.maxSessions) } func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -7,10 +7,14 @@ "testing" "time" + "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) type rejectCall struct { @@ -90,7 +94,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -128,8 +132,9 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test + return nil }) }() @@ -142,9 +147,10 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) + return nil }) require.True(t, channelHandled) @@ -160,8 +166,9 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true + return nil }) }() @@ -186,3 +193,33 @@ require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) } + +func TestSessionsMetrics(t *testing.T) { + // Unfortunately, there is no working way to reset Counter (not CounterVec) + // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index + initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) + initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) + initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) + + newChannel := &fakeNewChannel{channelType: "session"} + + conn, chans := setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return errors.New("custom error") + }) + + require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return grpcstatus.Error(grpccodes.Canceled, "error") + }) + + require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) +} diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,7 +22,6 @@ channel ssh.Channel gitlabKeyId string remoteAddr string - success bool // State managed by the session execCmd string @@ -42,11 +41,12 @@ ExitStatus uint32 } -func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { +func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) error { ctxlog := log.ContextLogger(ctx) ctxlog.Debug("session: handle: entering request loop") + var err error for req := range requests { sessionLog := ctxlog.WithFields(log.Fields{ "bytesize": len(req.Payload), @@ -58,12 +58,14 @@ var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(ctx, req) + shouldContinue, err = s.handleEnv(ctx, req) case "exec": - shouldContinue = s.handleExec(ctx, req) + shouldContinue, err = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(ctx, s.handleShell(ctx, req)) + var status uint32 + status, err = s.handleShell(ctx, req) + s.exit(ctx, status) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -84,15 +86,17 @@ } ctxlog.Debug("session: handle: exiting request loop") + + return err } -func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error) { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") - return false + return false, err } switch envRequest.Name { @@ -113,23 +117,24 @@ ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, ).Debug("session: handleEnv: processed") - return true + return true, nil } -func (s *session) handleExec(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleExec(ctx context.Context, req *ssh.Request) (bool, error) { var execRequest execRequest if err := ssh.Unmarshal(req.Payload, &execRequest); err != nil { - return false + return false, err } s.execCmd = execRequest.Command - s.exit(ctx, s.handleShell(ctx, req)) + status, err := s.handleShell(ctx, req) + s.exit(ctx, status) - return false + return false, err } -func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { +func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, error) { ctxlog := log.ContextLogger(ctx) if req.WantReply { @@ -157,7 +162,7 @@ s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) } s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) - return 128 + return 128, err } cmdName := reflect.TypeOf(cmd).String() @@ -165,12 +170,12 @@ if err := cmd.Execute(ctx); err != nil { s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) - return 1 + return 1, err } ctxlog.Info("session: handleShell: command executed successfully") - return 0 + return 0, nil } func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { @@ -183,8 +188,6 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} - s.success = status == 0 - s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -3,6 +3,7 @@ import ( "bytes" "context" + "errors" "io" "net/http" "testing" @@ -60,22 +61,26 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedProtocolVersion string expectedResult bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Name of type envRequest"), expectedProtocolVersion: "1", expectedResult: false, }, { desc: "valid payload", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "2", expectedResult: true, }, { desc: "valid payload with forbidden env var", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "1", expectedResult: true, }, @@ -86,8 +91,11 @@ s := &session{gitProtocolVersion: "1"} r := &ssh.Request{Payload: tc.payload} - require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) - require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + shouldContinue, err := s.handleEnv(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResult, shouldContinue) + require.Equal(t, tc.expectedProtocolVersion, s.gitProtocolVersion) }) } } @@ -96,23 +104,24 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedExecCmd string sentRequestName string sentRequestPayload []byte - success bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Command of type execRequest"), expectedExecCmd: "", sentRequestName: "", }, { desc: "valid payload", payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedErr: nil, expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), - success: true, }, } @@ -129,47 +138,53 @@ } r := &ssh.Request{Payload: tc.payload} - require.Equal(t, false, s.handleExec(context.Background(), r)) + shouldContinue, err := s.handleExec(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, false, shouldContinue) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) - require.Equal(t, tc.success, s.success) }) } } func TestHandleShell(t *testing.T) { testCases := []struct { - desc string - cmd string - errMsg string - gitlabKeyId string - expectedExitCode uint32 - success bool + desc string + cmd string + errMsg string + gitlabKeyId string + expectedErrString string + expectedExitCode uint32 }{ { - desc: "fails to parse command", - cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + gitlabKeyId: "root", + expectedErrString: "Invalid SSH command: invalid command line string", + expectedExitCode: 128, }, { - desc: "specified command is unknown", - cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedErrString: "Disallowed command", + expectedExitCode: 128, }, { - desc: "fails to parse command", - cmd: "discover", - gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", - expectedExitCode: 1, + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedErrString: "Failed to get username: who='' is invalid", + expectedExitCode: 1, }, { - desc: "fails to parse command", - cmd: "discover", - errMsg: "", - gitlabKeyId: "root", - expectedExitCode: 0, + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedErrString: "", + expectedExitCode: 0, }, } @@ -186,7 +201,13 @@ } r := &ssh.Request{} - require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + exitCode, err := s.handleShell(context.Background(), r) + + if tc.expectedErrString != "" { + require.Equal(t, tc.expectedErrString, err.Error()) + } + + require.Equal(t, tc.expectedExitCode, exitCode) require.Equal(t, tc.errMsg, out.String()) }) } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -181,7 +181,7 @@ started := time.Now() var establishSessionDuration float64 conn := newConnection(s.Config, remoteAddr, sconn) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { establishSessionDuration = time.Since(started).Seconds() metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) @@ -192,11 +192,7 @@ remoteAddr: remoteAddr, } - metrics.SliSshdSessionsTotal.Inc() - session.handle(ctx, requests) - if !session.success { - metrics.SliSshdSessionsErrorsTotal.Inc() - } + return session.handle(ctx, requests) }) reason := sconn.Wait() # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663185648 -7200 # Wed Sep 14 22:00:48 2022 +0200 # Branch heptapod # Node ID c19e92bccb5497c6d2c16280eaf2d695a5c48846 # Parent 7e62e4be19def9c1f1773e326480a9429210bb8d Added tag heptapod-14.3.0 for changeset 7e62e4be19de diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -42,3 +42,4 @@ bbf4eff5db1a60372d6a9828b15464d5207c1fbf heptapod-13.25.0 df16c7bb5675b839c8b7cac2252379e32850a7ab heptapod-14.0.0 98d781e90b1bb472b9c37ad5fbdbed541e1457c5 heptapod-14.2.0 +7e62e4be19def9c1f1773e326480a9429210bb8d heptapod-14.3.0 # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663503515 -7200 # Sun Sep 18 14:18:35 2022 +0200 # Branch heptapod # Node ID fca0cc645e5bbe898f18befe0f31f51f091db81b # Parent c19e92bccb5497c6d2c16280eaf2d695a5c48846 Updated HEPTAPOD_VERSION to match forthcoming tag diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,11 @@ The corresponding tag is heptapod-x.y.z +## 14.3.1 + +- Filled in `HEPTAPOD_VERSION` (had been forgotten in 14.0 through + 14.3.0) + ## 14.3.0 - Bump to upstream GitLab Shell v14.3.0 (GitLab 15.0 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.25.0 +14.3.1 # HG changeset patch # User Georges Racinet on purity.racinet.fr <georges@racinet.fr> # Date 1663503524 -7200 # Sun Sep 18 14:18:44 2022 +0200 # Branch heptapod # Node ID 82e49acb60d6a2848eefa344c8f9c77fdfbc2426 # Parent fca0cc645e5bbe898f18befe0f31f51f091db81b Added tag heptapod-14.3.1 for changeset fca0cc645e5b diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -43,3 +43,4 @@ df16c7bb5675b839c8b7cac2252379e32850a7ab heptapod-14.0.0 98d781e90b1bb472b9c37ad5fbdbed541e1457c5 heptapod-14.2.0 7e62e4be19def9c1f1773e326480a9429210bb8d heptapod-14.3.0 +fca0cc645e5bbe898f18befe0f31f51f091db81b heptapod-14.3.1 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1663792446 -7200 # Wed Sep 21 22:34:06 2022 +0200 # Branch heptapod # Node ID 7b25801e4afc9c3d6e7016fd220cce310db6bd1d # Parent 82e49acb60d6a2848eefa344c8f9c77fdfbc2426 # Parent 2ab8e6717d3b7798734e1bac9d079c41f52d5b0a Merged heptapod-stable branch into heptapod Just to flush the numerous changesets about x.y being the new stable. No real changes. # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1663931992 -7200 # Fri Sep 23 13:19:52 2022 +0200 # Branch heptapod-stable # Node ID 0b31292ecc0575dfcd23ee86046834b5a68cdd0d # Parent 2ab8e6717d3b7798734e1bac9d079c41f52d5b0a # Parent 7b25801e4afc9c3d6e7016fd220cce310db6bd1d heptapod#697: Making 0.33 the new stable diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,7 +60,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.16", "1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' @@ -92,9 +92,6 @@ gemnasium-dependency_scanning: rules: *workflow_rules -bundler-audit-dependency_scanning: - rules: *workflow_rules - # Secret Detection secret_detection: rules: *workflow_rules diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1,4 +1,4 @@ -* @ashmckenzie @igor.drozdov @nick.thomas @patrickbajao +* @ashmckenzie @igor.drozdov @patrickbajao [Documentation] *.md @aqualls diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -40,3 +40,7 @@ 61814961ec7c871e9a081f4399536e5b8a62fabf heptapod-13.23.0 eaa400f46c97a398037f0a72a5a30836f31a3586 heptapod-13.24.0 bbf4eff5db1a60372d6a9828b15464d5207c1fbf heptapod-13.25.0 +df16c7bb5675b839c8b7cac2252379e32850a7ab heptapod-14.0.0 +98d781e90b1bb472b9c37ad5fbdbed541e1457c5 heptapod-14.2.0 +7e62e4be19def9c1f1773e326480a9429210bb8d heptapod-14.3.0 +fca0cc645e5bbe898f18befe0f31f51f091db81b heptapod-14.3.1 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.8 +golang 1.17.9 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,39 @@ +v14.3.0 + +- Remove deprecated bundler-audit !626 +- Wait until all Gitaly sessions are executed !624 + +v14.2.0 + +- Implement ClientKeepAlive option !622 +- build: bump go-proxyproto to 0.6.2 !610 + +v14.1.1 + +- Log the error that happens on sconn.Wait() !613 + +v14.1.0 + +- Make PROXY policy configurable !619 +- Exclude authentication errors from apdex !611 +- Fix check_ip argument when gitlab-sshd used with PROXY protocol !616 +- Use labkit for FIPS check !607 + +v14.0.0 + +- Always use Gitaly sidechannel connections !567 + +v13.26.0 + +- Add JWT token to GitLab Rails request !596 +- Drop go 1.16 support !601 +- Remove `self_signed_cert` option !602 + +v13.25.2 + +- Revert "Abort long-running unauthenticated SSH connections" !605 +- Bump Go to 1.17.9 for asdf users !600 + v13.25.1 - Upgrade golang to 1.17.8 !591 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,25 @@ The corresponding tag is heptapod-x.y.z +## 14.3.1 + +- Filled in `HEPTAPOD_VERSION` (had been forgotten in 14.0 through + 14.3.0) + +## 14.3.0 + +- Bump to upstream GitLab Shell v14.3.0 (GitLab 15.0 series) + +## 14.2.0 + +- Jump to upstream GitLab Shell v14.2.0 (pre-GitLab 15.0) + +## 14.0.0 + +- Jump to upstream GitLab Shell v14.0.0 (pre-GitLab 15.0) +- `gitlab-shell -version` now displays the build time as expected + instead of an empty string, giving a trailing dash (e.g., `hpd-13-25-`). + ## 13.25.0 - Jump to upstream GitLab Shell v13.25.1 (GitLab 14.10 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -13.25.0 +14.3.1 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -3,10 +3,15 @@ FIPS_MODE ?= 0 GO_SOURCES := $(shell find . -name '*.go') VERSION_STRING := $(shell ./compute_version || echo unknown) +BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S) BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver ifeq (${FIPS_MODE}, 1) - BUILD_TAGS += boringcrypto + # boringcrypto tag is added automatically by golang-fips compiler + BUILD_TAGS += fips + # If the golang-fips compiler is built with CGO_ENABLED=0, this needs to be + # explicitly switched on. + export CGO_ENABLED=1 endif GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -13.25.1 +14.3.0 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -10,13 +10,19 @@ "path" "strings" "testing" + "time" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) +var ( + secret = []byte("sssh, it's a secret") +) + func TestClients(t *testing.T) { testhelper.PrepareTestRootDir(t) @@ -57,12 +63,10 @@ t.Run(tc.desc, func(t *testing.T) { url := tc.server(t, buildRequests(t, tc.relativeURLRoot)) - secret := "sssh, it's a secret" - - httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", secret, httpClient) + client, err := NewGitlabNetClient("", "", string(secret), httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -71,6 +75,7 @@ testMissing(t, client) testErrorMessage(t, client) testAuthenticationHeader(t, client) + testJWTAuthenticationHeader(t, client) }) } } @@ -160,7 +165,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -175,7 +180,44 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, "sssh, it's a secret", string(header)) + require.Equal(t, secret, header) + }) +} + +func testJWTAuthenticationHeader(t *testing.T, client *GitlabNetClient) { + verifyJWTToken := func(t *testing.T, response *http.Response) { + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + + claims := &jwt.RegisteredClaims{} + token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { + return secret, nil + }) + require.NoError(t, err) + require.True(t, token.Valid) + require.Equal(t, "gitlab-shell", claims.Issuer) + require.WithinDuration(t, time.Now().Truncate(time.Second), claims.IssuedAt.Time, time.Second) + require.WithinDuration(t, time.Now().Truncate(time.Second).Add(time.Minute), claims.ExpiresAt.Time, time.Second) + } + + t.Run("JWT authentication headers for GET", func(t *testing.T) { + response, err := client.Get(context.Background(), "/jwt_auth") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) + }) + + t.Run("JWT authentication headers for POST", func(t *testing.T) { + response, err := client.Post(context.Background(), "/jwt_auth", map[string]string{}) + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + verifyJWTToken(t, response) }) } @@ -209,6 +251,12 @@ }, }, { + Path: "/api/v4/internal/jwt_auth", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get(apiSecretHeaderName)) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -11,13 +11,18 @@ "strings" "time" + "github.com/golang-jwt/jwt/v4" + "gitlab.com/gitlab-org/labkit/log" ) const ( - internalApiPath = "/api/v4/internal" - secretHeaderName = "Gitlab-Shared-Secret" - defaultUserAgent = "GitLab-Shell" + internalApiPath = "/api/v4/internal" + secretHeaderName = "Gitlab-Shared-Secret" + apiSecretHeaderName = "Gitlab-Shell-Api-Request" + defaultUserAgent = "GitLab-Shell" + jwtTTL = time.Minute + jwtIssuer = "gitlab-shell" ) type ErrorResponse struct { @@ -121,10 +126,22 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } + secretBytes := []byte(c.secret) - encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) + encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) request.Header.Set(secretHeaderName, encodedSecret) + claims := jwt.RegisteredClaims{ + Issuer: jwtIssuer, + IssuedAt: jwt.NewNumericDate(time.Now()), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), + } + tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) + if err != nil { + return nil, err + } + request.Header.Set(apiSecretHeaderName, tokenString) + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true diff --git a/client/httpclient.go b/client/httpclient.go --- a/client/httpclient.go +++ b/client/httpclient.go @@ -14,7 +14,6 @@ "time" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/tracing" ) @@ -70,17 +69,8 @@ return nil } -// Deprecated: use NewHTTPClientWithOpts - https://gitlab.com/gitlab-org/gitlab-shell/-/issues/484 -func NewHTTPClient(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64) *HttpClient { - c, err := NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath, selfSignedCert, readTimeoutSeconds, nil) - if err != nil { - log.WithError(err).Error("new http client with opts") - } - return c -} - // NewHTTPClientWithOpts builds an HTTP client using the provided options -func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, selfSignedCert bool, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { +func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) { var transport *http.Transport var host string var err error @@ -103,7 +93,7 @@ opt(hcc) } - transport, host, err = buildHttpsTransport(*hcc, selfSignedCert, gitlabURL) + transport, host, err = buildHttpsTransport(*hcc, gitlabURL) if err != nil { return nil, err } @@ -140,7 +130,7 @@ return transport, host } -func buildHttpsTransport(hcc httpClientCfg, selfSignedCert bool, gitlabURL string) (*http.Transport, string, error) { +func buildHttpsTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport, string, error) { certPool, err := x509.SystemCertPool() if err != nil { @@ -162,12 +152,8 @@ } } tlsConfig := &tls.Config{ - RootCAs: certPool, - // The self_signed_cert config setting is deprecated - // The field and its usage is going to be removed in - // https://gitlab.com/gitlab-org/gitlab-shell/-/issues/541 - InsecureSkipVerify: selfSignedCert, - MinVersion: tls.VersionTLS12, + RootCAs: certPool, + MinVersion: tls.VersionTLS12, } if hcc.HaveCertAndKey() { diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -17,7 +17,7 @@ func TestReadTimeout(t *testing.T) { expectedSeconds := uint64(300) - client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", false, expectedSeconds, nil) + client, err := NewHTTPClientWithOpts("http://localhost:3000", "", "", "", expectedSeconds, nil) require.NoError(t, err) require.NotNil(t, client) @@ -123,7 +123,7 @@ func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient { url := testserver.StartHttpServer(t, requests) - httpClient, err := NewHTTPClientWithOpts(url, "", "", "", false, 1, nil) + httpClient, err := NewHTTPClientWithOpts(url, "", "", "", 1, nil) require.NoError(t, err) client, err := NewGitlabNetClient(username, password, "", httpClient) diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -18,7 +18,6 @@ testCases := []struct { desc string caFile, caPath string - selfSigned bool clientCAPath, clientCertPath, clientKeyPath string // used for TLS client certs }{ { @@ -31,9 +30,8 @@ caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { - desc: "Invalid cert with self signed cert option enabled", - caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), - selfSigned: true, + desc: "Invalid cert with self signed cert option enabled", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), }, { desc: "Client certs with CA", @@ -48,7 +46,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath, tc.selfSigned) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, tc.clientCAPath, tc.clientCertPath, tc.clientKeyPath) require.NoError(t, err) response, err := client.Get(context.Background(), "/hello") @@ -95,7 +93,7 @@ for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "", false) + client, err := setupWithRequests(t, tc.caFile, tc.caPath, "", "", "") if tc.expectedCaFileNotFound { require.Error(t, err) require.ErrorIs(t, err, ErrCafileNotFound) @@ -109,7 +107,7 @@ } } -func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string, selfSigned bool) (*GitlabNetClient, error) { +func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string) (*GitlabNetClient, error) { testhelper.PrepareTestRootDir(t) requests := []testserver.TestRequestHandler{ @@ -130,7 +128,7 @@ opts = append(opts, WithClientCert(clientCertPath, clientKeyPath)) } - httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, selfSigned, 1, opts) + httpClient, err := NewHTTPClientWithOpts(url, "", caFile, caPath, 1, opts) if err != nil { return nil, err } diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -8,10 +8,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/boring" "gitlab.com/gitlab-org/gitlab-shell/internal/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -74,7 +74,7 @@ cmdName := reflect.TypeOf(cmd).String() ctxlog := log.ContextLogger(ctx) ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") - boring.CheckBoring() + fips.Check() if err := cmd.Execute(ctx); err != nil { ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -43,11 +43,6 @@ # ca_file: /etc/ssl/cert.pem # ca_path: /etc/pki/tls/certs # -# The self_signed_cert option is deprecated -# When it's set to true, any certificate is accepted, which may make machine-in-the-middle attack possible -# Certificates specified in ca_file and ca_path are trusted anyway even if they are self-signed -# Issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/120 - self_signed_cert: false # File used as authorized_keys for gitlab user auth_file: "/home/git/.ssh/authorized_keys" @@ -90,18 +85,21 @@ # Set to true if gitlab-sshd is being fronted by a load balancer that implements # the PROXY protocol. proxy_protocol: false + # Proxy protocol policy ("use", "require", "reject", "ignore"), "use" is the default value + # Values: https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + proxy_policy: "use" # Address which the server listens on HTTP for monitoring/health checks. Defaults to localhost:9122. web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 + # Sets an interval after which server will send keepalive message to a client + client_alive_interval: 15 # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. grace_period: 10 # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" - # The server disconnects after this time (in seconds) if the user has not successfully logged in. Defaults to 60. - login_grace_time: 60 # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,22 +1,84 @@ module gitlab.com/gitlab-org/gitlab-shell -go 1.16 +go 1.17 require ( + github.com/golang-jwt/jwt/v4 v4.4.1 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mattn/go-shellwords v1.0.11 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 - github.com/pires/go-proxyproto v0.6.1 - github.com/prometheus/client_golang v1.11.0 + github.com/pires/go-proxyproto v0.6.2 + github.com/prometheus/client_golang v1.12.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.12.0 - golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 + gitlab.com/gitlab-org/labkit v1.14.0 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 gopkg.in/yaml.v2 v2.4.0 ) +require ( + cloud.google.com/go v0.92.2 // indirect + cloud.google.com/go/profiler v0.1.0 // indirect + cloud.google.com/go/trace v0.1.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // 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/aws/aws-sdk-go v1.38.35 // 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/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/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/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect + github.com/google/uuid v1.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/jmespath/go-jmespath v0.4.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // 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/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect + github.com/shirou/gopsutil/v3 v3.21.2 // indirect + github.com/sirupsen/logrus v1.8.1 // 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.7.0 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/api v0.54.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) + replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -165,8 +165,9 @@ github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -255,12 +256,13 @@ github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= -github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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.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= github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= @@ -294,6 +296,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -316,6 +319,10 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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.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/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -529,6 +536,7 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= @@ -575,6 +583,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -601,6 +610,8 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 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= @@ -609,6 +620,7 @@ 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/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= github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -639,6 +651,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/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= @@ -704,8 +717,8 @@ 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/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw= -github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= +github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= 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= @@ -721,8 +734,9 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -735,15 +749,17 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -844,6 +860,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= @@ -878,8 +895,8 @@ 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.12.0 h1:XVwGqXfHrhEr2bzZbYy/eA7xulAeyvk9HB3Q7nH2H4I= -gitlab.com/gitlab-org/labkit v1.12.0/go.mod h1:tnvyKiPF/Y0MeBy+ACYWRWexOEQk6PTRGUc9GstcnXc= +gitlab.com/gitlab-org/labkit v1.14.0 h1:LSrvHgybidPyH8fHnsy1GBghrLR4kFObFrtZwUfCgAI= +gitlab.com/gitlab-org/labkit v1.14.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= @@ -1008,6 +1025,8 @@ golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1109,6 +1128,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1123,8 +1143,11 @@ 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-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +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-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1134,12 +1157,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -43,7 +43,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.16", "1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/internal/boring/boring.go b/internal/boring/boring.go deleted file mode 100644 --- a/internal/boring/boring.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build boringcrypto -// +build boringcrypto - -package boring - -import ( - "crypto/boring" - - "gitlab.com/gitlab-org/labkit/log" -) - -// CheckBoring checks whether FIPS crypto has been enabled. For the FIPS Go -// compiler in https://github.com/golang-fips/go, this requires that: -// -// 1. The kernel has FIPS enabled (e.g. `/proc/sys/crypto/fips_enabled` is 1). -// 2. A system OpenSSL can be dynamically loaded via ldopen(). -func CheckBoring() { - if boring.Enabled() { - log.Info("FIPS mode is enabled. Using an external SSL library.") - return - } - log.Info("Gitaly was compiled with FIPS mode, but an external SSL library was not enabled.") -} diff --git a/internal/boring/notboring.go b/internal/boring/notboring.go deleted file mode 100644 --- a/internal/boring/notboring.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !boringcrypto -// +build !boringcrypto - -package boring - -// CheckBoring does nothing when the boringcrypto tag is not in the -// build. -func CheckBoring() { -} diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -57,8 +57,10 @@ args.GitlabKeyId = tc.keyId } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -41,8 +41,10 @@ Env: env, } + cfg := &config.Config{GitlabUrl: url} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, + Config: cfg, Args: args, ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, } diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -15,24 +15,7 @@ func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { gc := handler.NewGitalyCommand(c.Config, string(commandargs.UploadPack), response) - if response.Gitaly.UseSidechannel { - request := &pb.SSHUploadPackWithSidechannelRequest{ - Repository: &response.Gitaly.Repo, - GitProtocol: c.Args.Env.GitProtocolVersion, - GitConfigOptions: response.GitConfigOptions, - } - - return gc.RunGitalyCommand(ctx, func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { - ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) - defer cancel() - - registry := c.Config.GitalyClient.SidechannelRegistry - rw := c.ReadWriter - return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) - }) - } - - request := &pb.SSHUploadPackRequest{ + request := &pb.SSHUploadPackWithSidechannelRequest{ Repository: &response.Gitaly.Repo, GitProtocol: c.Args.Env.GitProtocolVersion, GitConfigOptions: response.GitConfigOptions, @@ -42,7 +25,8 @@ ctx, cancel := gc.PrepareContext(ctx, request.Repository, c.Args.Env) defer cancel() + registry := c.Config.GitalyClient.SidechannelRegistry rw := c.ReadWriter - return client.UploadPack(ctx, conn, rw.In, rw.Out, rw.ErrOut, request) + return client.UploadPackWithSidechannel(ctx, conn, registry, rw.In, rw.Out, rw.ErrOut, request) }) } diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -41,62 +41,6 @@ Env: env, } - cmd := &Command{ - Config: &config.Config{GitlabUrl: url}, - Args: args, - ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, - } - - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") - ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") - - err := cmd.Execute(ctx) - require.NoError(t, err) - - require.Equal(t, "UploadPack: "+repo, output.String()) - - for k, v := range map[string]string{ - "gitaly-feature-cache_invalidator": "true", - "gitaly-feature-inforef_uploadpack_cache": "false", - "x-gitlab-client-name": "gitlab-shell-tests-git-upload-pack", - "key_id": "123", - "user_id": "1", - "remote_ip": "127.0.0.1", - "key_type": "key", - } { - actual := testServer.ReceivedMD[k] - require.Len(t, actual, 1) - require.Equal(t, v, actual[0]) - } - require.Empty(t, testServer.ReceivedMD["some-other-ff"]) - require.Equal(t, testServer.ReceivedMD["x-gitlab-correlation-id"][0], "a-correlation-id") -} - -func TestUploadPack_withSidechannel(t *testing.T) { - gitalyAddress, testServer := testserver.StartGitalyServer(t) - - requests := requesthandlers.BuildAllowedWithGitalyHandlersWithSidechannel(t, gitalyAddress) - url := testserver.StartHttpServer(t, requests) - - output := &bytes.Buffer{} - input := &bytes.Buffer{} - - userId := "1" - repo := "group/repo" - - env := sshenv.Env{ - IsSSHConnection: true, - OriginalCommand: "git-upload-pack " + repo, - RemoteAddr: "127.0.0.1", - } - - args := &commandargs.Shell{ - GitlabKeyId: userId, - CommandType: commandargs.UploadPack, - SshArgs: []string{"git-upload-pack", repo}, - Env: env, - } - ctx := correlation.ContextWithCorrelation(context.Background(), "a-correlation-id") ctx = correlation.ContextWithClientName(ctx, "gitlab-shell-tests") diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -28,15 +28,16 @@ ) type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - LoginGraceTimeSeconds uint64 `yaml:"login_grace_time"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` + GracePeriodSeconds uint64 `yaml:"grace_period"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` } type HttpSettingsConfig struct { @@ -45,7 +46,6 @@ ReadTimeoutSeconds uint64 `yaml:"read_timeout"` CaFile string `yaml:"ca_file"` CaPath string `yaml:"ca_path"` - SelfSignedCert bool `yaml:"self_signed_cert"` } type MercurialConfig struct { @@ -103,13 +103,13 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - LoginGraceTimeSeconds: 60, - GracePeriodSeconds: 10, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriodSeconds: 10, + ClientAliveIntervalSeconds: 15, + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -118,8 +118,8 @@ } ) -func (sc *ServerConfig) LoginGraceTime() time.Duration { - return time.Duration(sc.LoginGraceTimeSeconds) * time.Second +func (sc *ServerConfig) ClientAliveInterval() time.Duration { + return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second } func (sc *ServerConfig) GracePeriod() time.Duration { @@ -139,7 +139,6 @@ c.GitlabRelativeURLRoot, c.HttpSettings.CaFile, c.HttpSettings.CaPath, - c.HttpSettings.SelfSignedCert, c.HttpSettings.ReadTimeoutSeconds, nil, ) diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -39,7 +39,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:9] { + for _, m := range ms[0:10] { actualNames = append(actualNames, m.GetName()) } @@ -47,6 +47,7 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", + "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -21,10 +21,9 @@ ) type Command struct { - ServiceName string - Address string - Token string - DialSidechannel bool + ServiceName string + Address string + Token string } type connectionsCache struct { @@ -125,9 +124,5 @@ ) } - if cmd.DialSidechannel { - return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) - } - - return client.DialContext(ctx, cmd.Address, connOpts) + return client.DialSidechannel(ctx, cmd.Address, c.SidechannelRegistry, connOpts) } diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -13,7 +13,7 @@ func TestPrometheusMetrics(t *testing.T) { metrics.GitalyConnectionsTotal.Reset() - c := &Client{} + c := newClient() cmd := Command{ServiceName: "git-upload-pack", Address: "tcp://localhost:9999"} c.newConnection(context.Background(), cmd) @@ -31,7 +31,7 @@ } func TestCachedConnections(t *testing.T) { - c := &Client{} + c := newClient() require.Len(t, c.cache.connections, 0) @@ -51,3 +51,9 @@ require.NoError(t, err) require.Len(t, c.cache.connections, 2) } + +func newClient() *Client { + c := &Client{} + c.InitSidechannelRegistry(context.Background()) + return c +} diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,6 +3,7 @@ import ( "context" "fmt" + "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -32,11 +33,10 @@ } type Gitaly struct { - Repo pb.Repository `json:"repository"` - Address string `json:"address"` - Token string `json:"token"` - Features map[string]string `json:"features"` - UseSidechannel bool `json:"use_sidechannel"` + Repo pb.Repository `json:"repository"` + Address string `json:"address"` + Token string `json:"token"` + Features map[string]string `json:"features"` } type CustomPayloadData struct { @@ -86,7 +86,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = args.Env.RemoteAddr + request.CheckIp = parseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -117,3 +117,18 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } + +func parseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -14,6 +14,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -86,41 +87,6 @@ } } -func TestSidechannelFlag(t *testing.T) { - okResponse := testResponse{body: responseBody(t, "allowed_sidechannel.json"), status: http.StatusOK} - client := setup(t, - map[string]testResponse{"first": okResponse}, - map[string]testResponse{"1": okResponse}, - ) - - testCases := []struct { - desc string - args *commandargs.Shell - who string - }{ - { - desc: "Provide key id within the request", - args: &commandargs.Shell{GitlabKeyId: "1"}, - who: "key-1", - }, { - desc: "Provide username within the request", - args: &commandargs.Shell{GitlabUsername: "first"}, - who: "user-1", - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - result, err := client.Verify(context.Background(), tc.args, uploadPackAction, repo) - require.NoError(t, err) - - response := buildExpectedResponse(tc.who) - response.Gitaly.UseSidechannel = true - require.Equal(t, response, result) - }) - } -} - func TestGeoPushGetCustomAction(t *testing.T) { client := setup(t, map[string]testResponse{ "custom": { @@ -215,6 +181,51 @@ } } +func TestCheckIP(t *testing.T) { + testCases := []struct { + desc string + remoteAddr string + expectedCheckIp string + }{ + { + desc: "IPv4 address", + remoteAddr: "18.245.0.42", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 address", + remoteAddr: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Host and port", + remoteAddr: "18.245.0.42:6345", + expectedCheckIp: "18.245.0.42", + }, + { + desc: "IPv6 host and port", + remoteAddr: "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80", + expectedCheckIp: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + }, + { + desc: "Bad remote addr", + remoteAddr: "[127.0", + expectedCheckIp: "[127.0", + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + client := setupWithApiInspector(t, + func(r *Request) { + require.Equal(t, tc.expectedCheckIp, r.CheckIp) + }) + + sshEnv := sshenv.Env{RemoteAddr: tc.remoteAddr} + client.Verify(context.Background(), &commandargs.Shell{Env: sshEnv}, uploadPackAction, repo) + }) + } +} + type testResponse struct { body []byte status int @@ -260,3 +271,29 @@ return client } + +func setupWithApiInspector(t *testing.T, inspector func(*Request)) *Client { + t.Helper() + requests := []testserver.TestRequestHandler{ + { + Path: "/api/v4/internal/allowed", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + require.NoError(t, err) + + var requestBody *Request + err = json.Unmarshal(b, &requestBody) + require.NoError(t, err) + + inspector(requestBody) + }, + }, + } + + url := testserver.StartSocketHttpServer(t, requests) + + client, err := NewClient(&config.Config{GitlabUrl: url}) + require.NoError(t, err) + + return client +} diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -33,10 +33,9 @@ func NewGitalyCommand(cfg *config.Config, serviceName string, response *accessverifier.Response) *GitalyCommand { gc := gitaly.Command{ - ServiceName: serviceName, - Address: response.Gitaly.Address, - Token: response.Gitaly.Token, - DialSidechannel: response.Gitaly.UseSidechannel, + ServiceName: serviceName, + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, } return &GitalyCommand{Config: cfg, Response: response, Command: gc} diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -29,7 +29,7 @@ func TestRunGitalyCommand(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -46,14 +46,12 @@ func TestCachingOfGitalyConnections(t *testing.T) { ctx := context.Background() - cfg := &config.Config{} - cfg.GitalyClient.InitSidechannelRegistry(ctx) + cfg := newConfig() response := &accessverifier.Response{ Username: "user", Gitaly: accessverifier.Gitaly{ - Address: "tcp://localhost:9999", - Token: "token", - UseSidechannel: true, + Address: "tcp://localhost:9999", + Token: "token", }, } @@ -71,7 +69,7 @@ } func TestMissingGitalyAddress(t *testing.T) { - cmd := GitalyCommand{Config: &config.Config{}} + cmd := GitalyCommand{Config: newConfig()} err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, nil)) require.EqualError(t, err, "no gitaly_address given") @@ -79,7 +77,7 @@ func TestUnavailableGitalyErr(t *testing.T) { cmd := NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{Address: "tcp://localhost:9999"}, @@ -101,7 +99,7 @@ { name: "gitaly_feature_flags", gc: NewGitalyCommand( - &config.Config{}, + newConfig(), string(commandargs.UploadPack), &accessverifier.Response{ Gitaly: accessverifier.Gitaly{ @@ -209,3 +207,9 @@ }) } } + +func newConfig() *config.Config { + cfg := &config.Config{} + cfg.GitalyClient.InitSidechannelRegistry(context.Background()) + return cfg +} diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -22,6 +22,7 @@ sshdHitMaxSessionsName = "concurrent_limited_sessions_total" sshdSessionDurationSecondsName = "session_duration_seconds" sshdSessionEstablishedDurationSecondsName = "session_established_duration_seconds" + sshdCanceledSessionsName = "canceled_sessions" sliSshdSessionsTotalName = "gitlab_sli:shell_sshd_sessions:total" sliSshdSessionsErrorsTotalName = "gitlab_sli:shell_sshd_sessions:errors_total" @@ -76,6 +77,15 @@ }, ) + SshdCanceledSessions = promauto.NewCounter( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: sshdSubsystem, + Name: sshdCanceledSessionsName, + Help: "The number of canceled gitlab-sshd sessions.", + }, + ) + SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,32 +2,54 @@ import ( "context" + "time" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) +const KeepAliveMsg = "keepalive@openssh.com" + +var EOFTimeout = 10 * time.Second + type connection struct { + cfg *config.Config concurrentSessions *semaphore.Weighted remoteAddr string + sconn *ssh.ServerConn + maxSessions int64 } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) +type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error -func newConnection(maxSessions int64, remoteAddr string) *connection { +func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { + maxSessions := cfg.Server.ConcurrentSessionsLimit + return &connection{ + cfg: cfg, + maxSessions: maxSessions, concurrentSessions: semaphore.NewWeighted(maxSessions), remoteAddr: remoteAddr, + sconn: sconn, } } func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + if c.cfg.Server.ClientAliveIntervalSeconds > 0 { + ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) + defer ticker.Stop() + go c.sendKeepAliveMsg(ctx, ticker) + } + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { @@ -49,6 +71,10 @@ } go func() { + defer func(started time.Time) { + metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + }(time.Now()) + defer c.concurrentSessions.Release(1) // Prevent a panic in a single session from taking out the whole server @@ -58,8 +84,40 @@ } }() - handler(ctx, channel, requests) + metrics.SliSshdSessionsTotal.Inc() + err := handler(ctx, channel, requests) + if err != nil { + if grpcstatus.Convert(err).Code() == grpccodes.Canceled { + metrics.SshdCanceledSessions.Inc() + } else { + metrics.SliSshdSessionsErrorsTotal.Inc() + } + } + ctxlog.Info("connection: handle: done") }() } + + // When a connection has been prematurely closed we block execution until all concurrent sessions are released + // in order to allow Gitaly complete the operations and close all the channels gracefully. + // If it didn't happen within timeout, we unblock the execution + // Related issue: https://gitlab.com/gitlab-org/gitlab-shell/-/issues/563 + ctx, cancel := context.WithTimeout(ctx, EOFTimeout) + defer cancel() + c.concurrentSessions.Acquire(ctx, c.maxSessions) } + +func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + ctxlog.Debug("session: handleShell: send keepalive message to a client") + + c.sconn.SendRequest(KeepAliveMsg, true, nil) + } + } +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -3,10 +3,18 @@ import ( "context" "errors" + "sync" "testing" + "time" + "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + + "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) type rejectCall struct { @@ -47,8 +55,32 @@ return f.extraData } +type fakeConn struct { + ssh.Conn + + sentRequestName string + mu sync.Mutex +} + +func (f *fakeConn) SentRequestName() string { + f.mu.Lock() + defer f.mu.Unlock() + + return f.sentRequestName +} + +func (f *fakeConn) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) { + f.mu.Lock() + defer f.mu.Unlock() + + f.sentRequestName = name + + return true, nil, nil +} + func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - conn := newConnection(sessionsNum, "127.0.0.1:50000") + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} + conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -62,7 +94,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -100,8 +132,9 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test + return nil }) }() @@ -114,9 +147,10 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) + return nil }) require.True(t, channelHandled) @@ -132,8 +166,9 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) { + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true + return nil }) }() @@ -145,3 +180,46 @@ require.False(t, channelHandled) } + +func TestClientAliveInterval(t *testing.T) { + f := &fakeConn{} + + conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) + + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + + go conn.sendKeepAliveMsg(context.Background(), ticker) + + require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) +} + +func TestSessionsMetrics(t *testing.T) { + // Unfortunately, there is no working way to reset Counter (not CounterVec) + // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index + initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) + initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) + initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) + + newChannel := &fakeNewChannel{channelType: "session"} + + conn, chans := setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return errors.New("custom error") + }) + + require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return grpcstatus.Error(grpccodes.Canceled, "error") + }) + + require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) +} diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -22,7 +22,6 @@ channel ssh.Channel gitlabKeyId string remoteAddr string - success bool // State managed by the session execCmd string @@ -42,11 +41,12 @@ ExitStatus uint32 } -func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) { +func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) error { ctxlog := log.ContextLogger(ctx) ctxlog.Debug("session: handle: entering request loop") + var err error for req := range requests { sessionLog := ctxlog.WithFields(log.Fields{ "bytesize": len(req.Payload), @@ -58,12 +58,14 @@ var shouldContinue bool switch req.Type { case "env": - shouldContinue = s.handleEnv(ctx, req) + shouldContinue, err = s.handleEnv(ctx, req) case "exec": - shouldContinue = s.handleExec(ctx, req) + shouldContinue, err = s.handleExec(ctx, req) case "shell": shouldContinue = false - s.exit(ctx, s.handleShell(ctx, req)) + var status uint32 + status, err = s.handleShell(ctx, req) + s.exit(ctx, status) default: // Ignore unknown requests but don't terminate the session shouldContinue = true @@ -84,15 +86,17 @@ } ctxlog.Debug("session: handle: exiting request loop") + + return err } -func (s *session) handleEnv(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error) { var accepted bool var envRequest envRequest if err := ssh.Unmarshal(req.Payload, &envRequest); err != nil { log.ContextLogger(ctx).WithError(err).Error("session: handleEnv: failed to unmarshal request") - return false + return false, err } switch envRequest.Name { @@ -113,23 +117,24 @@ ctx, log.Fields{"accepted": accepted, "env_request": envRequest}, ).Debug("session: handleEnv: processed") - return true + return true, nil } -func (s *session) handleExec(ctx context.Context, req *ssh.Request) bool { +func (s *session) handleExec(ctx context.Context, req *ssh.Request) (bool, error) { var execRequest execRequest if err := ssh.Unmarshal(req.Payload, &execRequest); err != nil { - return false + return false, err } s.execCmd = execRequest.Command - s.exit(ctx, s.handleShell(ctx, req)) + status, err := s.handleShell(ctx, req) + s.exit(ctx, status) - return false + return false, err } -func (s *session) handleShell(ctx context.Context, req *ssh.Request) uint32 { +func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, error) { ctxlog := log.ContextLogger(ctx) if req.WantReply { @@ -157,7 +162,7 @@ s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) } s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) - return 128 + return 128, err } cmdName := reflect.TypeOf(cmd).String() @@ -165,12 +170,12 @@ if err := cmd.Execute(ctx); err != nil { s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) - return 1 + return 1, err } ctxlog.Info("session: handleShell: command executed successfully") - return 0 + return 0, nil } func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { @@ -183,8 +188,6 @@ log.WithContextFields(ctx, log.Fields{"exit_status": status}).Info("session: exit: exiting") req := exitStatusReq{ExitStatus: status} - s.success = status == 0 - s.channel.CloseWrite() s.channel.SendRequest("exit-status", false, ssh.Marshal(req)) } diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -3,6 +3,7 @@ import ( "bytes" "context" + "errors" "io" "net/http" "testing" @@ -60,22 +61,26 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedProtocolVersion string expectedResult bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Name of type envRequest"), expectedProtocolVersion: "1", expectedResult: false, }, { desc: "valid payload", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "2", expectedResult: true, }, { desc: "valid payload with forbidden env var", payload: ssh.Marshal(envRequest{Name: "GIT_PROTOCOL_ENV", Value: "2"}), + expectedErr: nil, expectedProtocolVersion: "1", expectedResult: true, }, @@ -86,8 +91,11 @@ s := &session{gitProtocolVersion: "1"} r := &ssh.Request{Payload: tc.payload} - require.Equal(t, s.handleEnv(context.Background(), r), tc.expectedResult) - require.Equal(t, s.gitProtocolVersion, tc.expectedProtocolVersion) + shouldContinue, err := s.handleEnv(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedResult, shouldContinue) + require.Equal(t, tc.expectedProtocolVersion, s.gitProtocolVersion) }) } } @@ -96,23 +104,24 @@ testCases := []struct { desc string payload []byte + expectedErr error expectedExecCmd string sentRequestName string sentRequestPayload []byte - success bool }{ { desc: "invalid payload", payload: []byte("invalid"), + expectedErr: errors.New("ssh: unmarshal error for field Command of type execRequest"), expectedExecCmd: "", sentRequestName: "", }, { desc: "valid payload", payload: ssh.Marshal(execRequest{Command: "discover"}), + expectedErr: nil, expectedExecCmd: "discover", sentRequestName: "exit-status", sentRequestPayload: ssh.Marshal(exitStatusReq{ExitStatus: 0}), - success: true, }, } @@ -129,47 +138,53 @@ } r := &ssh.Request{Payload: tc.payload} - require.Equal(t, false, s.handleExec(context.Background(), r)) + shouldContinue, err := s.handleExec(context.Background(), r) + + require.Equal(t, tc.expectedErr, err) + require.Equal(t, false, shouldContinue) require.Equal(t, tc.sentRequestName, f.sentRequestName) require.Equal(t, tc.sentRequestPayload, f.sentRequestPayload) - require.Equal(t, tc.success, s.success) }) } } func TestHandleShell(t *testing.T) { testCases := []struct { - desc string - cmd string - errMsg string - gitlabKeyId string - expectedExitCode uint32 - success bool + desc string + cmd string + errMsg string + gitlabKeyId string + expectedErrString string + expectedExitCode uint32 }{ { - desc: "fails to parse command", - cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "fails to parse command", + cmd: `\`, + errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + gitlabKeyId: "root", + expectedErrString: "Invalid SSH command: invalid command line string", + expectedExitCode: 128, }, { - desc: "specified command is unknown", - cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", - gitlabKeyId: "root", - expectedExitCode: 128, + desc: "specified command is unknown", + cmd: "unknown-command", + errMsg: "Unknown command: unknown-command\n", + gitlabKeyId: "root", + expectedErrString: "Disallowed command", + expectedExitCode: 128, }, { - desc: "fails to parse command", - cmd: "discover", - gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", - expectedExitCode: 1, + desc: "fails to parse command", + cmd: "discover", + gitlabKeyId: "", + errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + expectedErrString: "Failed to get username: who='' is invalid", + expectedExitCode: 1, }, { - desc: "fails to parse command", - cmd: "discover", - errMsg: "", - gitlabKeyId: "root", - expectedExitCode: 0, + desc: "fails to parse command", + cmd: "discover", + errMsg: "", + gitlabKeyId: "root", + expectedErrString: "", + expectedExitCode: 0, }, } @@ -186,7 +201,13 @@ } r := &ssh.Request{} - require.Equal(t, tc.expectedExitCode, s.handleShell(context.Background(), r)) + exitCode, err := s.handleShell(context.Background(), r) + + if tc.expectedErrString != "" { + require.Equal(t, tc.expectedErrString, err.Error()) + } + + require.Equal(t, tc.expectedExitCode, exitCode) require.Equal(t, tc.errMsg, out.String()) }) } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -5,6 +5,7 @@ "fmt" "net" "net/http" + "strings" "sync" "time" @@ -32,7 +33,7 @@ Config *config.Config status status - statusMu sync.Mutex + statusMu sync.RWMutex wg sync.WaitGroup listener net.Listener serverConfig *serverConfig @@ -95,7 +96,7 @@ if s.Config.Server.ProxyProtocol { sshListener = &proxyproto.Listener{ Listener: sshListener, - Policy: unconditionalRequirePolicy, + Policy: s.requirePolicy, ReadHeaderTimeout: ProxyHeaderTimeout, } @@ -139,26 +140,15 @@ } func (s *Server) getStatus() status { - s.statusMu.Lock() - defer s.statusMu.Unlock() + s.statusMu.RLock() + defer s.statusMu.RUnlock() return s.status } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { - success := false - metrics.SshdConnectionsInFlight.Inc() - started := time.Now() - defer func() { - metrics.SshdConnectionsInFlight.Dec() - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) - - metrics.SliSshdSessionsTotal.Inc() - if !success { - metrics.SliSshdSessionsErrorsTotal.Inc() - } - }() + defer metrics.SshdConnectionsInFlight.Dec() remoteAddr := nconn.RemoteAddr().String() @@ -174,22 +164,24 @@ defer func() { if err := recover(); err != nil { ctxlog.Warn("panic handling session") + + metrics.SliSshdSessionsErrorsTotal.Inc() } }() ctxlog.Info("server: handleConn: start") - sconn, chans, reqs, err := s.initSSHConnection(ctx, nconn) + sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - ctxlog.WithError(err).Error("server: handleConn: failed to initialize SSH connection") + ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") return } - go ssh.DiscardRequests(reqs) + started := time.Now() var establishSessionDuration float64 - conn := newConnection(s.Config.Server.ConcurrentSessionsLimit, remoteAddr) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) { + conn := newConnection(s.Config, remoteAddr, sconn) + conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { establishSessionDuration = time.Since(started).Seconds() metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) @@ -200,31 +192,28 @@ remoteAddr: remoteAddr, } - session.handle(ctx, requests) - - success = session.success + return session.handle(ctx, requests) }) + reason := sconn.Wait() ctxlog.WithFields(log.Fields{ "duration_s": time.Since(started).Seconds(), "establish_session_duration_s": establishSessionDuration, + "reason": reason, }).Info("server: handleConn: done") } -func (s *Server) initSSHConnection(ctx context.Context, nconn net.Conn) (sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request, err error) { - timer := time.AfterFunc(s.Config.Server.LoginGraceTime(), func() { - nconn.Close() - }) - defer func() { - // If time.Stop() equals false, that means that AfterFunc has been executed - if !timer.Stop() { - err = fmt.Errorf("initSSHConnection: ssh handshake timeout of %v", s.Config.Server.LoginGraceTime()) - } - }() - - return ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) +func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { + // Set the Policy value based on config + // Values are taken from https://github.com/pires/go-proxyproto/blob/195fedcfbfc1be163f3a0d507fac1709e9d81fed/policy.go#L20 + switch strings.ToLower(s.Config.Server.ProxyPolicy) { + case "require": + return proxyproto.REQUIRE, nil + case "ignore": + return proxyproto.IGNORE, nil + case "reject": + return proxyproto.REJECT, nil + default: + return proxyproto.USE, nil + } } - -func unconditionalRequirePolicy(_ net.Addr) (proxyproto.Policy, error) { - return proxyproto.REQUIRE, nil -} diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -11,6 +11,7 @@ "testing" "time" + "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" @@ -49,15 +50,101 @@ } func TestListenAndServeRejectsPlainConnectionsWhenProxyProtocolEnabled(t *testing.T) { - setupServerWithProxyProtocolEnabled(t) + target, err := net.ResolveTCPAddr("tcp", serverUrl) + require.NoError(t, err) - client, err := ssh.Dial("tcp", serverUrl, clientConfig(t)) - if client != nil { - client.Close() + header := &proxyproto.Header{ + Version: 2, + Command: proxyproto.PROXY, + TransportProtocol: proxyproto.TCPv4, + SourceAddr: &net.TCPAddr{ + IP: net.ParseIP("10.1.1.1"), + Port: 1000, + }, + DestinationAddr: target, } - require.Error(t, err, "Expected plain SSH request to be failed") - require.Regexp(t, "ssh: handshake failed", err.Error()) + testCases := []struct { + desc string + proxyPolicy string + header *proxyproto.Header + isRejected bool + }{ + { + desc: "USE (default) without a header", + proxyPolicy: "", + header: nil, + isRejected: false, + }, + { + desc: "USE (default) with a header", + proxyPolicy: "", + header: header, + isRejected: false, + }, + { + desc: "REQUIRE without a header", + proxyPolicy: "require", + header: nil, + isRejected: true, + }, + { + desc: "REQUIRE with a header", + proxyPolicy: "require", + header: header, + isRejected: false, + }, + { + desc: "REJECT without a header", + proxyPolicy: "reject", + header: nil, + isRejected: false, + }, + { + desc: "REJECT with a header", + proxyPolicy: "reject", + header: header, + isRejected: true, + }, + { + desc: "IGNORE without a header", + proxyPolicy: "ignore", + header: nil, + isRejected: false, + }, + { + desc: "IGNORE with a header", + proxyPolicy: "ignore", + header: header, + isRejected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true, ProxyPolicy: tc.proxyPolicy}}) + + conn, err := net.DialTCP("tcp", nil, target) + require.NoError(t, err) + + if tc.header != nil { + _, err := header.WriteTo(conn) + require.NoError(t, err) + } + + sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + if sshConn != nil { + sshConn.Close() + } + + if tc.isRejected { + require.Error(t, err, "Expected plain SSH request to be failed") + require.Regexp(t, "ssh: handshake failed", err.Error()) + } else { + require.NoError(t, err) + } + }) + } } func TestCorrelationId(t *testing.T) { @@ -135,45 +222,12 @@ require.Nil(t, s.Shutdown()) } -func TestLoginGraceTime(t *testing.T) { - s := setupServer(t) - - unauthenticatedRequestStatus := make(chan string) - completed := make(chan bool) - - clientCfg := clientConfig(t) - clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { - unauthenticatedRequestStatus <- "authentication-started" - <-completed // Wait infinitely - - return nil - } - - go func() { - // Start an SSH connection that never ends - ssh.Dial("tcp", serverUrl, clientCfg) - }() - - require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) - - // Verify that the server shutdowns instantly without waiting for any connection to execute - // That means that the server doesn't have any connections to wait for - require.NoError(t, s.Shutdown()) - verifyStatus(t, s, StatusClosed) -} - func setupServer(t *testing.T) *Server { t.Helper() return setupServerWithConfig(t, nil) } -func setupServerWithProxyProtocolEnabled(t *testing.T) *Server { - t.Helper() - - return setupServerWithConfig(t, &config.Config{Server: config.ServerConfig{ProxyProtocol: true}}) -} - func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() @@ -211,7 +265,7 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.LoginGraceTimeSeconds = 1 + cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -81,14 +81,6 @@ } func BuildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, false) -} - -func BuildAllowedWithGitalyHandlersWithSidechannel(t *testing.T, gitalyAddress string) []testserver.TestRequestHandler { - return buildAllowedWithGitalyHandlers(t, gitalyAddress, true) -} - -func buildAllowedWithGitalyHandlers(t *testing.T, gitalyAddress string, useSidechannel bool) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/allowed", @@ -116,9 +108,6 @@ }, }, } - if useSidechannel { - body["gitaly"].(map[string]interface{})["use_sidechannel"] = true - } require.NoError(t, json.NewEncoder(w).Encode(body)) }, }, diff --git a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json b/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json deleted file mode 100644 --- a/internal/testhelper/testdata/testroot/responses/allowed_sidechannel.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "status": true, - "gl_repository": "project-26", - "gl_project_path": "group/private", - "gl_id": "user-1", - "gl_username": "root", - "git_config_options": ["option"], - "gitaly": { - "repository": { - "storage_name": "default", - "relative_path": "@hashed/5f/9c/5f9c4ab08cac7457e9111a30e4664920607ea2c115a1433d7be98e97e64244ca.git", - "git_object_directory": "path/to/git_object_directory", - "git_alternate_object_directories": ["path/to/git_alternate_object_directory"], - "gl_repository": "project-26", - "gl_project_path": "group/private" - }, - "address": "unix:gitaly.socket", - "token": "token", - "use_sidechannel": true - }, - "git_protocol": "protocol", - "gl_console_messages": ["console", "message"] -} # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1663967415 -7200 # Fri Sep 23 23:10:15 2022 +0200 # Branch heptapod # Node ID a0e3a223b1cf8987f61c0d293652171787290986 # Parent 7b25801e4afc9c3d6e7016fd220cce310db6bd1d # Parent 0ea5c918a3bf8342b43bb8ec5e616bec564f41f4 Merged upstream v14.3.1 into Heptapod Shell diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ tags tmp/* vendor +.DS_Store diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ - '/ci/danger-review.yml' variables: - DOCKER_VERSION: "20.10.3" + DOCKER_VERSION: "20.10.15" workflow: rules: &workflow_rules diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.3.1 + +- Exclude API errors from error rate !630 + v14.3.0 - Remove deprecated bundler-audit !626 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.3.0 +14.3.1 diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -37,6 +37,14 @@ userAgent string } +type ApiError struct { + Msg string +} + +func (e *ApiError) Error() string { + return e.Msg +} + func NewGitlabNetClient( user, password, @@ -101,9 +109,9 @@ parsedResponse := &ErrorResponse{} if err := json.NewDecoder(resp.Body).Decode(parsedResponse); err != nil { - return fmt.Errorf("Internal API error (%v)", resp.StatusCode) + return &ApiError{fmt.Sprintf("Internal API error (%v)", resp.StatusCode)} } else { - return fmt.Errorf(parsedResponse.Message) + return &ApiError{parsedResponse.Message} } } @@ -157,7 +165,7 @@ if err != nil { logger.WithError(err).Error("Internal API unreachable") - return nil, fmt.Errorf("Internal API unreachable") + return nil, &ApiError{"Internal API unreachable"} } if response != nil { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,6 +2,7 @@ import ( "context" + "errors" "time" "golang.org/x/crypto/ssh" @@ -9,6 +10,7 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" @@ -90,7 +92,10 @@ if grpcstatus.Convert(err).Code() == grpccodes.Canceled { metrics.SshdCanceledSessions.Inc() } else { - metrics.SliSshdSessionsErrorsTotal.Inc() + var apiError *client.ApiError + if !errors.As(err, &apiError) { + metrics.SliSshdSessionsErrorsTotal.Inc() + } } } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -13,6 +13,7 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -222,4 +223,14 @@ require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return &client.ApiError{"api error"} + }) + + require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) } # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1663967468 -7200 # Fri Sep 23 23:11:08 2022 +0200 # Branch heptapod # Node ID 61f29699614da28ec795cec912a75f398df84af3 # Parent a0e3a223b1cf8987f61c0d293652171787290986 Updated Heptapod version files diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.3.2 + +- Bump to upstream GitLab Shell v14.3.1 + ## 14.3.1 - Filled in `HEPTAPOD_VERSION` (had been forgotten in 14.0 through diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.3.1 +14.3.2 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1663967912 -7200 # Fri Sep 23 23:18:32 2022 +0200 # Branch heptapod # Node ID c0d78aade4f306a4f575ab4a56d488428690f485 # Parent 61f29699614da28ec795cec912a75f398df84af3 Added tag heptapod-14.3.2 for changeset 61f29699614d diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -44,3 +44,4 @@ 98d781e90b1bb472b9c37ad5fbdbed541e1457c5 heptapod-14.2.0 7e62e4be19def9c1f1773e326480a9429210bb8d heptapod-14.3.0 fca0cc645e5bbe898f18befe0f31f51f091db81b heptapod-14.3.1 +61f29699614da28ec795cec912a75f398df84af3 heptapod-14.3.2 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664039691 -7200 # Sat Sep 24 19:14:51 2022 +0200 # Branch heptapod # Node ID 8696661a67a6e7816fca8066dcbdc66b261feb5b # Parent c0d78aade4f306a4f575ab4a56d488428690f485 # Parent b5a0002e1a3887d92469d212c04d461bda32c6ef Merged upstream GitLab Shell v14.4.0 into Heptapod Shell and filled-in Heptapod version files diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +v14.4.0 + +- Allow configuring SSH server algorithms !633 +- Update gitlab-org/golang-crypto module version !632 + v14.3.1 - Exclude API errors from error rate !630 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.4.0 + +- Bump to upstream GitLab Shell v14.4.0 + ## 14.3.2 - Bump to upstream GitLab Shell v14.3.1 diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.3.2 +14.4.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.3.1 +14.4.0 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -100,6 +100,12 @@ readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" + # Specifies the available message authentication code algorithms that are used for protecting data integrity + macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] + # Specifies the available Key Exchange algorithms + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] + # Specified the ciphers allowed + ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -81,4 +81,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) -replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -888,8 +888,8 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac h1:qNUzqBTbEGGjF5Fp0NWz3rNmqamwchxM+QKUZYeOS1c= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -38,6 +38,9 @@ ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` + MACs []string `yaml:"macs"` + KexAlgorithms []string `yaml:"kex_algorithms"` + Ciphers []string `yaml:"ciphers"` } type HttpSettingsConfig struct { diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -16,6 +16,14 @@ "gitlab.com/gitlab-org/labkit/log" ) +var supportedMACs = []string{ + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1", +} + type serverConfig struct { cfg *config.Config hostKeys []ssh.Signer @@ -86,6 +94,20 @@ }, } + if len(s.cfg.Server.MACs) > 0 { + sshCfg.MACs = s.cfg.Server.MACs + } else { + sshCfg.MACs = supportedMACs + } + + if len(s.cfg.Server.KexAlgorithms) > 0 { + sshCfg.KeyExchanges = s.cfg.Server.KexAlgorithms + } + + if len(s.cfg.Server.Ciphers) > 0 { + sshCfg.Ciphers = s.cfg.Server.Ciphers + } + for _, key := range s.hostKeys { sshCfg.AddHostKey(key) } diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -80,6 +80,67 @@ } } +func TestDefaultAlgorithms(t *testing.T) { + srvCfg := &serverConfig{cfg: &config.Config{}} + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + require.Nil(t, sshServerConfig.KeyExchanges) + require.Nil(t, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + + defaultKeyExchanges := []string{ + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha256", + "diffie-hellman-group14-sha1", + } + require.Equal(t, defaultKeyExchanges, sshServerConfig.KeyExchanges) + + defaultCiphers := []string{ + "aes128-gcm@openssh.com", + "chacha20-poly1305@openssh.com", + "aes256-gcm@openssh.com", + "aes128-ctr", + "aes192-ctr", + "aes256-ctr", + } + require.Equal(t, defaultCiphers, sshServerConfig.Ciphers) +} + +func TestCustomAlgorithms(t *testing.T) { + customMACs := []string{"hmac-sha2-512-etm@openssh.com"} + customKexAlgos := []string{"curve25519-sha256"} + customCiphers := []string{"aes256-gcm@openssh.com"} + + srvCfg := &serverConfig{ + cfg: &config.Config{ + Server: config.ServerConfig{ + MACs: customMACs, + KexAlgorithms: customKexAlgos, + Ciphers: customCiphers, + }, + }, + } + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) +} + func rsaPublicKey(t *testing.T) ssh.PublicKey { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664040146 -7200 # Sat Sep 24 19:22:26 2022 +0200 # Branch heptapod # Node ID e8040b2b35ce6f600ac4d9bb0ffd03e5444f3402 # Parent 8696661a67a6e7816fca8066dcbdc66b261feb5b Added tag heptapod-14.4.0 for changeset 8696661a67a6 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -45,3 +45,4 @@ 7e62e4be19def9c1f1773e326480a9429210bb8d heptapod-14.3.0 fca0cc645e5bbe898f18befe0f31f51f091db81b heptapod-14.3.1 61f29699614da28ec795cec912a75f398df84af3 heptapod-14.3.2 +8696661a67a6e7816fca8066dcbdc66b261feb5b heptapod-14.4.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664446728 -7200 # Thu Sep 29 12:18:48 2022 +0200 # Branch heptapod # Node ID aaebb02398004cb60c56d98824084bf9a2c17073 # Parent e8040b2b35ce6f600ac4d9bb0ffd03e5444f3402 # Parent c1e06d31b6ef53cea0f58afa656b99c22fd38743 Merged upstream GitLab Shell v14.5.0 and updated Heptapod version files accordingly diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.5.0 + +- Make ProxyHeaderTimeout configurable !635 + v14.4.0 - Allow configuring SSH server algorithms !633 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -14,6 +14,10 @@ - Bump to upstream GitLab Shell v14.4.0 +## 14.5.0 + +- Bump to upstream GitLab Shell v14.5.0 + ## 14.3.2 - Bump to upstream GitLab Shell v14.3.1 diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.4.0 +14.5.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.4.0 +14.5.0 diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -99,11 +99,12 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + gracePeriod := time.Duration(cfg.Server.GracePeriod) + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": gracePeriod.Seconds(), "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() - <-time.After(cfg.Server.GracePeriod()) + <-time.After(gracePeriod) cancel() diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -96,6 +96,8 @@ client_alive_interval: 15 # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. grace_period: 10 + # A short timeout to decide to abort the connection if the protocol header is not seen within it. Defaults to 500ms + proxy_header_timeout: 500ms # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -27,20 +27,23 @@ defaultHgrcPath string = "/opt/gitlab/etc/docker.hgrc:/etc/gitlab/heptapod.hgrc" ) +type yamlDuration time.Duration + type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - ProxyPolicy string `yaml:"proxy_policy,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` - MACs []string `yaml:"macs"` - KexAlgorithms []string `yaml:"kex_algorithms"` - Ciphers []string `yaml:"ciphers"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveInterval yamlDuration `yaml:"client_alive_interval,omitempty"` + GracePeriod yamlDuration `yaml:"grace_period"` + ProxyHeaderTimeout yamlDuration `yaml:"proxy_header_timeout"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` + MACs []string `yaml:"macs"` + KexAlgorithms []string `yaml:"kex_algorithms"` + Ciphers []string `yaml:"ciphers"` } type HttpSettingsConfig struct { @@ -106,13 +109,14 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ClientAliveIntervalSeconds: 15, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriod: yamlDuration(10 * time.Second), + ClientAliveInterval: yamlDuration(15 * time.Second), + ProxyHeaderTimeout: yamlDuration(500 * time.Millisecond), + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -121,12 +125,15 @@ } ) -func (sc *ServerConfig) ClientAliveInterval() time.Duration { - return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second -} +func (d *yamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { + var intDuration int + if err := unmarshal(&intDuration); err != nil { + return unmarshal((*time.Duration)(d)) + } -func (sc *ServerConfig) GracePeriod() time.Duration { - return time.Duration(sc.GracePeriodSeconds) * time.Second + *d = yamlDuration(time.Duration(intDuration) * time.Second) + + return nil } func (c *Config) ApplyGlobalState() { diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -3,9 +3,11 @@ import ( "os" "testing" + "time" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" + yaml "gopkg.in/yaml.v2" "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" @@ -58,3 +60,40 @@ require.Equal(t, expectedMetricNames, actualNames) } + +func TestNewFromDir(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + cfg, err := NewFromDir(testhelper.TestRoot) + require.NoError(t, err) + + require.Equal(t, 10*time.Second, time.Duration(cfg.Server.GracePeriod)) + require.Equal(t, 1*time.Minute, time.Duration(cfg.Server.ClientAliveInterval)) + require.Equal(t, 500*time.Millisecond, time.Duration(cfg.Server.ProxyHeaderTimeout)) +} + +func TestYAMLDuration(t *testing.T) { + testCases := []struct { + desc string + data string + duration time.Duration + }{ + {"seconds assumed by default", "duration: 10", 10 * time.Second}, + {"milliseconds are parsed", "duration: 500ms", 500 * time.Millisecond}, + {"minutes are parsed", "duration: 1m", 1 * time.Minute}, + } + + type durationCfg struct { + Duration yamlDuration `yaml:"duration"` + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + var cfg durationCfg + err := yaml.Unmarshal([]byte(tc.data), &cfg) + require.NoError(t, err) + + require.Equal(t, tc.duration, time.Duration(cfg.Duration)) + }) + } +} diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -46,8 +46,8 @@ func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) - if c.cfg.Server.ClientAliveIntervalSeconds > 0 { - ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) + if c.cfg.Server.ClientAliveInterval > 0 { + ticker := time.NewTicker(time.Duration(c.cfg.Server.ClientAliveInterval)) defer ticker.Stop() go c.sendKeepAliveMsg(ctx, ticker) } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -80,7 +80,7 @@ } func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum}} conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) chans := make(chan ssh.NewChannel, 1) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -26,7 +26,6 @@ StatusReady StatusOnShutdown StatusClosed - ProxyHeaderTimeout = 90 * time.Second ) type Server struct { @@ -97,7 +96,7 @@ sshListener = &proxyproto.Listener{ Listener: sshListener, Policy: s.requirePolicy, - ReadHeaderTimeout: ProxyHeaderTimeout, + ReadHeaderTimeout: time.Duration(s.Config.Server.ProxyHeaderTimeout), } log.ContextLogger(ctx).Info("Proxy protocol is enabled") diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -265,7 +265,6 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) diff --git a/internal/testhelper/testdata/testroot/config.yml b/internal/testhelper/testdata/testroot/config.yml --- a/internal/testhelper/testdata/testroot/config.yml +++ b/internal/testhelper/testdata/testroot/config.yml @@ -0,0 +1,4 @@ +sshd: + grace_period: 10 + client_alive_interval: 1m + proxy_header_timeout: 500ms # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664447010 -7200 # Thu Sep 29 12:23:30 2022 +0200 # Branch heptapod # Node ID 5057028abd0982de557cdf6395653cb88a5e96e5 # Parent aaebb02398004cb60c56d98824084bf9a2c17073 Added tag heptapod-14.5.0 for changeset aaebb0239800 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -46,3 +46,4 @@ fca0cc645e5bbe898f18befe0f31f51f091db81b heptapod-14.3.1 61f29699614da28ec795cec912a75f398df84af3 heptapod-14.3.2 8696661a67a6e7816fca8066dcbdc66b261feb5b heptapod-14.4.0 +aaebb02398004cb60c56d98824084bf9a2c17073 heptapod-14.5.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664536178 -7200 # Fri Sep 30 13:09:38 2022 +0200 # Branch heptapod # Node ID 69c79e2a7c7cd53de504e610f85e0cc61bf184bd # Parent 5057028abd0982de557cdf6395653cb88a5e96e5 # Parent 363bcf081e7da20b57c13161133c718c3aa63c4c Merged upstream v14.6.0 into Heptapod Shell and updated Heptapod version files diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +v14.6.0 + +- Exclude Gitaly unavailable error from error rate !641 +- Downgrade auth EOF messages from warning to debug !641 +- Display constistently in gitlab-sshd and gitlab-shell !641 +- Downgrade host key mismatch messages from warning to debug !639 +- Introduce a GitLab-SSHD server version during handshake !640 +- Narrow supported kex algorithms !638 + v14.5.0 - Make ProxyHeaderTimeout configurable !635 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,14 +10,18 @@ The corresponding tag is heptapod-x.y.z -## 14.4.0 +## 14.6.0 -- Bump to upstream GitLab Shell v14.4.0 +- Bump to upstream GitLab Shell v14.6.0 ## 14.5.0 - Bump to upstream GitLab Shell v14.5.0 +## 14.4.0 + +- Bump to upstream GitLab Shell v14.4.0 + ## 14.3.2 - Bump to upstream GitLab Shell v14.3.1 diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.5.0 +14.6.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.5.0 +14.6.0 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -105,7 +105,7 @@ # Specifies the available message authentication code algorithms that are used for protecting data integrity macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] # Specifies the available Key Exchange algorithms - kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256] # Specified the ciphers allowed ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.1 + github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 gitlab.com/gitlab-org/labkit v1.14.0 @@ -59,7 +60,6 @@ github.com/prometheus/procfs v0.7.3 // indirect github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect github.com/shirou/gopsutil/v3 v3.21.2 // indirect - github.com/sirupsen/logrus v1.8.1 // 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 diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -41,7 +41,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:10] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -49,7 +49,6 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", - "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -58,13 +58,11 @@ exitStatus, err := handler(childCtx, conn) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { - ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") - return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + if grpcstatus.Code(err) == grpccodes.Unavailable { + return grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.") } - - ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") } return err diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -84,10 +84,8 @@ }, ) - expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") - err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) - - require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, grpcstatus.Error(grpccodes.Unavailable, "error"))) + require.Equal(t, err, grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.")) } func TestRunGitalyCommandMetadata(t *testing.T) { diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -77,15 +77,6 @@ }, ) - SshdCanceledSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: sshdCanceledSessionsName, - Help: "The number of canceled gitlab-sshd sessions.", - }, - ) - SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -89,14 +89,7 @@ metrics.SliSshdSessionsTotal.Inc() err := handler(ctx, channel, requests) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Canceled { - metrics.SshdCanceledSessions.Inc() - } else { - var apiError *client.ApiError - if !errors.As(err, &apiError) { - metrics.SliSshdSessionsErrorsTotal.Inc() - } - } + c.trackError(err) } ctxlog.Info("connection: handle: done") @@ -126,3 +119,17 @@ } } } + +func (c *connection) trackError(err error) { + var apiError *client.ApiError + if errors.As(err, &apiError) { + return + } + + grpcCode := grpcstatus.Code(err) + if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { + return + } + + metrics.SliSshdSessionsErrorsTotal.Inc() +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -200,7 +200,6 @@ // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) - initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) newChannel := &fakeNewChannel{channelType: "session"} @@ -212,17 +211,15 @@ require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) conn, chans = setup(1, newChannel) conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { close(chans) - return grpcstatus.Error(grpccodes.Canceled, "error") + return grpcstatus.Error(grpccodes.Canceled, "canceled") }) require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) conn, chans = setup(1, newChannel) conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { @@ -232,5 +229,13 @@ require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + + conn, chans = setup(1, newChannel) + conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return grpcstatus.Error(grpccodes.Unavailable, "unavailable") + }) + + require.InDelta(t, initialSessionsTotal+4, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) } diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -16,13 +16,24 @@ "gitlab.com/gitlab-org/labkit/log" ) -var supportedMACs = []string{ - "hmac-sha2-256-etm@openssh.com", - "hmac-sha2-512-etm@openssh.com", - "hmac-sha2-256", - "hmac-sha2-512", - "hmac-sha1", -} +var ( + supportedMACs = []string{ + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1", + } + + supportedKeyExchanges = []string{ + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha256", + } +) type serverConfig struct { cfg *config.Config @@ -92,6 +103,7 @@ }, }, nil }, + ServerVersion: "SSH-2.0-GitLab-SSHD", } if len(s.cfg.Server.MACs) > 0 { @@ -102,6 +114,8 @@ if len(s.cfg.Server.KexAlgorithms) > 0 { sshCfg.KeyExchanges = s.cfg.Server.KexAlgorithms + } else { + sshCfg.KeyExchanges = supportedKeyExchanges } if len(s.cfg.Server.Ciphers) > 0 { diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -85,23 +85,13 @@ sshServerConfig := srvCfg.get(context.Background()) require.Equal(t, supportedMACs, sshServerConfig.MACs) - require.Nil(t, sshServerConfig.KeyExchanges) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) require.Nil(t, sshServerConfig.Ciphers) sshServerConfig.SetDefaults() require.Equal(t, supportedMACs, sshServerConfig.MACs) - - defaultKeyExchanges := []string{ - "curve25519-sha256", - "curve25519-sha256@libssh.org", - "ecdh-sha2-nistp256", - "ecdh-sha2-nistp384", - "ecdh-sha2-nistp521", - "diffie-hellman-group14-sha256", - "diffie-hellman-group14-sha1", - } - require.Equal(t, defaultKeyExchanges, sshServerConfig.KeyExchanges) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) defaultCiphers := []string{ "aes128-gcm@openssh.com", diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -8,11 +8,14 @@ "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/console" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -158,10 +161,12 @@ cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) if err != nil { - if !errors.Is(err, disallowedcommand.Error) { - s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) + if errors.Is(err, disallowedcommand.Error) { + s.toStderr(ctx, "ERROR: Unknown command: %v\n", s.execCmd) + } else { + s.toStderr(ctx, "ERROR: Failed to parse command: %v\n", err.Error()) } - s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) + return 128, err } @@ -169,7 +174,11 @@ ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") if err := cmd.Execute(ctx); err != nil { - s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) + grpcStatus := grpcstatus.Convert(err) + if grpcStatus.Code() != grpccodes.Internal { + s.toStderr(ctx, "ERROR: %v\n", grpcStatus.Message()) + } + return 1, err } @@ -181,7 +190,7 @@ func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { out := fmt.Sprintf(format, args...) log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") - fmt.Fprint(s.channel.Stderr(), out) + console.DisplayWarningMessage(out, s.channel.Stderr()) } func (s *session) exit(ctx context.Context, status uint32) { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -13,6 +13,7 @@ "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/internal/console" ) type fakeChannel struct { @@ -160,14 +161,14 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + errMsg: "ERROR: Failed to parse command: Invalid SSH command: invalid command line string\n", gitlabKeyId: "root", expectedErrString: "Invalid SSH command: invalid command line string", expectedExitCode: 128, }, { desc: "specified command is unknown", cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", + errMsg: "ERROR: Unknown command: unknown-command\n", gitlabKeyId: "root", expectedErrString: "Disallowed command", expectedExitCode: 128, @@ -175,7 +176,7 @@ desc: "fails to parse command", cmd: "discover", gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + errMsg: "ERROR: Failed to get username: who='' is invalid\n", expectedErrString: "Failed to get username: who='' is invalid", expectedExitCode: 1, }, { @@ -208,7 +209,14 @@ } require.Equal(t, tc.expectedExitCode, exitCode) - require.Equal(t, tc.errMsg, out.String()) + + formattedErr := &bytes.Buffer{} + if tc.errMsg != "" { + console.DisplayWarningMessage(tc.errMsg, formattedErr) + require.Equal(t, formattedErr.String(), out.String()) + } else { + require.Equal(t, tc.errMsg, out.String()) + } }) } } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,6 +10,7 @@ "time" "github.com/pires/go-proxyproto" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -38,6 +39,18 @@ serverConfig *serverConfig } +func logSSHInitError(ctxlog *logrus.Entry, err error) { + msg := "server: handleConn: failed to initialize SSH connection" + + logger := ctxlog.WithError(err) + + if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { + logger.Debug(msg) + } else { + logger.Warn(msg) + } +} + func NewServer(cfg *config.Config) (*Server, error) { serverConfig, err := newServerConfig(cfg) if err != nil { @@ -168,11 +181,11 @@ } }() - ctxlog.Info("server: handleConn: start") + ctxlog.Debug("server: handleConn: start") sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) if err != nil { - ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") + logSSHInitError(ctxlog, err) return } go ssh.DiscardRequests(reqs) # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664543160 -7200 # Fri Sep 30 15:06:00 2022 +0200 # Branch heptapod # Node ID 43b06bc72118823afd19227f042e8117eeb1b6a9 # Parent 69c79e2a7c7cd53de504e610f85e0cc61bf184bd Added tag heptapod-14.6.0 for changeset 69c79e2a7c7c diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -47,3 +47,4 @@ 61f29699614da28ec795cec912a75f398df84af3 heptapod-14.3.2 8696661a67a6e7816fca8066dcbdc66b261feb5b heptapod-14.4.0 aaebb02398004cb60c56d98824084bf9a2c17073 heptapod-14.5.0 +69c79e2a7c7cd53de504e610f85e0cc61bf184bd heptapod-14.6.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664547977 -7200 # Fri Sep 30 16:26:17 2022 +0200 # Branch heptapod # Node ID 54e1067b740ecd4e2af0b52e4b2472366aeeb466 # Parent 43b06bc72118823afd19227f042e8117eeb1b6a9 # Parent c54d0c6dfdb2076fb1a80dfd40886d8d98eb9a98 Merged upstream v14.7.0 into Heptapod Shell diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +v14.7.0 + +- Abort long-running unauthenticated SSH connections !647 +- Close the connection when context is canceled !646 + +v14.6.1 + +- Return support for diffie-hellman-group14-sha1 !644 + v14.6.0 - Exclude Gitaly unavailable error from error rate !641 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.7.0 + +- Bump to upstream GitLab Shell v14.7.0 + ## 14.6.0 - Bump to upstream GitLab Shell v14.6.0 diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.6.0 +14.7.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.6.0 +14.7.0 diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -92,10 +92,12 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # Sets an interval after which server will send keepalive message to a client + # Sets an interval after which server will send keepalive message to a client. Defaults to 15s. client_alive_interval: 15 - # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + # The server waits for this time for the ongoing connections to complete before shutting down. Defaults to 10s. grace_period: 10 + # The server disconnects after this time if the user has not successfully logged in. Defaults to 60s. + login_grace_time: 60 # A short timeout to decide to abort the connection if the protocol header is not seen within it. Defaults to 500ms proxy_header_timeout: 500ms # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". @@ -105,7 +107,7 @@ # Specifies the available message authentication code algorithms that are used for protecting data integrity macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] # Specifies the available Key Exchange algorithms - kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256] + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] # Specified the ciphers allowed ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -27,7 +27,7 @@ defaultHgrcPath string = "/opt/gitlab/etc/docker.hgrc:/etc/gitlab/heptapod.hgrc" ) -type yamlDuration time.Duration +type YamlDuration time.Duration type ServerConfig struct { Listen string `yaml:"listen,omitempty"` @@ -35,9 +35,10 @@ ProxyPolicy string `yaml:"proxy_policy,omitempty"` WebListen string `yaml:"web_listen,omitempty"` ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - ClientAliveInterval yamlDuration `yaml:"client_alive_interval,omitempty"` - GracePeriod yamlDuration `yaml:"grace_period"` - ProxyHeaderTimeout yamlDuration `yaml:"proxy_header_timeout"` + ClientAliveInterval YamlDuration `yaml:"client_alive_interval,omitempty"` + GracePeriod YamlDuration `yaml:"grace_period"` + ProxyHeaderTimeout YamlDuration `yaml:"proxy_header_timeout"` + LoginGraceTime YamlDuration `yaml:"login_grace_time"` ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` @@ -112,9 +113,10 @@ Listen: "[::]:22", WebListen: "localhost:9122", ConcurrentSessionsLimit: 10, - GracePeriod: yamlDuration(10 * time.Second), - ClientAliveInterval: yamlDuration(15 * time.Second), - ProxyHeaderTimeout: yamlDuration(500 * time.Millisecond), + GracePeriod: YamlDuration(10 * time.Second), + ClientAliveInterval: YamlDuration(15 * time.Second), + ProxyHeaderTimeout: YamlDuration(500 * time.Millisecond), + LoginGraceTime: YamlDuration(60 * time.Second), ReadinessProbe: "/start", LivenessProbe: "/health", HostKeyFiles: []string{ @@ -125,13 +127,13 @@ } ) -func (d *yamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (d *YamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { var intDuration int if err := unmarshal(&intDuration); err != nil { return unmarshal((*time.Duration)(d)) } - *d = yamlDuration(time.Duration(intDuration) * time.Second) + *d = YamlDuration(time.Duration(intDuration) * time.Second) return nil } diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -83,7 +83,7 @@ } type durationCfg struct { - Duration yamlDuration `yaml:"duration"` + Duration YamlDuration `yaml:"duration"` } for _, tc := range testCases { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -3,6 +3,8 @@ import ( "context" "errors" + "net" + "strings" "time" "golang.org/x/crypto/ssh" @@ -22,52 +24,95 @@ var EOFTimeout = 10 * time.Second type connection struct { - cfg *config.Config - concurrentSessions *semaphore.Weighted - remoteAddr string - sconn *ssh.ServerConn - maxSessions int64 + cfg *config.Config + concurrentSessions *semaphore.Weighted + nconn net.Conn + maxSessions int64 + remoteAddr string + started time.Time + establishSessionDuration float64 } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error +type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error -func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { +func newConnection(cfg *config.Config, nconn net.Conn) *connection { maxSessions := cfg.Server.ConcurrentSessionsLimit return &connection{ cfg: cfg, maxSessions: maxSessions, concurrentSessions: semaphore.NewWeighted(maxSessions), - remoteAddr: remoteAddr, - sconn: sconn, + nconn: nconn, + remoteAddr: nconn.RemoteAddr().String(), + started: time.Now(), } } -func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) +func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handler channelHandler) { + sconn, chans, err := c.initServerConn(ctx, srvCfg) + if err != nil { + return + } if c.cfg.Server.ClientAliveInterval > 0 { ticker := time.NewTicker(time.Duration(c.cfg.Server.ClientAliveInterval)) defer ticker.Stop() - go c.sendKeepAliveMsg(ctx, ticker) + go c.sendKeepAliveMsg(ctx, sconn, ticker) + } + + c.handleRequests(ctx, sconn, chans, handler) + + reason := sconn.Wait() + log.WithContextFields(ctx, log.Fields{ + "duration_s": time.Since(c.started).Seconds(), + "establish_session_duration_s": c.establishSessionDuration, + "reason": reason, + }).Info("server: handleConn: done") +} + +func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { + if c.cfg.Server.LoginGraceTime > 0 { + c.nconn.SetDeadline(time.Now().Add(time.Duration(c.cfg.Server.LoginGraceTime))) + defer c.nconn.SetDeadline(time.Time{}) } + sconn, chans, reqs, err := ssh.NewServerConn(c.nconn, srvCfg) + if err != nil { + msg := "connection: initServerConn: failed to initialize SSH connection" + logger := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}).WithError(err) + + if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { + logger.Debug(msg) + } else { + logger.Warn(msg) + } + + return nil, nil, err + } + go ssh.DiscardRequests(reqs) + + return sconn, chans, err +} + +func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { - ctxlog.Info("connection: handle: unknown channel type") + ctxlog.Info("connection: handleRequests: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { - ctxlog.Info("connection: handle: too many concurrent sessions") + ctxlog.Info("connection: handleRequests: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - ctxlog.WithError(err).Error("connection: handle: accepting channel failed") + ctxlog.WithError(err).Error("connection: handleRequests: accepting channel failed") c.concurrentSessions.Release(1) continue } @@ -76,6 +121,8 @@ defer func(started time.Time) { metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) }(time.Now()) + c.establishSessionDuration = time.Since(c.started).Seconds() + metrics.SshdSessionEstablishedDuration.Observe(c.establishSessionDuration) defer c.concurrentSessions.Release(1) @@ -87,12 +134,12 @@ }() metrics.SliSshdSessionsTotal.Inc() - err := handler(ctx, channel, requests) + err := handler(sconn, channel, requests) if err != nil { c.trackError(err) } - ctxlog.Info("connection: handle: done") + ctxlog.Info("connection: handleRequests: done") }() } @@ -105,7 +152,7 @@ c.concurrentSessions.Acquire(ctx, c.maxSessions) } -func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { +func (c *connection) sendKeepAliveMsg(ctx context.Context, sconn *ssh.ServerConn, ticker *time.Ticker) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) for { @@ -113,9 +160,9 @@ case <-ctx.Done(): return case <-ticker.C: - ctxlog.Debug("session: handleShell: send keepalive message to a client") + ctxlog.Debug("connection: sendKeepAliveMsg: send keepalive message to a client") - c.sconn.SendRequest(KeepAliveMsg, true, nil) + sconn.SendRequest(KeepAliveMsg, true, nil) } } } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -10,6 +10,7 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" @@ -81,7 +82,7 @@ func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum}} - conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) + conn := &connection{cfg: cfg, concurrentSessions: semaphore.NewWeighted(sessionsNum)} chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -95,7 +96,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -113,7 +114,7 @@ conn, chans := setup(1, newChannel) go func() { - conn.handle(context.Background(), chans, nil) + conn.handleRequests(context.Background(), nil, chans, nil) }() rejectionData := <-rejectCh @@ -133,7 +134,7 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test return nil }) @@ -148,7 +149,7 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) return nil @@ -167,7 +168,7 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true return nil }) @@ -185,12 +186,11 @@ func TestClientAliveInterval(t *testing.T) { f := &fakeConn{} - conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) - ticker := time.NewTicker(time.Millisecond) defer ticker.Stop() - go conn.sendKeepAliveMsg(context.Background(), ticker) + conn := &connection{} + go conn.sendKeepAliveMsg(context.Background(), &ssh.ServerConn{f, nil}, ticker) require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) } @@ -204,7 +204,7 @@ newChannel := &fakeNewChannel{channelType: "session"} conn, chans := setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return errors.New("custom error") }) @@ -213,7 +213,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return grpcstatus.Error(grpccodes.Canceled, "canceled") }) @@ -222,7 +222,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return &client.ApiError{"api error"} }) @@ -231,7 +231,7 @@ require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return grpcstatus.Error(grpccodes.Unavailable, "unavailable") }) diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -32,6 +32,7 @@ "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", + "diffie-hellman-group14-sha1", } ) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -10,7 +10,6 @@ "time" "github.com/pires/go-proxyproto" - "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "gitlab.com/gitlab-org/gitlab-shell/internal/config" @@ -39,18 +38,6 @@ serverConfig *serverConfig } -func logSSHInitError(ctxlog *logrus.Entry, err error) { - msg := "server: handleConn: failed to initialize SSH connection" - - logger := ctxlog.WithError(err) - - if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { - logger.Debug(msg) - } else { - logger.Warn(msg) - } -} - func NewServer(cfg *config.Config) (*Server, error) { serverConfig, err := newServerConfig(cfg) if err != nil { @@ -159,18 +146,21 @@ } func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + defer s.wg.Done() + metrics.SshdConnectionsInFlight.Inc() defer metrics.SshdConnectionsInFlight.Dec() - remoteAddr := nconn.RemoteAddr().String() - - defer s.wg.Done() - defer nconn.Close() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) defer cancel() + go func() { + <-ctx.Done() + nconn.Close() // Close the connection when context is cancelled + }() + remoteAddr := nconn.RemoteAddr().String() ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + ctxlog.Debug("server: handleConn: start") // Prevent a panic in a single connection from taking out the whole server defer func() { @@ -181,22 +171,8 @@ } }() - ctxlog.Debug("server: handleConn: start") - - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) - if err != nil { - logSSHInitError(ctxlog, err) - return - } - go ssh.DiscardRequests(reqs) - - started := time.Now() - var establishSessionDuration float64 - conn := newConnection(s.Config, remoteAddr, sconn) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { - establishSessionDuration = time.Since(started).Seconds() - metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) - + conn := newConnection(s.Config, nconn) + conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ cfg: s.Config, channel: channel, @@ -206,13 +182,6 @@ return session.handle(ctx, requests) }) - - reason := sconn.Wait() - ctxlog.WithFields(log.Fields{ - "duration_s": time.Since(started).Seconds(), - "establish_session_duration_s": establishSessionDuration, - "reason": reason, - }).Info("server: handleConn: done") } func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -222,6 +222,68 @@ require.Nil(t, s.Shutdown()) } +func TestClosingHangedConnections(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + s := setupServerWithContext(t, nil, ctx) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + require.NoError(t, s.Shutdown()) + cancel() + verifyStatus(t, s, StatusClosed) +} + +func TestLoginGraceTime(t *testing.T) { + cfg := &config.Config{ + Server: config.ServerConfig{ + LoginGraceTime: config.YamlDuration(50 * time.Millisecond), + }, + } + s := setupServerWithConfig(t, cfg) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Shutdown the server and verify that it's closed + // If LoginGraceTime doesn't work, then the connection that runs infinitely, will stop it from closing. + // The close won't happen until the context is canceled like in TestClosingHangedConnections + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -231,6 +293,12 @@ func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() + return setupServerWithContext(t, cfg, context.Background()) +} + +func setupServerWithContext(t *testing.T, cfg *config.Config, ctx context.Context) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -270,7 +338,7 @@ s, err := NewServer(cfg) require.NoError(t, err) - go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + go func() { require.NoError(t, s.ListenAndServe(ctx)) }() t.Cleanup(func() { s.Shutdown() }) verifyStatus(t, s, StatusReady) # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664548247 -7200 # Fri Sep 30 16:30:47 2022 +0200 # Branch heptapod # Node ID fffd61a882079fd2402c56a951a8968e9e135844 # Parent 54e1067b740ecd4e2af0b52e4b2472366aeeb466 Added tag heptapod-14.7.0 for changeset 54e1067b740e diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -48,3 +48,4 @@ 8696661a67a6e7816fca8066dcbdc66b261feb5b heptapod-14.4.0 aaebb02398004cb60c56d98824084bf9a2c17073 heptapod-14.5.0 69c79e2a7c7cd53de504e610f85e0cc61bf184bd heptapod-14.6.0 +54e1067b740ecd4e2af0b52e4b2472366aeeb466 heptapod-14.7.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664869865 -7200 # Tue Oct 04 09:51:05 2022 +0200 # Branch heptapod # Node ID cfb031a1e9de24b88498850cff796c224ba48edd # Parent fffd61a882079fd2402c56a951a8968e9e135844 # Parent d27c5af605da53832cae29fa0f9a200c1447047b Merged upstream v14.7.4 into Heptapod Shell This is the version in use in GitLab 15.1 (up to 15.1.6), we're updating Heptapod version files accordingly diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ variables: DOCKER_VERSION: "20.10.15" + BUNDLE_FROZEN: "true" workflow: rules: &workflow_rules diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,20 @@ +v14.7.4 + +- gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent !662 + +v14.7.3 + +- Ignore "not our ref" errors from gitlab-sshd error metrics !656 + +v14.7.2 + +- Exclude disallowed command from error rate !654 + +v14.7.1 + +- Log gitlab-sshd session level indicator errors !650 +- Improve establish session duration metrics !651 + v14.7.0 - Abort long-running unauthenticated SSH connections !647 diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,4 +113,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.3.6 + 2.3.15 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.7.1 + +- Bump to upstream GitLab Shell v14.7.4 (GitLab 15.1 series) + ## 14.7.0 - Bump to upstream GitLab Shell v14.7.0 diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.7.0 +14.7.1 diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -58,6 +58,44 @@ There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). +## GitLab SaaS + +A diagram of the flow of `gitlab-shell` on GitLab.com: + +```mermaid +graph LR + a2 --> b2 + a2 --> b3 + a2 --> b4 + b2 --> c1 + b3 --> c1 + b4 --> c1 + c2 --> d1 + c2 --> d2 + c2 --> d3 + d1 --> e1 + d2 --> e1 + d3 --> e1 + a1[Cloudflare] --> a2[TCP<br/> load balancer] + e1[Git] + + subgraph HAProxy Fleet + b2[HAProxy] + b3[HAProxy] + b4[HAProxy] + end + + subgraph GKE + c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods] + end + + subgraph Gitaly + d1[Gitaly] + d2[Gitaly] + d3[Gitaly] + end +``` + ## Releasing See [PROCESS.md](./PROCESS.md) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.0 +14.7.4 diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -81,4 +81,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) -replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -888,8 +888,8 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac h1:qNUzqBTbEGGjF5Fp0NWz3rNmqamwchxM+QKUZYeOS1c= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220518204012-9dd4a7273aac/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -7,30 +7,33 @@ "strings" "time" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) -const KeepAliveMsg = "keepalive@openssh.com" +const ( + KeepAliveMsg = "keepalive@openssh.com" + NotOurRefError = `exit status 128, stderr: "fatal: git upload-pack: not our ref ` +) var EOFTimeout = 10 * time.Second type connection struct { - cfg *config.Config - concurrentSessions *semaphore.Weighted - nconn net.Conn - maxSessions int64 - remoteAddr string - started time.Time - establishSessionDuration float64 + cfg *config.Config + concurrentSessions *semaphore.Weighted + nconn net.Conn + maxSessions int64 + remoteAddr string } type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error @@ -44,7 +47,6 @@ concurrentSessions: semaphore.NewWeighted(maxSessions), nconn: nconn, remoteAddr: nconn.RemoteAddr().String(), - started: time.Now(), } } @@ -63,11 +65,7 @@ c.handleRequests(ctx, sconn, chans, handler) reason := sconn.Wait() - log.WithContextFields(ctx, log.Fields{ - "duration_s": time.Since(c.started).Seconds(), - "establish_session_duration_s": c.establishSessionDuration, - "reason": reason, - }).Info("server: handleConn: done") + log.WithContextFields(ctx, log.Fields{"reason": reason}).Info("server: handleConn: done") } func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { @@ -119,10 +117,10 @@ go func() { defer func(started time.Time) { - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + duration := time.Since(started).Seconds() + metrics.SshdSessionDuration.Observe(duration) + ctxlog.WithFields(log.Fields{"duration_s": duration}).Info("connection: handleRequests: done") }(time.Now()) - c.establishSessionDuration = time.Since(c.started).Seconds() - metrics.SshdSessionEstablishedDuration.Observe(c.establishSessionDuration) defer c.concurrentSessions.Release(1) @@ -136,10 +134,8 @@ metrics.SliSshdSessionsTotal.Inc() err := handler(sconn, channel, requests) if err != nil { - c.trackError(err) + c.trackError(ctxlog, err) } - - ctxlog.Info("connection: handleRequests: done") }() } @@ -167,16 +163,23 @@ } } -func (c *connection) trackError(err error) { +func (c *connection) trackError(ctxlog *logrus.Entry, err error) { var apiError *client.ApiError if errors.As(err, &apiError) { return } + if errors.Is(err, disallowedcommand.Error) { + return + } + grpcCode := grpcstatus.Code(err) if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { return + } else if grpcCode == grpccodes.Internal && strings.Contains(err.Error(), NotOurRefError) { + return } metrics.SliSshdSessionsErrorsTotal.Inc() + ctxlog.WithError(err).Warn("connection: session error") } diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -15,6 +15,7 @@ grpcstatus "google.golang.org/grpc/status" "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" ) @@ -212,30 +213,25 @@ require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return grpcstatus.Error(grpccodes.Canceled, "canceled") - }) - - require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + for i, ignoredError := range []struct { + desc string + err error + }{ + {"canceled requests", grpcstatus.Error(grpccodes.Canceled, "canceled")}, + {"unavailable Gitaly", grpcstatus.Error(grpccodes.Unavailable, "unavailable")}, + {"api error", &client.ApiError{"api error"}}, + {"disallowed command", disallowedcommand.Error}, + {"not our ref", grpcstatus.Error(grpccodes.Internal, `rpc error: code = Internal desc = cmd wait: exit status 128, stderr: "fatal: git upload-pack: not our ref 9106d18f6a1b8022f6517f479696f3e3ea5e68c1"`)}, + } { + t.Run(ignoredError.desc, func(t *testing.T) { + conn, chans = setup(1, newChannel) + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return ignoredError.err + }) - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return &client.ApiError{"api error"} - }) - - require.InDelta(t, initialSessionsTotal+3, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - - conn, chans = setup(1, newChannel) - conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return grpcstatus.Error(grpccodes.Unavailable, "unavailable") - }) - - require.InDelta(t, initialSessionsTotal+4, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + }) + } } diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -5,6 +5,7 @@ "errors" "fmt" "reflect" + "time" "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" @@ -16,6 +17,7 @@ "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" ) @@ -29,6 +31,7 @@ // State managed by the session execCmd string gitProtocolVersion string + started time.Time } type execRequest struct { @@ -171,7 +174,12 @@ } cmdName := reflect.TypeOf(cmd).String() - ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + + establishSessionDuration := time.Since(s.started).Seconds() + ctxlog.WithFields(log.Fields{ + "env": env, "command": cmdName, "established_session_duration_s": establishSessionDuration, + }).Info("session: handleShell: executing command") + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) if err := cmd.Execute(ctx); err != nil { grpcStatus := grpcstatus.Convert(err) diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -178,6 +178,7 @@ channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, + started: time.Now(), } return session.handle(ctx, requests) # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1664870532 -7200 # Tue Oct 04 10:02:12 2022 +0200 # Branch heptapod # Node ID eb391a3351eed2440ab3be3d26f43c219b184699 # Parent cfb031a1e9de24b88498850cff796c224ba48edd Added tag heptapod-14.7.1 for changeset cfb031a1e9de diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -49,3 +49,4 @@ aaebb02398004cb60c56d98824084bf9a2c17073 heptapod-14.5.0 69c79e2a7c7cd53de504e610f85e0cc61bf184bd heptapod-14.6.0 54e1067b740ecd4e2af0b52e4b2472366aeeb466 heptapod-14.7.0 +cfb031a1e9de24b88498850cff796c224ba48edd heptapod-14.7.1 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1668442235 -3600 # Mon Nov 14 17:10:35 2022 +0100 # Branch heptapod # Node ID cf818cb4e4fe5440a953da19e2e8650bddbf45d5 # Parent eb391a3351eed2440ab3be3d26f43c219b184699 # Parent 00502e780098673e6e130e33b80b04710dca7ad5 Merged upstream GitLab Shell 14.9 into Heptapod Shell As usual, we're setting the version to 14.9.0 The modules import path now includes a `v14` (virtual) segment, apparently needed for Golang tooling to be able to use versions instead of just commit hashes (see 91f2a74d0d6c), we're followint suit. There was a complication found by the race detector CI job (amounting to `go test -race`): `internal/sshd/connection_test.go` has a race condition between the loop over data (tabular-oriented testing) and the inner call. The puzzling part is that it is detected in Heptapod context only (several runs on upstream v14.9.0 didn't find it) diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,14 @@ +v14.9.0 + +- Update LabKit library to v1.16.0 !668 + +v14.8.0 + +- go: Bump major version to v14 !666 +- Pass original IP from PROXY requests to internal API calls !665 +- Fix make install copying the wrong binaries !664 +- gitlab-sshd: Add support for configuring host certificates !661 + v14.7.4 - gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent !662 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.9.0 + +- Bump to upstream GitLab Shell v14.9.0 (GitLab 15.2 series) + ## 14.7.1 - Bump to upstream GitLab Shell v14.7.4 (GitLab 15.1 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.7.1 +14.9.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ mkdir -p $(DESTDIR)$(PREFIX)/bin/ install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd - + install -m755 bin/gitlab-shell-authorized-keys-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell-authorized-principals-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-sshd $(DESTDIR)$(PREFIX)/bin/gitlab-sshd diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.7.4 +14.9.0 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -15,8 +15,8 @@ "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( @@ -76,6 +76,7 @@ testErrorMessage(t, client) testAuthenticationHeader(t, client) testJWTAuthenticationHeader(t, client) + testXForwardedForHeader(t, client) }) } } @@ -221,6 +222,21 @@ }) } +func testXForwardedForHeader(t *testing.T, client *GitlabNetClient) { + t.Run("X-Forwarded-For Header inserted if original address in context", func(t *testing.T) { + ctx := context.WithValue(context.Background(), OriginalRemoteIPContextKey{}, "196.7.0.238") + response, err := client.Get(ctx, "/x_forwarded_for") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + require.Equal(t, "196.7.0.238", string(responseBody)) + }) +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { @@ -257,6 +273,12 @@ }, }, { + Path: "/api/v4/internal/x_forwarded_for", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get("X-Forwarded-For")) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -41,6 +41,9 @@ Msg string } +// To use as the key in a Context to set an X-Forwarded-For header in a request +type OriginalRemoteIPContextKey struct{} + func (e *ApiError) Error() string { return e.Msg } @@ -150,6 +153,11 @@ } request.Header.Set(apiSecretHeaderName, tokenString) + originalRemoteIP, ok := ctx.Value(OriginalRemoteIPContextKey{}).(string) + if ok { + request.Header.Add("X-Forwarded-For", originalRemoteIP) + } + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -11,7 +11,7 @@ "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func TestReadTimeout(t *testing.T) { diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -9,8 +9,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) //go:generate openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 -out ../internal/testhelper/testdata/testroot/certs/client/server.crt -keyout ../internal/testhelper/testdata/testroot/certs/client/key.pem -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=GitLab-Shell/CN=localhost" diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -14,7 +14,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go --- a/cmd/check/command/command.go +++ b/cmd/check/command/command.go @@ -1,11 +1,11 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go --- a/cmd/check/command/command_test.go +++ b/cmd/check/command/command_test.go @@ -4,11 +4,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" - checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go --- a/cmd/gitlab-shell/command/command.go +++ b/cmd/gitlab-shell/command/command.go @@ -1,21 +1,21 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/hg" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/hg" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -5,20 +5,20 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,14 +11,14 @@ "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -24,7 +24,7 @@ "github.com/stretchr/testify/require" gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -8,10 +8,10 @@ "syscall" "time" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshd" "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -115,3 +115,7 @@ - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key + host_key_certs: + - /run/secrets/ssh-hostkeys/ssh_host_rsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key-cert.pub diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module gitlab.com/gitlab-org/gitlab-shell +module gitlab.com/gitlab-org/gitlab-shell/v14 go 1.17 @@ -14,7 +14,7 @@ github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.14.0 + gitlab.com/gitlab-org/labkit v1.16.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -887,6 +887,7 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -895,8 +896,8 @@ 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.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= +gitlab.com/gitlab-org/labkit v1.16.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= diff --git a/internal/command/authorizedkeys/authorized_keys.go b/internal/command/authorizedkeys/authorized_keys.go --- a/internal/command/authorizedkeys/authorized_keys.go +++ b/internal/command/authorizedkeys/authorized_keys.go @@ -5,11 +5,11 @@ "fmt" "strconv" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedkeys/authorized_keys_test.go b/internal/command/authorizedkeys/authorized_keys_test.go --- a/internal/command/authorizedkeys/authorized_keys_test.go +++ b/internal/command/authorizedkeys/authorized_keys_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/authorizedprincipals/authorized_principals.go b/internal/command/authorizedprincipals/authorized_principals.go --- a/internal/command/authorizedprincipals/authorized_principals.go +++ b/internal/command/authorizedprincipals/authorized_principals.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedprincipals/authorized_principals_test.go b/internal/command/authorizedprincipals/authorized_principals_test.go --- a/internal/command/authorizedprincipals/authorized_principals_test.go +++ b/internal/command/authorizedprincipals/authorized_principals_test.go @@ -7,9 +7,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestExecute(t *testing.T) { diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,7 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -6,7 +6,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" ) diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -6,7 +6,7 @@ "strings" "github.com/mattn/go-shellwords" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) const ( diff --git a/internal/command/discover/discover.go b/internal/command/discover/discover.go --- a/internal/command/discover/discover.go +++ b/internal/command/discover/discover.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Command struct { diff --git a/internal/command/discover/discover_test.go b/internal/command/discover/discover_test.go --- a/internal/command/discover/discover_test.go +++ b/internal/command/discover/discover_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/healthcheck/healthcheck.go b/internal/command/healthcheck/healthcheck.go --- a/internal/command/healthcheck/healthcheck.go +++ b/internal/command/healthcheck/healthcheck.go @@ -4,9 +4,9 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/healthcheck/healthcheck_test.go b/internal/command/healthcheck/healthcheck_test.go --- a/internal/command/healthcheck/healthcheck_test.go +++ b/internal/command/healthcheck/healthcheck_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/hg/hg.go b/internal/command/hg/hg.go --- a/internal/command/hg/hg.go +++ b/internal/command/hg/hg.go @@ -10,11 +10,11 @@ "strings" "syscall" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/hgaccesslevel" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/hgaccesslevel" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func Exec(filename string, args []string, env []string) error { diff --git a/internal/command/hg/hg_test.go b/internal/command/hg/hg_test.go --- a/internal/command/hg/hg_test.go +++ b/internal/command/hg/hg_test.go @@ -8,11 +8,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) type fakeExec struct { diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -8,12 +8,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" ) const ( diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -10,13 +10,13 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestFailedRequests(t *testing.T) { diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -10,10 +10,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) const ( diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) var ( diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { diff --git a/internal/command/receivepack/receivepack.go b/internal/command/receivepack/receivepack.go --- a/internal/command/receivepack/receivepack.go +++ b/internal/command/receivepack/receivepack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/receivepack/receivepack_test.go b/internal/command/receivepack/receivepack_test.go --- a/internal/command/receivepack/receivepack_test.go +++ b/internal/command/receivepack/receivepack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/shared/accessverifier/accessverifier.go b/internal/command/shared/accessverifier/accessverifier.go --- a/internal/command/shared/accessverifier/accessverifier.go +++ b/internal/command/shared/accessverifier/accessverifier.go @@ -4,11 +4,11 @@ "context" "errors" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) type Response = accessverifier.Response diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) var ( diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -9,12 +9,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/pktline" ) type Request struct { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) func TestExecuteEOFSent(t *testing.T) { diff --git a/internal/command/shared/hgaccesslevel/hgaccesslevel.go b/internal/command/shared/hgaccesslevel/hgaccesslevel.go --- a/internal/command/shared/hgaccesslevel/hgaccesslevel.go +++ b/internal/command/shared/hgaccesslevel/hgaccesslevel.go @@ -5,10 +5,10 @@ "errors" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) type Response = accessverifier.HgResponse diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -8,10 +8,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) const readerLimit = 1024 diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) var ( diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -7,10 +7,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) type Command struct { diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) func setup(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadArchive(t *testing.T) { diff --git a/internal/command/uploadarchive/uploadarchive.go b/internal/command/uploadarchive/uploadarchive.go --- a/internal/command/uploadarchive/uploadarchive.go +++ b/internal/command/uploadarchive/uploadarchive.go @@ -3,11 +3,11 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadarchive/uploadarchive_test.go b/internal/command/uploadarchive/uploadarchive_test.go --- a/internal/command/uploadarchive/uploadarchive_test.go +++ b/internal/command/uploadarchive/uploadarchive_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadPack(t *testing.T) { diff --git a/internal/command/uploadpack/uploadpack.go b/internal/command/uploadpack/uploadpack.go --- a/internal/command/uploadpack/uploadpack.go +++ b/internal/command/uploadpack/uploadpack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadpack/uploadpack_test.go b/internal/command/uploadpack/uploadpack_test.go --- a/internal/command/uploadpack/uploadpack_test.go +++ b/internal/command/uploadpack/uploadpack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,9 +12,9 @@ yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) const ( @@ -42,6 +42,7 @@ ReadinessProbe string `yaml:"readiness_probe"` LivenessProbe string `yaml:"liveness_probe"` HostKeyFiles []string `yaml:"host_key_files,omitempty"` + HostCertFiles []string `yaml:"host_cert_files,omitempty"` MACs []string `yaml:"macs"` KexAlgorithms []string `yaml:"kex_algorithms"` Ciphers []string `yaml:"ciphers"` diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -9,8 +9,8 @@ "github.com/stretchr/testify/require" yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestConfigApplyGlobalState(t *testing.T) { diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -4,7 +4,7 @@ "errors" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "github.com/stretchr/testify/require" ) diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -17,7 +17,7 @@ "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type Command struct { diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -7,7 +7,7 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) func TestPrometheusMetrics(t *testing.T) { diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,14 +3,13 @@ import ( "context" "fmt" - "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( @@ -86,7 +85,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = parseIP(args.Env.RemoteAddr) + request.CheckIp = gitlabnet.ParseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -117,18 +116,3 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } - -func parseIP(remoteAddr string) string { - // The remoteAddr field can be filled by: - // 1. An IP address via the SSH_CONNECTION environment variable - // 2. A host:port combination via the PROXY protocol - ip, _, err := net.SplitHostPort(remoteAddr) - - // If we don't have a port or can't parse this address for some reason, - // just return the original string. - if err != nil { - return remoteAddr - } - - return ip -} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/internal/gitlabnet/accessverifier/hg_client.go b/internal/gitlabnet/accessverifier/hg_client.go --- a/internal/gitlabnet/accessverifier/hg_client.go +++ b/internal/gitlabnet/accessverifier/hg_client.go @@ -5,10 +5,10 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type HgClient struct { diff --git a/internal/gitlabnet/accessverifier/hg_client_test.go b/internal/gitlabnet/accessverifier/hg_client_test.go --- a/internal/gitlabnet/accessverifier/hg_client_test.go +++ b/internal/gitlabnet/accessverifier/hg_client_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func buildHgExpectedResponse() *HgResponse { diff --git a/internal/gitlabnet/authorizedkeys/client.go b/internal/gitlabnet/authorizedkeys/client.go --- a/internal/gitlabnet/authorizedkeys/client.go +++ b/internal/gitlabnet/authorizedkeys/client.go @@ -5,9 +5,9 @@ "fmt" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/authorizedkeys/client_test.go b/internal/gitlabnet/authorizedkeys/client_test.go --- a/internal/gitlabnet/authorizedkeys/client_test.go +++ b/internal/gitlabnet/authorizedkeys/client_test.go @@ -7,9 +7,9 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -3,11 +3,12 @@ import ( "encoding/json" "fmt" + "net" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( @@ -34,3 +35,18 @@ return nil } + +func ParseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/gitlabnet/discover/client.go b/internal/gitlabnet/discover/client.go --- a/internal/gitlabnet/discover/client.go +++ b/internal/gitlabnet/discover/client.go @@ -6,10 +6,10 @@ "net/http" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/discover/client_test.go b/internal/gitlabnet/discover/client_test.go --- a/internal/gitlabnet/discover/client_test.go +++ b/internal/gitlabnet/discover/client_test.go @@ -8,11 +8,11 @@ "net/url" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/healthcheck/client.go b/internal/gitlabnet/healthcheck/client.go --- a/internal/gitlabnet/healthcheck/client.go +++ b/internal/gitlabnet/healthcheck/client.go @@ -5,9 +5,9 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/healthcheck/client_test.go b/internal/gitlabnet/healthcheck/client_test.go --- a/internal/gitlabnet/healthcheck/client_test.go +++ b/internal/gitlabnet/healthcheck/client_test.go @@ -6,8 +6,8 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "github.com/stretchr/testify/require" ) diff --git a/internal/gitlabnet/lfsauthenticate/client.go b/internal/gitlabnet/lfsauthenticate/client.go --- a/internal/gitlabnet/lfsauthenticate/client.go +++ b/internal/gitlabnet/lfsauthenticate/client.go @@ -6,10 +6,10 @@ "net/http" "strings" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -9,9 +9,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) const ( diff --git a/internal/gitlabnet/personalaccesstoken/client.go b/internal/gitlabnet/personalaccesstoken/client.go --- a/internal/gitlabnet/personalaccesstoken/client.go +++ b/internal/gitlabnet/personalaccesstoken/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorrecover/client.go b/internal/gitlabnet/twofactorrecover/client.go --- a/internal/gitlabnet/twofactorrecover/client.go +++ b/internal/gitlabnet/twofactorrecover/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -7,13 +7,13 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func initialize(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -11,10 +11,10 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -12,10 +12,10 @@ grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { diff --git a/internal/keyline/key_line.go b/internal/keyline/key_line.go --- a/internal/keyline/key_line.go +++ b/internal/keyline/key_line.go @@ -7,8 +7,8 @@ "regexp" "strings" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" ) var ( diff --git a/internal/keyline/key_line_test.go b/internal/keyline/key_line_test.go --- a/internal/keyline/key_line_test.go +++ b/internal/keyline/key_line_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestFailingNewPublicKeyLine(t *testing.T) { diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -9,7 +9,7 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func logFmt(inFmt string) string { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -8,7 +8,7 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestConfigure(t *testing.T) { diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -13,10 +13,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -14,10 +14,10 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type rejectCall struct { @@ -223,6 +223,7 @@ {"disallowed command", disallowedcommand.Error}, {"not our ref", grpcstatus.Error(grpccodes.Internal, `rpc error: code = Internal desc = cmd wait: exit status 128, stderr: "fatal: git upload-pack: not our ref 9106d18f6a1b8022f6517f479696f3e3ea5e68c1"`)}, } { + ignoredError := ignoredError // Capture range variable, see "Race on loop counter" in https://go.dev/doc/articles/race_detector t.Run(ignoredError.desc, func(t *testing.T) { conn, chans = setup(1, newChannel) conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -10,8 +10,8 @@ "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/log" ) @@ -39,17 +39,14 @@ type serverConfig struct { cfg *config.Config hostKeys []ssh.Signer + hostKeyToCertMap map[string]*ssh.Certificate authorizedKeysClient *authorizedkeys.Client } -func newServerConfig(cfg *config.Config) (*serverConfig, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) - if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) - } +func parseHostKeys(keyFiles []string) []ssh.Signer { + var hostKeys []ssh.Signer - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { + for _, filename := range keyFiles { keyRaw, err := os.ReadFile(filename) if err != nil { log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") @@ -63,11 +60,70 @@ hostKeys = append(hostKeys, key) } + + return hostKeys +} + +func parseHostCerts(hostKeys []ssh.Signer, certFiles []string) map[string]*ssh.Certificate { + keyToCertMap := map[string]*ssh.Certificate{} + hostKeyIndex := make(map[string]int) + + for index, hostKey := range hostKeys { + hostKeyIndex[string(hostKey.PublicKey().Marshal())] = index + } + + for _, filename := range certFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to read host certificate") + continue + } + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to parse host certificate") + continue + } + + cert, ok := publicKey.(*ssh.Certificate) + if !ok { + log.WithFields(log.Fields{"filename": filename}).Warn("failed to decode host certificate") + continue + } + + hostRawKey := string(cert.Key.Marshal()) + index, found := hostKeyIndex[hostRawKey] + if found { + keyToCertMap[hostRawKey] = cert + + certSigner, err := ssh.NewCertSigner(cert, hostKeys[index]) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("the host certificate doesn't match the host private key") + continue + } + + hostKeys[index] = certSigner + } else { + log.WithFields(log.Fields{"filename": filename}).Warnf("no matching private key for certificate %s", filename) + } + } + + return keyToCertMap +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + hostKeys := parseHostKeys(cfg.Server.HostKeyFiles) if len(hostKeys) == 0 { return nil, fmt.Errorf("No host keys could be loaded, aborting") } - return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + hostKeyToCertMap := parseHostCerts(hostKeys, cfg.Server.HostCertFiles) + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys, hostKeyToCertMap: hostKeyToCertMap}, nil } func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -5,14 +5,15 @@ "crypto/dsa" "crypto/rand" "crypto/rsa" + "os" "path" "testing" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewServerConfigWithoutHosts(t *testing.T) { @@ -22,6 +23,45 @@ require.Equal(t, "No host keys could be loaded, aborting", err.Error()) } +func TestHostKeyAndCerts(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + }, + HostCertFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/valid/server2-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + require.Len(t, cfg.hostKeys, 1) + require.Len(t, cfg.hostKeyToCertMap, 1) + + // Check that the entry is pointing to the server's public key + data, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server.pub")) + require.NoError(t, err) + + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(data) + require.NoError(t, err) + require.NotNil(t, publicKey) + cert, ok := cfg.hostKeyToCertMap[string(publicKey.Marshal())] + require.True(t, ok) + require.NotNil(t, cert) + require.Equal(t, cert, cfg.hostKeys[0].PublicKey()) +} + func TestFailedAuthorizedKeysClient(t *testing.T) { _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -12,13 +12,13 @@ grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) type session struct { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -11,9 +11,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" ) type fakeChannel struct { diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,8 +12,10 @@ "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -145,13 +147,26 @@ return s.status } +func contextWithValues(parent context.Context, nconn net.Conn) context.Context { + ctx := correlation.ContextWithCorrelation(parent, correlation.SafeRandomID()) + + // If we're dealing with a PROXY connection, register the original requester's IP + mconn, ok := nconn.(*proxyproto.Conn) + if ok { + ip := gitlabnet.ParseIP(mconn.Raw().RemoteAddr().String()) + ctx = context.WithValue(ctx, client.OriginalRemoteIPContextKey{}, ip) + } + + return ctx +} + func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { defer s.wg.Done() metrics.SshdConnectionsInFlight.Inc() defer metrics.SshdConnectionsInFlight.Dec() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) + ctx, cancel := context.WithCancel(contextWithValues(ctx, nconn)) defer cancel() go func() { <-ctx.Done() diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -15,9 +15,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) const ( @@ -27,6 +27,7 @@ var ( correlationId = "" + xForwardedFor = "" ) func TestListenAndServe(t *testing.T) { @@ -63,6 +64,10 @@ }, DestinationAddr: target, } + xForwardedFor = "127.0.0.1" + defer func() { + xForwardedFor = "" // Cleanup for other test cases + }() testCases := []struct { desc string @@ -132,9 +137,9 @@ require.NoError(t, err) } - sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + sshConn, sshChans, sshRequs, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) if sshConn != nil { - sshConn.Close() + defer sshConn.Close() } if tc.isRejected { @@ -142,6 +147,10 @@ require.Regexp(t, "ssh: handshake failed", err.Error()) } else { require.NoError(t, err) + client := ssh.NewClient(sshConn, sshChans, sshRequs) + defer client.Close() + + holdSession(t, client) } }) } @@ -306,6 +315,7 @@ correlationId = r.Header.Get("X-Request-Id") require.NotEmpty(t, correlationId) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "key": "key"}`) }, @@ -313,6 +323,7 @@ Path: "/api/v4/internal/discover", Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) }, diff --git a/internal/sshenv/sshenv_test.go b/internal/sshenv/sshenv_test.go --- a/internal/sshenv/sshenv_test.go +++ b/internal/sshenv/sshenv_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewFromEnv(t *testing.T) { diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -7,7 +7,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func BuildDisallowedByApiHandlers(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql not_a_valid_cert.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca b/internal/testhelper/testdata/testroot/certs/valid/ca new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV ++IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfw +FoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj +4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4 +NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqI +cXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfX +KGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCf +EG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAAFkA5fIlIOXyJSAAAAB3NzaC1yc2 +EAAAGBANyFATfNPwSRubrfVNt/BcCBgHzGUKDl2GxbYkGaPlPnHWxiZRBoFfiE6Bje/GCc +qZGyvDYqbTDDoFmfHrugwiTDcYz2+3t12Bq5hz3qCuWfYqBEg8NEEpMQyH8BaC0p8dPnol +0td/MqRDYC0/4TjJfn5q6AO+Gab5LyKSvkaAKNapVglrQOzcoJEJFkYJ5wI+I5AyqvWk9Y +hxmvZ0GC7k7X4l95d+f6DjjCRaw4O22+RB5wbCnsA6AMXajW8aeFv7EMlBeDWzhSxs0Wrw +OnjUXzsfVF3HctL/flIAprvdp24j5jQaPcGNw/aa8FwFnrUzNQd2Qg5NYaiHF0YOqTQTQv +Xthbm3IbPU3Ky2maa+JIBb03pBnKH9ZtqMyU1ZXCCZSacveZqdbl8MUz231yhj7yruza6E +dmr5ACH8EY+RP/B8K4Ax9q/+LkT2nUQsfYZt/ByNZ+kuGK67Ji/X3y1ukgnxBunO/lEQ0K +9fFavWMsTJrtPRCu1ZQw19CTNFGp+QAAAAMBAAEAAAGACHnYRSPPc0aCpAsngNRODUss/B +7HRJfxDKEqkqjyElmEyQCzL8FAbu/019fiTXhYEDCViWNyFPi/9hHmpYGVVMJqX+eyXNl3 +t/c/moKfbpoEuXJIuj2olRyFCFSug2XkVKfHlttDjAYo3waWzWJE+iXAuR5WruI3vacvK+ ++4i7iRyzIOONeE02orx9ra19wplO1qEL7ysrANaVBToLH+pOspWVAa6sCywT2+XdM/fYVd +qunZTncy4Hj5NJ8mZLEATfJKnT2v7C47fBjN+ylqpyTImBZxSfVyjrljcQXb9ExjAhVTjv +tBuZdB1NPnok9cycwpg6aGXuZX2mSQWROhHM/r80kUzfxJpRDs/AqMWRZYC2k/kCKbXg7S +1cuAwJ2SiH5jslekhbB8bCU3rL2SgUV4oZsqh5fb6ZsytXarbzX/8Kcmb4KGsjZ7wBD6Yu +sJ05TkzC/HkOT3xTXwyzZpEldKucLClnY3Boq8pkO1EoUD8uPJNgSgukH9W5SleaIxAAAA +wEzXR8Av4SxsgWW2pPVtQaeKhUKrid21RuPF5/7c4PZ4GlnhL3Fod4PwdD8yPjuIuI7s6/ +9HRxzi+vr616/BXMagGWPSZEQMaX6I/L5CSratN2Dk1jSYcH501GseILr+kIcZhe7HoEf2 +xbr8ByF88DXpeSdimIqMeVYTPGWac7oSf3Y5WHi9FUuJ4BEccu8bLIXWkGMK6yi/zJo1RQ +u4aMzdMyzat0C2aeAm40HABdUv350K/H20Voj7zfhmlXvQ7wAAAMEA8a1oEPFL1+cAqfUD +Jbx+KWyw/1kFBIpU93rk2qfJR593nMLebAk0l9qfhbvlN6GTNcGETjzGK1bHaD9G14c2IT +bFcIoKmah6LygIlMGwdTMSWPPrczeIhMy6H0rJ2lDa208+nLwKqlFlMDYNpycL2Q1ZynnB +fYqfRiUSDJcs+2jfTX0gA17NuSwqp6j/JlMm45tN3GK1neIVH+4PBazBXqZTzdfCfqJ9r5 +TWJw2i6CsSlCDAtO3uo+Pyj327RbNtAAAAwQDplpqK2+0+QiQB+LUeT0hfWp5/HmXJjfgm +u+xIICJKPqOYwDvBWEHHssv7YS70dFJrbENJ66NZfdv+foDbQXrr10odbIntk9QoO4CS1g +zd63kolFCLhbwkYos45CjJIPuzNDeiYIgsLEOQwnjHbp3HxAIywxtUPKj80YmfoogeidiD +JNMwRoJfqlNziW1PDq0r8Zhw2lbyGZPI218ox7tsJ94BS4MFJfgASwO9qcDsaYz23sS8uQ +BBbY6cCknC7T0AAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca.pub b/internal/testhelper/testdata/testroot/certs/valid/ca.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDchQE3zT8Ekbm631TbfwXAgYB8xlCg5dhsW2JBmj5T5x1sYmUQaBX4hOgY3vxgnKmRsrw2Km0ww6BZnx67oMIkw3GM9vt7ddgauYc96grln2KgRIPDRBKTEMh/AWgtKfHT56JdLXfzKkQ2AtP+E4yX5+augDvhmm+S8ikr5GgCjWqVYJa0Ds3KCRCRZGCecCPiOQMqr1pPWIcZr2dBgu5O1+JfeXfn+g44wkWsODttvkQecGwp7AOgDF2o1vGnhb+xDJQXg1s4UsbNFq8Dp41F87H1Rdx3LS/35SAKa73aduI+Y0Gj3BjcP2mvBcBZ61MzUHdkIOTWGohxdGDqk0E0L17YW5tyGz1NystpmmviSAW9N6QZyh/WbajMlNWVwgmUmnL3manW5fDFM9t9coY+8q7s2uhHZq+QAh/BGPkT/wfCuAMfav/i5E9p1ELH2GbfwcjWfpLhiuuyYv198tbpIJ8Qbpzv5RENCvXxWr1jLEya7T0QrtWUMNfQkzRRqfk= test@test.example.org diff --git a/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgNGUtD+qw0Xj5NU2uj4+4LoCWPcvXP54F9Adw/hWN5LAAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yqlAAAAAAAAAAAAAAACAAAABnNlcnZlcgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGAapK5VzLDoRe88tnLORrH8VxLegTWPKGdn0k5Ye8tS5XUgd0N98gU669y4ErDNf0kPxlz40bjsfisEEtJ/N7m14IskCepScfZRh8w6QgPxbTOhmrc89xooqBUE50y5FU9hIIbzUrnEP+Dfu4IiFPToAguCa+KoAKiOX7lBQqEugV6uOWVZ2erPopEv+OiMLD8hXsuKKjQ+TomHZ/IjuXsFdXH7Vcl0VsPaAcxyCtDU7nCTJSTUoUZtMtwwpulp0e/zNmFrEn2Binz4jRaUlk3FM2fdbotviDQYeOY3npmxaWUvvQ/eKn0/DzUTAKAGr2LDa2XWnPhj51BS1XkNaUlnupdYmZ2Sok0R4U3bfVwokteREvAltGbXQSDtZwLS5NEY6vIdDrxpn5QRf9vGjqnc7piXxye9gcLne4YDUi24IhGyHrnWKCC0HjF7tuUhCOVKrqRdmHxRGWX3PlS8Xn6HHEPWU+YZnfT1V2W7LAFcDMozQbs4GPGzZdR3f3vCOJ8 server.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server.pub b/internal/testhelper/testdata/testroot/certs/valid/server.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg3XO30wn4+lFxc5fLsanH4Pvu0OuKGHoR94zZjxx7qAEAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgokAAAAAAAAAAAAAAAIAAAAHc2VydmVyMgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGANOKG8Tq7kp9B5+CQEyb+mEatJOoQRV+4rpemWlfEw6TuVwQN2wSXc6XKBHzSG4NRnFkwk6GgiPLQEf4lBBKA8VYQnDKuhrHJlU4DFCRPw/aceHfCwNOruyJmuf91W3yEO/kYAd6EhkQiW/K3ky7BuXCqR34T2fBZSCeYhNcXWxhEMLoAuj0kEdX+YMNBmiPtinPE13KMFGyIVBm/ojgSZa8j4WnhDcK0cWv0OSGTgJF6q3hENCWRz2E1HroKUiABOy5Nca6gPVAi4OTd7gwER8eh9MngVHYorAJ3N9HjUh640SbL3zCC8f/lqIztqsHY0u3olsQ0gLXpFain+430HeyJlmVlsDZgQKRb90Mm1viSCKvHGpmVDYMimE9y0DCQS1i0yRGF1uSIPtuQ0NCbhS/HPKsT3nYgGCEuoB8aGOu3aGB/tmUkYXW+pwXRKqw0f/zX088XWYWvA+AR4hmmr6DDMnf/4EHgJp3xHTEwOBHCVj69xvlOawBNlL2X0b2p server2.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.key b/internal/testhelper/testdata/testroot/certs/valid/server2.key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.key @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEAyuDL6ZomdHC0uPqd2BMHAsKOJFWyT0xHoiDLqBCOyid8qgIyibp7 +OlaZwumkYLty5rjOLgR3IpkIuNeQpQTpuPrRYlbFTXAJLAPkLlPK0xAusT7PestWP6gvv1 +kJ+vriqdfnwLKVrC6YoN1V0k36vmAHMWX03Tv+nJNJB1b8V9PemHuw9JnatpVmxsEgZQG8 +1NcF/2Z7+YS2Q+A0htXCIwPb0P3yfacHJWYktKkNVV3aCFALy/bUwCo9veVRk9jTBhmGUA +ENL17TNWBzjAGeF6Dy9aFRY1RGaC0Q+fGug6XuIWPECnul9cO81Na6+b1WK8+zE1Guac7F +EjnlE3N5MiiaxMVZKC8gYGEKvKlvZGJPzsfcx8EwCsPb8IiLNjMHup5cSe3MOM8pDLMTyu +M/R5G2aExVst6YbjxarP1kKArx0yjY1j2m+1AGpnjOg59DfNwRdtbQkzFo5EQr7WVRiBme +2OHAIojdDj80Fg2rCfyClQ0YLmSUZ95IBwjGAoKJAAAFkBOZmjETmZoxAAAAB3NzaC1yc2 +EAAAGBAMrgy+maJnRwtLj6ndgTBwLCjiRVsk9MR6Igy6gQjsonfKoCMom6ezpWmcLppGC7 +cua4zi4EdyKZCLjXkKUE6bj60WJWxU1wCSwD5C5TytMQLrE+z3rLVj+oL79ZCfr64qnX58 +CylawumKDdVdJN+r5gBzFl9N07/pyTSQdW/FfT3ph7sPSZ2raVZsbBIGUBvNTXBf9me/mE +tkPgNIbVwiMD29D98n2nByVmJLSpDVVd2ghQC8v21MAqPb3lUZPY0wYZhlABDS9e0zVgc4 +wBnheg8vWhUWNURmgtEPnxroOl7iFjxAp7pfXDvNTWuvm9VivPsxNRrmnOxRI55RNzeTIo +msTFWSgvIGBhCrypb2RiT87H3MfBMArD2/CIizYzB7qeXEntzDjPKQyzE8rjP0eRtmhMVb +LemG48Wqz9ZCgK8dMo2NY9pvtQBqZ4zoOfQ3zcEXbW0JMxaOREK+1lUYgZntjhwCKI3Q4/ +NBYNqwn8gpUNGC5klGfeSAcIxgKCiQAAAAMBAAEAAAGAUxojzMt85wNns8HMuD6LB6FkEh +QcVwka6plecrhdlQb5tLXzt6DwayQgFcwYrhr6ZPHcWtMvbbeb8AM017OcfU4YSJzccuzq +hOIPLL7b/PrK9YWR/W2fJbIh5NJ3GRx9ji7HWpKMZpwrnvEq/1s705GIQL7Pv3Ocxsw6BM +ynzt4VdwZrpLYE9fdawx1GxLkifViat1Rmgf3PnxwOyBB1Vlx1RTVQiBHMBpDBhlMdCBPK +hM8tFd5EpXZoFgoCEXqlssIptaf0zUZAgeES31GwNrP7+n6SlL+xZxbs7ykWKjA1ibYDTE +fLIojOQCOgnIFaDFbbgUiqxoYg1SAr2SRPOjopc5EXSt5kfCdQk3I5MKoSm2INNuwBqprI +/BL0Do3VowAQkxjXJUWit9RR0wS7FiA54WJqOrfU+2ChRooVUvtt0i/0y9tJMr6+PJYawZ +uLwQ4DXs3UNVFKdopyh+zcLht+1xIZO6VrMteXejVhcz8UnRQE7leCdOvCYbBX87eRAAAA +wFX+Q0Cp8SD3Pf607nq0GNYgY+vQR/zqqTnIlYt3kKt0jP6TuvkOUnaANOt29W17LxIR1U +tZxFfyktrT4/RiVRP+QWvdLS32IN3mpCPt+J0oKujlSWrUT0SJgd7ZLePJIOscjuFqW72M +dNV7aCNIisc2QgJbp5EwCNTFxQmdqryk9Pd80kWSSAwWQ5A6jXSrLEAdaFTa9kF/o3DGNe +E/6HOTnt7BFvdE1hetYFnUTR1vqjD21Pi3d5rnePYUOGI1nAAAAMEA9fDwdHOCjosfA1ri +pWZDYYkR5JaxrCFZC5h2LcYL01aCutISH07Z5gmnAVM+CfHkihck9wiGDJuJNTo1mYR1pg +aFgoIFg8LjZzBConlSnHTPYkIYHvYFaE9T4PIS8yjlHjaDn59P06nHRNa5W/4vvhGK8eEn +hpBCQ68huqMZyCH9az6BYR1TasHY7GMbIuMXpswXt9tWRzXpuvQq0BFThNelviTw3JNFhC +cdR2+2wMCErnT0w1Y9fd+8SIHL3OdVAAAAwQDTLPokbpKxlOQOdKMGgn0CZnhiAiLMKp6k +ZQmqNjVEdiOkLWvmoBYMxW93n6uCpyc7p9R+++xXWvfIH7o4fCpiIcMKQtd7Ikp4s4uC6q +xP0QOtGui5wac/iBgd0QB7ZlRh0WNIRS0ej5sn3wHz7es5eq1F/auGhxR6i5N0EhB/qI72 +lFgWtRJsIxi0tm424K6XWEjjj7fe7k9qQ712BVOvvhZp1OK/qfsOl6lj7VPXtcVPr9+6Aw +MsHc/xbLoyRmUAAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.pub b/internal/testhelper/testdata/testroot/certs/valid/server2.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgok= # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1668447678 -3600 # Mon Nov 14 18:41:18 2022 +0100 # Branch heptapod # Node ID e32995c877bf1786724c9937855ef18d0fdc30c7 # Parent cf818cb4e4fe5440a953da19e2e8650bddbf45d5 Added tag heptapod-14.9.0 for changeset cf818cb4e4fe diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -50,3 +50,4 @@ 69c79e2a7c7cd53de504e610f85e0cc61bf184bd heptapod-14.6.0 54e1067b740ecd4e2af0b52e4b2472366aeeb466 heptapod-14.7.0 cfb031a1e9de24b88498850cff796c224ba48edd heptapod-14.7.1 +cf818cb4e4fe5440a953da19e2e8650bddbf45d5 heptapod-14.9.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1669027173 -3600 # Mon Nov 21 11:39:33 2022 +0100 # Branch heptapod # Node ID c6529456e762c07071757b58ff7e1cc87b6947da # Parent e32995c877bf1786724c9937855ef18d0fdc30c7 # Parent 45813b7245308037d79785402e6ab9a6b99fd3a2 Merged upstream v14.10.0 into Heptapod Shell As usual, including changes in Heptapod version files. In 3c492987c9aa, upstream fixed the race condition that we previously had to fix in cf818cb4e4fe. diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.10.0 + +- Implement Push Auth support for 2FA verification !454 + v14.9.0 - Update LabKit library to v1.16.0 !668 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.10.0 + +- Bump to upstream GitLab Shell v14.10.0 (GitLab 15.3 and 15.4 series) + ## 14.9.0 - Bump to upstream GitLab Shell v14.9.0 (GitLab 15.2 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.9.0 +14.10.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.9.0 +14.10.0 diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -4,6 +4,7 @@ "context" "fmt" "io" + "time" "gitlab.com/gitlab-org/labkit/log" @@ -13,6 +14,11 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) +const ( + timeout = 30 * time.Second + prompt = "OTP: " +) + type Command struct { Config *config.Config Args *commandargs.Shell @@ -20,25 +26,51 @@ } func (c *Command) Execute(ctx context.Context) error { - ctxlog := log.ContextLogger(ctx) - ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP(ctx) - - ctxlog.Info("twofactorverify: execute: verifying entered OTP") - err := c.verifyOTP(ctx, otp) + client, err := twofactorverify.NewClient(c.Config) if err != nil { - ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } - ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + fmt.Fprint(c.ReadWriter.Out, prompt) + + resultCh := make(chan string) + go func() { + err := client.PushAuth(ctx, c.Args) + if err == nil { + resultCh <- "OTP has been validated by Push Authentication. Git operations are now allowed." + } + }() + + go func() { + answer, err := c.getOTP(ctx) + if err != nil { + resultCh <- formatErr(err) + } + + if err := client.VerifyOTP(ctx, c.Args, answer); err != nil { + resultCh <- formatErr(err) + } else { + resultCh <- "OTP validation successful. Git operations are now allowed." + } + }() + + var message string + select { + case message = <-resultCh: + case <-ctx.Done(): + message = formatErr(ctx.Err()) + } + + log.WithContextFields(ctx, log.Fields{"message": message}).Info("Two factor verify command finished") + fmt.Fprintf(c.ReadWriter.Out, "\n%v\n", message) + return nil } -func (c *Command) getOTP(ctx context.Context) string { - prompt := "OTP: " - fmt.Fprint(c.ReadWriter.Out, prompt) - +func (c *Command) getOTP(ctx context.Context) (string, error) { var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) @@ -46,21 +78,13 @@ log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") } - return answer -} - -func (c *Command) verifyOTP(ctx context.Context, otp string) error { - client, err := twofactorverify.NewClient(c.Config) - if err != nil { - return err + if answer == "" { + return "", fmt.Errorf("OTP cannot be blank.") } - err = client.VerifyOTP(ctx, c.Args, otp) - if err == nil { - fmt.Fprint(c.ReadWriter.Out, "\nOTP validation successful. Git operations are now allowed.\n") - } else { - fmt.Fprintf(c.ReadWriter.Out, "\nOTP validation failed.\n%v\n", err) - } + return answer, nil +} - return nil +func formatErr(err error) string { + return fmt.Sprintf("OTP validation failed: %v", err) } diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -17,10 +17,20 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) +type blockingReader struct{} + +func (*blockingReader) Read([]byte) (int, error) { + waitInfinitely := make(chan struct{}) + <-waitInfinitely + + return 0, nil +} + func setup(t *testing.T) []testserver.TestRequestHandler { + waitInfinitely := make(chan struct{}) requests := []testserver.TestRequestHandler{ { - Path: "/api/v4/internal/two_factor_otp_check", + Path: "/api/v4/internal/two_factor_manual_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { b, err := io.ReadAll(r.Body) defer r.Body.Close() @@ -31,11 +41,13 @@ require.NoError(t, json.Unmarshal(b, &requestBody)) switch requestBody.KeyId { - case "1": + case "verify_via_otp", "verify_via_otp_with_push_error": body := map[string]interface{}{ "success": true, } json.NewEncoder(w).Encode(body) + case "wait_infinitely": + <-waitInfinitely case "error": body := map[string]interface{}{ "success": false, @@ -47,15 +59,36 @@ } }, }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "verify_via_push": + body := map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "verify_via_otp_with_push_error": + w.WriteHeader(http.StatusInternalServerError) + default: + <-waitInfinitely + } + }, + }, } return requests } -const ( - question = "OTP: \n" - errorHeader = "OTP validation failed.\n" -) +const errorHeader = "OTP validation failed: " func TestExecute(t *testing.T) { requests := setup(t) @@ -65,46 +98,61 @@ testCases := []struct { desc string arguments *commandargs.Shell - answer string + input io.Reader expectedOutput string }{ { - desc: "With a known key id", - arguments: &commandargs.Shell{GitlabKeyId: "1"}, - answer: "123456\n", - expectedOutput: question + - "OTP validation successful. Git operations are now allowed.\n", + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp_with_push_error"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via push authentication", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_push"}, + input: &blockingReader{}, + expectedOutput: "OTP has been validated by Push Authentication. Git operations are now allowed.\n", + }, + { + desc: "With an empty OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + input: bytes.NewBufferString("\n"), + expectedOutput: errorHeader + "OTP cannot be blank.\n", }, { desc: "With bad response", arguments: &commandargs.Shell{GitlabKeyId: "-1"}, - answer: "123456\n", - expectedOutput: question + errorHeader + "Parsing failed\n", + expectedOutput: errorHeader + "Parsing failed\n", }, { desc: "With API returns an error", arguments: &commandargs.Shell{GitlabKeyId: "error"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "error message\n", + expectedOutput: errorHeader + "error message\n", }, { desc: "With API fails", arguments: &commandargs.Shell{GitlabKeyId: "broken"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "Internal API error (500)\n", + expectedOutput: errorHeader + "Internal API error (500)\n", }, { desc: "With missing arguments", arguments: &commandargs.Shell{}, - answer: "yes\n", - expectedOutput: question + errorHeader + "who='' is invalid\n", + expectedOutput: errorHeader + "who='' is invalid\n", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { output := &bytes.Buffer{} - input := bytes.NewBufferString(tc.answer) + + input := tc.input + if input == nil { + input = bytes.NewBufferString("123456\n") + } cmd := &Command{ Config: &config.Config{GitlabUrl: url}, @@ -115,7 +163,29 @@ err := cmd.Execute(context.Background()) require.NoError(t, err) - require.Equal(t, tc.expectedOutput, output.String()) + require.Equal(t, prompt+"\n"+tc.expectedOutput, output.String()) }) } } + +func TestCanceledContext(t *testing.T) { + requests := setup(t) + + output := &bytes.Buffer{} + + url := testserver.StartSocketHttpServer(t, requests) + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: &commandargs.Shell{GitlabKeyId: "wait_infinitely"}, + ReadWriter: &readwriter.ReadWriter{Out: output, In: &bytes.Buffer{}}, + } + + ctx, cancel := context.WithCancel(context.Background()) + + errCh := make(chan error) + go func() { errCh <- cmd.Execute(ctx) }() + cancel() + + require.NoError(t, <-errCh) + require.Equal(t, prompt+"\n"+errorHeader+"context canceled\n", output.String()) +} diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -26,7 +26,7 @@ type RequestBody struct { KeyId string `json:"key_id,omitempty"` UserId int64 `json:"user_id,omitempty"` - OTPAttempt string `json:"otp_attempt"` + OTPAttempt string `json:"otp_attempt,omitempty"` } func NewClient(config *config.Config) (*Client, error) { @@ -44,7 +44,22 @@ return err } - response, err := c.client.Post(ctx, "/two_factor_otp_check", requestBody) + response, err := c.client.Post(ctx, "/two_factor_manual_otp_check", requestBody) + if err != nil { + return err + } + defer response.Body.Close() + + return parse(response) +} + +func (c *Client) PushAuth(ctx context.Context, args *commandargs.Shell) error { + requestBody, err := c.getRequestBody(ctx, args, "") + if err != nil { + return err + } + + response, err := c.client.Post(ctx, "/two_factor_push_otp_check", requestBody) if err != nil { return err } diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -17,49 +17,55 @@ ) func initialize(t *testing.T) []testserver.TestRequestHandler { + handler := func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "0": + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "1": + body := map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "2": + w.WriteHeader(http.StatusForbidden) + body := &client.ErrorResponse{ + Message: "Not allowed!", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "3": + w.Write([]byte("{ \"message\": \"broken json!\"")) + case "4": + w.WriteHeader(http.StatusForbidden) + } + + if requestBody.UserId == 1 { + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + } + } + requests := []testserver.TestRequestHandler{ { - Path: "/api/v4/internal/two_factor_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - switch requestBody.KeyId { - case "0": - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "1": - body := map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "2": - w.WriteHeader(http.StatusForbidden) - body := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) - } - - if requestBody.UserId == 1 { - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - } - }, + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: handler, + }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: handler, }, { Path: "/api/v4/internal/discover", @@ -140,6 +146,57 @@ } } +func TestVerifyPush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "0"} + err := client.PushAuth(context.Background(), args) + require.NoError(t, err) +} + +func TestErrorMessagePush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "1"} + err := client.PushAuth(context.Background(), args) + require.Equal(t, "error message", err.Error()) +} + +func TestErrorResponsesPush(t *testing.T) { + client := setup(t) + + testCases := []struct { + desc string + fakeId string + expectedError string + }{ + { + desc: "A response with an error message", + fakeId: "2", + expectedError: "Not allowed!", + }, + { + desc: "A response with bad JSON", + fakeId: "3", + expectedError: "Parsing failed", + }, + { + desc: "An error response without message", + fakeId: "4", + expectedError: "Internal API error (403)", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + args := &commandargs.Shell{GitlabKeyId: tc.fakeId} + err := client.PushAuth(context.Background(), args) + + require.EqualError(t, err, tc.expectedError) + }) + } +} + func setup(t *testing.T) *Client { requests := initialize(t) url := testserver.StartSocketHttpServer(t, requests) diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -223,12 +223,12 @@ {"disallowed command", disallowedcommand.Error}, {"not our ref", grpcstatus.Error(grpccodes.Internal, `rpc error: code = Internal desc = cmd wait: exit status 128, stderr: "fatal: git upload-pack: not our ref 9106d18f6a1b8022f6517f479696f3e3ea5e68c1"`)}, } { - ignoredError := ignoredError // Capture range variable, see "Race on loop counter" in https://go.dev/doc/articles/race_detector t.Run(ignoredError.desc, func(t *testing.T) { conn, chans = setup(1, newChannel) + ignored := ignoredError.err conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) - return ignoredError.err + return ignored }) require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) diff --git a/spec/gitlab_shell_two_factor_verify_spec.rb b/spec/gitlab_shell_two_factor_verify_spec.rb --- a/spec/gitlab_shell_two_factor_verify_spec.rb +++ b/spec/gitlab_shell_two_factor_verify_spec.rb @@ -11,71 +11,115 @@ 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } end + let(:correct_otp) { '123456' } + before(:context) do write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") end def mock_server(server) - server.mount_proc('/api/v4/internal/two_factor_otp_check') do |req, res| + server.mount_proc('/api/v4/internal/two_factor_manual_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + + res.body = if params['otp_attempt'] == correct_otp + { success: true }.to_json + else + { success: false, message: 'boom!' }.to_json + end + end + + server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| res.content_type = 'application/json' res.status = 200 params = JSON.parse(req.body) - key_id = params['key_id'] || params['user_id'].to_s + id = params['key_id'] || params['user_id'].to_s - if key_id == '100' + if id == '100' + res.body = { success: false, message: 'boom!' }.to_json + else res.body = { success: true }.to_json - else - res.body = { success: false, message: 'boom!' }.to_json end end - server.mount_proc('/api/v4/internal/discover') do |_, res| + server.mount_proc('/api/v4/internal/discover') do |req, res| res.status = 200 res.content_type = 'application/json' - res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + + if req.query['username'] == 'someone' + res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + else + res.body = { id: 101, name: 'Another User', username: 'another' }.to_json + end end end - describe 'command' do + describe 'entering OTP manually' do + let(:cmd) { "#{gitlab_shell_path} key-100" } + context 'when key is provided' do - let(:cmd) { "#{gitlab_shell_path} key-100" } - - it 'prints a successful verification message' do - verify_successful_verification!(cmd) + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) end end context 'when username is provided' do let(:cmd) { "#{gitlab_shell_path} username-someone" } - it 'prints a successful verification message' do - verify_successful_verification!(cmd) + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) end end - context 'when API error occurs' do - let(:cmd) { "#{gitlab_shell_path} key-101" } + it 'shows an error when an invalid otp is provided' do + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + stdin.puts('000000') - it 'prints the error message' do - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') - - expect(stdout.flush.read).to eq("\nOTP validation failed.\nboom!\n") - end + expect(stdout.flush.read).to eq("\nOTP validation failed: boom!\n") end end end - def verify_successful_verification!(cmd) + describe 'authorizing via push' do + context 'when key is provided' do + let(:cmd) { "#{gitlab_shell_path} key-101" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + + context 'when username is provided' do + let(:cmd) { "#{gitlab_shell_path} username-another" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + end + + def verify_successful_otp_verification!(cmd) Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') + asks_for_otp(stdout) + stdin.puts(correct_otp) expect(stdout.flush.read).to eq("\nOTP validation successful. Git operations are now allowed.\n") end end + + def verify_successful_push_verification!(cmd) + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + + expect(stdout.flush.read).to eq("\nOTP has been validated by Push Authentication. Git operations are now allowed.\n") + end + end + + def asks_for_otp(stdout) + expect(stdout.gets(5)).to eq('OTP: ') + end end # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1669113408 -3600 # Tue Nov 22 11:36:48 2022 +0100 # Branch heptapod-stable # Node ID f8f9fec42f926a6cee1f1b54a90d371e96c44d77 # Parent 0b31292ecc0575dfcd23ee86046834b5a68cdd0d # Parent e32995c877bf1786724c9937855ef18d0fdc30c7 heptapod#711: making 0.34 the new stable diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ tags tmp/* vendor +.DS_Store diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,8 @@ - '/ci/danger-review.yml' variables: - DOCKER_VERSION: "20.10.3" + DOCKER_VERSION: "20.10.15" + BUNDLE_FROZEN: "true" workflow: rules: &workflow_rules diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -44,3 +44,10 @@ 98d781e90b1bb472b9c37ad5fbdbed541e1457c5 heptapod-14.2.0 7e62e4be19def9c1f1773e326480a9429210bb8d heptapod-14.3.0 fca0cc645e5bbe898f18befe0f31f51f091db81b heptapod-14.3.1 +61f29699614da28ec795cec912a75f398df84af3 heptapod-14.3.2 +8696661a67a6e7816fca8066dcbdc66b261feb5b heptapod-14.4.0 +aaebb02398004cb60c56d98824084bf9a2c17073 heptapod-14.5.0 +69c79e2a7c7cd53de504e610f85e0cc61bf184bd heptapod-14.6.0 +54e1067b740ecd4e2af0b52e4b2472366aeeb466 heptapod-14.7.0 +cfb031a1e9de24b88498850cff796c224ba48edd heptapod-14.7.1 +cf818cb4e4fe5440a953da19e2e8650bddbf45d5 heptapod-14.9.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,62 @@ +v14.9.0 + +- Update LabKit library to v1.16.0 !668 + +v14.8.0 + +- go: Bump major version to v14 !666 +- Pass original IP from PROXY requests to internal API calls !665 +- Fix make install copying the wrong binaries !664 +- gitlab-sshd: Add support for configuring host certificates !661 + +v14.7.4 + +- gitlab-sshd: Update crypto module to fix RSA keys with old gpg-agent !662 + +v14.7.3 + +- Ignore "not our ref" errors from gitlab-sshd error metrics !656 + +v14.7.2 + +- Exclude disallowed command from error rate !654 + +v14.7.1 + +- Log gitlab-sshd session level indicator errors !650 +- Improve establish session duration metrics !651 + +v14.7.0 + +- Abort long-running unauthenticated SSH connections !647 +- Close the connection when context is canceled !646 + +v14.6.1 + +- Return support for diffie-hellman-group14-sha1 !644 + +v14.6.0 + +- Exclude Gitaly unavailable error from error rate !641 +- Downgrade auth EOF messages from warning to debug !641 +- Display constistently in gitlab-sshd and gitlab-shell !641 +- Downgrade host key mismatch messages from warning to debug !639 +- Introduce a GitLab-SSHD server version during handshake !640 +- Narrow supported kex algorithms !638 + +v14.5.0 + +- Make ProxyHeaderTimeout configurable !635 + +v14.4.0 + +- Allow configuring SSH server algorithms !633 +- Update gitlab-org/golang-crypto module version !632 + +v14.3.1 + +- Exclude API errors from error rate !630 + v14.3.0 - Remove deprecated bundler-audit !626 diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -113,4 +113,4 @@ rspec (~> 3.8.0) BUNDLED WITH - 2.3.6 + 2.3.15 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,34 @@ The corresponding tag is heptapod-x.y.z +## 14.9.0 + +- Bump to upstream GitLab Shell v14.9.0 (GitLab 15.2 series) + +## 14.7.1 + +- Bump to upstream GitLab Shell v14.7.4 (GitLab 15.1 series) + +## 14.7.0 + +- Bump to upstream GitLab Shell v14.7.0 + +## 14.6.0 + +- Bump to upstream GitLab Shell v14.6.0 + +## 14.5.0 + +- Bump to upstream GitLab Shell v14.5.0 + +## 14.4.0 + +- Bump to upstream GitLab Shell v14.4.0 + +## 14.3.2 + +- Bump to upstream GitLab Shell v14.3.1 + ## 14.3.1 - Filled in `HEPTAPOD_VERSION` (had been forgotten in 14.0 through diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.3.1 +14.9.0 diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ mkdir -p $(DESTDIR)$(PREFIX)/bin/ install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check - install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-sshd - + install -m755 bin/gitlab-shell-authorized-keys-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check + install -m755 bin/gitlab-shell-authorized-principals-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check + install -m755 bin/gitlab-sshd $(DESTDIR)$(PREFIX)/bin/gitlab-sshd diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -58,6 +58,44 @@ There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails). +## GitLab SaaS + +A diagram of the flow of `gitlab-shell` on GitLab.com: + +```mermaid +graph LR + a2 --> b2 + a2 --> b3 + a2 --> b4 + b2 --> c1 + b3 --> c1 + b4 --> c1 + c2 --> d1 + c2 --> d2 + c2 --> d3 + d1 --> e1 + d2 --> e1 + d3 --> e1 + a1[Cloudflare] --> a2[TCP<br/> load balancer] + e1[Git] + + subgraph HAProxy Fleet + b2[HAProxy] + b3[HAProxy] + b4[HAProxy] + end + + subgraph GKE + c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods] + end + + subgraph Gitaly + d1[Gitaly] + d2[Gitaly] + d3[Gitaly] + end +``` + ## Releasing See [PROCESS.md](./PROCESS.md) diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.3.0 +14.9.0 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -15,8 +15,8 @@ "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( @@ -76,6 +76,7 @@ testErrorMessage(t, client) testAuthenticationHeader(t, client) testJWTAuthenticationHeader(t, client) + testXForwardedForHeader(t, client) }) } } @@ -221,6 +222,21 @@ }) } +func testXForwardedForHeader(t *testing.T, client *GitlabNetClient) { + t.Run("X-Forwarded-For Header inserted if original address in context", func(t *testing.T) { + ctx := context.WithValue(context.Background(), OriginalRemoteIPContextKey{}, "196.7.0.238") + response, err := client.Get(ctx, "/x_forwarded_for") + require.NoError(t, err) + require.NotNil(t, response) + + defer response.Body.Close() + + responseBody, err := io.ReadAll(response.Body) + require.NoError(t, err) + require.Equal(t, "196.7.0.238", string(responseBody)) + }) +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { @@ -257,6 +273,12 @@ }, }, { + Path: "/api/v4/internal/x_forwarded_for", + Handler: func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, r.Header.Get("X-Forwarded-For")) + }, + }, + { Path: "/api/v4/internal/error", Handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -37,6 +37,17 @@ userAgent string } +type ApiError struct { + Msg string +} + +// To use as the key in a Context to set an X-Forwarded-For header in a request +type OriginalRemoteIPContextKey struct{} + +func (e *ApiError) Error() string { + return e.Msg +} + func NewGitlabNetClient( user, password, @@ -101,9 +112,9 @@ parsedResponse := &ErrorResponse{} if err := json.NewDecoder(resp.Body).Decode(parsedResponse); err != nil { - return fmt.Errorf("Internal API error (%v)", resp.StatusCode) + return &ApiError{fmt.Sprintf("Internal API error (%v)", resp.StatusCode)} } else { - return fmt.Errorf(parsedResponse.Message) + return &ApiError{parsedResponse.Message} } } @@ -142,6 +153,11 @@ } request.Header.Set(apiSecretHeaderName, tokenString) + originalRemoteIP, ok := ctx.Value(OriginalRemoteIPContextKey{}).(string) + if ok { + request.Header.Add("X-Forwarded-For", originalRemoteIP) + } + request.Header.Add("Content-Type", "application/json") request.Header.Add("User-Agent", c.userAgent) request.Close = true @@ -157,7 +173,7 @@ if err != nil { logger.WithError(err).Error("Internal API unreachable") - return nil, fmt.Errorf("Internal API unreachable") + return nil, &ApiError{"Internal API unreachable"} } if response != nil { diff --git a/client/httpclient_test.go b/client/httpclient_test.go --- a/client/httpclient_test.go +++ b/client/httpclient_test.go @@ -11,7 +11,7 @@ "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func TestReadTimeout(t *testing.T) { diff --git a/client/httpsclient_test.go b/client/httpsclient_test.go --- a/client/httpsclient_test.go +++ b/client/httpsclient_test.go @@ -9,8 +9,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) //go:generate openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 -out ../internal/testhelper/testdata/testroot/certs/client/server.crt -keyout ../internal/testhelper/testdata/testroot/certs/client/key.pem -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=GitLab-Shell/CN=localhost" diff --git a/client/testserver/testserver.go b/client/testserver/testserver.go --- a/client/testserver/testserver.go +++ b/client/testserver/testserver.go @@ -14,7 +14,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/cmd/check/command/command.go b/cmd/check/command/command.go --- a/cmd/check/command/command.go +++ b/cmd/check/command/command.go @@ -1,11 +1,11 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/check/command/command_test.go b/cmd/check/command/command_test.go --- a/cmd/check/command/command_test.go +++ b/cmd/check/command/command_test.go @@ -4,11 +4,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/healthcheck" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/check/main.go b/cmd/check/main.go --- a/cmd/check/main.go +++ b/cmd/check/main.go @@ -4,12 +4,12 @@ "fmt" "os" - checkCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + checkCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command.go b/cmd/gitlab-shell-authorized-keys-check/command/command.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-keys-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-keys-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-keys-check/main.go b/cmd/gitlab-shell-authorized-keys-check/main.go --- a/cmd/gitlab-shell-authorized-keys-check/main.go +++ b/cmd/gitlab-shell-authorized-keys-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-keys-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-keys-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command.go b/cmd/gitlab-shell-authorized-principals-check/command/command.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command.go @@ -1,12 +1,12 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go --- a/cmd/gitlab-shell-authorized-principals-check/command/command_test.go +++ b/cmd/gitlab-shell-authorized-principals-check/command/command_test.go @@ -4,12 +4,12 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/authorizedprincipals" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/authorizedprincipals" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell-authorized-principals-check/main.go b/cmd/gitlab-shell-authorized-principals-check/main.go --- a/cmd/gitlab-shell-authorized-principals-check/main.go +++ b/cmd/gitlab-shell-authorized-principals-check/main.go @@ -4,13 +4,13 @@ "fmt" "os" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell-authorized-principals-check/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell-authorized-principals-check/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" ) func main() { diff --git a/cmd/gitlab-shell/command/command.go b/cmd/gitlab-shell/command/command.go --- a/cmd/gitlab-shell/command/command.go +++ b/cmd/gitlab-shell/command/command.go @@ -1,21 +1,21 @@ package command import ( - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/hg" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/hg" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { diff --git a/cmd/gitlab-shell/command/command_test.go b/cmd/gitlab-shell/command/command_test.go --- a/cmd/gitlab-shell/command/command_test.go +++ b/cmd/gitlab-shell/command/command_test.go @@ -5,20 +5,20 @@ "testing" "github.com/stretchr/testify/require" - cmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/personalaccesstoken" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/receivepack" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorrecover" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/twofactorverify" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadarchive" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/uploadpack" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + cmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/receivepack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadarchive" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/uploadpack" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-shell/main.go b/cmd/gitlab-shell/main.go --- a/cmd/gitlab-shell/main.go +++ b/cmd/gitlab-shell/main.go @@ -11,14 +11,14 @@ "gitlab.com/gitlab-org/labkit/fips" "gitlab.com/gitlab-org/labkit/log" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) var ( diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -24,7 +24,7 @@ "github.com/stretchr/testify/require" gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) diff --git a/cmd/gitlab-sshd/main.go b/cmd/gitlab-sshd/main.go --- a/cmd/gitlab-sshd/main.go +++ b/cmd/gitlab-sshd/main.go @@ -8,10 +8,10 @@ "syscall" "time" - "gitlab.com/gitlab-org/gitlab-shell/internal/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshd" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/logger" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshd" "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/monitoring" @@ -99,11 +99,12 @@ sig := <-done signal.Reset(syscall.SIGINT, syscall.SIGTERM) - log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": cfg.Server.GracePeriodSeconds, "signal": sig.String()}).Info("Shutdown initiated") + gracePeriod := time.Duration(cfg.Server.GracePeriod) + log.WithContextFields(ctx, log.Fields{"shutdown_timeout_s": gracePeriod.Seconds(), "signal": sig.String()}).Info("Shutdown initiated") server.Shutdown() - <-time.After(cfg.Server.GracePeriod()) + <-time.After(gracePeriod) cancel() diff --git a/config.yml.example b/config.yml.example --- a/config.yml.example +++ b/config.yml.example @@ -92,16 +92,30 @@ web_listen: "localhost:9122" # Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10. concurrent_sessions_limit: 10 - # Sets an interval after which server will send keepalive message to a client + # Sets an interval after which server will send keepalive message to a client. Defaults to 15s. client_alive_interval: 15 - # The server waits for this time (in seconds) for the ongoing connections to complete before shutting down. Defaults to 10. + # The server waits for this time for the ongoing connections to complete before shutting down. Defaults to 10s. grace_period: 10 + # The server disconnects after this time if the user has not successfully logged in. Defaults to 60s. + login_grace_time: 60 + # A short timeout to decide to abort the connection if the protocol header is not seen within it. Defaults to 500ms + proxy_header_timeout: 500ms # The endpoint that returns 200 OK if the server is ready to receive incoming connections; otherwise, it returns 503 Service Unavailable. Defaults to "/start". readiness_probe: "/start" # The endpoint that returns 200 OK if the server is alive. Defaults to "/health". liveness_probe: "/health" + # Specifies the available message authentication code algorithms that are used for protecting data integrity + macs: [hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1] + # Specifies the available Key Exchange algorithms + kex_algorithms: [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1] + # Specified the ciphers allowed + ciphers: [aes128-gcm@openssh.com, chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-ctr, aes192-ctr,aes256-ctr] # SSH host key files. host_key_files: - /run/secrets/ssh-hostkeys/ssh_host_rsa_key - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key + host_key_certs: + - /run/secrets/ssh-hostkeys/ssh_host_rsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ecdsa_key-cert.pub + - /run/secrets/ssh-hostkeys/ssh_host_ed25519_key-cert.pub diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module gitlab.com/gitlab-org/gitlab-shell +module gitlab.com/gitlab-org/gitlab-shell/v14 go 1.17 @@ -11,9 +11,10 @@ github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.1 + github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 - gitlab.com/gitlab-org/labkit v1.14.0 + gitlab.com/gitlab-org/labkit v1.16.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/grpc v1.40.0 @@ -59,7 +60,6 @@ github.com/prometheus/procfs v0.7.3 // indirect github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect github.com/shirou/gopsutil/v3 v3.21.2 // indirect - github.com/sirupsen/logrus v1.8.1 // 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 @@ -81,4 +81,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) -replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 +replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -887,16 +887,17 @@ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= +gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80 h1:rVzTLlEDlX/ocWqNxeuxb9XklLzmI9FdP0teRqkSg00= -gitlab.com/gitlab-org/golang-crypto v0.0.0-20220128174055-5be136049a80/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= +gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= 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.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= +gitlab.com/gitlab-org/labkit v1.16.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= diff --git a/internal/command/authorizedkeys/authorized_keys.go b/internal/command/authorizedkeys/authorized_keys.go --- a/internal/command/authorizedkeys/authorized_keys.go +++ b/internal/command/authorizedkeys/authorized_keys.go @@ -5,11 +5,11 @@ "fmt" "strconv" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedkeys/authorized_keys_test.go b/internal/command/authorizedkeys/authorized_keys_test.go --- a/internal/command/authorizedkeys/authorized_keys_test.go +++ b/internal/command/authorizedkeys/authorized_keys_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/authorizedprincipals/authorized_principals.go b/internal/command/authorizedprincipals/authorized_principals.go --- a/internal/command/authorizedprincipals/authorized_principals.go +++ b/internal/command/authorizedprincipals/authorized_principals.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/keyline" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" ) type Command struct { diff --git a/internal/command/authorizedprincipals/authorized_principals_test.go b/internal/command/authorizedprincipals/authorized_principals_test.go --- a/internal/command/authorizedprincipals/authorized_principals_test.go +++ b/internal/command/authorizedprincipals/authorized_principals_test.go @@ -7,9 +7,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestExecute(t *testing.T) { diff --git a/internal/command/command.go b/internal/command/command.go --- a/internal/command/command.go +++ b/internal/command/command.go @@ -3,7 +3,7 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) diff --git a/internal/command/command_test.go b/internal/command/command_test.go --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -6,7 +6,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" ) diff --git a/internal/command/commandargs/shell.go b/internal/command/commandargs/shell.go --- a/internal/command/commandargs/shell.go +++ b/internal/command/commandargs/shell.go @@ -6,7 +6,7 @@ "strings" "github.com/mattn/go-shellwords" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) const ( diff --git a/internal/command/discover/discover.go b/internal/command/discover/discover.go --- a/internal/command/discover/discover.go +++ b/internal/command/discover/discover.go @@ -4,10 +4,10 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Command struct { diff --git a/internal/command/discover/discover_test.go b/internal/command/discover/discover_test.go --- a/internal/command/discover/discover_test.go +++ b/internal/command/discover/discover_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/command/healthcheck/healthcheck.go b/internal/command/healthcheck/healthcheck.go --- a/internal/command/healthcheck/healthcheck.go +++ b/internal/command/healthcheck/healthcheck.go @@ -4,9 +4,9 @@ "context" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/healthcheck/healthcheck_test.go b/internal/command/healthcheck/healthcheck_test.go --- a/internal/command/healthcheck/healthcheck_test.go +++ b/internal/command/healthcheck/healthcheck_test.go @@ -9,10 +9,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/healthcheck" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" ) var ( diff --git a/internal/command/hg/hg.go b/internal/command/hg/hg.go --- a/internal/command/hg/hg.go +++ b/internal/command/hg/hg.go @@ -10,11 +10,11 @@ "strings" "syscall" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/hgaccesslevel" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/hgaccesslevel" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func Exec(filename string, args []string, env []string) error { diff --git a/internal/command/hg/hg_test.go b/internal/command/hg/hg_test.go --- a/internal/command/hg/hg_test.go +++ b/internal/command/hg/hg_test.go @@ -8,11 +8,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) type fakeExec struct { diff --git a/internal/command/lfsauthenticate/lfsauthenticate.go b/internal/command/lfsauthenticate/lfsauthenticate.go --- a/internal/command/lfsauthenticate/lfsauthenticate.go +++ b/internal/command/lfsauthenticate/lfsauthenticate.go @@ -8,12 +8,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" ) const ( diff --git a/internal/command/lfsauthenticate/lfsauthenticate_test.go b/internal/command/lfsauthenticate/lfsauthenticate_test.go --- a/internal/command/lfsauthenticate/lfsauthenticate_test.go +++ b/internal/command/lfsauthenticate/lfsauthenticate_test.go @@ -10,13 +10,13 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/lfsauthenticate" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/lfsauthenticate" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestFailedRequests(t *testing.T) { diff --git a/internal/command/personalaccesstoken/personalaccesstoken.go b/internal/command/personalaccesstoken/personalaccesstoken.go --- a/internal/command/personalaccesstoken/personalaccesstoken.go +++ b/internal/command/personalaccesstoken/personalaccesstoken.go @@ -10,10 +10,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) const ( diff --git a/internal/command/personalaccesstoken/personalaccesstoken_test.go b/internal/command/personalaccesstoken/personalaccesstoken_test.go --- a/internal/command/personalaccesstoken/personalaccesstoken_test.go +++ b/internal/command/personalaccesstoken/personalaccesstoken_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/personalaccesstoken" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" ) var ( diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/receivepack/gitalycall_test.go b/internal/command/receivepack/gitalycall_test.go --- a/internal/command/receivepack/gitalycall_test.go +++ b/internal/command/receivepack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestReceivePack(t *testing.T) { diff --git a/internal/command/receivepack/receivepack.go b/internal/command/receivepack/receivepack.go --- a/internal/command/receivepack/receivepack.go +++ b/internal/command/receivepack/receivepack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/receivepack/receivepack_test.go b/internal/command/receivepack/receivepack_test.go --- a/internal/command/receivepack/receivepack_test.go +++ b/internal/command/receivepack/receivepack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/shared/accessverifier/accessverifier.go b/internal/command/shared/accessverifier/accessverifier.go --- a/internal/command/shared/accessverifier/accessverifier.go +++ b/internal/command/shared/accessverifier/accessverifier.go @@ -4,11 +4,11 @@ "context" "errors" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/console" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) type Response = accessverifier.Response diff --git a/internal/command/shared/accessverifier/accessverifier_test.go b/internal/command/shared/accessverifier/accessverifier_test.go --- a/internal/command/shared/accessverifier/accessverifier_test.go +++ b/internal/command/shared/accessverifier/accessverifier_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) var ( diff --git a/internal/command/shared/customaction/customaction.go b/internal/command/shared/customaction/customaction.go --- a/internal/command/shared/customaction/customaction.go +++ b/internal/command/shared/customaction/customaction.go @@ -9,12 +9,12 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/pktline" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/pktline" ) type Request struct { diff --git a/internal/command/shared/customaction/customaction_test.go b/internal/command/shared/customaction/customaction_test.go --- a/internal/command/shared/customaction/customaction_test.go +++ b/internal/command/shared/customaction/customaction_test.go @@ -10,10 +10,10 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) func TestExecuteEOFSent(t *testing.T) { diff --git a/internal/command/shared/hgaccesslevel/hgaccesslevel.go b/internal/command/shared/hgaccesslevel/hgaccesslevel.go --- a/internal/command/shared/hgaccesslevel/hgaccesslevel.go +++ b/internal/command/shared/hgaccesslevel/hgaccesslevel.go @@ -5,10 +5,10 @@ "errors" "fmt" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" ) type Response = accessverifier.HgResponse diff --git a/internal/command/twofactorrecover/twofactorrecover.go b/internal/command/twofactorrecover/twofactorrecover.go --- a/internal/command/twofactorrecover/twofactorrecover.go +++ b/internal/command/twofactorrecover/twofactorrecover.go @@ -8,10 +8,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) const readerLimit = 1024 diff --git a/internal/command/twofactorrecover/twofactorrecover_test.go b/internal/command/twofactorrecover/twofactorrecover_test.go --- a/internal/command/twofactorrecover/twofactorrecover_test.go +++ b/internal/command/twofactorrecover/twofactorrecover_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorrecover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" ) var ( diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -7,10 +7,10 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) type Command struct { diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/twofactorverify" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) func setup(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadarchive/gitalycall_test.go b/internal/command/uploadarchive/gitalycall_test.go --- a/internal/command/uploadarchive/gitalycall_test.go +++ b/internal/command/uploadarchive/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadArchive(t *testing.T) { diff --git a/internal/command/uploadarchive/uploadarchive.go b/internal/command/uploadarchive/uploadarchive.go --- a/internal/command/uploadarchive/uploadarchive.go +++ b/internal/command/uploadarchive/uploadarchive.go @@ -3,11 +3,11 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadarchive/uploadarchive_test.go b/internal/command/uploadarchive/uploadarchive_test.go --- a/internal/command/uploadarchive/uploadarchive_test.go +++ b/internal/command/uploadarchive/uploadarchive_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -7,9 +7,9 @@ "gitlab.com/gitlab-org/gitaly/v14/client" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/handler" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" ) func (c *Command) performGitalyCall(ctx context.Context, response *accessverifier.Response) error { diff --git a/internal/command/uploadpack/gitalycall_test.go b/internal/command/uploadpack/gitalycall_test.go --- a/internal/command/uploadpack/gitalycall_test.go +++ b/internal/command/uploadpack/gitalycall_test.go @@ -8,12 +8,12 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestUploadPack(t *testing.T) { diff --git a/internal/command/uploadpack/uploadpack.go b/internal/command/uploadpack/uploadpack.go --- a/internal/command/uploadpack/uploadpack.go +++ b/internal/command/uploadpack/uploadpack.go @@ -3,12 +3,12 @@ import ( "context" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/customaction" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/customaction" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) type Command struct { diff --git a/internal/command/uploadpack/uploadpack_test.go b/internal/command/uploadpack/uploadpack_test.go --- a/internal/command/uploadpack/uploadpack_test.go +++ b/internal/command/uploadpack/uploadpack_test.go @@ -7,11 +7,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper/requesthandlers" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper/requesthandlers" ) func TestForbiddenAccess(t *testing.T) { diff --git a/internal/config/config.go b/internal/config/config.go --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,9 +12,9 @@ yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) const ( @@ -27,17 +27,25 @@ defaultHgrcPath string = "/opt/gitlab/etc/docker.hgrc:/etc/gitlab/heptapod.hgrc" ) +type YamlDuration time.Duration + type ServerConfig struct { - Listen string `yaml:"listen,omitempty"` - ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` - ProxyPolicy string `yaml:"proxy_policy,omitempty"` - WebListen string `yaml:"web_listen,omitempty"` - ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` - ClientAliveIntervalSeconds int64 `yaml:"client_alive_interval,omitempty"` - GracePeriodSeconds uint64 `yaml:"grace_period"` - ReadinessProbe string `yaml:"readiness_probe"` - LivenessProbe string `yaml:"liveness_probe"` - HostKeyFiles []string `yaml:"host_key_files,omitempty"` + Listen string `yaml:"listen,omitempty"` + ProxyProtocol bool `yaml:"proxy_protocol,omitempty"` + ProxyPolicy string `yaml:"proxy_policy,omitempty"` + WebListen string `yaml:"web_listen,omitempty"` + ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"` + ClientAliveInterval YamlDuration `yaml:"client_alive_interval,omitempty"` + GracePeriod YamlDuration `yaml:"grace_period"` + ProxyHeaderTimeout YamlDuration `yaml:"proxy_header_timeout"` + LoginGraceTime YamlDuration `yaml:"login_grace_time"` + ReadinessProbe string `yaml:"readiness_probe"` + LivenessProbe string `yaml:"liveness_probe"` + HostKeyFiles []string `yaml:"host_key_files,omitempty"` + HostCertFiles []string `yaml:"host_cert_files,omitempty"` + MACs []string `yaml:"macs"` + KexAlgorithms []string `yaml:"kex_algorithms"` + Ciphers []string `yaml:"ciphers"` } type HttpSettingsConfig struct { @@ -103,13 +111,15 @@ } DefaultServerConfig = ServerConfig{ - Listen: "[::]:22", - WebListen: "localhost:9122", - ConcurrentSessionsLimit: 10, - GracePeriodSeconds: 10, - ClientAliveIntervalSeconds: 15, - ReadinessProbe: "/start", - LivenessProbe: "/health", + Listen: "[::]:22", + WebListen: "localhost:9122", + ConcurrentSessionsLimit: 10, + GracePeriod: YamlDuration(10 * time.Second), + ClientAliveInterval: YamlDuration(15 * time.Second), + ProxyHeaderTimeout: YamlDuration(500 * time.Millisecond), + LoginGraceTime: YamlDuration(60 * time.Second), + ReadinessProbe: "/start", + LivenessProbe: "/health", HostKeyFiles: []string{ "/run/secrets/ssh-hostkeys/ssh_host_rsa_key", "/run/secrets/ssh-hostkeys/ssh_host_ecdsa_key", @@ -118,12 +128,15 @@ } ) -func (sc *ServerConfig) ClientAliveInterval() time.Duration { - return time.Duration(sc.ClientAliveIntervalSeconds) * time.Second -} +func (d *YamlDuration) UnmarshalYAML(unmarshal func(interface{}) error) error { + var intDuration int + if err := unmarshal(&intDuration); err != nil { + return unmarshal((*time.Duration)(d)) + } -func (sc *ServerConfig) GracePeriod() time.Duration { - return time.Duration(sc.GracePeriodSeconds) * time.Second + *d = YamlDuration(time.Duration(intDuration) * time.Second) + + return nil } func (c *Config) ApplyGlobalState() { diff --git a/internal/config/config_test.go b/internal/config/config_test.go --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -3,12 +3,14 @@ import ( "os" "testing" + "time" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" + yaml "gopkg.in/yaml.v2" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestConfigApplyGlobalState(t *testing.T) { @@ -39,7 +41,7 @@ require.NoError(t, err) var actualNames []string - for _, m := range ms[0:10] { + for _, m := range ms[0:9] { actualNames = append(actualNames, m.GetName()) } @@ -47,7 +49,6 @@ "gitlab_shell_http_in_flight_requests", "gitlab_shell_http_request_duration_seconds", "gitlab_shell_http_requests_total", - "gitlab_shell_sshd_canceled_sessions", "gitlab_shell_sshd_concurrent_limited_sessions_total", "gitlab_shell_sshd_in_flight_connections", "gitlab_shell_sshd_session_duration_seconds", @@ -58,3 +59,40 @@ require.Equal(t, expectedMetricNames, actualNames) } + +func TestNewFromDir(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + cfg, err := NewFromDir(testhelper.TestRoot) + require.NoError(t, err) + + require.Equal(t, 10*time.Second, time.Duration(cfg.Server.GracePeriod)) + require.Equal(t, 1*time.Minute, time.Duration(cfg.Server.ClientAliveInterval)) + require.Equal(t, 500*time.Millisecond, time.Duration(cfg.Server.ProxyHeaderTimeout)) +} + +func TestYAMLDuration(t *testing.T) { + testCases := []struct { + desc string + data string + duration time.Duration + }{ + {"seconds assumed by default", "duration: 10", 10 * time.Second}, + {"milliseconds are parsed", "duration: 500ms", 500 * time.Millisecond}, + {"minutes are parsed", "duration: 1m", 1 * time.Minute}, + } + + type durationCfg struct { + Duration YamlDuration `yaml:"duration"` + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + var cfg durationCfg + err := yaml.Unmarshal([]byte(tc.data), &cfg) + require.NoError(t, err) + + require.Equal(t, tc.duration, time.Duration(cfg.Duration)) + }) + } +} diff --git a/internal/executable/executable_test.go b/internal/executable/executable_test.go --- a/internal/executable/executable_test.go +++ b/internal/executable/executable_test.go @@ -4,7 +4,7 @@ "errors" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "github.com/stretchr/testify/require" ) diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -17,7 +17,7 @@ "gitlab.com/gitlab-org/labkit/log" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type Command struct { diff --git a/internal/gitaly/gitaly_test.go b/internal/gitaly/gitaly_test.go --- a/internal/gitaly/gitaly_test.go +++ b/internal/gitaly/gitaly_test.go @@ -7,7 +7,7 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) func TestPrometheusMetrics(t *testing.T) { diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -3,14 +3,13 @@ import ( "context" "fmt" - "net" "net/http" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( @@ -86,7 +85,7 @@ request.KeyId = args.GitlabKeyId } - request.CheckIp = parseIP(args.Env.RemoteAddr) + request.CheckIp = gitlabnet.ParseIP(args.Env.RemoteAddr) response, err := c.client.Post(ctx, "/allowed", request) if err != nil { @@ -117,18 +116,3 @@ func (r *Response) IsCustomAction() bool { return r.StatusCode == http.StatusMultipleChoices } - -func parseIP(remoteAddr string) string { - // The remoteAddr field can be filled by: - // 1. An IP address via the SSH_CONNECTION environment variable - // 2. A host:port combination via the PROXY protocol - ip, _, err := net.SplitHostPort(remoteAddr) - - // If we don't have a port or can't parse this address for some reason, - // just return the original string. - if err != nil { - return remoteAddr - } - - return ip -} diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -11,11 +11,11 @@ "github.com/stretchr/testify/require" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) var ( diff --git a/internal/gitlabnet/accessverifier/hg_client.go b/internal/gitlabnet/accessverifier/hg_client.go --- a/internal/gitlabnet/accessverifier/hg_client.go +++ b/internal/gitlabnet/accessverifier/hg_client.go @@ -5,10 +5,10 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type HgClient struct { diff --git a/internal/gitlabnet/accessverifier/hg_client_test.go b/internal/gitlabnet/accessverifier/hg_client_test.go --- a/internal/gitlabnet/accessverifier/hg_client_test.go +++ b/internal/gitlabnet/accessverifier/hg_client_test.go @@ -10,11 +10,11 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func buildHgExpectedResponse() *HgResponse { diff --git a/internal/gitlabnet/authorizedkeys/client.go b/internal/gitlabnet/authorizedkeys/client.go --- a/internal/gitlabnet/authorizedkeys/client.go +++ b/internal/gitlabnet/authorizedkeys/client.go @@ -5,9 +5,9 @@ "fmt" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/authorizedkeys/client_test.go b/internal/gitlabnet/authorizedkeys/client_test.go --- a/internal/gitlabnet/authorizedkeys/client_test.go +++ b/internal/gitlabnet/authorizedkeys/client_test.go @@ -7,9 +7,9 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -3,11 +3,12 @@ import ( "encoding/json" "fmt" + "net" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( @@ -34,3 +35,18 @@ return nil } + +func ParseIP(remoteAddr string) string { + // The remoteAddr field can be filled by: + // 1. An IP address via the SSH_CONNECTION environment variable + // 2. A host:port combination via the PROXY protocol + ip, _, err := net.SplitHostPort(remoteAddr) + + // If we don't have a port or can't parse this address for some reason, + // just return the original string. + if err != nil { + return remoteAddr + } + + return ip +} diff --git a/internal/gitlabnet/discover/client.go b/internal/gitlabnet/discover/client.go --- a/internal/gitlabnet/discover/client.go +++ b/internal/gitlabnet/discover/client.go @@ -6,10 +6,10 @@ "net/http" "net/url" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/discover/client_test.go b/internal/gitlabnet/discover/client_test.go --- a/internal/gitlabnet/discover/client_test.go +++ b/internal/gitlabnet/discover/client_test.go @@ -8,11 +8,11 @@ "net/url" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) var ( diff --git a/internal/gitlabnet/healthcheck/client.go b/internal/gitlabnet/healthcheck/client.go --- a/internal/gitlabnet/healthcheck/client.go +++ b/internal/gitlabnet/healthcheck/client.go @@ -5,9 +5,9 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) const ( diff --git a/internal/gitlabnet/healthcheck/client_test.go b/internal/gitlabnet/healthcheck/client_test.go --- a/internal/gitlabnet/healthcheck/client_test.go +++ b/internal/gitlabnet/healthcheck/client_test.go @@ -6,8 +6,8 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "github.com/stretchr/testify/require" ) diff --git a/internal/gitlabnet/lfsauthenticate/client.go b/internal/gitlabnet/lfsauthenticate/client.go --- a/internal/gitlabnet/lfsauthenticate/client.go +++ b/internal/gitlabnet/lfsauthenticate/client.go @@ -6,10 +6,10 @@ "net/http" "strings" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" ) type Client struct { diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -9,9 +9,9 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) const ( diff --git a/internal/gitlabnet/personalaccesstoken/client.go b/internal/gitlabnet/personalaccesstoken/client.go --- a/internal/gitlabnet/personalaccesstoken/client.go +++ b/internal/gitlabnet/personalaccesstoken/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/personalaccesstoken/client_test.go b/internal/gitlabnet/personalaccesstoken/client_test.go --- a/internal/gitlabnet/personalaccesstoken/client_test.go +++ b/internal/gitlabnet/personalaccesstoken/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorrecover/client.go b/internal/gitlabnet/twofactorrecover/client.go --- a/internal/gitlabnet/twofactorrecover/client.go +++ b/internal/gitlabnet/twofactorrecover/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -8,11 +8,11 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) var ( diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -6,11 +6,11 @@ "fmt" "net/http" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" ) type Client struct { diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -7,13 +7,13 @@ "net/http" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func initialize(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -11,10 +11,10 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitaly" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitaly" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" @@ -58,13 +58,11 @@ exitStatus, err := handler(childCtx, conn) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Unavailable { - ctxlog.WithError(fmt.Errorf("RunGitalyCommand: %v", err)).Error("Gitaly is unavailable") + ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") - return fmt.Errorf("The git server, Gitaly, is not available at this time. Please contact your administrator.") + if grpcstatus.Code(err) == grpccodes.Unavailable { + return grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.") } - - ctxlog.WithError(err).WithFields(log.Fields{"exit_status": exitStatus}).Error("Failed to execute Git command") } return err diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -12,10 +12,10 @@ grpcstatus "google.golang.org/grpc/status" pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/accessverifier" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) func makeHandler(t *testing.T, err error) func(context.Context, *grpc.ClientConn) (int32, error) { @@ -84,10 +84,8 @@ }, ) - expectedErr := grpcstatus.Error(grpccodes.Unavailable, "error") - err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, expectedErr)) - - require.EqualError(t, err, "The git server, Gitaly, is not available at this time. Please contact your administrator.") + err := cmd.RunGitalyCommand(context.Background(), makeHandler(t, grpcstatus.Error(grpccodes.Unavailable, "error"))) + require.Equal(t, err, grpcstatus.Error(grpccodes.Unavailable, "The git server, Gitaly, is not available at this time. Please contact your administrator.")) } func TestRunGitalyCommandMetadata(t *testing.T) { diff --git a/internal/keyline/key_line.go b/internal/keyline/key_line.go --- a/internal/keyline/key_line.go +++ b/internal/keyline/key_line.go @@ -7,8 +7,8 @@ "regexp" "strings" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/executable" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/executable" ) var ( diff --git a/internal/keyline/key_line_test.go b/internal/keyline/key_line_test.go --- a/internal/keyline/key_line_test.go +++ b/internal/keyline/key_line_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestFailingNewPublicKeyLine(t *testing.T) { diff --git a/internal/logger/logger.go b/internal/logger/logger.go --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -9,7 +9,7 @@ "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func logFmt(inFmt string) string { diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -8,7 +8,7 @@ "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/log" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" ) func TestConfigure(t *testing.T) { diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -77,15 +77,6 @@ }, ) - SshdCanceledSessions = promauto.NewCounter( - prometheus.CounterOpts{ - Namespace: namespace, - Subsystem: sshdSubsystem, - Name: sshdCanceledSessionsName, - Help: "The number of canceled gitlab-sshd sessions.", - }, - ) - SliSshdSessionsTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: sliSshdSessionsTotalName, diff --git a/internal/sshd/connection.go b/internal/sshd/connection.go --- a/internal/sshd/connection.go +++ b/internal/sshd/connection.go @@ -2,77 +2,124 @@ import ( "context" + "errors" + "net" + "strings" "time" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/log" ) -const KeepAliveMsg = "keepalive@openssh.com" +const ( + KeepAliveMsg = "keepalive@openssh.com" + NotOurRefError = `exit status 128, stderr: "fatal: git upload-pack: not our ref ` +) var EOFTimeout = 10 * time.Second type connection struct { cfg *config.Config concurrentSessions *semaphore.Weighted + nconn net.Conn + maxSessions int64 remoteAddr string - sconn *ssh.ServerConn - maxSessions int64 } -type channelHandler func(context.Context, ssh.Channel, <-chan *ssh.Request) error +type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error -func newConnection(cfg *config.Config, remoteAddr string, sconn *ssh.ServerConn) *connection { +func newConnection(cfg *config.Config, nconn net.Conn) *connection { maxSessions := cfg.Server.ConcurrentSessionsLimit return &connection{ cfg: cfg, maxSessions: maxSessions, concurrentSessions: semaphore.NewWeighted(maxSessions), - remoteAddr: remoteAddr, - sconn: sconn, + nconn: nconn, + remoteAddr: nconn.RemoteAddr().String(), } } -func (c *connection) handle(ctx context.Context, chans <-chan ssh.NewChannel, handler channelHandler) { - ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) +func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handler channelHandler) { + sconn, chans, err := c.initServerConn(ctx, srvCfg) + if err != nil { + return + } + + if c.cfg.Server.ClientAliveInterval > 0 { + ticker := time.NewTicker(time.Duration(c.cfg.Server.ClientAliveInterval)) + defer ticker.Stop() + go c.sendKeepAliveMsg(ctx, sconn, ticker) + } + + c.handleRequests(ctx, sconn, chans, handler) + + reason := sconn.Wait() + log.WithContextFields(ctx, log.Fields{"reason": reason}).Info("server: handleConn: done") +} - if c.cfg.Server.ClientAliveIntervalSeconds > 0 { - ticker := time.NewTicker(c.cfg.Server.ClientAliveInterval()) - defer ticker.Stop() - go c.sendKeepAliveMsg(ctx, ticker) +func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { + if c.cfg.Server.LoginGraceTime > 0 { + c.nconn.SetDeadline(time.Now().Add(time.Duration(c.cfg.Server.LoginGraceTime))) + defer c.nconn.SetDeadline(time.Time{}) } + sconn, chans, reqs, err := ssh.NewServerConn(c.nconn, srvCfg) + if err != nil { + msg := "connection: initServerConn: failed to initialize SSH connection" + logger := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}).WithError(err) + + if strings.Contains(err.Error(), "no common algorithm for host key") || err.Error() == "EOF" { + logger.Debug(msg) + } else { + logger.Warn(msg) + } + + return nil, nil, err + } + go ssh.DiscardRequests(reqs) + + return sconn, chans, err +} + +func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, handler channelHandler) { + ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) + for newChannel := range chans { ctxlog.WithField("channel_type", newChannel.ChannelType()).Info("connection: handle: new channel requested") if newChannel.ChannelType() != "session" { - ctxlog.Info("connection: handle: unknown channel type") + ctxlog.Info("connection: handleRequests: unknown channel type") newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } if !c.concurrentSessions.TryAcquire(1) { - ctxlog.Info("connection: handle: too many concurrent sessions") + ctxlog.Info("connection: handleRequests: too many concurrent sessions") newChannel.Reject(ssh.ResourceShortage, "too many concurrent sessions") metrics.SshdHitMaxSessions.Inc() continue } channel, requests, err := newChannel.Accept() if err != nil { - ctxlog.WithError(err).Error("connection: handle: accepting channel failed") + ctxlog.WithError(err).Error("connection: handleRequests: accepting channel failed") c.concurrentSessions.Release(1) continue } go func() { defer func(started time.Time) { - metrics.SshdSessionDuration.Observe(time.Since(started).Seconds()) + duration := time.Since(started).Seconds() + metrics.SshdSessionDuration.Observe(duration) + ctxlog.WithFields(log.Fields{"duration_s": duration}).Info("connection: handleRequests: done") }(time.Now()) defer c.concurrentSessions.Release(1) @@ -85,16 +132,10 @@ }() metrics.SliSshdSessionsTotal.Inc() - err := handler(ctx, channel, requests) + err := handler(sconn, channel, requests) if err != nil { - if grpcstatus.Convert(err).Code() == grpccodes.Canceled { - metrics.SshdCanceledSessions.Inc() - } else { - metrics.SliSshdSessionsErrorsTotal.Inc() - } + c.trackError(ctxlog, err) } - - ctxlog.Info("connection: handle: done") }() } @@ -107,7 +148,7 @@ c.concurrentSessions.Acquire(ctx, c.maxSessions) } -func (c *connection) sendKeepAliveMsg(ctx context.Context, ticker *time.Ticker) { +func (c *connection) sendKeepAliveMsg(ctx context.Context, sconn *ssh.ServerConn, ticker *time.Ticker) { ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) for { @@ -115,9 +156,30 @@ case <-ctx.Done(): return case <-ticker.C: - ctxlog.Debug("session: handleShell: send keepalive message to a client") + ctxlog.Debug("connection: sendKeepAliveMsg: send keepalive message to a client") - c.sconn.SendRequest(KeepAliveMsg, true, nil) + sconn.SendRequest(KeepAliveMsg, true, nil) } } } + +func (c *connection) trackError(ctxlog *logrus.Entry, err error) { + var apiError *client.ApiError + if errors.As(err, &apiError) { + return + } + + if errors.Is(err, disallowedcommand.Error) { + return + } + + grpcCode := grpcstatus.Code(err) + if grpcCode == grpccodes.Canceled || grpcCode == grpccodes.Unavailable { + return + } else if grpcCode == grpccodes.Internal && strings.Contains(err.Error(), NotOurRefError) { + return + } + + metrics.SliSshdSessionsErrorsTotal.Inc() + ctxlog.WithError(err).Warn("connection: session error") +} diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -10,11 +10,14 @@ "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" + "golang.org/x/sync/semaphore" grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" ) type rejectCall struct { @@ -79,8 +82,8 @@ } func setup(sessionsNum int64, newChannel *fakeNewChannel) (*connection, chan ssh.NewChannel) { - cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum, ClientAliveIntervalSeconds: 1}} - conn := newConnection(cfg, "127.0.0.1:50000", &ssh.ServerConn{&fakeConn{}, nil}) + cfg := &config.Config{Server: config.ServerConfig{ConcurrentSessionsLimit: sessionsNum}} + conn := &connection{cfg: cfg, concurrentSessions: semaphore.NewWeighted(sessionsNum)} chans := make(chan ssh.NewChannel, 1) chans <- newChannel @@ -94,7 +97,7 @@ numSessions := 0 require.NotPanics(t, func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { numSessions += 1 close(chans) panic("This is a panic") @@ -112,7 +115,7 @@ conn, chans := setup(1, newChannel) go func() { - conn.handle(context.Background(), chans, nil) + conn.handleRequests(context.Background(), nil, chans, nil) }() rejectionData := <-rejectCh @@ -132,7 +135,7 @@ defer cancel() go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { <-ctx.Done() // Keep the accepted channel open until the end of the test return nil }) @@ -147,7 +150,7 @@ conn, chans := setup(1, newChannel) channelHandled := false - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true close(chans) return nil @@ -166,7 +169,7 @@ channelHandled := false go func() { - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { channelHandled = true return nil }) @@ -184,12 +187,11 @@ func TestClientAliveInterval(t *testing.T) { f := &fakeConn{} - conn := newConnection(&config.Config{}, "127.0.0.1:50000", &ssh.ServerConn{f, nil}) - ticker := time.NewTicker(time.Millisecond) defer ticker.Stop() - go conn.sendKeepAliveMsg(context.Background(), ticker) + conn := &connection{} + go conn.sendKeepAliveMsg(context.Background(), &ssh.ServerConn{f, nil}, ticker) require.Eventually(t, func() bool { return KeepAliveMsg == f.SentRequestName() }, time.Second, time.Millisecond) } @@ -199,27 +201,38 @@ // https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#pkg-index initialSessionsTotal := testutil.ToFloat64(metrics.SliSshdSessionsTotal) initialSessionsErrorTotal := testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal) - initialCanceledSessions := testutil.ToFloat64(metrics.SshdCanceledSessions) newChannel := &fakeNewChannel{channelType: "session"} conn, chans := setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) return errors.New("custom error") }) require.InDelta(t, initialSessionsTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) - conn, chans = setup(1, newChannel) - conn.handle(context.Background(), chans, func(context.Context, ssh.Channel, <-chan *ssh.Request) error { - close(chans) - return grpcstatus.Error(grpccodes.Canceled, "error") - }) + for i, ignoredError := range []struct { + desc string + err error + }{ + {"canceled requests", grpcstatus.Error(grpccodes.Canceled, "canceled")}, + {"unavailable Gitaly", grpcstatus.Error(grpccodes.Unavailable, "unavailable")}, + {"api error", &client.ApiError{"api error"}}, + {"disallowed command", disallowedcommand.Error}, + {"not our ref", grpcstatus.Error(grpccodes.Internal, `rpc error: code = Internal desc = cmd wait: exit status 128, stderr: "fatal: git upload-pack: not our ref 9106d18f6a1b8022f6517f479696f3e3ea5e68c1"`)}, + } { + ignoredError := ignoredError // Capture range variable, see "Race on loop counter" in https://go.dev/doc/articles/race_detector + t.Run(ignoredError.desc, func(t *testing.T) { + conn, chans = setup(1, newChannel) + conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { + close(chans) + return ignoredError.err + }) - require.InDelta(t, initialSessionsTotal+2, testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) - require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) - require.InDelta(t, initialCanceledSessions+1, testutil.ToFloat64(metrics.SshdCanceledSessions), 0.1) + require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) + require.InDelta(t, initialSessionsErrorTotal+1, testutil.ToFloat64(metrics.SliSshdSessionsErrorsTotal), 0.1) + }) + } } diff --git a/internal/sshd/server_config.go b/internal/sshd/server_config.go --- a/internal/sshd/server_config.go +++ b/internal/sshd/server_config.go @@ -10,26 +10,43 @@ "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/labkit/log" ) +var ( + supportedMACs = []string{ + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1", + } + + supportedKeyExchanges = []string{ + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group14-sha256", + "diffie-hellman-group14-sha1", + } +) + type serverConfig struct { cfg *config.Config hostKeys []ssh.Signer + hostKeyToCertMap map[string]*ssh.Certificate authorizedKeysClient *authorizedkeys.Client } -func newServerConfig(cfg *config.Config) (*serverConfig, error) { - authorizedKeysClient, err := authorizedkeys.NewClient(cfg) - if err != nil { - return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) - } +func parseHostKeys(keyFiles []string) []ssh.Signer { + var hostKeys []ssh.Signer - var hostKeys []ssh.Signer - for _, filename := range cfg.Server.HostKeyFiles { + for _, filename := range keyFiles { keyRaw, err := os.ReadFile(filename) if err != nil { log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("Failed to read host key") @@ -43,11 +60,70 @@ hostKeys = append(hostKeys, key) } + + return hostKeys +} + +func parseHostCerts(hostKeys []ssh.Signer, certFiles []string) map[string]*ssh.Certificate { + keyToCertMap := map[string]*ssh.Certificate{} + hostKeyIndex := make(map[string]int) + + for index, hostKey := range hostKeys { + hostKeyIndex[string(hostKey.PublicKey().Marshal())] = index + } + + for _, filename := range certFiles { + keyRaw, err := os.ReadFile(filename) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to read host certificate") + continue + } + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(keyRaw) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("failed to parse host certificate") + continue + } + + cert, ok := publicKey.(*ssh.Certificate) + if !ok { + log.WithFields(log.Fields{"filename": filename}).Warn("failed to decode host certificate") + continue + } + + hostRawKey := string(cert.Key.Marshal()) + index, found := hostKeyIndex[hostRawKey] + if found { + keyToCertMap[hostRawKey] = cert + + certSigner, err := ssh.NewCertSigner(cert, hostKeys[index]) + if err != nil { + log.WithError(err).WithFields(log.Fields{"filename": filename}).Warn("the host certificate doesn't match the host private key") + continue + } + + hostKeys[index] = certSigner + } else { + log.WithFields(log.Fields{"filename": filename}).Warnf("no matching private key for certificate %s", filename) + } + } + + return keyToCertMap +} + +func newServerConfig(cfg *config.Config) (*serverConfig, error) { + authorizedKeysClient, err := authorizedkeys.NewClient(cfg) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitLab client: %w", err) + } + + hostKeys := parseHostKeys(cfg.Server.HostKeyFiles) if len(hostKeys) == 0 { return nil, fmt.Errorf("No host keys could be loaded, aborting") } - return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys}, nil + hostKeyToCertMap := parseHostCerts(hostKeys, cfg.Server.HostCertFiles) + + return &serverConfig{cfg: cfg, authorizedKeysClient: authorizedKeysClient, hostKeys: hostKeys, hostKeyToCertMap: hostKeyToCertMap}, nil } func (s *serverConfig) getAuthKey(ctx context.Context, user string, key ssh.PublicKey) (*authorizedkeys.Response, error) { @@ -84,6 +160,23 @@ }, }, nil }, + ServerVersion: "SSH-2.0-GitLab-SSHD", + } + + if len(s.cfg.Server.MACs) > 0 { + sshCfg.MACs = s.cfg.Server.MACs + } else { + sshCfg.MACs = supportedMACs + } + + if len(s.cfg.Server.KexAlgorithms) > 0 { + sshCfg.KeyExchanges = s.cfg.Server.KexAlgorithms + } else { + sshCfg.KeyExchanges = supportedKeyExchanges + } + + if len(s.cfg.Server.Ciphers) > 0 { + sshCfg.Ciphers = s.cfg.Server.Ciphers } for _, key := range s.hostKeys { diff --git a/internal/sshd/server_config_test.go b/internal/sshd/server_config_test.go --- a/internal/sshd/server_config_test.go +++ b/internal/sshd/server_config_test.go @@ -5,14 +5,15 @@ "crypto/dsa" "crypto/rand" "crypto/rsa" + "os" "path" "testing" "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewServerConfigWithoutHosts(t *testing.T) { @@ -22,6 +23,45 @@ require.Equal(t, "No host keys could be loaded, aborting", err.Error()) } +func TestHostKeyAndCerts(t *testing.T) { + testhelper.PrepareTestRootDir(t) + + srvCfg := config.ServerConfig{ + Listen: "127.0.0.1", + ConcurrentSessionsLimit: 1, + HostKeyFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server.key"), + }, + HostCertFiles: []string{ + path.Join(testhelper.TestRoot, "certs/valid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/valid/server2-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid/server-cert.pub"), + path.Join(testhelper.TestRoot, "certs/invalid-path.key"), + path.Join(testhelper.TestRoot, "certs/invalid/server.crt"), + }, + } + + cfg, err := newServerConfig( + &config.Config{GitlabUrl: "http://localhost", User: "user", Server: srvCfg}, + ) + require.NoError(t, err) + + require.Len(t, cfg.hostKeys, 1) + require.Len(t, cfg.hostKeyToCertMap, 1) + + // Check that the entry is pointing to the server's public key + data, err := os.ReadFile(path.Join(testhelper.TestRoot, "certs/valid/server.pub")) + require.NoError(t, err) + + publicKey, _, _, _, err := ssh.ParseAuthorizedKey(data) + require.NoError(t, err) + require.NotNil(t, publicKey) + cert, ok := cfg.hostKeyToCertMap[string(publicKey.Marshal())] + require.True(t, ok) + require.NotNil(t, cert) + require.Equal(t, cert, cfg.hostKeys[0].PublicKey()) +} + func TestFailedAuthorizedKeysClient(t *testing.T) { _, err := newServerConfig(&config.Config{GitlabUrl: "ftp://localhost"}) @@ -80,6 +120,57 @@ } } +func TestDefaultAlgorithms(t *testing.T) { + srvCfg := &serverConfig{cfg: &config.Config{}} + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) + require.Nil(t, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, supportedMACs, sshServerConfig.MACs) + require.Equal(t, supportedKeyExchanges, sshServerConfig.KeyExchanges) + + defaultCiphers := []string{ + "aes128-gcm@openssh.com", + "chacha20-poly1305@openssh.com", + "aes256-gcm@openssh.com", + "aes128-ctr", + "aes192-ctr", + "aes256-ctr", + } + require.Equal(t, defaultCiphers, sshServerConfig.Ciphers) +} + +func TestCustomAlgorithms(t *testing.T) { + customMACs := []string{"hmac-sha2-512-etm@openssh.com"} + customKexAlgos := []string{"curve25519-sha256"} + customCiphers := []string{"aes256-gcm@openssh.com"} + + srvCfg := &serverConfig{ + cfg: &config.Config{ + Server: config.ServerConfig{ + MACs: customMACs, + KexAlgorithms: customKexAlgos, + Ciphers: customCiphers, + }, + }, + } + sshServerConfig := srvCfg.get(context.Background()) + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) + + sshServerConfig.SetDefaults() + + require.Equal(t, customMACs, sshServerConfig.MACs) + require.Equal(t, customKexAlgos, sshServerConfig.KeyExchanges) + require.Equal(t, customCiphers, sshServerConfig.Ciphers) +} + func rsaPublicKey(t *testing.T) ssh.PublicKey { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) diff --git a/internal/sshd/session.go b/internal/sshd/session.go --- a/internal/sshd/session.go +++ b/internal/sshd/session.go @@ -5,15 +5,20 @@ "errors" "fmt" "reflect" + "time" "gitlab.com/gitlab-org/labkit/log" "golang.org/x/crypto/ssh" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" - shellCmd "gitlab.com/gitlab-org/gitlab-shell/cmd/gitlab-shell/command" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter" - "gitlab.com/gitlab-org/gitlab-shell/internal/command/shared/disallowedcommand" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/sshenv" + shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" ) type session struct { @@ -26,6 +31,7 @@ // State managed by the session execCmd string gitProtocolVersion string + started time.Time } type execRequest struct { @@ -158,18 +164,29 @@ cmd, err := shellCmd.NewWithKey(s.gitlabKeyId, env, s.cfg, rw) if err != nil { - if !errors.Is(err, disallowedcommand.Error) { - s.toStderr(ctx, "Failed to parse command: %v\n", err.Error()) + if errors.Is(err, disallowedcommand.Error) { + s.toStderr(ctx, "ERROR: Unknown command: %v\n", s.execCmd) + } else { + s.toStderr(ctx, "ERROR: Failed to parse command: %v\n", err.Error()) } - s.toStderr(ctx, "Unknown command: %v\n", s.execCmd) + return 128, err } cmdName := reflect.TypeOf(cmd).String() - ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("session: handleShell: executing command") + + establishSessionDuration := time.Since(s.started).Seconds() + ctxlog.WithFields(log.Fields{ + "env": env, "command": cmdName, "established_session_duration_s": establishSessionDuration, + }).Info("session: handleShell: executing command") + metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) if err := cmd.Execute(ctx); err != nil { - s.toStderr(ctx, "remote: ERROR: %v\n", err.Error()) + grpcStatus := grpcstatus.Convert(err) + if grpcStatus.Code() != grpccodes.Internal { + s.toStderr(ctx, "ERROR: %v\n", grpcStatus.Message()) + } + return 1, err } @@ -181,7 +198,7 @@ func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { out := fmt.Sprintf(format, args...) log.WithContextFields(ctx, log.Fields{"stderr": out}).Debug("session: toStderr: output") - fmt.Fprint(s.channel.Stderr(), out) + console.DisplayWarningMessage(out, s.channel.Stderr()) } func (s *session) exit(ctx context.Context, status uint32) { diff --git a/internal/sshd/session_test.go b/internal/sshd/session_test.go --- a/internal/sshd/session_test.go +++ b/internal/sshd/session_test.go @@ -11,8 +11,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/console" ) type fakeChannel struct { @@ -160,14 +161,14 @@ { desc: "fails to parse command", cmd: `\`, - errMsg: "Failed to parse command: Invalid SSH command: invalid command line string\nUnknown command: \\\n", + errMsg: "ERROR: Failed to parse command: Invalid SSH command: invalid command line string\n", gitlabKeyId: "root", expectedErrString: "Invalid SSH command: invalid command line string", expectedExitCode: 128, }, { desc: "specified command is unknown", cmd: "unknown-command", - errMsg: "Unknown command: unknown-command\n", + errMsg: "ERROR: Unknown command: unknown-command\n", gitlabKeyId: "root", expectedErrString: "Disallowed command", expectedExitCode: 128, @@ -175,7 +176,7 @@ desc: "fails to parse command", cmd: "discover", gitlabKeyId: "", - errMsg: "remote: ERROR: Failed to get username: who='' is invalid\n", + errMsg: "ERROR: Failed to get username: who='' is invalid\n", expectedErrString: "Failed to get username: who='' is invalid", expectedExitCode: 1, }, { @@ -208,7 +209,14 @@ } require.Equal(t, tc.expectedExitCode, exitCode) - require.Equal(t, tc.errMsg, out.String()) + + formattedErr := &bytes.Buffer{} + if tc.errMsg != "" { + console.DisplayWarningMessage(tc.errMsg, formattedErr) + require.Equal(t, formattedErr.String(), out.String()) + } else { + require.Equal(t, tc.errMsg, out.String()) + } }) } } diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go --- a/internal/sshd/sshd.go +++ b/internal/sshd/sshd.go @@ -12,8 +12,10 @@ "github.com/pires/go-proxyproto" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/metrics" + "gitlab.com/gitlab-org/gitlab-shell/v14/client" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/log" @@ -26,7 +28,6 @@ StatusReady StatusOnShutdown StatusClosed - ProxyHeaderTimeout = 90 * time.Second ) type Server struct { @@ -97,7 +98,7 @@ sshListener = &proxyproto.Listener{ Listener: sshListener, Policy: s.requirePolicy, - ReadHeaderTimeout: ProxyHeaderTimeout, + ReadHeaderTimeout: time.Duration(s.Config.Server.ProxyHeaderTimeout), } log.ContextLogger(ctx).Info("Proxy protocol is enabled") @@ -146,19 +147,35 @@ return s.status } +func contextWithValues(parent context.Context, nconn net.Conn) context.Context { + ctx := correlation.ContextWithCorrelation(parent, correlation.SafeRandomID()) + + // If we're dealing with a PROXY connection, register the original requester's IP + mconn, ok := nconn.(*proxyproto.Conn) + if ok { + ip := gitlabnet.ParseIP(mconn.Raw().RemoteAddr().String()) + ctx = context.WithValue(ctx, client.OriginalRemoteIPContextKey{}, ip) + } + + return ctx +} + func (s *Server) handleConn(ctx context.Context, nconn net.Conn) { + defer s.wg.Done() + metrics.SshdConnectionsInFlight.Inc() defer metrics.SshdConnectionsInFlight.Dec() - remoteAddr := nconn.RemoteAddr().String() - - defer s.wg.Done() - defer nconn.Close() + ctx, cancel := context.WithCancel(contextWithValues(ctx, nconn)) + defer cancel() + go func() { + <-ctx.Done() + nconn.Close() // Close the connection when context is cancelled + }() - ctx, cancel := context.WithCancel(correlation.ContextWithCorrelation(ctx, correlation.SafeRandomID())) - defer cancel() - + remoteAddr := nconn.RemoteAddr().String() ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": remoteAddr}) + ctxlog.Debug("server: handleConn: start") // Prevent a panic in a single connection from taking out the whole server defer func() { @@ -169,38 +186,18 @@ } }() - ctxlog.Info("server: handleConn: start") - - sconn, chans, reqs, err := ssh.NewServerConn(nconn, s.serverConfig.get(ctx)) - if err != nil { - ctxlog.WithError(err).Warn("server: handleConn: failed to initialize SSH connection") - return - } - go ssh.DiscardRequests(reqs) - - started := time.Now() - var establishSessionDuration float64 - conn := newConnection(s.Config, remoteAddr, sconn) - conn.handle(ctx, chans, func(ctx context.Context, channel ssh.Channel, requests <-chan *ssh.Request) error { - establishSessionDuration = time.Since(started).Seconds() - metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) - + conn := newConnection(s.Config, nconn) + conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { session := &session{ cfg: s.Config, channel: channel, gitlabKeyId: sconn.Permissions.Extensions["key-id"], remoteAddr: remoteAddr, + started: time.Now(), } return session.handle(ctx, requests) }) - - reason := sconn.Wait() - ctxlog.WithFields(log.Fields{ - "duration_s": time.Since(started).Seconds(), - "establish_session_duration_s": establishSessionDuration, - "reason": reason, - }).Info("server: handleConn: done") } func (s *Server) requirePolicy(_ net.Addr) (proxyproto.Policy, error) { diff --git a/internal/sshd/sshd_test.go b/internal/sshd/sshd_test.go --- a/internal/sshd/sshd_test.go +++ b/internal/sshd/sshd_test.go @@ -15,9 +15,9 @@ "github.com/stretchr/testify/require" "golang.org/x/crypto/ssh" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) const ( @@ -27,6 +27,7 @@ var ( correlationId = "" + xForwardedFor = "" ) func TestListenAndServe(t *testing.T) { @@ -63,6 +64,10 @@ }, DestinationAddr: target, } + xForwardedFor = "127.0.0.1" + defer func() { + xForwardedFor = "" // Cleanup for other test cases + }() testCases := []struct { desc string @@ -132,9 +137,9 @@ require.NoError(t, err) } - sshConn, _, _, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) + sshConn, sshChans, sshRequs, err := ssh.NewClientConn(conn, serverUrl, clientConfig(t)) if sshConn != nil { - sshConn.Close() + defer sshConn.Close() } if tc.isRejected { @@ -142,6 +147,10 @@ require.Regexp(t, "ssh: handshake failed", err.Error()) } else { require.NoError(t, err) + client := ssh.NewClient(sshConn, sshChans, sshRequs) + defer client.Close() + + holdSession(t, client) } }) } @@ -222,6 +231,68 @@ require.Nil(t, s.Shutdown()) } +func TestClosingHangedConnections(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + s := setupServerWithContext(t, nil, ctx) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + require.NoError(t, s.Shutdown()) + cancel() + verifyStatus(t, s, StatusClosed) +} + +func TestLoginGraceTime(t *testing.T) { + cfg := &config.Config{ + Server: config.ServerConfig{ + LoginGraceTime: config.YamlDuration(50 * time.Millisecond), + }, + } + s := setupServerWithConfig(t, cfg) + + unauthenticatedRequestStatus := make(chan string) + completed := make(chan bool) + + clientCfg := clientConfig(t) + clientCfg.HostKeyCallback = func(_ string, _ net.Addr, _ ssh.PublicKey) error { + unauthenticatedRequestStatus <- "authentication-started" + <-completed // Wait infinitely + + return nil + } + + go func() { + // Start an SSH connection that never ends + ssh.Dial("tcp", serverUrl, clientCfg) + }() + + require.Equal(t, "authentication-started", <-unauthenticatedRequestStatus) + + // Shutdown the server and verify that it's closed + // If LoginGraceTime doesn't work, then the connection that runs infinitely, will stop it from closing. + // The close won't happen until the context is canceled like in TestClosingHangedConnections + require.NoError(t, s.Shutdown()) + verifyStatus(t, s, StatusClosed) +} + func setupServer(t *testing.T) *Server { t.Helper() @@ -231,6 +302,12 @@ func setupServerWithConfig(t *testing.T, cfg *config.Config) *Server { t.Helper() + return setupServerWithContext(t, cfg, context.Background()) +} + +func setupServerWithContext(t *testing.T, cfg *config.Config, ctx context.Context) *Server { + t.Helper() + requests := []testserver.TestRequestHandler{ { Path: "/api/v4/internal/authorized_keys", @@ -238,6 +315,7 @@ correlationId = r.Header.Get("X-Request-Id") require.NotEmpty(t, correlationId) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "key": "key"}`) }, @@ -245,6 +323,7 @@ Path: "/api/v4/internal/discover", Handler: func(w http.ResponseWriter, r *http.Request) { require.Equal(t, correlationId, r.Header.Get("X-Request-Id")) + require.Equal(t, xForwardedFor, r.Header.Get("X-Forwarded-For")) fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`) }, @@ -265,13 +344,12 @@ cfg.User = user cfg.Server.Listen = serverUrl cfg.Server.ConcurrentSessionsLimit = 1 - cfg.Server.ClientAliveIntervalSeconds = 15 cfg.Server.HostKeyFiles = []string{path.Join(testhelper.TestRoot, "certs/valid/server.key")} s, err := NewServer(cfg) require.NoError(t, err) - go func() { require.NoError(t, s.ListenAndServe(context.Background())) }() + go func() { require.NoError(t, s.ListenAndServe(ctx)) }() t.Cleanup(func() { s.Shutdown() }) verifyStatus(t, s, StatusReady) diff --git a/internal/sshenv/sshenv_test.go b/internal/sshenv/sshenv_test.go --- a/internal/sshenv/sshenv_test.go +++ b/internal/sshenv/sshenv_test.go @@ -4,7 +4,7 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" ) func TestNewFromEnv(t *testing.T) { diff --git a/internal/testhelper/requesthandlers/requesthandlers.go b/internal/testhelper/requesthandlers/requesthandlers.go --- a/internal/testhelper/requesthandlers/requesthandlers.go +++ b/internal/testhelper/requesthandlers/requesthandlers.go @@ -7,7 +7,7 @@ "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" ) func BuildDisallowedByApiHandlers(t *testing.T) []testserver.TestRequestHandler { diff --git a/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/invalid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql not_a_valid_cert.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca b/internal/testhelper/testdata/testroot/certs/valid/ca new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV ++IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfw +FoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj +4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4 +NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqI +cXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfX +KGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCf +EG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAAFkA5fIlIOXyJSAAAAB3NzaC1yc2 +EAAAGBANyFATfNPwSRubrfVNt/BcCBgHzGUKDl2GxbYkGaPlPnHWxiZRBoFfiE6Bje/GCc +qZGyvDYqbTDDoFmfHrugwiTDcYz2+3t12Bq5hz3qCuWfYqBEg8NEEpMQyH8BaC0p8dPnol +0td/MqRDYC0/4TjJfn5q6AO+Gab5LyKSvkaAKNapVglrQOzcoJEJFkYJ5wI+I5AyqvWk9Y +hxmvZ0GC7k7X4l95d+f6DjjCRaw4O22+RB5wbCnsA6AMXajW8aeFv7EMlBeDWzhSxs0Wrw +OnjUXzsfVF3HctL/flIAprvdp24j5jQaPcGNw/aa8FwFnrUzNQd2Qg5NYaiHF0YOqTQTQv +Xthbm3IbPU3Ky2maa+JIBb03pBnKH9ZtqMyU1ZXCCZSacveZqdbl8MUz231yhj7yruza6E +dmr5ACH8EY+RP/B8K4Ax9q/+LkT2nUQsfYZt/ByNZ+kuGK67Ji/X3y1ukgnxBunO/lEQ0K +9fFavWMsTJrtPRCu1ZQw19CTNFGp+QAAAAMBAAEAAAGACHnYRSPPc0aCpAsngNRODUss/B +7HRJfxDKEqkqjyElmEyQCzL8FAbu/019fiTXhYEDCViWNyFPi/9hHmpYGVVMJqX+eyXNl3 +t/c/moKfbpoEuXJIuj2olRyFCFSug2XkVKfHlttDjAYo3waWzWJE+iXAuR5WruI3vacvK+ ++4i7iRyzIOONeE02orx9ra19wplO1qEL7ysrANaVBToLH+pOspWVAa6sCywT2+XdM/fYVd +qunZTncy4Hj5NJ8mZLEATfJKnT2v7C47fBjN+ylqpyTImBZxSfVyjrljcQXb9ExjAhVTjv +tBuZdB1NPnok9cycwpg6aGXuZX2mSQWROhHM/r80kUzfxJpRDs/AqMWRZYC2k/kCKbXg7S +1cuAwJ2SiH5jslekhbB8bCU3rL2SgUV4oZsqh5fb6ZsytXarbzX/8Kcmb4KGsjZ7wBD6Yu +sJ05TkzC/HkOT3xTXwyzZpEldKucLClnY3Boq8pkO1EoUD8uPJNgSgukH9W5SleaIxAAAA +wEzXR8Av4SxsgWW2pPVtQaeKhUKrid21RuPF5/7c4PZ4GlnhL3Fod4PwdD8yPjuIuI7s6/ +9HRxzi+vr616/BXMagGWPSZEQMaX6I/L5CSratN2Dk1jSYcH501GseILr+kIcZhe7HoEf2 +xbr8ByF88DXpeSdimIqMeVYTPGWac7oSf3Y5WHi9FUuJ4BEccu8bLIXWkGMK6yi/zJo1RQ +u4aMzdMyzat0C2aeAm40HABdUv350K/H20Voj7zfhmlXvQ7wAAAMEA8a1oEPFL1+cAqfUD +Jbx+KWyw/1kFBIpU93rk2qfJR593nMLebAk0l9qfhbvlN6GTNcGETjzGK1bHaD9G14c2IT +bFcIoKmah6LygIlMGwdTMSWPPrczeIhMy6H0rJ2lDa208+nLwKqlFlMDYNpycL2Q1ZynnB +fYqfRiUSDJcs+2jfTX0gA17NuSwqp6j/JlMm45tN3GK1neIVH+4PBazBXqZTzdfCfqJ9r5 +TWJw2i6CsSlCDAtO3uo+Pyj327RbNtAAAAwQDplpqK2+0+QiQB+LUeT0hfWp5/HmXJjfgm +u+xIICJKPqOYwDvBWEHHssv7YS70dFJrbENJ66NZfdv+foDbQXrr10odbIntk9QoO4CS1g +zd63kolFCLhbwkYos45CjJIPuzNDeiYIgsLEOQwnjHbp3HxAIywxtUPKj80YmfoogeidiD +JNMwRoJfqlNziW1PDq0r8Zhw2lbyGZPI218ox7tsJ94BS4MFJfgASwO9qcDsaYz23sS8uQ +BBbY6cCknC7T0AAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/ca.pub b/internal/testhelper/testdata/testroot/certs/valid/ca.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/ca.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDchQE3zT8Ekbm631TbfwXAgYB8xlCg5dhsW2JBmj5T5x1sYmUQaBX4hOgY3vxgnKmRsrw2Km0ww6BZnx67oMIkw3GM9vt7ddgauYc96grln2KgRIPDRBKTEMh/AWgtKfHT56JdLXfzKkQ2AtP+E4yX5+augDvhmm+S8ikr5GgCjWqVYJa0Ds3KCRCRZGCecCPiOQMqr1pPWIcZr2dBgu5O1+JfeXfn+g44wkWsODttvkQecGwp7AOgDF2o1vGnhb+xDJQXg1s4UsbNFq8Dp41F87H1Rdx3LS/35SAKa73aduI+Y0Gj3BjcP2mvBcBZ61MzUHdkIOTWGohxdGDqk0E0L17YW5tyGz1NystpmmviSAW9N6QZyh/WbajMlNWVwgmUmnL3manW5fDFM9t9coY+8q7s2uhHZq+QAh/BGPkT/wfCuAMfav/i5E9p1ELH2GbfwcjWfpLhiuuyYv198tbpIJ8Qbpzv5RENCvXxWr1jLEya7T0QrtWUMNfQkzRRqfk= test@test.example.org diff --git a/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgNGUtD+qw0Xj5NU2uj4+4LoCWPcvXP54F9Adw/hWN5LAAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yqlAAAAAAAAAAAAAAACAAAABnNlcnZlcgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGAapK5VzLDoRe88tnLORrH8VxLegTWPKGdn0k5Ye8tS5XUgd0N98gU669y4ErDNf0kPxlz40bjsfisEEtJ/N7m14IskCepScfZRh8w6QgPxbTOhmrc89xooqBUE50y5FU9hIIbzUrnEP+Dfu4IiFPToAguCa+KoAKiOX7lBQqEugV6uOWVZ2erPopEv+OiMLD8hXsuKKjQ+TomHZ/IjuXsFdXH7Vcl0VsPaAcxyCtDU7nCTJSTUoUZtMtwwpulp0e/zNmFrEn2Binz4jRaUlk3FM2fdbotviDQYeOY3npmxaWUvvQ/eKn0/DzUTAKAGr2LDa2XWnPhj51BS1XkNaUlnupdYmZ2Sok0R4U3bfVwokteREvAltGbXQSDtZwLS5NEY6vIdDrxpn5QRf9vGjqnc7piXxye9gcLne4YDUi24IhGyHrnWKCC0HjF7tuUhCOVKrqRdmHxRGWX3PlS8Xn6HHEPWU+YZnfT1V2W7LAFcDMozQbs4GPGzZdR3f3vCOJ8 server.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server.pub b/internal/testhelper/testdata/testroot/certs/valid/server.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCa17cb94P6q5qbDIWX7aMSjyeBIBPQVZ5jlkDBG90XgWC1MEu9sB1OfKLukcx6wJJSTLFccc9rMzhINXq6K7ks0oXSLP81jvqsu0WipIZSDKBNkdVtno1FcI1RnQ+yUP3nA4Ja9L233GA1evLrqTz6Z9k2ET5wVB+s7+k3lak24bJZN8qVRDDk1UveahuPe1KMj7DNKls8y9tNCgGJn9UeTLJzXlh2tt4/AUHZ0lvET9eCzKT9PBZJQWcCzqLXHa37jbc0ib2sgNN1bZhgkle/cxRx0MjEmdjRt4Z48wjKaf1khFQm0r9lebAxvna/vT5hNywbru5KbfUJHyM23yql diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2-cert.pub @@ -0,0 +1,1 @@ +ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg3XO30wn4+lFxc5fLsanH4Pvu0OuKGHoR94zZjxx7qAEAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgokAAAAAAAAAAAAAAAIAAAAHc2VydmVyMgAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEA3IUBN80/BJG5ut9U238FwIGAfMZQoOXYbFtiQZo+U+cdbGJlEGgV+IToGN78YJypkbK8NiptMMOgWZ8eu6DCJMNxjPb7e3XYGrmHPeoK5Z9ioESDw0QSkxDIfwFoLSnx0+eiXS138ypENgLT/hOMl+fmroA74ZpvkvIpK+RoAo1qlWCWtA7NygkQkWRgnnAj4jkDKq9aT1iHGa9nQYLuTtfiX3l35/oOOMJFrDg7bb5EHnBsKewDoAxdqNbxp4W/sQyUF4NbOFLGzRavA6eNRfOx9UXcdy0v9+UgCmu92nbiPmNBo9wY3D9prwXAWetTM1B3ZCDk1hqIcXRg6pNBNC9e2Fubchs9TcrLaZpr4kgFvTekGcof1m2ozJTVlcIJlJpy95mp1uXwxTPbfXKGPvKu7NroR2avkAIfwRj5E/8HwrgDH2r/4uRPadRCx9hm38HI1n6S4YrrsmL9ffLW6SCfEG6c7+URDQr18Vq9YyxMmu09EK7VlDDX0JM0Uan5AAABlAAAAAxyc2Etc2hhMi01MTIAAAGANOKG8Tq7kp9B5+CQEyb+mEatJOoQRV+4rpemWlfEw6TuVwQN2wSXc6XKBHzSG4NRnFkwk6GgiPLQEf4lBBKA8VYQnDKuhrHJlU4DFCRPw/aceHfCwNOruyJmuf91W3yEO/kYAd6EhkQiW/K3ky7BuXCqR34T2fBZSCeYhNcXWxhEMLoAuj0kEdX+YMNBmiPtinPE13KMFGyIVBm/ojgSZa8j4WnhDcK0cWv0OSGTgJF6q3hENCWRz2E1HroKUiABOy5Nca6gPVAi4OTd7gwER8eh9MngVHYorAJ3N9HjUh640SbL3zCC8f/lqIztqsHY0u3olsQ0gLXpFain+430HeyJlmVlsDZgQKRb90Mm1viSCKvHGpmVDYMimE9y0DCQS1i0yRGF1uSIPtuQ0NCbhS/HPKsT3nYgGCEuoB8aGOu3aGB/tmUkYXW+pwXRKqw0f/zX088XWYWvA+AR4hmmr6DDMnf/4EHgJp3xHTEwOBHCVj69xvlOawBNlL2X0b2p server2.pub diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.key b/internal/testhelper/testdata/testroot/certs/valid/server2.key new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.key @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAYEAyuDL6ZomdHC0uPqd2BMHAsKOJFWyT0xHoiDLqBCOyid8qgIyibp7 +OlaZwumkYLty5rjOLgR3IpkIuNeQpQTpuPrRYlbFTXAJLAPkLlPK0xAusT7PestWP6gvv1 +kJ+vriqdfnwLKVrC6YoN1V0k36vmAHMWX03Tv+nJNJB1b8V9PemHuw9JnatpVmxsEgZQG8 +1NcF/2Z7+YS2Q+A0htXCIwPb0P3yfacHJWYktKkNVV3aCFALy/bUwCo9veVRk9jTBhmGUA +ENL17TNWBzjAGeF6Dy9aFRY1RGaC0Q+fGug6XuIWPECnul9cO81Na6+b1WK8+zE1Guac7F +EjnlE3N5MiiaxMVZKC8gYGEKvKlvZGJPzsfcx8EwCsPb8IiLNjMHup5cSe3MOM8pDLMTyu +M/R5G2aExVst6YbjxarP1kKArx0yjY1j2m+1AGpnjOg59DfNwRdtbQkzFo5EQr7WVRiBme +2OHAIojdDj80Fg2rCfyClQ0YLmSUZ95IBwjGAoKJAAAFkBOZmjETmZoxAAAAB3NzaC1yc2 +EAAAGBAMrgy+maJnRwtLj6ndgTBwLCjiRVsk9MR6Igy6gQjsonfKoCMom6ezpWmcLppGC7 +cua4zi4EdyKZCLjXkKUE6bj60WJWxU1wCSwD5C5TytMQLrE+z3rLVj+oL79ZCfr64qnX58 +CylawumKDdVdJN+r5gBzFl9N07/pyTSQdW/FfT3ph7sPSZ2raVZsbBIGUBvNTXBf9me/mE +tkPgNIbVwiMD29D98n2nByVmJLSpDVVd2ghQC8v21MAqPb3lUZPY0wYZhlABDS9e0zVgc4 +wBnheg8vWhUWNURmgtEPnxroOl7iFjxAp7pfXDvNTWuvm9VivPsxNRrmnOxRI55RNzeTIo +msTFWSgvIGBhCrypb2RiT87H3MfBMArD2/CIizYzB7qeXEntzDjPKQyzE8rjP0eRtmhMVb +LemG48Wqz9ZCgK8dMo2NY9pvtQBqZ4zoOfQ3zcEXbW0JMxaOREK+1lUYgZntjhwCKI3Q4/ +NBYNqwn8gpUNGC5klGfeSAcIxgKCiQAAAAMBAAEAAAGAUxojzMt85wNns8HMuD6LB6FkEh +QcVwka6plecrhdlQb5tLXzt6DwayQgFcwYrhr6ZPHcWtMvbbeb8AM017OcfU4YSJzccuzq +hOIPLL7b/PrK9YWR/W2fJbIh5NJ3GRx9ji7HWpKMZpwrnvEq/1s705GIQL7Pv3Ocxsw6BM +ynzt4VdwZrpLYE9fdawx1GxLkifViat1Rmgf3PnxwOyBB1Vlx1RTVQiBHMBpDBhlMdCBPK +hM8tFd5EpXZoFgoCEXqlssIptaf0zUZAgeES31GwNrP7+n6SlL+xZxbs7ykWKjA1ibYDTE +fLIojOQCOgnIFaDFbbgUiqxoYg1SAr2SRPOjopc5EXSt5kfCdQk3I5MKoSm2INNuwBqprI +/BL0Do3VowAQkxjXJUWit9RR0wS7FiA54WJqOrfU+2ChRooVUvtt0i/0y9tJMr6+PJYawZ +uLwQ4DXs3UNVFKdopyh+zcLht+1xIZO6VrMteXejVhcz8UnRQE7leCdOvCYbBX87eRAAAA +wFX+Q0Cp8SD3Pf607nq0GNYgY+vQR/zqqTnIlYt3kKt0jP6TuvkOUnaANOt29W17LxIR1U +tZxFfyktrT4/RiVRP+QWvdLS32IN3mpCPt+J0oKujlSWrUT0SJgd7ZLePJIOscjuFqW72M +dNV7aCNIisc2QgJbp5EwCNTFxQmdqryk9Pd80kWSSAwWQ5A6jXSrLEAdaFTa9kF/o3DGNe +E/6HOTnt7BFvdE1hetYFnUTR1vqjD21Pi3d5rnePYUOGI1nAAAAMEA9fDwdHOCjosfA1ri +pWZDYYkR5JaxrCFZC5h2LcYL01aCutISH07Z5gmnAVM+CfHkihck9wiGDJuJNTo1mYR1pg +aFgoIFg8LjZzBConlSnHTPYkIYHvYFaE9T4PIS8yjlHjaDn59P06nHRNa5W/4vvhGK8eEn +hpBCQ68huqMZyCH9az6BYR1TasHY7GMbIuMXpswXt9tWRzXpuvQq0BFThNelviTw3JNFhC +cdR2+2wMCErnT0w1Y9fd+8SIHL3OdVAAAAwQDTLPokbpKxlOQOdKMGgn0CZnhiAiLMKp6k +ZQmqNjVEdiOkLWvmoBYMxW93n6uCpyc7p9R+++xXWvfIH7o4fCpiIcMKQtd7Ikp4s4uC6q +xP0QOtGui5wac/iBgd0QB7ZlRh0WNIRS0ej5sn3wHz7es5eq1F/auGhxR6i5N0EhB/qI72 +lFgWtRJsIxi0tm424K6XWEjjj7fe7k9qQ712BVOvvhZp1OK/qfsOl6lj7VPXtcVPr9+6Aw +MsHc/xbLoyRmUAAAAUc3Rhbmh1QGpldC1hcm0ubG9jYWwBAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/internal/testhelper/testdata/testroot/certs/valid/server2.pub b/internal/testhelper/testdata/testroot/certs/valid/server2.pub new file mode 100644 --- /dev/null +++ b/internal/testhelper/testdata/testroot/certs/valid/server2.pub @@ -0,0 +1,1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK4MvpmiZ0cLS4+p3YEwcCwo4kVbJPTEeiIMuoEI7KJ3yqAjKJuns6VpnC6aRgu3LmuM4uBHcimQi415ClBOm4+tFiVsVNcAksA+QuU8rTEC6xPs96y1Y/qC+/WQn6+uKp1+fAspWsLpig3VXSTfq+YAcxZfTdO/6ck0kHVvxX096Ye7D0mdq2lWbGwSBlAbzU1wX/Znv5hLZD4DSG1cIjA9vQ/fJ9pwclZiS0qQ1VXdoIUAvL9tTAKj295VGT2NMGGYZQAQ0vXtM1YHOMAZ4XoPL1oVFjVEZoLRD58a6Dpe4hY8QKe6X1w7zU1rr5vVYrz7MTUa5pzsUSOeUTc3kyKJrExVkoLyBgYQq8qW9kYk/Ox9zHwTAKw9vwiIs2Mwe6nlxJ7cw4zykMsxPK4z9HkbZoTFWy3phuPFqs/WQoCvHTKNjWPab7UAameM6Dn0N83BF21tCTMWjkRCvtZVGIGZ7Y4cAiiN0OPzQWDasJ/IKVDRguZJRn3kgHCMYCgok= diff --git a/internal/testhelper/testdata/testroot/config.yml b/internal/testhelper/testdata/testroot/config.yml --- a/internal/testhelper/testdata/testroot/config.yml +++ b/internal/testhelper/testdata/testroot/config.yml @@ -0,0 +1,4 @@ +sshd: + grace_period: 10 + client_alive_interval: 1m + proxy_header_timeout: 500ms # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1669161776 -3600 # Wed Nov 23 01:02:56 2022 +0100 # Branch heptapod # Node ID 61e96ffd4b49d8579dfda6a058fb4b62e7362183 # Parent c6529456e762c07071757b58ff7e1cc87b6947da Added tag heptapod-14.10.0 for changeset c6529456e762 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -51,3 +51,4 @@ 54e1067b740ecd4e2af0b52e4b2472366aeeb466 heptapod-14.7.0 cfb031a1e9de24b88498850cff796c224ba48edd heptapod-14.7.1 cf818cb4e4fe5440a953da19e2e8650bddbf45d5 heptapod-14.9.0 +c6529456e762c07071757b58ff7e1cc87b6947da heptapod-14.10.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1678698223 -3600 # Mon Mar 13 10:03:43 2023 +0100 # Branch heptapod-stable # Node ID afce5deb7f84e3e4259b43e9f1eee78f0df83e8d # Parent f8f9fec42f926a6cee1f1b54a90d371e96c44d77 # Parent 61e96ffd4b49d8579dfda6a058fb4b62e7362183 heptapod#731: making 0.35 the new stable series diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -51,3 +51,4 @@ 54e1067b740ecd4e2af0b52e4b2472366aeeb466 heptapod-14.7.0 cfb031a1e9de24b88498850cff796c224ba48edd heptapod-14.7.1 cf818cb4e4fe5440a953da19e2e8650bddbf45d5 heptapod-14.9.0 +c6529456e762c07071757b58ff7e1cc87b6947da heptapod-14.10.0 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v14.10.0 + +- Implement Push Auth support for 2FA verification !454 + v14.9.0 - Update LabKit library to v1.16.0 !668 diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.10.0 + +- Bump to upstream GitLab Shell v14.10.0 (GitLab 15.3 and 15.4 series) + ## 14.9.0 - Bump to upstream GitLab Shell v14.9.0 (GitLab 15.2 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.9.0 +14.10.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.9.0 +14.10.0 diff --git a/internal/command/twofactorverify/twofactorverify.go b/internal/command/twofactorverify/twofactorverify.go --- a/internal/command/twofactorverify/twofactorverify.go +++ b/internal/command/twofactorverify/twofactorverify.go @@ -4,6 +4,7 @@ "context" "fmt" "io" + "time" "gitlab.com/gitlab-org/labkit/log" @@ -13,6 +14,11 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) +const ( + timeout = 30 * time.Second + prompt = "OTP: " +) + type Command struct { Config *config.Config Args *commandargs.Shell @@ -20,25 +26,51 @@ } func (c *Command) Execute(ctx context.Context) error { - ctxlog := log.ContextLogger(ctx) - ctxlog.Info("twofactorverify: execute: waiting for user input") - otp := c.getOTP(ctx) - - ctxlog.Info("twofactorverify: execute: verifying entered OTP") - err := c.verifyOTP(ctx, otp) + client, err := twofactorverify.NewClient(c.Config) if err != nil { - ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed") return err } - ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified") + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + fmt.Fprint(c.ReadWriter.Out, prompt) + + resultCh := make(chan string) + go func() { + err := client.PushAuth(ctx, c.Args) + if err == nil { + resultCh <- "OTP has been validated by Push Authentication. Git operations are now allowed." + } + }() + + go func() { + answer, err := c.getOTP(ctx) + if err != nil { + resultCh <- formatErr(err) + } + + if err := client.VerifyOTP(ctx, c.Args, answer); err != nil { + resultCh <- formatErr(err) + } else { + resultCh <- "OTP validation successful. Git operations are now allowed." + } + }() + + var message string + select { + case message = <-resultCh: + case <-ctx.Done(): + message = formatErr(ctx.Err()) + } + + log.WithContextFields(ctx, log.Fields{"message": message}).Info("Two factor verify command finished") + fmt.Fprintf(c.ReadWriter.Out, "\n%v\n", message) + return nil } -func (c *Command) getOTP(ctx context.Context) string { - prompt := "OTP: " - fmt.Fprint(c.ReadWriter.Out, prompt) - +func (c *Command) getOTP(ctx context.Context) (string, error) { var answer string otpLength := int64(64) reader := io.LimitReader(c.ReadWriter.In, otpLength) @@ -46,21 +78,13 @@ log.ContextLogger(ctx).WithError(err).Debug("twofactorverify: getOTP: Failed to get user input") } - return answer -} - -func (c *Command) verifyOTP(ctx context.Context, otp string) error { - client, err := twofactorverify.NewClient(c.Config) - if err != nil { - return err + if answer == "" { + return "", fmt.Errorf("OTP cannot be blank.") } - err = client.VerifyOTP(ctx, c.Args, otp) - if err == nil { - fmt.Fprint(c.ReadWriter.Out, "\nOTP validation successful. Git operations are now allowed.\n") - } else { - fmt.Fprintf(c.ReadWriter.Out, "\nOTP validation failed.\n%v\n", err) - } + return answer, nil +} - return nil +func formatErr(err error) string { + return fmt.Sprintf("OTP validation failed: %v", err) } diff --git a/internal/command/twofactorverify/twofactorverify_test.go b/internal/command/twofactorverify/twofactorverify_test.go --- a/internal/command/twofactorverify/twofactorverify_test.go +++ b/internal/command/twofactorverify/twofactorverify_test.go @@ -17,10 +17,20 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" ) +type blockingReader struct{} + +func (*blockingReader) Read([]byte) (int, error) { + waitInfinitely := make(chan struct{}) + <-waitInfinitely + + return 0, nil +} + func setup(t *testing.T) []testserver.TestRequestHandler { + waitInfinitely := make(chan struct{}) requests := []testserver.TestRequestHandler{ { - Path: "/api/v4/internal/two_factor_otp_check", + Path: "/api/v4/internal/two_factor_manual_otp_check", Handler: func(w http.ResponseWriter, r *http.Request) { b, err := io.ReadAll(r.Body) defer r.Body.Close() @@ -31,11 +41,13 @@ require.NoError(t, json.Unmarshal(b, &requestBody)) switch requestBody.KeyId { - case "1": + case "verify_via_otp", "verify_via_otp_with_push_error": body := map[string]interface{}{ "success": true, } json.NewEncoder(w).Encode(body) + case "wait_infinitely": + <-waitInfinitely case "error": body := map[string]interface{}{ "success": false, @@ -47,15 +59,36 @@ } }, }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *twofactorverify.RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "verify_via_push": + body := map[string]interface{}{ + "success": true, + } + json.NewEncoder(w).Encode(body) + case "verify_via_otp_with_push_error": + w.WriteHeader(http.StatusInternalServerError) + default: + <-waitInfinitely + } + }, + }, } return requests } -const ( - question = "OTP: \n" - errorHeader = "OTP validation failed.\n" -) +const errorHeader = "OTP validation failed: " func TestExecute(t *testing.T) { requests := setup(t) @@ -65,46 +98,61 @@ testCases := []struct { desc string arguments *commandargs.Shell - answer string + input io.Reader expectedOutput string }{ { - desc: "With a known key id", - arguments: &commandargs.Shell{GitlabKeyId: "1"}, - answer: "123456\n", - expectedOutput: question + - "OTP validation successful. Git operations are now allowed.\n", + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp_with_push_error"}, + expectedOutput: "OTP validation successful. Git operations are now allowed.\n", + }, + { + desc: "Verify via push authentication", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_push"}, + input: &blockingReader{}, + expectedOutput: "OTP has been validated by Push Authentication. Git operations are now allowed.\n", + }, + { + desc: "With an empty OTP", + arguments: &commandargs.Shell{GitlabKeyId: "verify_via_otp"}, + input: bytes.NewBufferString("\n"), + expectedOutput: errorHeader + "OTP cannot be blank.\n", }, { desc: "With bad response", arguments: &commandargs.Shell{GitlabKeyId: "-1"}, - answer: "123456\n", - expectedOutput: question + errorHeader + "Parsing failed\n", + expectedOutput: errorHeader + "Parsing failed\n", }, { desc: "With API returns an error", arguments: &commandargs.Shell{GitlabKeyId: "error"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "error message\n", + expectedOutput: errorHeader + "error message\n", }, { desc: "With API fails", arguments: &commandargs.Shell{GitlabKeyId: "broken"}, - answer: "yes\n", - expectedOutput: question + errorHeader + "Internal API error (500)\n", + expectedOutput: errorHeader + "Internal API error (500)\n", }, { desc: "With missing arguments", arguments: &commandargs.Shell{}, - answer: "yes\n", - expectedOutput: question + errorHeader + "who='' is invalid\n", + expectedOutput: errorHeader + "who='' is invalid\n", }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { output := &bytes.Buffer{} - input := bytes.NewBufferString(tc.answer) + + input := tc.input + if input == nil { + input = bytes.NewBufferString("123456\n") + } cmd := &Command{ Config: &config.Config{GitlabUrl: url}, @@ -115,7 +163,29 @@ err := cmd.Execute(context.Background()) require.NoError(t, err) - require.Equal(t, tc.expectedOutput, output.String()) + require.Equal(t, prompt+"\n"+tc.expectedOutput, output.String()) }) } } + +func TestCanceledContext(t *testing.T) { + requests := setup(t) + + output := &bytes.Buffer{} + + url := testserver.StartSocketHttpServer(t, requests) + cmd := &Command{ + Config: &config.Config{GitlabUrl: url}, + Args: &commandargs.Shell{GitlabKeyId: "wait_infinitely"}, + ReadWriter: &readwriter.ReadWriter{Out: output, In: &bytes.Buffer{}}, + } + + ctx, cancel := context.WithCancel(context.Background()) + + errCh := make(chan error) + go func() { errCh <- cmd.Execute(ctx) }() + cancel() + + require.NoError(t, <-errCh) + require.Equal(t, prompt+"\n"+errorHeader+"context canceled\n", output.String()) +} diff --git a/internal/gitlabnet/twofactorverify/client.go b/internal/gitlabnet/twofactorverify/client.go --- a/internal/gitlabnet/twofactorverify/client.go +++ b/internal/gitlabnet/twofactorverify/client.go @@ -26,7 +26,7 @@ type RequestBody struct { KeyId string `json:"key_id,omitempty"` UserId int64 `json:"user_id,omitempty"` - OTPAttempt string `json:"otp_attempt"` + OTPAttempt string `json:"otp_attempt,omitempty"` } func NewClient(config *config.Config) (*Client, error) { @@ -44,7 +44,22 @@ return err } - response, err := c.client.Post(ctx, "/two_factor_otp_check", requestBody) + response, err := c.client.Post(ctx, "/two_factor_manual_otp_check", requestBody) + if err != nil { + return err + } + defer response.Body.Close() + + return parse(response) +} + +func (c *Client) PushAuth(ctx context.Context, args *commandargs.Shell) error { + requestBody, err := c.getRequestBody(ctx, args, "") + if err != nil { + return err + } + + response, err := c.client.Post(ctx, "/two_factor_push_otp_check", requestBody) if err != nil { return err } diff --git a/internal/gitlabnet/twofactorverify/client_test.go b/internal/gitlabnet/twofactorverify/client_test.go --- a/internal/gitlabnet/twofactorverify/client_test.go +++ b/internal/gitlabnet/twofactorverify/client_test.go @@ -17,49 +17,55 @@ ) func initialize(t *testing.T) []testserver.TestRequestHandler { + handler := func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + defer r.Body.Close() + + require.NoError(t, err) + + var requestBody *RequestBody + require.NoError(t, json.Unmarshal(b, &requestBody)) + + switch requestBody.KeyId { + case "0": + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "1": + body := map[string]interface{}{ + "success": false, + "message": "error message", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "2": + w.WriteHeader(http.StatusForbidden) + body := &client.ErrorResponse{ + Message: "Not allowed!", + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + case "3": + w.Write([]byte("{ \"message\": \"broken json!\"")) + case "4": + w.WriteHeader(http.StatusForbidden) + } + + if requestBody.UserId == 1 { + body := map[string]interface{}{ + "success": true, + } + require.NoError(t, json.NewEncoder(w).Encode(body)) + } + } + requests := []testserver.TestRequestHandler{ { - Path: "/api/v4/internal/two_factor_otp_check", - Handler: func(w http.ResponseWriter, r *http.Request) { - b, err := io.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - var requestBody *RequestBody - require.NoError(t, json.Unmarshal(b, &requestBody)) - - switch requestBody.KeyId { - case "0": - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "1": - body := map[string]interface{}{ - "success": false, - "message": "error message", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "2": - w.WriteHeader(http.StatusForbidden) - body := &client.ErrorResponse{ - Message: "Not allowed!", - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - case "3": - w.Write([]byte("{ \"message\": \"broken json!\"")) - case "4": - w.WriteHeader(http.StatusForbidden) - } - - if requestBody.UserId == 1 { - body := map[string]interface{}{ - "success": true, - } - require.NoError(t, json.NewEncoder(w).Encode(body)) - } - }, + Path: "/api/v4/internal/two_factor_manual_otp_check", + Handler: handler, + }, + { + Path: "/api/v4/internal/two_factor_push_otp_check", + Handler: handler, }, { Path: "/api/v4/internal/discover", @@ -140,6 +146,57 @@ } } +func TestVerifyPush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "0"} + err := client.PushAuth(context.Background(), args) + require.NoError(t, err) +} + +func TestErrorMessagePush(t *testing.T) { + client := setup(t) + + args := &commandargs.Shell{GitlabKeyId: "1"} + err := client.PushAuth(context.Background(), args) + require.Equal(t, "error message", err.Error()) +} + +func TestErrorResponsesPush(t *testing.T) { + client := setup(t) + + testCases := []struct { + desc string + fakeId string + expectedError string + }{ + { + desc: "A response with an error message", + fakeId: "2", + expectedError: "Not allowed!", + }, + { + desc: "A response with bad JSON", + fakeId: "3", + expectedError: "Parsing failed", + }, + { + desc: "An error response without message", + fakeId: "4", + expectedError: "Internal API error (403)", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + args := &commandargs.Shell{GitlabKeyId: tc.fakeId} + err := client.PushAuth(context.Background(), args) + + require.EqualError(t, err, tc.expectedError) + }) + } +} + func setup(t *testing.T) *Client { requests := initialize(t) url := testserver.StartSocketHttpServer(t, requests) diff --git a/internal/sshd/connection_test.go b/internal/sshd/connection_test.go --- a/internal/sshd/connection_test.go +++ b/internal/sshd/connection_test.go @@ -223,12 +223,12 @@ {"disallowed command", disallowedcommand.Error}, {"not our ref", grpcstatus.Error(grpccodes.Internal, `rpc error: code = Internal desc = cmd wait: exit status 128, stderr: "fatal: git upload-pack: not our ref 9106d18f6a1b8022f6517f479696f3e3ea5e68c1"`)}, } { - ignoredError := ignoredError // Capture range variable, see "Race on loop counter" in https://go.dev/doc/articles/race_detector t.Run(ignoredError.desc, func(t *testing.T) { conn, chans = setup(1, newChannel) + ignored := ignoredError.err conn.handleRequests(context.Background(), nil, chans, func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error { close(chans) - return ignoredError.err + return ignored }) require.InDelta(t, initialSessionsTotal+2+float64(i), testutil.ToFloat64(metrics.SliSshdSessionsTotal), 0.1) diff --git a/spec/gitlab_shell_two_factor_verify_spec.rb b/spec/gitlab_shell_two_factor_verify_spec.rb --- a/spec/gitlab_shell_two_factor_verify_spec.rb +++ b/spec/gitlab_shell_two_factor_verify_spec.rb @@ -11,71 +11,115 @@ 'SSH_ORIGINAL_COMMAND' => '2fa_verify' } end + let(:correct_otp) { '123456' } + before(:context) do write_config('gitlab_url' => "http+unix://#{CGI.escape(tmp_socket_path)}") end def mock_server(server) - server.mount_proc('/api/v4/internal/two_factor_otp_check') do |req, res| + server.mount_proc('/api/v4/internal/two_factor_manual_otp_check') do |req, res| + res.content_type = 'application/json' + res.status = 200 + + params = JSON.parse(req.body) + + res.body = if params['otp_attempt'] == correct_otp + { success: true }.to_json + else + { success: false, message: 'boom!' }.to_json + end + end + + server.mount_proc('/api/v4/internal/two_factor_push_otp_check') do |req, res| res.content_type = 'application/json' res.status = 200 params = JSON.parse(req.body) - key_id = params['key_id'] || params['user_id'].to_s + id = params['key_id'] || params['user_id'].to_s - if key_id == '100' + if id == '100' + res.body = { success: false, message: 'boom!' }.to_json + else res.body = { success: true }.to_json - else - res.body = { success: false, message: 'boom!' }.to_json end end - server.mount_proc('/api/v4/internal/discover') do |_, res| + server.mount_proc('/api/v4/internal/discover') do |req, res| res.status = 200 res.content_type = 'application/json' - res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + + if req.query['username'] == 'someone' + res.body = { id: 100, name: 'Some User', username: 'someuser' }.to_json + else + res.body = { id: 101, name: 'Another User', username: 'another' }.to_json + end end end - describe 'command' do + describe 'entering OTP manually' do + let(:cmd) { "#{gitlab_shell_path} key-100" } + context 'when key is provided' do - let(:cmd) { "#{gitlab_shell_path} key-100" } - - it 'prints a successful verification message' do - verify_successful_verification!(cmd) + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) end end context 'when username is provided' do let(:cmd) { "#{gitlab_shell_path} username-someone" } - it 'prints a successful verification message' do - verify_successful_verification!(cmd) + it 'asks a user for a correct OTP' do + verify_successful_otp_verification!(cmd) end end - context 'when API error occurs' do - let(:cmd) { "#{gitlab_shell_path} key-101" } + it 'shows an error when an invalid otp is provided' do + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + stdin.puts('000000') - it 'prints the error message' do - Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') - - expect(stdout.flush.read).to eq("\nOTP validation failed.\nboom!\n") - end + expect(stdout.flush.read).to eq("\nOTP validation failed: boom!\n") end end end - def verify_successful_verification!(cmd) + describe 'authorizing via push' do + context 'when key is provided' do + let(:cmd) { "#{gitlab_shell_path} key-101" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + + context 'when username is provided' do + let(:cmd) { "#{gitlab_shell_path} username-another" } + + it 'asks a user for a correct OTP' do + verify_successful_push_verification!(cmd) + end + end + end + + def verify_successful_otp_verification!(cmd) Open3.popen2(env, cmd) do |stdin, stdout| - expect(stdout.gets(5)).to eq('OTP: ') - - stdin.puts('123456') + asks_for_otp(stdout) + stdin.puts(correct_otp) expect(stdout.flush.read).to eq("\nOTP validation successful. Git operations are now allowed.\n") end end + + def verify_successful_push_verification!(cmd) + Open3.popen2(env, cmd) do |stdin, stdout| + asks_for_otp(stdout) + + expect(stdout.flush.read).to eq("\nOTP has been validated by Push Authentication. Git operations are now allowed.\n") + end + end + + def asks_for_otp(stdout) + expect(stdout.gets(5)).to eq('OTP: ') + end end # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1649505502 -14400 # Sat Apr 09 15:58:22 2022 +0400 # Node ID 7a969fe59508e1e4661d3103d063604f19d585f7 # Parent 7a403c86ddc5c76f20d2f07f247092aa2afe4837 Add developer documentation to command package diff --git a/internal/command/README.md b/internal/command/README.md new file mode 100644 --- /dev/null +++ b/internal/command/README.md @@ -0,0 +1,26 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Overview + +This package consists of a set of packages that are responsible for executing a particular command/feature/operation. +The full list of features can be viewed [here](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/doc/features.md). +The commands implement the common interface: + +```go +type Command interface { + Execute(ctx context.Context) error +} +``` + +A command is executed by running the `Execute` method. The execution logic mostly shares the common pattern: + +- Parse the arguments and validate them. +- Communicate with GitLab Rails using [gitlabnet](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitlabnet) package. For example, it can be checking whether a client is authorized to execute this particular command or asking for a personal access token in order to return it to the client. +- If a command is related to Git operations, establish a connection with Gitaly using [handler](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/handler) and [gitaly](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitaly) packages and provide two-way communication between Gitaly and the client. +- Return results to the client. + +[cmd/gitlab-shell/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell/command) is using this package to build a particular command based on the passed arguments. # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1654254444 0 # Fri Jun 03 11:07:24 2022 +0000 # Node ID cf0db2e04f7269d3af3a6b5c6cac0a150fa388e9 # Parent 7a969fe59508e1e4661d3103d063604f19d585f7 Specify all packages that use commands diff --git a/internal/command/README.md b/internal/command/README.md --- a/internal/command/README.md +++ b/internal/command/README.md @@ -23,4 +23,8 @@ - If a command is related to Git operations, establish a connection with Gitaly using [handler](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/handler) and [gitaly](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitaly) packages and provide two-way communication between Gitaly and the client. - Return results to the client. -[cmd/gitlab-shell/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell/command) is using this package to build a particular command based on the passed arguments. +This package is being used to build a particular command based on the passed arguments in the following files that are under `cmd` directory: +- [cmd/gitlab-shell/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell/command) +- [cmd/check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/check/command) +- [cmd/gitlab-shell-authorized-keys-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-keys-check/command) +- [cmd/gitlab-shell-authorized-principals-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-principals-check/command) # HG changeset patch # User Patrick Bajao <ebajao@gitlab.com> # Date 1663745718 0 # Wed Sep 21 07:35:18 2022 +0000 # Node ID 306cbe44b82355a5fa0f7c0cfd01a2d2c7f23ac3 # Parent 2640fced7a7dd0d0a80a54598e441c666a60906d # Parent cf0db2e04f7269d3af3a6b5c6cac0a150fa388e9 Merge branch 'id-add-documentation-to-command' into 'main' Add developer documentation to command package See merge request https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/594 Merged-by: Patrick Bajao <ebajao@gitlab.com> Approved-by: Patrick Bajao <ebajao@gitlab.com> Co-authored-by: Igor Drozdov <idrozdov@gitlab.com> diff --git a/internal/command/README.md b/internal/command/README.md new file mode 100644 --- /dev/null +++ b/internal/command/README.md @@ -0,0 +1,30 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Overview + +This package consists of a set of packages that are responsible for executing a particular command/feature/operation. +The full list of features can be viewed [here](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/doc/features.md). +The commands implement the common interface: + +```go +type Command interface { + Execute(ctx context.Context) error +} +``` + +A command is executed by running the `Execute` method. The execution logic mostly shares the common pattern: + +- Parse the arguments and validate them. +- Communicate with GitLab Rails using [gitlabnet](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitlabnet) package. For example, it can be checking whether a client is authorized to execute this particular command or asking for a personal access token in order to return it to the client. +- If a command is related to Git operations, establish a connection with Gitaly using [handler](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/handler) and [gitaly](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitaly) packages and provide two-way communication between Gitaly and the client. +- Return results to the client. + +This package is being used to build a particular command based on the passed arguments in the following files that are under `cmd` directory: +- [cmd/gitlab-shell/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell/command) +- [cmd/check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/check/command) +- [cmd/gitlab-shell-authorized-keys-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-keys-check/command) +- [cmd/gitlab-shell-authorized-principals-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-principals-check/command) # HG changeset patch # User Amy Qualls <aqualls@gitlab.com> # Date 1663840209 0 # Thu Sep 22 09:50:09 2022 +0000 # Node ID 4389cacccc8dda3ec99f9810ba9a3caec54c0eba # Parent 306cbe44b82355a5fa0f7c0cfd01a2d2c7f23ac3 Update docs metadata link in gitlab-shell repo diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md --- a/doc/beginners_guide.md +++ b/doc/beginners_guide.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Beginner's guide to GitLab Shell contributions diff --git a/doc/features.md b/doc/features.md --- a/doc/features.md +++ b/doc/features.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Feature list # HG changeset patch # User Alejandro RodrÃÂguez <alejandro@gitlab.com> # Date 1663840210 0 # Thu Sep 22 09:50:10 2022 +0000 # Node ID 519720296fd6a08938196933a308625235332758 # Parent 306cbe44b82355a5fa0f7c0cfd01a2d2c7f23ac3 # Parent 4389cacccc8dda3ec99f9810ba9a3caec54c0eba Merge branch 'aqualls-update-docs-metadata' into 'main' Update docs metadata link in gitlab-shell repo See merge request https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/684 Merged-by: Alejandro RodrÃÂguez <alejandro@gitlab.com> Approved-by: Alejandro RodrÃÂguez <alejandro@gitlab.com> Co-authored-by: Amy Qualls <aqualls@gitlab.com> diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md --- a/doc/beginners_guide.md +++ b/doc/beginners_guide.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Beginner's guide to GitLab Shell contributions diff --git a/doc/features.md b/doc/features.md --- a/doc/features.md +++ b/doc/features.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Feature list # HG changeset patch # User Stan Hu <stanhu@gmail.com> # Date 1664255032 25200 # Mon Sep 26 22:03:52 2022 -0700 # Node ID 52f1fd79a9efb6dfe56f7d688b966cc5b1d8c1d9 # Parent 519720296fd6a08938196933a308625235332758 Bump .tool-versions to use Go 1.18.6 go 1.17 is no longer receiving security updates. Update to go 1.18 in preparation for upgrading. Part of https://gitlab.com/groups/gitlab-org/-/epics/8843 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.9 +golang 1.18.6 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1664265694 0 # Tue Sep 27 08:01:34 2022 +0000 # Node ID 436213b02160b1488ee48fba208bfffcf1532726 # Parent 519720296fd6a08938196933a308625235332758 # Parent 52f1fd79a9efb6dfe56f7d688b966cc5b1d8c1d9 Merge branch 'sh-bump-go-1.18' into 'main' Bump .tool-versions to use Go 1.18.6 See merge request https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/685 Merged-by: Igor Drozdov <idrozdov@gitlab.com> Approved-by: Igor Drozdov <idrozdov@gitlab.com> Co-authored-by: Stan Hu <stanhu@gmail.com> diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.9 +golang 1.18.6 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1664270337 -7200 # Tue Sep 27 11:18:57 2022 +0200 # Node ID fc481f87acc38d85940b88ca5a3664635f7016d0 # Parent 2640fced7a7dd0d0a80a54598e441c666a60906d Trim secret before signing JWT tokens With this change we don't rely on the secret to either contain a newline or not contain it. diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -20,7 +20,7 @@ ) var ( - secret = []byte("sssh, it's a secret") + secret = "sssh, it's a secret" ) func TestClients(t *testing.T) { @@ -31,24 +31,29 @@ relativeURLRoot string caFile string server func(*testing.T, []testserver.TestRequestHandler) string + secret string }{ { desc: "Socket client", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with a relative URL at /", relativeURLRoot: "/", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with relative URL at /gitlab", relativeURLRoot: "/gitlab", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Http client", server: testserver.StartHttpServer, + secret: secret, }, { desc: "Https client", @@ -56,6 +61,15 @@ server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { return testserver.StartHttpsServer(t, handlers, "") }, + secret: secret, + }, + { + desc: "Secret with newlines", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), + server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { + return testserver.StartHttpsServer(t, handlers, "") + }, + secret: "\n" + secret + "\n", }, } @@ -66,7 +80,7 @@ httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", string(secret), httpClient) + client, err := NewGitlabNetClient("", "", tc.secret, httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -74,7 +88,7 @@ testSuccessfulPost(t, client) testMissing(t, client) testErrorMessage(t, client) - testAuthenticationHeader(t, client) + testAuthenticationHeader(t, tc.secret, client) testJWTAuthenticationHeader(t, client) testXForwardedForHeader(t, client) testHostWithTrailingSlash(t, client) @@ -154,7 +168,7 @@ }) } -func testAuthenticationHeader(t *testing.T, client *GitlabNetClient) { +func testAuthenticationHeader(t *testing.T, secret string, client *GitlabNetClient) { t.Run("Authentication headers for GET", func(t *testing.T) { response, err := client.Get(context.Background(), "/auth") require.NoError(t, err) @@ -167,7 +181,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -182,7 +196,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) } @@ -193,7 +207,7 @@ claims := &jwt.RegisteredClaims{} token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { - return secret, nil + return []byte(secret), nil }) require.NoError(t, err) require.True(t, token.Valid) diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -141,9 +141,7 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } - secretBytes := []byte(c.secret) - - encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) + encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) request.Header.Set(secretHeaderName, encodedSecret) claims := jwt.RegisteredClaims{ @@ -151,6 +149,7 @@ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), } + secretBytes := []byte(strings.TrimSpace(c.secret)) tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) if err != nil { return nil, err # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1664352839 0 # Wed Sep 28 08:13:59 2022 +0000 # Node ID 6f3c156c319912e41280b8778890b0e2b300db14 # Parent 436213b02160b1488ee48fba208bfffcf1532726 # Parent fc481f87acc38d85940b88ca5a3664635f7016d0 Merge branch 'id-fix-jwt-tokens' into 'main' Trim secret before signing JWT tokens See merge request https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/686 Merged-by: Ash McKenzie <amckenzie@gitlab.com> Approved-by: Alejandro RodrÃÂguez <alejandro@gitlab.com> Approved-by: Ash McKenzie <amckenzie@gitlab.com> Co-authored-by: Igor Drozdov <idrozdov@gitlab.com> diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -20,7 +20,7 @@ ) var ( - secret = []byte("sssh, it's a secret") + secret = "sssh, it's a secret" ) func TestClients(t *testing.T) { @@ -31,24 +31,29 @@ relativeURLRoot string caFile string server func(*testing.T, []testserver.TestRequestHandler) string + secret string }{ { desc: "Socket client", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with a relative URL at /", relativeURLRoot: "/", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with relative URL at /gitlab", relativeURLRoot: "/gitlab", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Http client", server: testserver.StartHttpServer, + secret: secret, }, { desc: "Https client", @@ -56,6 +61,15 @@ server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { return testserver.StartHttpsServer(t, handlers, "") }, + secret: secret, + }, + { + desc: "Secret with newlines", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), + server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { + return testserver.StartHttpsServer(t, handlers, "") + }, + secret: "\n" + secret + "\n", }, } @@ -66,7 +80,7 @@ httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", string(secret), httpClient) + client, err := NewGitlabNetClient("", "", tc.secret, httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -74,7 +88,7 @@ testSuccessfulPost(t, client) testMissing(t, client) testErrorMessage(t, client) - testAuthenticationHeader(t, client) + testAuthenticationHeader(t, tc.secret, client) testJWTAuthenticationHeader(t, client) testXForwardedForHeader(t, client) testHostWithTrailingSlash(t, client) @@ -154,7 +168,7 @@ }) } -func testAuthenticationHeader(t *testing.T, client *GitlabNetClient) { +func testAuthenticationHeader(t *testing.T, secret string, client *GitlabNetClient) { t.Run("Authentication headers for GET", func(t *testing.T) { response, err := client.Get(context.Background(), "/auth") require.NoError(t, err) @@ -167,7 +181,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -182,7 +196,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) } @@ -193,7 +207,7 @@ claims := &jwt.RegisteredClaims{} token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { - return secret, nil + return []byte(secret), nil }) require.NoError(t, err) require.True(t, token.Valid) diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -141,9 +141,7 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } - secretBytes := []byte(c.secret) - - encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) + encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) request.Header.Set(secretHeaderName, encodedSecret) claims := jwt.RegisteredClaims{ @@ -151,6 +149,7 @@ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), } + secretBytes := []byte(strings.TrimSpace(c.secret)) tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) if err != nil { return nil, err # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1664355316 -7200 # Wed Sep 28 10:55:16 2022 +0200 # Node ID 7349d3cd7ec70f9378771a4696f3b19c98b69285 # Parent 6f3c156c319912e41280b8778890b0e2b300db14 Release v14.12.0 - Trim secret before signing JWT tokens !686 - Bump .tool-versions to use Go 1.18.6 !685 - Update Gitaly to 15.4.0-rc2 !681 - Test against Golang v1.19 !680 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +v14.12.0 + +- Trim secret before signing JWT tokens !686 +- Bump .tool-versions to use Go 1.18.6 !685 +- Update Gitaly to 15.4.0-rc2 !681 +- Test against Golang v1.19 !680 + v14.11.0 - Update Gitaly to v15 !676 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.11.0 +14.12.0 # HG changeset patch # User Igor Drozdov <idrozdov@gitlab.com> # Date 1664355922 0 # Wed Sep 28 09:05:22 2022 +0000 # Node ID 2c02c21df3911c7d4cf2bb425be879e2786c2b69 # Parent 6f3c156c319912e41280b8778890b0e2b300db14 # Parent 7349d3cd7ec70f9378771a4696f3b19c98b69285 Merge branch 'id-release-14-12-0' into 'main' Release v14.12.0 See merge request https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/687 Merged-by: Igor Drozdov <idrozdov@gitlab.com> Approved-by: Igor Drozdov <idrozdov@gitlab.com> diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +v14.12.0 + +- Trim secret before signing JWT tokens !686 +- Bump .tool-versions to use Go 1.18.6 !685 +- Update Gitaly to 15.4.0-rc2 !681 +- Test against Golang v1.19 !680 + v14.11.0 - Update Gitaly to v15 !676 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.11.0 +14.12.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1681211144 -7200 # Tue Apr 11 13:05:44 2023 +0200 # Branch heptapod # Node ID 8ecde27776526bb72c31795c54d68ac62e3b8a9d # Parent 61e96ffd4b49d8579dfda6a058fb4b62e7362183 # Parent 2c02c21df3911c7d4cf2bb425be879e2786c2b69 Merged upstream v14.12.0 into Heptapod Shell diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,7 +61,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18", "1.19"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.9 +golang 1.18.6 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,15 @@ +v14.12.0 + +- Trim secret before signing JWT tokens !686 +- Bump .tool-versions to use Go 1.18.6 !685 +- Update Gitaly to 15.4.0-rc2 !681 +- Test against Golang v1.19 !680 + +v14.11.0 + +- Update Gitaly to v15 !676 +- Fixed extra slashes in API request paths generated for geo !673 + v14.10.0 - Implement Push Auth support for 2FA verification !454 diff --git a/Dangerfile b/Dangerfile --- a/Dangerfile +++ b/Dangerfile @@ -5,5 +5,5 @@ Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| gitlab_dangerfiles.import_plugins - gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages]) end diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -5,5 +5,5 @@ end group :development, :danger do - gem 'gitlab-dangerfiles', '~> 3.0.0' + gem 'gitlab-dangerfiles', '~> 3.5.1' end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ colored2 (3.1.2) cork (0.3.0) colored2 (~> 3.1) - danger (8.5.0) + danger (8.6.1) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) @@ -28,7 +28,7 @@ danger gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) - faraday (1.10.0) + faraday (1.10.1) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -43,29 +43,29 @@ faraday-em_http (1.0.0) faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) - faraday-http-cache (2.2.0) + faraday-http-cache (2.4.1) faraday (>= 0.8) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - git (1.10.2) + git (1.11.0) rchardet (~> 1.8) - gitlab (4.18.0) - httparty (~> 0.18) + gitlab (4.19.0) + httparty (~> 0.20) terminal-table (>= 1.5.1) - gitlab-dangerfiles (3.0.0) + gitlab-dangerfiles (3.5.1) danger (>= 8.4.5) danger-gitlab (>= 8.0.0) rake httparty (0.20.0) mime-types (~> 3.0) multi_xml (>= 0.5.2) - kramdown (2.3.2) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) @@ -73,14 +73,14 @@ mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) multi_xml (0.6.0) - multipart-post (2.1.1) + multipart-post (2.2.3) nap (1.1.0) no_proxy_fix (0.1.2) - octokit (4.22.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) open4 (1.3.4) - public_suffix (4.0.6) + public_suffix (4.0.7) rake (13.0.6) rchardet (1.8.0) rexml (3.2.5) @@ -98,18 +98,18 @@ rspec-support (~> 3.8.0) rspec-support (3.8.0) ruby2_keywords (0.0.5) - sawyer (0.8.2) + sawyer (0.9.2) addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) + faraday (>= 0.17.3, < 3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - unicode-display_width (2.1.0) + unicode-display_width (2.2.0) PLATFORMS ruby DEPENDENCIES - gitlab-dangerfiles (~> 3.0.0) + gitlab-dangerfiles (~> 3.5.1) rspec (~> 3.8.0) BUNDLED WITH diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.12.0 + +- Bump to upstream GitLab Shell v14.12.0 (GitLab 15.5) + ## 14.10.0 - Bump to upstream GitLab Shell v14.10.0 (GitLab 15.3 and 15.4 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.10.0 +14.12.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.10.0 +14.12.0 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -20,7 +20,7 @@ ) var ( - secret = []byte("sssh, it's a secret") + secret = "sssh, it's a secret" ) func TestClients(t *testing.T) { @@ -31,24 +31,29 @@ relativeURLRoot string caFile string server func(*testing.T, []testserver.TestRequestHandler) string + secret string }{ { desc: "Socket client", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with a relative URL at /", relativeURLRoot: "/", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with relative URL at /gitlab", relativeURLRoot: "/gitlab", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Http client", server: testserver.StartHttpServer, + secret: secret, }, { desc: "Https client", @@ -56,6 +61,15 @@ server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { return testserver.StartHttpsServer(t, handlers, "") }, + secret: secret, + }, + { + desc: "Secret with newlines", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), + server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { + return testserver.StartHttpsServer(t, handlers, "") + }, + secret: "\n" + secret + "\n", }, } @@ -66,7 +80,7 @@ httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", string(secret), httpClient) + client, err := NewGitlabNetClient("", "", tc.secret, httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -74,9 +88,10 @@ testSuccessfulPost(t, client) testMissing(t, client) testErrorMessage(t, client) - testAuthenticationHeader(t, client) + testAuthenticationHeader(t, tc.secret, client) testJWTAuthenticationHeader(t, client) testXForwardedForHeader(t, client) + testHostWithTrailingSlash(t, client) }) } } @@ -153,7 +168,7 @@ }) } -func testAuthenticationHeader(t *testing.T, client *GitlabNetClient) { +func testAuthenticationHeader(t *testing.T, secret string, client *GitlabNetClient) { t.Run("Authentication headers for GET", func(t *testing.T) { response, err := client.Get(context.Background(), "/auth") require.NoError(t, err) @@ -166,7 +181,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -181,7 +196,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) } @@ -192,7 +207,7 @@ claims := &jwt.RegisteredClaims{} token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { - return secret, nil + return []byte(secret), nil }) require.NoError(t, err) require.True(t, token.Valid) @@ -237,6 +252,16 @@ }) } +func testHostWithTrailingSlash(t *testing.T, client *GitlabNetClient) { + oldHost := client.httpClient.Host + client.httpClient.Host = oldHost + "/" + + testSuccessfulGet(t, client) + testSuccessfulPost(t, client) + + client.httpClient.Host = oldHost +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -85,6 +85,10 @@ return path } +func appendPath(host string, path string) string { + return strings.TrimSuffix(host, "/") + "/" + strings.TrimPrefix(path, "/") +} + func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { @@ -96,7 +100,7 @@ jsonReader = bytes.NewReader(jsonData) } - request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) + request, err := http.NewRequestWithContext(ctx, method, appendPath(host, path), jsonReader) if err != nil { return nil, err } @@ -137,9 +141,7 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } - secretBytes := []byte(c.secret) - - encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) + encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) request.Header.Set(secretHeaderName, encodedSecret) claims := jwt.RegisteredClaims{ @@ -147,6 +149,7 @@ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), } + secretBytes := []byte(strings.TrimSpace(c.secret)) tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) if err != nil { return nil, err diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -10,8 +10,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -22,8 +22,8 @@ "github.com/mikesmitty/edkey" "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" - gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyClient "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) @@ -387,12 +387,25 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-receive-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + err = session.Start(fmt.Sprintf("git-receive-pack %s", testRepo)) + require.NoError(t, err) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + stdin.Close() + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md --- a/doc/beginners_guide.md +++ b/doc/beginners_guide.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Beginner's guide to GitLab Shell contributions diff --git a/doc/features.md b/doc/features.md --- a/doc/features.md +++ b/doc/features.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Feature list diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,27 +10,29 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 - github.com/prometheus/client_golang v1.12.1 - github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 + github.com/prometheus/client_golang v1.12.2 + github.com/sirupsen/logrus v1.9.0 + github.com/stretchr/testify v1.8.0 + gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 gitlab.com/gitlab-org/labkit v1.16.0 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.40.0 + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa + golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f + google.golang.org/grpc v1.48.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.92.2 // indirect + 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 v0.1.0 // indirect - contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // indirect + cloud.google.com/go/trace v1.2.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.10 // 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/aws/aws-sdk-go v1.38.35 // indirect + github.com/aws/aws-sdk-go v1.43.31 // 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 @@ -41,12 +43,13 @@ github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.6 // indirect + github.com/google/go-cmp v0.5.8 // indirect github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect - github.com/google/uuid v1.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.0.5 // indirect - github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kr/text v0.2.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // indirect @@ -63,22 +66,23 @@ 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-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect go.opencensus.io v0.23.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/api v0.54.0 // indirect + google.golang.org/api v0.74.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,9 +1,6 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -22,104 +19,123 @@ 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.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= -github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= -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/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.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +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/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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -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 v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= 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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +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/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20220810064516-de89276ce0f3/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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= @@ -128,40 +144,56 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +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 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +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/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= +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/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= +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/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= +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/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= +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/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= +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/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/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/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= +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= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -171,63 +203,57 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= -github.com/cloudflare/tableflip v0.0.0-20190329062924-8392f1641731/go.mod h1:erh4dYezoMVbIa52pi7i1Du7+cXOgqNuTamt10qvMoA= -github.com/cloudflare/tableflip v1.2.2 h1:WkhiowHlg0nZuH7Y2beLVIZDfxtSvKta1f22PEgUN7w= -github.com/cloudflare/tableflip v1.2.2/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw= +github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= 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-20211001041855-01bcc9b48dfe/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 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/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +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= +github.com/dpotapov/go-spnego v0.0.0-20210315154721-298b63a54430/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= +github.com/dpotapov/go-spnego v0.0.0-20220426193508-b7f82e4507db/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -235,41 +261,38 @@ 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/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= 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= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -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/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/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= -github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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= -github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= -github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/git-lfs/git-lfs/v3 v3.2.0/go.mod h1:GZZO3jw2Yn3/1KFV4nRoXUzH+yPzGypIdTeQpkzxEvQ= +github.com/git-lfs/gitobj/v2 v2.1.0/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8COmU45ncAxw= +github.com/git-lfs/go-netrc v0.0.0-20210914205454-f0c862dd687a/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= +github.com/git-lfs/pktline v0.0.0-20210330133718-06e9096e2825/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A= +github.com/git-lfs/wildmatch/v2 v2.0.1/go.mod h1:EVqonpk9mXbREP3N8UkwoWdrF249uHpCUo5CPXY81gw= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= +github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -281,10 +304,10 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -297,42 +320,36 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -361,7 +378,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -377,11 +393,13 @@ 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/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= +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= @@ -390,6 +408,7 @@ 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/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= @@ -403,6 +422,7 @@ 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= @@ -411,33 +431,30 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -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/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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.3-0.20210213123510-be4c235f9d1c/go.mod h1:RXwzibsL7UhPcEmGyGvXKJ8kyJsOCOEaLgGce4igMFs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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/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.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -448,6 +465,8 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -458,22 +477,21 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= @@ -486,7 +504,8 @@ github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= 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/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= 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= @@ -500,39 +519,42 @@ github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= 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/pgtype v1.12.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/pgx/v4 v4.17.0/go.mod h1:Gd6RmOhtFLTu8cp/Fhq4kP195KrshxYJH3oW8AWJ1pw= 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/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -541,38 +563,30 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -582,30 +596,27 @@ 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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leonelquinteros/gotext v1.5.0/go.mod h1:OCiUVHuhP9LGFBQ1oAmdtNCHJCiHiQA8lf4nAifHkr0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= -github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -613,6 +624,7 @@ 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-ieproxy v0.0.3/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= @@ -621,23 +633,23 @@ 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/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= -github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -647,33 +659,27 @@ 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/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -682,111 +688,82 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.3/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -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/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= +github.com/rubenv/sql-migrate v1.1.2/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= -github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= @@ -795,67 +772,60 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -868,41 +838,28 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= -gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 h1:ngV/NWEMz4TRlnJFzBpatdXkEIDMHsU3YUzGdZU63qY= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2/go.mod h1:Rv/LoDU5I3cOP6KLUWFjC1eigcay2u8b8ZcsW86A0Xo= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= -gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= -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.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= gitlab.com/gitlab-org/labkit v1.16.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.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -917,20 +874,24 @@ 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +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.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= 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= @@ -948,7 +909,6 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -960,7 +920,6 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -973,16 +932,15 @@ 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -995,7 +953,6 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1005,7 +962,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1023,13 +979,20 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +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/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= +golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 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= @@ -1042,12 +1005,17 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -1058,16 +1026,15 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1077,33 +1044,28 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-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= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1122,20 +1084,14 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1144,13 +1100,30 @@ 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-20210809222454-d867a43fc93e/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/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +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= @@ -1161,18 +1134,16 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1193,12 +1164,10 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1213,6 +1182,7 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= @@ -1238,8 +1208,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1252,13 +1222,10 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -1277,31 +1244,42 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= 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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1341,12 +1319,9 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= 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= @@ -1355,19 +1330,43 @@ 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/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/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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1388,8 +1387,12 @@ 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/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -1403,10 +1406,10 @@ 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= -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= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1416,28 +1419,17 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v2 v2.0.0/go.mod h1:vCwK9HeXksMeUmQ4SxDd1tRz4LejrKh3KRVjQWhjvZI= -gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= -gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1448,9 +1440,10 @@ 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= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1458,11 +1451,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/command/README.md b/internal/command/README.md new file mode 100644 --- /dev/null +++ b/internal/command/README.md @@ -0,0 +1,30 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Overview + +This package consists of a set of packages that are responsible for executing a particular command/feature/operation. +The full list of features can be viewed [here](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/doc/features.md). +The commands implement the common interface: + +```go +type Command interface { + Execute(ctx context.Context) error +} +``` + +A command is executed by running the `Execute` method. The execution logic mostly shares the common pattern: + +- Parse the arguments and validate them. +- Communicate with GitLab Rails using [gitlabnet](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitlabnet) package. For example, it can be checking whether a client is authorized to execute this particular command or asking for a personal access token in order to return it to the client. +- If a command is related to Git operations, establish a connection with Gitaly using [handler](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/handler) and [gitaly](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitaly) packages and provide two-way communication between Gitaly and the client. +- Return results to the client. + +This package is being used to build a particular command based on the passed arguments in the following files that are under `cmd` directory: +- [cmd/gitlab-shell/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell/command) +- [cmd/check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/check/command) +- [cmd/gitlab-shell-authorized-keys-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-keys-check/command) +- [cmd/gitlab-shell-authorized-principals-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-principals-check/command) diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -9,9 +9,9 @@ grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v15/client" "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -5,7 +5,7 @@ "fmt" "net/http" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -10,7 +10,7 @@ "testing" "github.com/stretchr/testify/require" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -16,7 +16,7 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,7 +11,7 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1681211921 -7200 # Tue Apr 11 13:18:41 2023 +0200 # Branch heptapod # Node ID b6d4930111c1dc7f4662ed98544211d2b0ad3593 # Parent 8ecde27776526bb72c31795c54d68ac62e3b8a9d CI/CD: testing with Golang 1.19 This is following upstream changes at v14.12.0 in .gitlab-ci.yml diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -43,7 +43,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18", "1.19"] after_script: - make coverage coverage: '/\d+.\d+%/' # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1681212146 -7200 # Tue Apr 11 13:22:26 2023 +0200 # Branch heptapod # Node ID 4879c15232ec66f811816160bc46f21db45c3f9b # Parent b6d4930111c1dc7f4662ed98544211d2b0ad3593 CI/CD: bumping Gitaly version to match GitLab 15.5 Upstream configuration `.gitlab-ci.yml` is actually using `master`, which obviously cannot suit us. Still, we were on a really old Gitaly version. diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -31,7 +31,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.10.1 + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v15.5.0 # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1681429800 -7200 # Fri Apr 14 01:50:00 2023 +0200 # Branch heptapod # Node ID 49a2ffd1d601b19efbf9ec46480a2491937306fe # Parent 4879c15232ec66f811816160bc46f21db45c3f9b Added tag heptapod-14.12.0 for changeset 4879c15232ec diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -52,3 +52,4 @@ cfb031a1e9de24b88498850cff796c224ba48edd heptapod-14.7.1 cf818cb4e4fe5440a953da19e2e8650bddbf45d5 heptapod-14.9.0 c6529456e762c07071757b58ff7e1cc87b6947da heptapod-14.10.0 +4879c15232ec66f811816160bc46f21db45c3f9b heptapod-14.12.0 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1683116023 -7200 # Wed May 03 14:13:43 2023 +0200 # Branch heptapod-stable # Node ID 5603c54514186b70bfd3a4013d8eace4811cc85a # Parent afce5deb7f84e3e4259b43e9f1eee78f0df83e8d # Parent 49a2ffd1d601b19efbf9ec46480a2491937306fe heptapod#743: making 0.36 the new stable diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,7 +61,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18", "1.19"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -52,3 +52,4 @@ cfb031a1e9de24b88498850cff796c224ba48edd heptapod-14.7.1 cf818cb4e4fe5440a953da19e2e8650bddbf45d5 heptapod-14.9.0 c6529456e762c07071757b58ff7e1cc87b6947da heptapod-14.10.0 +4879c15232ec66f811816160bc46f21db45c3f9b heptapod-14.12.0 diff --git a/.tool-versions b/.tool-versions --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ ruby 2.7.5 -golang 1.17.9 +golang 1.18.6 diff --git a/CHANGELOG b/CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,15 @@ +v14.12.0 + +- Trim secret before signing JWT tokens !686 +- Bump .tool-versions to use Go 1.18.6 !685 +- Update Gitaly to 15.4.0-rc2 !681 +- Test against Golang v1.19 !680 + +v14.11.0 + +- Update Gitaly to v15 !676 +- Fixed extra slashes in API request paths generated for geo !673 + v14.10.0 - Implement Push Auth support for 2FA verification !454 diff --git a/Dangerfile b/Dangerfile --- a/Dangerfile +++ b/Dangerfile @@ -5,5 +5,5 @@ Gitlab::Dangerfiles.for_project(self) do |gitlab_dangerfiles| gitlab_dangerfiles.import_plugins - gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages simple_roulette]) + gitlab_dangerfiles.import_dangerfiles(except: %w[changelog commit_messages]) end diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -5,5 +5,5 @@ end group :development, :danger do - gem 'gitlab-dangerfiles', '~> 3.0.0' + gem 'gitlab-dangerfiles', '~> 3.5.1' end diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ colored2 (3.1.2) cork (0.3.0) colored2 (~> 3.1) - danger (8.5.0) + danger (8.6.1) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) @@ -28,7 +28,7 @@ danger gitlab (~> 4.2, >= 4.2.0) diff-lcs (1.3) - faraday (1.10.0) + faraday (1.10.1) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -43,29 +43,29 @@ faraday-em_http (1.0.0) faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) - faraday-http-cache (2.2.0) + faraday-http-cache (2.4.1) faraday (>= 0.8) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - git (1.10.2) + git (1.11.0) rchardet (~> 1.8) - gitlab (4.18.0) - httparty (~> 0.18) + gitlab (4.19.0) + httparty (~> 0.20) terminal-table (>= 1.5.1) - gitlab-dangerfiles (3.0.0) + gitlab-dangerfiles (3.5.1) danger (>= 8.4.5) danger-gitlab (>= 8.0.0) rake httparty (0.20.0) mime-types (~> 3.0) multi_xml (>= 0.5.2) - kramdown (2.3.2) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) @@ -73,14 +73,14 @@ mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) multi_xml (0.6.0) - multipart-post (2.1.1) + multipart-post (2.2.3) nap (1.1.0) no_proxy_fix (0.1.2) - octokit (4.22.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) open4 (1.3.4) - public_suffix (4.0.6) + public_suffix (4.0.7) rake (13.0.6) rchardet (1.8.0) rexml (3.2.5) @@ -98,18 +98,18 @@ rspec-support (~> 3.8.0) rspec-support (3.8.0) ruby2_keywords (0.0.5) - sawyer (0.8.2) + sawyer (0.9.2) addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) + faraday (>= 0.17.3, < 3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - unicode-display_width (2.1.0) + unicode-display_width (2.2.0) PLATFORMS ruby DEPENDENCIES - gitlab-dangerfiles (~> 3.0.0) + gitlab-dangerfiles (~> 3.5.1) rspec (~> 3.8.0) BUNDLED WITH diff --git a/HEPTAPOD_CHANGELOG b/HEPTAPOD_CHANGELOG --- a/HEPTAPOD_CHANGELOG +++ b/HEPTAPOD_CHANGELOG @@ -10,6 +10,10 @@ The corresponding tag is heptapod-x.y.z +## 14.12.0 + +- Bump to upstream GitLab Shell v14.12.0 (GitLab 15.5) + ## 14.10.0 - Bump to upstream GitLab Shell v14.10.0 (GitLab 15.3 and 15.4 series) diff --git a/HEPTAPOD_VERSION b/HEPTAPOD_VERSION --- a/HEPTAPOD_VERSION +++ b/HEPTAPOD_VERSION @@ -1,1 +1,1 @@ -14.10.0 +14.12.0 diff --git a/VERSION b/VERSION --- a/VERSION +++ b/VERSION @@ -1,1 +1,1 @@ -14.10.0 +14.12.0 diff --git a/client/client_test.go b/client/client_test.go --- a/client/client_test.go +++ b/client/client_test.go @@ -20,7 +20,7 @@ ) var ( - secret = []byte("sssh, it's a secret") + secret = "sssh, it's a secret" ) func TestClients(t *testing.T) { @@ -31,24 +31,29 @@ relativeURLRoot string caFile string server func(*testing.T, []testserver.TestRequestHandler) string + secret string }{ { desc: "Socket client", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with a relative URL at /", relativeURLRoot: "/", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Socket client with relative URL at /gitlab", relativeURLRoot: "/gitlab", server: testserver.StartSocketHttpServer, + secret: secret, }, { desc: "Http client", server: testserver.StartHttpServer, + secret: secret, }, { desc: "Https client", @@ -56,6 +61,15 @@ server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { return testserver.StartHttpsServer(t, handlers, "") }, + secret: secret, + }, + { + desc: "Secret with newlines", + caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"), + server: func(t *testing.T, handlers []testserver.TestRequestHandler) string { + return testserver.StartHttpsServer(t, handlers, "") + }, + secret: "\n" + secret + "\n", }, } @@ -66,7 +80,7 @@ httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil) require.NoError(t, err) - client, err := NewGitlabNetClient("", "", string(secret), httpClient) + client, err := NewGitlabNetClient("", "", tc.secret, httpClient) require.NoError(t, err) testBrokenRequest(t, client) @@ -74,9 +88,10 @@ testSuccessfulPost(t, client) testMissing(t, client) testErrorMessage(t, client) - testAuthenticationHeader(t, client) + testAuthenticationHeader(t, tc.secret, client) testJWTAuthenticationHeader(t, client) testXForwardedForHeader(t, client) + testHostWithTrailingSlash(t, client) }) } } @@ -153,7 +168,7 @@ }) } -func testAuthenticationHeader(t *testing.T, client *GitlabNetClient) { +func testAuthenticationHeader(t *testing.T, secret string, client *GitlabNetClient) { t.Run("Authentication headers for GET", func(t *testing.T) { response, err := client.Get(context.Background(), "/auth") require.NoError(t, err) @@ -166,7 +181,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) t.Run("Authentication headers for POST", func(t *testing.T) { @@ -181,7 +196,7 @@ header, err := base64.StdEncoding.DecodeString(string(responseBody)) require.NoError(t, err) - require.Equal(t, secret, header) + require.Equal(t, secret, string(header)) }) } @@ -192,7 +207,7 @@ claims := &jwt.RegisteredClaims{} token, err := jwt.ParseWithClaims(string(responseBody), claims, func(token *jwt.Token) (interface{}, error) { - return secret, nil + return []byte(secret), nil }) require.NoError(t, err) require.True(t, token.Valid) @@ -237,6 +252,16 @@ }) } +func testHostWithTrailingSlash(t *testing.T, client *GitlabNetClient) { + oldHost := client.httpClient.Host + client.httpClient.Host = oldHost + "/" + + testSuccessfulGet(t, client) + testSuccessfulPost(t, client) + + client.httpClient.Host = oldHost +} + func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestRequestHandler { requests := []testserver.TestRequestHandler{ { diff --git a/client/gitlabnet.go b/client/gitlabnet.go --- a/client/gitlabnet.go +++ b/client/gitlabnet.go @@ -85,6 +85,10 @@ return path } +func appendPath(host string, path string) string { + return strings.TrimSuffix(host, "/") + "/" + strings.TrimPrefix(path, "/") +} + func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) { var jsonReader io.Reader if data != nil { @@ -96,7 +100,7 @@ jsonReader = bytes.NewReader(jsonData) } - request, err := http.NewRequestWithContext(ctx, method, host+path, jsonReader) + request, err := http.NewRequestWithContext(ctx, method, appendPath(host, path), jsonReader) if err != nil { return nil, err } @@ -137,9 +141,7 @@ if user != "" && password != "" { request.SetBasicAuth(user, password) } - secretBytes := []byte(c.secret) - - encodedSecret := base64.StdEncoding.EncodeToString(secretBytes) + encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.secret)) request.Header.Set(secretHeaderName, encodedSecret) claims := jwt.RegisteredClaims{ @@ -147,6 +149,7 @@ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtTTL)), } + secretBytes := []byte(strings.TrimSpace(c.secret)) tokenString, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secretBytes) if err != nil { return nil, err diff --git a/client/testserver/gitalyserver.go b/client/testserver/gitalyserver.go --- a/client/testserver/gitalyserver.go +++ b/client/testserver/gitalyserver.go @@ -10,8 +10,8 @@ "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go --- a/cmd/gitlab-sshd/acceptance_test.go +++ b/cmd/gitlab-sshd/acceptance_test.go @@ -22,8 +22,8 @@ "github.com/mikesmitty/edkey" "github.com/pires/go-proxyproto" "github.com/stretchr/testify/require" - gitalyClient "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + gitalyClient "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper" "golang.org/x/crypto/ssh" ) @@ -387,12 +387,25 @@ ensureGitalyRepository(t) client := runSSHD(t, successAPI(t)) - session, err := client.NewSession() require.NoError(t, err) defer session.Close() - output, err := session.Output(fmt.Sprintf("git-receive-pack %s", testRepo)) + stdin, err := session.StdinPipe() + require.NoError(t, err) + + stdout, err := session.StdoutPipe() + require.NoError(t, err) + + err = session.Start(fmt.Sprintf("git-receive-pack %s", testRepo)) + require.NoError(t, err) + + // Gracefully close connection + _, err = fmt.Fprintln(stdin, "0000") + require.NoError(t, err) + stdin.Close() + + output, err := io.ReadAll(stdout) require.NoError(t, err) outputLines := strings.Split(string(output), "\n") diff --git a/doc/beginners_guide.md b/doc/beginners_guide.md --- a/doc/beginners_guide.md +++ b/doc/beginners_guide.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Beginner's guide to GitLab Shell contributions diff --git a/doc/features.md b/doc/features.md --- a/doc/features.md +++ b/doc/features.md @@ -1,7 +1,7 @@ --- stage: Create group: Source Code -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- # Feature list diff --git a/go.mod b/go.mod --- a/go.mod +++ b/go.mod @@ -10,27 +10,29 @@ github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a github.com/otiai10/copy v1.4.2 github.com/pires/go-proxyproto v0.6.2 - github.com/prometheus/client_golang v1.12.1 - github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.7.0 - gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 + github.com/prometheus/client_golang v1.12.2 + github.com/sirupsen/logrus v1.9.0 + github.com/stretchr/testify v1.8.0 + gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 gitlab.com/gitlab-org/labkit v1.16.0 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.40.0 + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa + golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f + google.golang.org/grpc v1.48.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.92.2 // indirect + 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 v0.1.0 // indirect - contrib.go.opencensus.io/exporter/stackdriver v0.13.8 // indirect + cloud.google.com/go/trace v1.2.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.10 // 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/aws/aws-sdk-go v1.38.35 // indirect + github.com/aws/aws-sdk-go v1.43.31 // 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 @@ -41,12 +43,13 @@ github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.6 // indirect + github.com/google/go-cmp v0.5.8 // indirect github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect - github.com/google/uuid v1.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.0.5 // indirect - github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kr/text v0.2.0 // 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/matttproud/golang_protobuf_extensions v1.0.1 // indirect @@ -63,22 +66,23 @@ 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-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect go.opencensus.io v0.23.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect + golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/api v0.54.0 // indirect + google.golang.org/api v0.74.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) replace golang.org/x/crypto => gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed diff --git a/go.sum b/go.sum --- a/go.sum +++ b/go.sum @@ -1,9 +1,6 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -22,104 +19,123 @@ 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.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +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= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 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/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-service-bus-go v0.10.11/go.mod h1:AWw9eTTWZVZyvgpPahD1ybz3a8/vT3GsJDS8KYex55U= -github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= -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/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.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +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/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/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -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 v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= 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/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI= +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/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +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/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/datadog-go v4.4.0+incompatible h1:R7WqXWP4fIOAqWJtUKmSfuc7eDsBT58k9AY5WSHVosk= github.com/DataDog/datadog-go v4.4.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/DataDog/sketches-go v1.0.0 h1:chm5KSXO7kO+ywGWJ0Zs6tdmWU8PBXSbywFVciL6BG4= github.com/DataDog/sketches-go v1.0.0/go.mod h1:O+XkJHWk9w4hDwY2ZUDU31ZC9sNYlYo8DiFsxjYeo1k= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.22.0/go.mod h1:mAm5O/zik2RFmcpigNjg6nMotDL8ZXJaxKzgGVcSMFA= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= github.com/HdrHistogram/hdrhistogram-go v1.1.1 h1:cJXY5VLMHgejurPjZH6Fo9rIwRGLefBGdiaENZALqrg= github.com/HdrHistogram/hdrhistogram-go v1.1.1/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.19/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20220810064516-de89276ce0f3/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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= @@ -128,40 +144,56 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexbrainman/sspi v0.0.0-20180125232955-4729b3d4d858/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go v2.4.2+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +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 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +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/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= +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/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= +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/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= +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/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= +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/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= +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/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/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/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= +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= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -171,63 +203,57 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws= github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ= -github.com/cloudflare/tableflip v0.0.0-20190329062924-8392f1641731/go.mod h1:erh4dYezoMVbIa52pi7i1Du7+cXOgqNuTamt10qvMoA= -github.com/cloudflare/tableflip v1.2.2 h1:WkhiowHlg0nZuH7Y2beLVIZDfxtSvKta1f22PEgUN7w= -github.com/cloudflare/tableflip v1.2.2/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw= +github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= 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-20211001041855-01bcc9b48dfe/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= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 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/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/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= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544/go.mod h1:VBi0XHpFy0xiMySf6YpVbRqrupW4RprJ5QTyN+XvGSM= github.com/dgryski/go-spooky v0.0.0-20170606183049-ed3d087f40e2/go.mod h1:hgHYKsoIw7S/hlWtP7wD1wZ7SX1jPTtKko5X9jrOgPQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +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= +github.com/dpotapov/go-spnego v0.0.0-20210315154721-298b63a54430/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= +github.com/dpotapov/go-spnego v0.0.0-20220426193508-b7f82e4507db/go.mod h1:AVSs/gZKt1bOd2AhkhbS7Qh56Hv7klde22yXVbwYJhc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1/go.mod h1:yEtCVi+QamvzjEH4U/m6ZGkALIkF2xfQnFp0BcKmIOk= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -235,41 +261,38 @@ 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/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= 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= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -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/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/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 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= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw= -github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg= -github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 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= -github.com/git-lfs/go-netrc v0.0.0-20180525200031-e0e9ca483a18/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= -github.com/git-lfs/wildmatch v1.0.4/go.mod h1:SdHAGnApDpnFYQ0vAxbniWR0sn7yLJ3QXo9RRfhn2ew= +github.com/git-lfs/git-lfs/v3 v3.2.0/go.mod h1:GZZO3jw2Yn3/1KFV4nRoXUzH+yPzGypIdTeQpkzxEvQ= +github.com/git-lfs/gitobj/v2 v2.1.0/go.mod h1:q6aqxl6Uu3gWsip5GEKpw+7459F97er8COmU45ncAxw= +github.com/git-lfs/go-netrc v0.0.0-20210914205454-f0c862dd687a/go.mod h1:70O4NAtvWn1jW8V8V+OKrJJYcxDLTmIozfi2fmSz5SI= +github.com/git-lfs/pktline v0.0.0-20210330133718-06e9096e2825/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A= +github.com/git-lfs/wildmatch/v2 v2.0.1/go.mod h1:EVqonpk9mXbREP3N8UkwoWdrF249uHpCUo5CPXY81gw= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-license-detector/v4 v4.3.0/go.mod h1:HaM4wdNxSlz/9Gw0uVOKSQS5JVFqf2Pk8xUPEn6bldI= +github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= @@ -281,10 +304,10 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -297,42 +320,36 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -361,7 +378,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -377,11 +393,13 @@ 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/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= -github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= +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= @@ -390,6 +408,7 @@ 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/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= @@ -403,6 +422,7 @@ 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= @@ -411,33 +431,30 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -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/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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.3-0.20210213123510-be4c235f9d1c/go.mod h1:RXwzibsL7UhPcEmGyGvXKJ8kyJsOCOEaLgGce4igMFs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/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/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.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -448,6 +465,8 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -458,22 +477,21 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 h1:Y4V+SFe7d3iH+9pJCoeWIOS5/xBJIFsltS7E+KJSsJY= -github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b/go.mod h1:HmaZGXHdSwQh1jnUlBGN2BeEYOHACLVGzYOXCbsLvxY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= @@ -486,7 +504,8 @@ github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= 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/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= 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= @@ -500,39 +519,42 @@ github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= 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/pgtype v1.12.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/pgx/v4 v4.17.0/go.mod h1:Gd6RmOhtFLTu8cp/Fhq4kP195KrshxYJH3oW8AWJ1pw= 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/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jdkato/prose v1.1.0/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -541,38 +563,30 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -582,30 +596,27 @@ 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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= 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= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leonelquinteros/gotext v1.5.0/go.mod h1:OCiUVHuhP9LGFBQ1oAmdtNCHJCiHiQA8lf4nAifHkr0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 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/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/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libgit2/git2go/v33 v33.0.9/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7/go.mod h1:Spd59icnvRxSKuyijbbwe5AemzvcyXAUBgApa7VybMw= -github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5PpHMUcYCFgml8+r4SS53y7A= github.com/lightstep/lightstep-tracer-go v0.25.0 h1:sGVnz8h3jTQuHKMbUe2949nXm3Sg09N1UcR3VoQNN5E= github.com/lightstep/lightstep-tracer-go v0.25.0/go.mod h1:G1ZAEaqTHFPWpWunnbUn1ADEY/Jvzz7jIOaXwAfD6A8= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -613,6 +624,7 @@ 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/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-ieproxy v0.0.3/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= @@ -621,23 +633,23 @@ 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/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= -github.com/mattn/go-shellwords v0.0.0-20190425161501-2444a32a19f4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -647,33 +659,27 @@ 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/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -682,111 +688,82 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/copy v1.4.2 h1:RTiz2sol3eoXPLF4o+YWqEybwfUa/Q2Nkc4ZIUs3fwI= github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.3/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -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/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= +github.com/rubenv/sql-migrate v1.1.2/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= 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/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY= -github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc= @@ -795,67 +772,60 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9VrZuz3wSlI+OEI= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.27.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -868,41 +838,28 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98= -gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg= -gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059 h1:X7+3GQIxUpScXpIMCU5+sfpYvZyBIQ3GMlEosP7Jssw= -gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2 h1:zz/4sD22gZqvAdBgd6gYLRIbvrgoQLDE7emPK0sXC6o= -gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2 h1:ngV/NWEMz4TRlnJFzBpatdXkEIDMHsU3YUzGdZU63qY= +gitlab.com/gitlab-org/gitaly/v15 v15.4.0-rc2/go.mod h1:Rv/LoDU5I3cOP6KLUWFjC1eigcay2u8b8ZcsW86A0Xo= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed h1:aXSyBpG6K/QsTGevZnpFoDR7Nwvn24RpkDoWe37B8eY= gitlab.com/gitlab-org/golang-crypto v0.0.0-20220616060731-4818747c9fed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= -gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= -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.16.0 h1:Vm3NAMZ8RqAunXlvPWby3GJ2R35vsYGP6Uu0YjyMIlY= gitlab.com/gitlab-org/labkit v1.16.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.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -917,20 +874,24 @@ 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/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +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.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/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/go.mod h1:zklCCIIo1N9ELkU2S2E7tW8P8eeMU7oGLeQCXdDwx9Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= 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= @@ -948,7 +909,6 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -960,7 +920,6 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -973,16 +932,15 @@ 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -995,7 +953,6 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1005,7 +962,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1023,13 +979,20 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210420210106-798c2154c571/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 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-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +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/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= +golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 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= @@ -1042,12 +1005,17 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 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= @@ -1058,16 +1026,15 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1077,33 +1044,28 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-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= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1122,20 +1084,14 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1144,13 +1100,30 @@ 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-20210809222454-d867a43fc93e/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/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +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= @@ -1161,18 +1134,16 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1193,12 +1164,10 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1213,6 +1182,7 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= @@ -1238,8 +1208,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1252,13 +1222,10 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -1277,31 +1244,42 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= 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= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1341,12 +1319,9 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210423144448-3a41ef94ed2b/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= 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= @@ -1355,19 +1330,43 @@ 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/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/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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1388,8 +1387,12 @@ 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/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 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= @@ -1403,10 +1406,10 @@ 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= -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= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1416,28 +1419,17 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v2 v2.0.0/go.mod h1:vCwK9HeXksMeUmQ4SxDd1tRz4LejrKh3KRVjQWhjvZI= -gopkg.in/jcmturner/gokrb5.v5 v5.3.0/go.mod h1:oQz8Wc5GsctOTgCVyKad1Vw4TCWz5G6gfIQr88RPv4k= -gopkg.in/jcmturner/rpc.v0 v0.0.2/go.mod h1:NzMq6cRzR9lipgw7WxRBHNx5N8SifBuaCQsOT1kWY/E= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1448,9 +1440,10 @@ 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= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1458,11 +1451,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/heptapod-ci.yml b/heptapod-ci.yml --- a/heptapod-ci.yml +++ b/heptapod-ci.yml @@ -31,7 +31,7 @@ - go version - which go services: - - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v14.10.1 + - name: registry.gitlab.com/gitlab-org/build/cng/gitaly:v15.5.0 # Disable the hooks so we don't have to stub the GitLab API command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"] alias: gitaly @@ -43,7 +43,7 @@ image: golang:${GO_VERSION} parallel: matrix: - - GO_VERSION: ["1.17", "1.18"] + - GO_VERSION: ["1.17", "1.18", "1.19"] after_script: - make coverage coverage: '/\d+.\d+%/' diff --git a/internal/command/README.md b/internal/command/README.md new file mode 100644 --- /dev/null +++ b/internal/command/README.md @@ -0,0 +1,30 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Overview + +This package consists of a set of packages that are responsible for executing a particular command/feature/operation. +The full list of features can be viewed [here](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/doc/features.md). +The commands implement the common interface: + +```go +type Command interface { + Execute(ctx context.Context) error +} +``` + +A command is executed by running the `Execute` method. The execution logic mostly shares the common pattern: + +- Parse the arguments and validate them. +- Communicate with GitLab Rails using [gitlabnet](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitlabnet) package. For example, it can be checking whether a client is authorized to execute this particular command or asking for a personal access token in order to return it to the client. +- If a command is related to Git operations, establish a connection with Gitaly using [handler](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/handler) and [gitaly](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/gitaly) packages and provide two-way communication between Gitaly and the client. +- Return results to the client. + +This package is being used to build a particular command based on the passed arguments in the following files that are under `cmd` directory: +- [cmd/gitlab-shell/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell/command) +- [cmd/check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/check/command) +- [cmd/gitlab-shell-authorized-keys-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-keys-check/command) +- [cmd/gitlab-shell-authorized-principals-check/command](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/cmd/gitlab-shell-authorized-principals-check/command) diff --git a/internal/command/receivepack/gitalycall.go b/internal/command/receivepack/gitalycall.go --- a/internal/command/receivepack/gitalycall.go +++ b/internal/command/receivepack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadarchive/gitalycall.go b/internal/command/uploadarchive/gitalycall.go --- a/internal/command/uploadarchive/gitalycall.go +++ b/internal/command/uploadarchive/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/command/uploadpack/gitalycall.go b/internal/command/uploadpack/gitalycall.go --- a/internal/command/uploadpack/gitalycall.go +++ b/internal/command/uploadpack/gitalycall.go @@ -5,8 +5,8 @@ "google.golang.org/grpc" - "gitlab.com/gitlab-org/gitaly/v14/client" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/v15/client" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/handler" diff --git a/internal/gitaly/gitaly.go b/internal/gitaly/gitaly.go --- a/internal/gitaly/gitaly.go +++ b/internal/gitaly/gitaly.go @@ -9,9 +9,9 @@ grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" - gitalyauth "gitlab.com/gitlab-org/gitaly/v14/auth" - "gitlab.com/gitlab-org/gitaly/v14/client" - gitalyclient "gitlab.com/gitlab-org/gitaly/v14/client" + gitalyauth "gitlab.com/gitlab-org/gitaly/v15/auth" + "gitlab.com/gitlab-org/gitaly/v15/client" + gitalyclient "gitlab.com/gitlab-org/gitaly/v15/client" "gitlab.com/gitlab-org/labkit/correlation" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" "gitlab.com/gitlab-org/labkit/log" diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -5,7 +5,7 @@ "fmt" "net/http" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -10,7 +10,7 @@ "testing" "github.com/stretchr/testify/require" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" diff --git a/internal/handler/exec.go b/internal/handler/exec.go --- a/internal/handler/exec.go +++ b/internal/handler/exec.go @@ -16,7 +16,7 @@ "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/labkit/log" ) diff --git a/internal/handler/exec_test.go b/internal/handler/exec_test.go --- a/internal/handler/exec_test.go +++ b/internal/handler/exec_test.go @@ -11,7 +11,7 @@ "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" - pb "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" # HG changeset patch # User Ash McKenzie <amckenzie@gitlab.com> # Date 1673320652 -39600 # Tue Jan 10 14:17:32 2023 +1100 # Branch heptapod-oldstable # Node ID a9bf7061f262b69e9b1aef4166629deb84215166 # Parent 5603c54514186b70bfd3a4013d8eace4811cc85a Fix build for Golang 1.19 by graft from more recent GitLab Shell Graft of 7a2e02b17485 done by gracinet. The specific problem with CI is that the `golang:1.19` is now based on Debian 12. Orginal description: Explicitly install webrick for Ruby 3.x diff --git a/Gemfile b/Gemfile --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,7 @@ group :development, :test do gem 'rspec', '~> 3.8.0' + gem 'webrick', '~> 1.7' end group :development, :danger do diff --git a/Gemfile.lock b/Gemfile.lock --- a/Gemfile.lock +++ b/Gemfile.lock @@ -104,6 +104,7 @@ terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) unicode-display_width (2.2.0) + webrick (1.7.0) PLATFORMS ruby @@ -111,6 +112,7 @@ DEPENDENCIES gitlab-dangerfiles (~> 3.5.1) rspec (~> 3.8.0) + webrick (~> 1.7) BUNDLED WITH 2.3.15 # HG changeset patch # User Georges Racinet <georges.racinet@octobus.net> # Date 1690886693 -7200 # Tue Aug 01 12:44:53 2023 +0200 # Branch heptapod-oldstable # Node ID 87760aef72bc44fd60c199df20504b69200e5644 # Parent a9bf7061f262b69e9b1aef4166629deb84215166 # Parent d33b6e207eb85d15eeaa7364a79b2d7084644084 heptapod#823: making 0.36 the old stable