diff options
author | John Cai <jcai@gitlab.com> | 2020-05-26 02:30:01 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2020-06-01 19:42:01 +0300 |
commit | 87b8dde88db42036d6c03b5537e7ee9b720c1aa5 (patch) | |
tree | ec5622a315c1e2ab99ac253bb17f918da1ce77a2 | |
parent | 2b825079253900d72cab202b9673b857ed103da5 (diff) |
Dependency inject gitlab api
-rwxr-xr-x | _support/test-boot | 5 | ||||
-rw-r--r-- | cmd/gitaly-hooks/hooks_test.go | 35 | ||||
-rw-r--r-- | cmd/gitaly-ssh/auth_test.go | 5 | ||||
-rw-r--r-- | cmd/gitaly/main.go | 8 | ||||
-rw-r--r-- | internal/bootstrap/server_factory.go | 10 | ||||
-rw-r--r-- | internal/praefect/replicator_test.go | 2 | ||||
-rw-r--r-- | internal/server/auth_test.go | 4 | ||||
-rw-r--r-- | internal/server/server.go | 13 | ||||
-rw-r--r-- | internal/server/testdata/gitlab-shell/.gitlab_shell_secret | 1 | ||||
-rw-r--r-- | internal/service/conflicts/resolve_conflicts_test.go | 2 | ||||
-rw-r--r-- | internal/service/hook/access.go (renamed from internal/service/hooks/api/access.go) | 53 | ||||
-rw-r--r-- | internal/service/hook/access_test.go (renamed from internal/service/hooks/api/access_test.go) | 57 | ||||
-rw-r--r-- | internal/service/hook/custom_hooks.go (renamed from internal/service/hooks/custom_hooks.go) | 0 | ||||
-rw-r--r-- | internal/service/hook/custom_hooks_test.go (renamed from internal/service/hooks/custom_hooks_test.go) | 0 | ||||
-rw-r--r-- | internal/service/hook/post_receive.go (renamed from internal/service/hooks/post_receive.go) | 0 | ||||
-rw-r--r-- | internal/service/hook/post_receive_test.go (renamed from internal/service/hooks/post_receive_test.go) | 0 | ||||
-rw-r--r-- | internal/service/hook/pre_receive.go (renamed from internal/service/hooks/pre_receive.go) | 0 | ||||
-rw-r--r-- | internal/service/hook/pre_receive_test.go (renamed from internal/service/hooks/pre_receive_test.go) | 0 | ||||
-rw-r--r-- | internal/service/hook/server.go (renamed from internal/service/hooks/server.go) | 7 | ||||
-rw-r--r-- | internal/service/hook/stream_command.go (renamed from internal/service/hooks/stream_command.go) | 0 | ||||
-rwxr-xr-x | internal/service/hook/testdata/gitlab-shell/hooks/post-receive (renamed from internal/service/hooks/testdata/gitlab-shell/hooks/post-receive) | 0 | ||||
-rwxr-xr-x | internal/service/hook/testdata/gitlab-shell/hooks/pre-receive (renamed from internal/service/hooks/testdata/gitlab-shell/hooks/pre-receive) | 0 | ||||
-rwxr-xr-x | internal/service/hook/testdata/gitlab-shell/hooks/update (renamed from internal/service/hooks/testdata/gitlab-shell/hooks/update) | 0 | ||||
-rw-r--r-- | internal/service/hook/testhelper_test.go (renamed from internal/service/hooks/testhelper_test.go) | 2 | ||||
-rw-r--r-- | internal/service/hook/update.go (renamed from internal/service/hooks/update.go) | 0 | ||||
-rw-r--r-- | internal/service/hook/update_test.go (renamed from internal/service/hooks/update_test.go) | 0 | ||||
-rw-r--r-- | internal/service/operations/testhelper_test.go | 4 | ||||
-rw-r--r-- | internal/service/register.go | 6 | ||||
-rw-r--r-- | internal/service/remote/fetch_internal_remote_test.go | 2 | ||||
-rw-r--r-- | internal/service/repository/fetch_test.go | 4 | ||||
-rw-r--r-- | internal/service/repository/optimize.go | 4 | ||||
-rw-r--r-- | internal/service/smarthttp/receive_pack_test.go | 6 | ||||
-rw-r--r-- | internal/testhelper/testhelper.go | 15 | ||||
-rw-r--r-- | ruby/spec/support/helpers/integration_helper.rb | 5 |
34 files changed, 179 insertions, 71 deletions
diff --git a/_support/test-boot b/_support/test-boot index 61eeeef3f..3f9f810fc 100755 --- a/_support/test-boot +++ b/_support/test-boot @@ -17,6 +17,7 @@ def main(gitaly_dir) Dir.mktmpdir do |dir| Dir.chdir(dir) + File.write(File.join("#{gitaly_dir}/ruby/gitlab-shell", '.gitlab_shell_secret'), 'test_gitlab_shell_token') File.write('config.toml', <<~CONFIG socket_path = "#{ADDR}" @@ -31,6 +32,10 @@ def main(gitaly_dir) [gitlab-shell] dir = "#{gitaly_dir}/ruby/gitlab-shell" + + [gitlab] + url = 'http://gitlab_url' + CONFIG ) diff --git a/cmd/gitaly-hooks/hooks_test.go b/cmd/gitaly-hooks/hooks_test.go index f22489a1f..bf13a4707 100644 --- a/cmd/gitaly-hooks/hooks_test.go +++ b/cmd/gitaly-hooks/hooks_test.go @@ -17,7 +17,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/command" "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag" - hook "gitlab.com/gitlab-org/gitaly/internal/service/hooks" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "google.golang.org/grpc/reflection" @@ -108,8 +108,6 @@ func TestHooksPrePostReceive(t *testing.T) { gitObjectDirRegex := regexp.MustCompile(`(?m)^GIT_OBJECT_DIRECTORY=(.*)$`) gitAlternateObjectDirRegex := regexp.MustCompile(`(?m)^GIT_ALTERNATE_OBJECT_DIRECTORIES=(.*)$`) token := "abc123" - socket, stop := runHookServiceServer(t, token) - defer stop() hookNames := []string{"pre-receive", "post-receive"} @@ -127,6 +125,12 @@ func TestHooksPrePostReceive(t *testing.T) { config.Config.Gitlab.HTTPSettings.User = gitlabUser config.Config.Gitlab.HTTPSettings.Password = gitlabPassword + gitlabAPI, err := hook.NewGitlabAPI(config.Config.Gitlab) + require.NoError(t, err) + + socket, stop := runHookServiceServerWithAPI(t, token, gitlabAPI) + defer stop() + var stderr, stdout bytes.Buffer stdin := bytes.NewBuffer([]byte(changes)) hookPath, err := filepath.Abs(fmt.Sprintf("../../ruby/git-hooks/%s", hookName)) @@ -336,15 +340,19 @@ func TestHooksPostReceiveFailed(t *testing.T) { featureSets, err := testhelper.NewFeatureSets([]string{featureflag.HooksRPC}) require.NoError(t, err) + token := "abc123" + + gitlabAPI, err := hook.NewGitlabAPI(config.Config.Gitlab) + require.NoError(t, err) + + socket, stop := runHookServiceServerWithAPI(t, token, gitlabAPI) + defer stop() + for _, featureSet := range featureSets { t.Run(fmt.Sprintf("features: %v", featureSet), func(t *testing.T) { customHookOutputPath, cleanup := testhelper.WriteEnvToCustomHook(t, testRepoPath, "post-receive") defer cleanup() - token := "abc123" - socket, stop := runHookServiceServer(t, token) - defer stop() - var stdout, stderr bytes.Buffer postReceiveHookPath, err := filepath.Abs("../../ruby/git-hooks/post-receive") @@ -415,12 +423,17 @@ func TestHooksNotAllowed(t *testing.T) { config.Config.GitlabShell.Dir = tempGitlabShellDir config.Config.Gitlab.URL = ts.URL + config.Config.Gitlab.SecretFile = filepath.Join(tempGitlabShellDir, ".gitlab_shell_secret") customHookOutputPath, cleanup := testhelper.WriteEnvToCustomHook(t, testRepoPath, "post-receive") defer cleanup() token := "abc123" - socket, stop := runHookServiceServer(t, token) + + gitlabAPI, err := hook.NewGitlabAPI(config.Config.Gitlab) + require.NoError(t, err) + + socket, stop := runHookServiceServerWithAPI(t, token, gitlabAPI) defer stop() var stderr, stdout bytes.Buffer @@ -543,9 +556,13 @@ func TestCheckBadCreds(t *testing.T) { } func runHookServiceServer(t *testing.T, token string) (string, func()) { + return runHookServiceServerWithAPI(t, token, testhelper.GitlabAPIStub) +} + +func runHookServiceServerWithAPI(t *testing.T, token string, gitlabAPI hook.GitlabAPI) (string, func()) { server := testhelper.NewServerWithAuth(t, nil, nil, token) - gitalypb.RegisterHookServiceServer(server.GrpcServer(), hook.NewServer()) + gitalypb.RegisterHookServiceServer(server.GrpcServer(), hook.NewServer(gitlabAPI, config.Config.Hooks)) reflection.Register(server.GrpcServer()) require.NoError(t, server.Start()) diff --git a/cmd/gitaly-ssh/auth_test.go b/cmd/gitaly-ssh/auth_test.go index 1956400f2..b4d10ffaa 100644 --- a/cmd/gitaly-ssh/auth_test.go +++ b/cmd/gitaly-ssh/auth_test.go @@ -15,6 +15,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/rubyserver" "gitlab.com/gitlab-org/gitaly/internal/server" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "google.golang.org/grpc" @@ -116,8 +117,8 @@ func TestConnectivity(t *testing.T) { } } -func runServer(t *testing.T, newServer func(rubyServer *rubyserver.Server, cfg config.Cfg) *grpc.Server, cfg config.Cfg, connectionType string, addr string) (*grpc.Server, int) { - srv := newServer(nil, cfg) +func runServer(t *testing.T, newServer func(rubyServer *rubyserver.Server, gitlabAPI hook.GitlabAPI, cfg config.Cfg) *grpc.Server, cfg config.Cfg, connectionType string, addr string) (*grpc.Server, int) { + srv := newServer(nil, testhelper.GitlabAPIStub, cfg) listener, err := net.Listen(connectionType, addr) require.NoError(t, err) diff --git a/cmd/gitaly/main.go b/cmd/gitaly/main.go index 05f8b599a..0ead8eefd 100644 --- a/cmd/gitaly/main.go +++ b/cmd/gitaly/main.go @@ -11,6 +11,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/config/sentry" "gitlab.com/gitlab-org/gitaly/internal/git" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "gitlab.com/gitlab-org/gitaly/internal/storage" "gitlab.com/gitlab-org/gitaly/internal/tempdir" "gitlab.com/gitlab-org/gitaly/internal/version" @@ -84,7 +85,12 @@ func main() { // Inside here we can use deferred functions. This is needed because // log.Fatal bypasses deferred functions. func run(b *bootstrap.Bootstrap) error { - servers := bootstrap.NewGitalyServerFactory() + gitlabAPI, err := hook.NewGitlabAPI(config.Config.Gitlab) + if err != nil { + log.Fatalf("could not create gitlab api client: %v", err) + } + + servers := bootstrap.NewGitalyServerFactory(gitlabAPI) defer servers.Stop() b.StopAction = servers.GracefulStop diff --git a/internal/bootstrap/server_factory.go b/internal/bootstrap/server_factory.go index 30bfea16b..f6d146b06 100644 --- a/internal/bootstrap/server_factory.go +++ b/internal/bootstrap/server_factory.go @@ -7,12 +7,14 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/rubyserver" "gitlab.com/gitlab-org/gitaly/internal/server" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "google.golang.org/grpc" ) // GitalyServerFactory is a factory of gitaly grpc servers type GitalyServerFactory struct { ruby *rubyserver.Server + gitlabAPI hook.GitlabAPI secure, insecure *grpc.Server } @@ -24,8 +26,8 @@ type GracefulStoppableServer interface { } // NewGitalyServerFactory initializes a rubyserver and then lazily initializes both secure and insecure grpc.Server -func NewGitalyServerFactory() *GitalyServerFactory { - return &GitalyServerFactory{ruby: &rubyserver.Server{}} +func NewGitalyServerFactory(api hook.GitlabAPI) *GitalyServerFactory { + return &GitalyServerFactory{ruby: &rubyserver.Server{}, gitlabAPI: api} } // StartRuby starts the ruby process @@ -69,14 +71,14 @@ func (s *GitalyServerFactory) Serve(l net.Listener, secure bool) error { func (s *GitalyServerFactory) get(secure bool) *grpc.Server { if secure { if s.secure == nil { - s.secure = server.NewSecure(s.ruby, config.Config) + s.secure = server.NewSecure(s.ruby, s.gitlabAPI, config.Config) } return s.secure } if s.insecure == nil { - s.insecure = server.NewInsecure(s.ruby, config.Config) + s.insecure = server.NewInsecure(s.ruby, s.gitlabAPI, config.Config) } return s.insecure diff --git a/internal/praefect/replicator_test.go b/internal/praefect/replicator_test.go index f658dc92e..9e8873910 100644 --- a/internal/praefect/replicator_test.go +++ b/internal/praefect/replicator_test.go @@ -762,7 +762,7 @@ func TestBackoff(t *testing.T) { } func runFullGitalyServer(t *testing.T) (*grpc.Server, string) { - server := serverPkg.NewInsecure(RubyServer, gitaly_config.Config) + server := serverPkg.NewInsecure(RubyServer, testhelper.GitlabAPIStub, gitaly_config.Config) serverSocketPath := testhelper.GetTemporaryGitalySocketFileName() diff --git a/internal/server/auth_test.go b/internal/server/auth_test.go index 737476bb1..433b74991 100644 --- a/internal/server/auth_test.go +++ b/internal/server/auth_test.go @@ -184,7 +184,7 @@ func newOperationClient(t *testing.T, serverSocketPath string) (gitalypb.Operati } func runServerWithRuby(t *testing.T, ruby *rubyserver.Server) (*grpc.Server, string) { - srv := NewInsecure(ruby, config.Config) + srv := NewInsecure(ruby, nil, config.Config) serverSocketPath := testhelper.GetTemporaryGitalySocketFileName() @@ -205,7 +205,7 @@ func runSecureServer(t *testing.T) (*grpc.Server, string) { KeyPath: "testdata/gitalykey.pem", } - srv := NewSecure(nil, config.Config) + srv := NewSecure(nil, nil, config.Config) listener, err := net.Listen("tcp", "localhost:9999") require.NoError(t, err) diff --git a/internal/server/server.go b/internal/server/server.go index ca7962fbf..9d974762d 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -25,6 +25,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/rubyserver" "gitlab.com/gitlab-org/gitaly/internal/server/auth" "gitlab.com/gitlab-org/gitaly/internal/service" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" grpccorrelation "gitlab.com/gitlab-org/labkit/correlation/grpc" grpctracing "gitlab.com/gitlab-org/labkit/tracing/grpc" "google.golang.org/grpc" @@ -69,7 +70,7 @@ func init() { // createNewServer returns a GRPC server with all Gitaly services and interceptors set up. // allows for specifying secure = true to enable tls credentials -func createNewServer(rubyServer *rubyserver.Server, cfg config.Cfg, secure bool) *grpc.Server { +func createNewServer(rubyServer *rubyserver.Server, gitlabAPI hook.GitlabAPI, cfg config.Cfg, secure bool) *grpc.Server { ctxTagOpts := []grpc_ctxtags.Option{ grpc_ctxtags.WithFieldExtractorForInitialReq(fieldextractors.FieldExtractor), } @@ -123,7 +124,7 @@ func createNewServer(rubyServer *rubyserver.Server, cfg config.Cfg, secure bool) server := grpc.NewServer(opts...) - service.RegisterAll(server, cfg, rubyServer) + service.RegisterAll(server, cfg, rubyServer, gitlabAPI) reflection.Register(server) grpc_prometheus.Register(server) @@ -132,13 +133,13 @@ func createNewServer(rubyServer *rubyserver.Server, cfg config.Cfg, secure bool) } // NewInsecure returns a GRPC server with all Gitaly services and interceptors set up. -func NewInsecure(rubyServer *rubyserver.Server, cfg config.Cfg) *grpc.Server { - return createNewServer(rubyServer, cfg, false) +func NewInsecure(rubyServer *rubyserver.Server, gitlabAPI hook.GitlabAPI, cfg config.Cfg) *grpc.Server { + return createNewServer(rubyServer, gitlabAPI, cfg, false) } // NewSecure returns a GRPC server enabling TLS credentials -func NewSecure(rubyServer *rubyserver.Server, cfg config.Cfg) *grpc.Server { - return createNewServer(rubyServer, cfg, true) +func NewSecure(rubyServer *rubyserver.Server, gitlabAPI hook.GitlabAPI, cfg config.Cfg) *grpc.Server { + return createNewServer(rubyServer, gitlabAPI, cfg, true) } // CleanupInternalSocketDir will clean up the directory for internal sockets if it is a generated temp dir diff --git a/internal/server/testdata/gitlab-shell/.gitlab_shell_secret b/internal/server/testdata/gitlab-shell/.gitlab_shell_secret new file mode 100644 index 000000000..62c88b4cd --- /dev/null +++ b/internal/server/testdata/gitlab-shell/.gitlab_shell_secret @@ -0,0 +1 @@ +secretToken
\ No newline at end of file diff --git a/internal/service/conflicts/resolve_conflicts_test.go b/internal/service/conflicts/resolve_conflicts_test.go index 7dea2b29a..ce5843abf 100644 --- a/internal/service/conflicts/resolve_conflicts_test.go +++ b/internal/service/conflicts/resolve_conflicts_test.go @@ -309,7 +309,7 @@ func TestFailedResolveConflictsRequestDueToValidation(t *testing.T) { } func runFullServer(t *testing.T) (*grpc.Server, string) { - server := serverPkg.NewInsecure(conflicts.RubyServer, config.Config) + server := serverPkg.NewInsecure(conflicts.RubyServer, nil, config.Config) serverSocketPath := testhelper.GetTemporaryGitalySocketFileName() listener, err := net.Listen("unix", serverSocketPath) diff --git a/internal/service/hooks/api/access.go b/internal/service/hook/access.go index f29a9e37a..dbb5db2ec 100644 --- a/internal/service/hooks/api/access.go +++ b/internal/service/hook/access.go @@ -1,4 +1,4 @@ -package api +package hook import ( "encoding/json" @@ -10,6 +10,7 @@ import ( "regexp" "strings" + "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/helper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitlab-shell/client" @@ -49,20 +50,50 @@ func marshallGitObjectDirs(gitObjectDirRel string, gitAltObjectDirsRel []string) return string(envString), nil } -// API is a wrapper around client.GitlabNetClient with api methods for gitlab git receive hooks -type API struct { +// GitlabAPI is an interface for accessing the gitlab internal API +type GitlabAPI interface { + // Allowed queries the gitlab internal api /allowed endpoint to determine if a ref change for a given repository and user is allowed + Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, error) + // PreReceive queries the gitlab internal api /pre_receive to increase the reference counter + PreReceive(glRepository string) (bool, error) +} + +// gitlabAPI is a wrapper around client.GitlabNetClient with API methods for gitlab git receive hooks +type gitlabAPI struct { client *client.GitlabNetClient } -// New creates a new API -func New(c *client.GitlabNetClient) *API { - return &API{ - client: c, +// New creates a new GitlabAPI +func NewGitlabAPI(gitlabCfg config.Gitlab) (GitlabAPI, error) { + httpClient := client.NewHTTPClient( + gitlabCfg.URL, + gitlabCfg.HTTPSettings.CAFile, + gitlabCfg.HTTPSettings.CAPath, + gitlabCfg.HTTPSettings.SelfSigned, + uint64(gitlabCfg.HTTPSettings.ReadTimeout), + ) + + if httpClient == nil { + return nil, fmt.Errorf("%s is not a valid url", gitlabCfg.URL) + } + + secret, err := ioutil.ReadFile(gitlabCfg.SecretFile) + if err != nil { + return nil, fmt.Errorf("reading secret file: %w", err) } + + gitlabnetClient, err := client.NewGitlabNetClient(gitlabCfg.HTTPSettings.User, gitlabCfg.HTTPSettings.Password, string(secret), httpClient) + if err != nil { + return nil, fmt.Errorf("instantiating gitlab net client: %w", err) + } + + return &gitlabAPI{ + client: gitlabnetClient, + }, nil } // Allowed checks if a ref change for a given repository is allowed through the gitlab internal api /allowed endpoint -func (a *API) Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, error) { +func (a *gitlabAPI) Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, error) { repoPath, err := helper.GetRepoPath(repo) if err != nil { return false, fmt.Errorf("getting the repository path: %w", err) @@ -115,7 +146,7 @@ func (a *API) Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, return false, fmt.Errorf("decoding response from /allowed endpoint: %w", err) } default: - return false, fmt.Errorf("API is not accessible: %d", resp.StatusCode) + return false, fmt.Errorf("gitlab api is not accessible: %d", resp.StatusCode) } return response.Status, nil @@ -125,8 +156,8 @@ type preReceiveResponse struct { ReferenceCounterIncreased bool `json:"reference_counter_increased"` } -// PreReceive increases the reference counter for a push for a given gl_repository through the gitlab internal api /pre_receive endpoint -func (a *API) PreReceive(glRepository string) (bool, error) { +// PreReceive increases the reference counter for a push for a given gl_repository through the gitlab internal API /pre_receive endpoint +func (a *gitlabAPI) PreReceive(glRepository string) (bool, error) { resp, err := a.client.Post("/pre_receive", map[string]string{"gl_repository": glRepository}) if err != nil { return false, fmt.Errorf("http post to gitlab api /pre_receive endpoint: %w", err) diff --git a/internal/service/hooks/api/access_test.go b/internal/service/hook/access_test.go index a197fe5af..432ad2b04 100644 --- a/internal/service/hooks/api/access_test.go +++ b/internal/service/hook/access_test.go @@ -1,24 +1,18 @@ -package api_test +package hook_test import ( "net/http" "net/http/httptest" - "os" "path/filepath" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/internal/service/hooks/api" + "gitlab.com/gitlab-org/gitaly/internal/config" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" - "gitlab.com/gitlab-org/gitlab-shell/client" ) -func TestMain(m *testing.M) { - testhelper.Configure() - os.Exit(m.Run()) -} - func TestAllowedVerifyParams(t *testing.T) { user, password := "user", "password" secretToken := "topsecret" @@ -39,6 +33,12 @@ func TestAllowedVerifyParams(t *testing.T) { gitAlternateObjectDirsFull = append(gitAlternateObjectDirsFull, filepath.Join(testRepoPath, gitAlternateObjectDirRel)) } + tempDir, cleanup := testhelper.TempDir(t) + defer cleanup() + testhelper.WriteShellSecretFile(t, tempDir, secretToken) + + secretFilePath := filepath.Join(tempDir, ".gitlab_shell_secret") + server := testhelper.NewGitlabTestServer(testhelper.GitlabTestServerOptions{ User: user, Password: password, @@ -56,12 +56,16 @@ func TestAllowedVerifyParams(t *testing.T) { defer server.Close() - httpClient := client.NewHTTPClient(server.URL, "", "", false, 100) - gitlabnetClient, err := client.NewGitlabNetClient(user, password, secretToken, httpClient) + c, err := hook.NewGitlabAPI(config.Gitlab{ + URL: server.URL, + SecretFile: secretFilePath, + HTTPSettings: config.HTTPSettings{ + User: user, + Password: password, + }, + }) require.NoError(t, err) - c := api.New(gitlabnetClient) - badRepo := *testRepo badRepo.GitObjectDirectory = filepath.Join(testRepoPath, "bad/object/directory") @@ -109,6 +113,12 @@ func TestAllowedResponseHandling(t *testing.T) { defer cleanup() + tempDir, cleanup := testhelper.TempDir(t) + defer cleanup() + testhelper.WriteShellSecretFile(t, tempDir, "secret_token") + + secretFilePath := filepath.Join(tempDir, ".gitlab_shell_secret") + testCases := []struct { desc string allowedHandler func(w http.ResponseWriter, r *http.Request) @@ -200,11 +210,12 @@ func TestAllowedResponseHandling(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(tc.allowedHandler)) defer server.Close() - httpClient := client.NewHTTPClient(server.URL, "", "", false, 100) - gitlabnetClient, err := client.NewGitlabNetClient("", "", "", httpClient) + c, err := hook.NewGitlabAPI(config.Gitlab{ + URL: server.URL, + SecretFile: secretFilePath, + }) require.NoError(t, err) - c := api.New(gitlabnetClient) allowed, err := c.Allowed(testRepo, "repo-1", "key-123", "http", "a\nb\nc\nd") require.Equal(t, tc.allowed, allowed) if err != nil { @@ -215,6 +226,13 @@ func TestAllowedResponseHandling(t *testing.T) { } func TestPrereceive(t *testing.T) { + tempDir, cleanup := testhelper.TempDir(t) + defer cleanup() + + testhelper.WriteShellSecretFile(t, tempDir, "secret_token") + + secretFilePath := filepath.Join(tempDir, ".gitlab_shell_secret") + testCases := []struct { desc string prereceiveHandler func(w http.ResponseWriter, r *http.Request) @@ -278,11 +296,12 @@ func TestPrereceive(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(tc.prereceiveHandler)) defer server.Close() - httpClient := client.NewHTTPClient(server.URL, "", "", false, 100) - gitlabnetClient, err := client.NewGitlabNetClient("", "", "", httpClient) + c, err := hook.NewGitlabAPI(config.Gitlab{ + URL: server.URL, + SecretFile: secretFilePath, + }) require.NoError(t, err) - c := api.New(gitlabnetClient) success, err := c.PreReceive("key-123") require.Equal(t, tc.success, success) if err != nil { diff --git a/internal/service/hooks/custom_hooks.go b/internal/service/hook/custom_hooks.go index 04f9b4d78..04f9b4d78 100644 --- a/internal/service/hooks/custom_hooks.go +++ b/internal/service/hook/custom_hooks.go diff --git a/internal/service/hooks/custom_hooks_test.go b/internal/service/hook/custom_hooks_test.go index 3b43971c8..3b43971c8 100644 --- a/internal/service/hooks/custom_hooks_test.go +++ b/internal/service/hook/custom_hooks_test.go diff --git a/internal/service/hooks/post_receive.go b/internal/service/hook/post_receive.go index 55ec0323f..55ec0323f 100644 --- a/internal/service/hooks/post_receive.go +++ b/internal/service/hook/post_receive.go diff --git a/internal/service/hooks/post_receive_test.go b/internal/service/hook/post_receive_test.go index 451c322f7..451c322f7 100644 --- a/internal/service/hooks/post_receive_test.go +++ b/internal/service/hook/post_receive_test.go diff --git a/internal/service/hooks/pre_receive.go b/internal/service/hook/pre_receive.go index b4627ee13..b4627ee13 100644 --- a/internal/service/hooks/pre_receive.go +++ b/internal/service/hook/pre_receive.go diff --git a/internal/service/hooks/pre_receive_test.go b/internal/service/hook/pre_receive_test.go index e1d89dccf..e1d89dccf 100644 --- a/internal/service/hooks/pre_receive_test.go +++ b/internal/service/hook/pre_receive_test.go diff --git a/internal/service/hooks/server.go b/internal/service/hook/server.go index 0acd1d502..ed1171861 100644 --- a/internal/service/hooks/server.go +++ b/internal/service/hook/server.go @@ -3,6 +3,7 @@ package hook import ( "sync" + "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "google.golang.org/grpc" ) @@ -10,11 +11,15 @@ import ( type server struct { mutex sync.RWMutex praefectConnPool map[string]*grpc.ClientConn + hooksConfig config.Hooks + gitlabAPI GitlabAPI } // NewServer creates a new instance of a gRPC namespace server -func NewServer() gitalypb.HookServiceServer { +func NewServer(gitlab GitlabAPI, hooksConfig config.Hooks) gitalypb.HookServiceServer { return &server{ + gitlabAPI: gitlab, + hooksConfig: hooksConfig, praefectConnPool: make(map[string]*grpc.ClientConn), } } diff --git a/internal/service/hooks/stream_command.go b/internal/service/hook/stream_command.go index 2893dd5a8..2893dd5a8 100644 --- a/internal/service/hooks/stream_command.go +++ b/internal/service/hook/stream_command.go diff --git a/internal/service/hooks/testdata/gitlab-shell/hooks/post-receive b/internal/service/hook/testdata/gitlab-shell/hooks/post-receive index 09af4c677..09af4c677 100755 --- a/internal/service/hooks/testdata/gitlab-shell/hooks/post-receive +++ b/internal/service/hook/testdata/gitlab-shell/hooks/post-receive diff --git a/internal/service/hooks/testdata/gitlab-shell/hooks/pre-receive b/internal/service/hook/testdata/gitlab-shell/hooks/pre-receive index 12574b7b7..12574b7b7 100755 --- a/internal/service/hooks/testdata/gitlab-shell/hooks/pre-receive +++ b/internal/service/hook/testdata/gitlab-shell/hooks/pre-receive diff --git a/internal/service/hooks/testdata/gitlab-shell/hooks/update b/internal/service/hook/testdata/gitlab-shell/hooks/update index b9f19fd2f..b9f19fd2f 100755 --- a/internal/service/hooks/testdata/gitlab-shell/hooks/update +++ b/internal/service/hook/testdata/gitlab-shell/hooks/update diff --git a/internal/service/hooks/testhelper_test.go b/internal/service/hook/testhelper_test.go index 8311bc869..28fdf720f 100644 --- a/internal/service/hooks/testhelper_test.go +++ b/internal/service/hook/testhelper_test.go @@ -34,7 +34,7 @@ func newHooksClient(t *testing.T, serverSocketPath string) (gitalypb.HookService func runHooksServer(t *testing.T) (string, func()) { srv := testhelper.NewServer(t, nil, nil) - gitalypb.RegisterHookServiceServer(srv.GrpcServer(), NewServer()) + gitalypb.RegisterHookServiceServer(srv.GrpcServer(), NewServer(testhelper.GitlabAPIStub, config.Config.Hooks)) reflection.Register(srv.GrpcServer()) require.NoError(t, srv.Start()) diff --git a/internal/service/hooks/update.go b/internal/service/hook/update.go index 5741da00c..5741da00c 100644 --- a/internal/service/hooks/update.go +++ b/internal/service/hook/update.go diff --git a/internal/service/hooks/update_test.go b/internal/service/hook/update_test.go index 1155371d3..1155371d3 100644 --- a/internal/service/hooks/update_test.go +++ b/internal/service/hook/update_test.go diff --git a/internal/service/operations/testhelper_test.go b/internal/service/operations/testhelper_test.go index aae8c07ec..b7f86f1e4 100644 --- a/internal/service/operations/testhelper_test.go +++ b/internal/service/operations/testhelper_test.go @@ -13,7 +13,7 @@ import ( gitalylog "gitlab.com/gitlab-org/gitaly/internal/log" "gitlab.com/gitlab-org/gitaly/internal/rubyserver" "gitlab.com/gitlab-org/gitaly/internal/service/commit" - hook "gitlab.com/gitlab-org/gitaly/internal/service/hooks" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "gitlab.com/gitlab-org/gitaly/internal/service/ref" "gitlab.com/gitlab-org/gitaly/internal/service/repository" "gitlab.com/gitlab-org/gitaly/internal/service/ssh" @@ -87,7 +87,7 @@ func runOperationServiceServerWithRubyServer(t *testing.T, ruby *rubyserver.Serv require.NoError(t, err) gitalypb.RegisterOperationServiceServer(srv.GrpcServer(), &server{ruby: ruby}) - gitalypb.RegisterHookServiceServer(srv.GrpcServer(), hook.NewServer()) + gitalypb.RegisterHookServiceServer(srv.GrpcServer(), hook.NewServer(testhelper.GitlabAPIStub, config.Config.Hooks)) gitalypb.RegisterRepositoryServiceServer(srv.GrpcServer(), repository.NewServer(ruby, internalSocket)) gitalypb.RegisterRefServiceServer(srv.GrpcServer(), ref.NewServer()) gitalypb.RegisterCommitServiceServer(srv.GrpcServer(), commit.NewServer()) diff --git a/internal/service/register.go b/internal/service/register.go index 4015f99fc..cb55fa24f 100644 --- a/internal/service/register.go +++ b/internal/service/register.go @@ -10,7 +10,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/service/commit" "gitlab.com/gitlab-org/gitaly/internal/service/conflicts" "gitlab.com/gitlab-org/gitaly/internal/service/diff" - hook "gitlab.com/gitlab-org/gitaly/internal/service/hooks" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "gitlab.com/gitlab-org/gitaly/internal/service/internalgitaly" "gitlab.com/gitlab-org/gitaly/internal/service/namespace" "gitlab.com/gitlab-org/gitaly/internal/service/objectpool" @@ -52,7 +52,7 @@ var ( // RegisterAll will register all the known grpc services with // the specified grpc service instance -func RegisterAll(grpcServer *grpc.Server, cfg config.Cfg, rubyServer *rubyserver.Server) { +func RegisterAll(grpcServer *grpc.Server, cfg config.Cfg, rubyServer *rubyserver.Server, gitlabAPI hook.GitlabAPI) { gitalypb.RegisterBlobServiceServer(grpcServer, blob.NewServer(rubyServer)) gitalypb.RegisterCleanupServiceServer(grpcServer, cleanup.NewServer()) gitalypb.RegisterCommitServiceServer(grpcServer, commit.NewServer()) @@ -72,7 +72,7 @@ func RegisterAll(grpcServer *grpc.Server, cfg config.Cfg, rubyServer *rubyserver gitalypb.RegisterRemoteServiceServer(grpcServer, remote.NewServer(rubyServer)) gitalypb.RegisterServerServiceServer(grpcServer, server.NewServer(cfg.Storages)) gitalypb.RegisterObjectPoolServiceServer(grpcServer, objectpool.NewServer()) - gitalypb.RegisterHookServiceServer(grpcServer, hook.NewServer()) + gitalypb.RegisterHookServiceServer(grpcServer, hook.NewServer(gitlabAPI, config.Config.Hooks)) gitalypb.RegisterInternalGitalyServer(grpcServer, internalgitaly.NewServer(config.Config.Storages)) healthpb.RegisterHealthServer(grpcServer, health.NewServer()) diff --git a/internal/service/remote/fetch_internal_remote_test.go b/internal/service/remote/fetch_internal_remote_test.go index ea7ea78b0..73dff1c50 100644 --- a/internal/service/remote/fetch_internal_remote_test.go +++ b/internal/service/remote/fetch_internal_remote_test.go @@ -152,7 +152,7 @@ func TestFailedFetchInternalRemoteDueToValidations(t *testing.T) { } func runFullServer(t *testing.T) (*grpc.Server, string) { - server := serverPkg.NewInsecure(remote.RubyServer, config.Config) + server := serverPkg.NewInsecure(remote.RubyServer, nil, config.Config) serverSocketPath := testhelper.GetTemporaryGitalySocketFileName() listener, err := net.Listen("unix", serverSocketPath) diff --git a/internal/service/repository/fetch_test.go b/internal/service/repository/fetch_test.go index 9257f1a90..d33b0a2bd 100644 --- a/internal/service/repository/fetch_test.go +++ b/internal/service/repository/fetch_test.go @@ -191,7 +191,7 @@ func newTestRepo(t *testing.T, relativePath string) (*gitalypb.Repository, strin } func runFullServer(t *testing.T) (*grpc.Server, string) { - server := serverPkg.NewInsecure(repository.RubyServer, config.Config) + server := serverPkg.NewInsecure(repository.RubyServer, nil, config.Config) serverSocketPath := testhelper.GetTemporaryGitalySocketFileName() listener, err := net.Listen("unix", serverSocketPath) @@ -208,7 +208,7 @@ func runFullServer(t *testing.T) (*grpc.Server, string) { } func runFullSecureServer(t *testing.T) (*grpc.Server, string, testhelper.Cleanup) { - server := serverPkg.NewSecure(repository.RubyServer, config.Config) + server := serverPkg.NewSecure(repository.RubyServer, nil, config.Config) listener, addr := testhelper.GetLocalhostListener(t) errQ := make(chan error) diff --git a/internal/service/repository/optimize.go b/internal/service/repository/optimize.go index 5c366e881..1b831c1ef 100644 --- a/internal/service/repository/optimize.go +++ b/internal/service/repository/optimize.go @@ -31,8 +31,8 @@ func init() { func removeEmptyDirs(ctx context.Context, target string) error { if err := ctx.Err(); err != nil { - return err - } + return err + } entries, err := ioutil.ReadDir(target) switch { diff --git a/internal/service/smarthttp/receive_pack_test.go b/internal/service/smarthttp/receive_pack_test.go index 1c61b626e..35a83d23f 100644 --- a/internal/service/smarthttp/receive_pack_test.go +++ b/internal/service/smarthttp/receive_pack_test.go @@ -20,7 +20,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/git/hooks" "gitlab.com/gitlab-org/gitaly/internal/helper/text" "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag" - hook "gitlab.com/gitlab-org/gitaly/internal/service/hooks" + "gitlab.com/gitlab-org/gitaly/internal/service/hook" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/streamio" @@ -449,7 +449,7 @@ func runSmartHTTPHookServiceServer(t *testing.T) (*grpc.Server, string) { } gitalypb.RegisterSmartHTTPServiceServer(server, NewServer()) - gitalypb.RegisterHookServiceServer(server, hook.NewServer()) + gitalypb.RegisterHookServiceServer(server, hook.NewServer(testhelper.GitlabAPIStub, config.Config.Hooks)) reflection.Register(server) go server.Serve(listener) @@ -510,7 +510,7 @@ func TestPostReceiveWithTransactions(t *testing.T) { gitalyServer := testhelper.NewServerWithAuth(t, nil, nil, config.Config.Auth.Token) gitalypb.RegisterSmartHTTPServiceServer(gitalyServer.GrpcServer(), NewServer()) - gitalypb.RegisterHookServiceServer(gitalyServer.GrpcServer(), hook.NewServer()) + gitalypb.RegisterHookServiceServer(gitalyServer.GrpcServer(), hook.NewServer(testhelper.GitlabAPIStub, config.Config.Hooks)) reflection.Register(gitalyServer.GrpcServer()) require.NoError(t, gitalyServer.Start()) defer gitalyServer.Stop() diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go index 0780d6ace..e2fabb33f 100644 --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -790,3 +790,18 @@ func NewFeatureSets(goFeatures []string, rubyFeatures ...string) (FeatureSets, e return f, nil } + +// mockAPI is a noop gitlab API client +type mockAPI struct { +} + +func (m *mockAPI) Allowed(repo *gitalypb.Repository, glRepository, glID, glProtocol, changes string) (bool, error) { + return true, nil +} + +func (m *mockAPI) PreReceive(glRepository string) (bool, error) { + return true, nil +} + +// GitlabAPIStub is a global mock that can be used in testing +var GitlabAPIStub = &mockAPI{} diff --git a/ruby/spec/support/helpers/integration_helper.rb b/ruby/spec/support/helpers/integration_helper.rb index 23a65ed55..6804a68a7 100644 --- a/ruby/spec/support/helpers/integration_helper.rb +++ b/ruby/spec/support/helpers/integration_helper.rb @@ -68,6 +68,8 @@ def start_gitaly cert_path = File.join(File.dirname(__FILE__), "/certs") + File.write(File.join(GITLAB_SHELL_DIR, '.gitlab_shell_secret'), 'test_gitlab_shell_token') + config_toml = <<~CONFIG socket_path = "#{SOCKET_PATH}" listen_addr = "localhost:#{GitalyConfig.dynamic_port('tcp')}" @@ -81,6 +83,9 @@ def start_gitaly [gitlab-shell] dir = "#{GITLAB_SHELL_DIR}" + [gitlab] + url = 'http://gitlab_url' + [gitaly-ruby] dir = "#{GITALY_RUBY_DIR}" |