diff options
author | Karthik Nayak <knayak@gitlab.com> | 2022-09-28 22:45:38 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2022-11-02 21:40:44 +0300 |
commit | 8e8d639d420088b9cd0ee8103d487e0952472f53 (patch) | |
tree | 78f02f96962cd036b366bbc8762bb5673ad60b29 | |
parent | be7cbb60434349041c173a671ad6497d4428e555 (diff) |
remote: Use `GetURLAndResolveConfig()`
Use the `GetURLAndResolveConfig()` to get modified URL and any
configPair if necessary to avoid DNS rebinding. Use this modified URL
instead and add the configPair to the git subcommand.
To make it easier to test, move the command instantiation part to a new
separate function `findRemoteRootRefCmd`. This makes it easier to test
the changes to the `git.Cmd`.
-rw-r--r-- | internal/gitaly/service/remote/find_remote_root_ref.go | 24 | ||||
-rw-r--r-- | internal/gitaly/service/remote/find_remote_root_ref_test.go | 72 |
2 files changed, 92 insertions, 4 deletions
diff --git a/internal/gitaly/service/remote/find_remote_root_ref.go b/internal/gitaly/service/remote/find_remote_root_ref.go index b464c7c77..275463e43 100644 --- a/internal/gitaly/service/remote/find_remote_root_ref.go +++ b/internal/gitaly/service/remote/find_remote_root_ref.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "gitlab.com/gitlab-org/gitaly/v15/internal/command" gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors" "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" @@ -14,11 +15,22 @@ import ( const headPrefix = "HEAD branch: " -func (s *server) findRemoteRootRef(ctx context.Context, request *gitalypb.FindRemoteRootRefRequest) (string, error) { - config := []git.ConfigPair{ - {Key: "remote.inmemory.url", Value: request.RemoteUrl}, +func (s *server) findRemoteRootRefCmd(ctx context.Context, request *gitalypb.FindRemoteRootRefRequest) (*command.Command, error) { + remoteURL := request.GetRemoteUrl() + var config []git.ConfigPair + + if resolvedAddress := request.GetResolvedAddress(); resolvedAddress != "" { + modifiedURL, resolveConfig, err := git.GetURLAndResolveConfig(remoteURL, resolvedAddress) + if err != nil { + return nil, helper.ErrInvalidArgumentf("couldn't get curloptResolve config: %w", err) + } + + remoteURL = modifiedURL + config = append(config, resolveConfig...) } + config = append(config, git.ConfigPair{Key: "remote.inmemory.url", Value: remoteURL}) + if authHeader := request.GetHttpAuthorizationHeader(); authHeader != "" { config = append(config, git.ConfigPair{ Key: fmt.Sprintf("http.%s.extraHeader", request.RemoteUrl), @@ -33,7 +45,7 @@ func (s *server) findRemoteRootRef(ctx context.Context, request *gitalypb.FindRe }) } - cmd, err := s.gitCmdFactory.New(ctx, request.Repository, + return s.gitCmdFactory.New(ctx, request.Repository, git.SubSubCmd{ Name: "remote", Action: "show", @@ -42,6 +54,10 @@ func (s *server) findRemoteRootRef(ctx context.Context, request *gitalypb.FindRe git.WithRefTxHook(request.Repository), git.WithConfigEnv(config...), ) +} + +func (s *server) findRemoteRootRef(ctx context.Context, request *gitalypb.FindRemoteRootRefRequest) (string, error) { + cmd, err := s.findRemoteRootRefCmd(ctx, request) if err != nil { return "", err } diff --git a/internal/gitaly/service/remote/find_remote_root_ref_test.go b/internal/gitaly/service/remote/find_remote_root_ref_test.go index 2067a73c4..45a2b1edb 100644 --- a/internal/gitaly/service/remote/find_remote_root_ref_test.go +++ b/internal/gitaly/service/remote/find_remote_root_ref_test.go @@ -12,6 +12,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" @@ -156,3 +157,74 @@ func newGitRequestValidationMiddleware(host, secret string) func(http.ResponseWr next.ServeHTTP(w, r) } } + +func TestServer_findRemoteRootRefCmd(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + repo, _ := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + s := server{gitCmdFactory: gittest.NewCommandFactory(t, cfg)} + + for _, tc := range []struct { + desc string + request *gitalypb.FindRemoteRootRefRequest + expectedErrorStr string + expectedConfig []string + }{ + { + desc: "no resolved address is present", + request: &gitalypb.FindRemoteRootRefRequest{ + RemoteUrl: "git@gitlab.com:foo/bar.git", + ResolvedAddress: "", + Repository: repo, + }, + expectedConfig: []string{ + "GIT_CONFIG_KEY_0=remote.inmemory.url", + "GIT_CONFIG_VALUE_0=git@gitlab.com:foo/bar.git", + }, + }, + { + desc: "resolved address is present", + request: &gitalypb.FindRemoteRootRefRequest{ + RemoteUrl: "https://gitlab.com/foo/bar.git", + ResolvedAddress: "192.168.0.1", + Repository: repo, + }, + expectedConfig: []string{ + "GIT_CONFIG_KEY_0=http.curloptResolve", + "GIT_CONFIG_VALUE_0=*:443:192.168.0.1", + }, + }, + { + desc: "corrupt resolved address is present", + request: &gitalypb.FindRemoteRootRefRequest{ + RemoteUrl: "git@gitlab.com:foo/bar.git", + ResolvedAddress: "foo/bar", + Repository: repo, + }, + expectedErrorStr: "resolved address has invalid IPv4/IPv6 address", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + cmd, err := s.findRemoteRootRefCmd(ctx, tc.request) + if err == nil { + defer func() { + err := cmd.Wait() + require.Error(t, err) + }() + } + + if tc.expectedErrorStr != "" { + require.Error(t, err, tc.expectedErrorStr) + } else { + require.NoError(t, err) + require.Subset(t, cmd.Env(), tc.expectedConfig) + } + }) + } +} |