diff --git a/CHANGELOG.md b/CHANGELOG.md index e43bf3b55024b4d4e693e3f358c8898cb5a324d3..67d18635c39b4ff336e4b593efe926416fd97be4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ v 1.1.0 - Fix: Don't restore cache if not defined in gitlab-ci.yml - Fix: Always use `json-file` when starting docker containers - Fix: Error level checking for Windows Batch and PowerShell +- Fix: Inject GIT_SSL_CA_INFO only if Repo URL matches the Runner URL v 1.0.4 - Fix support for Windows PowerShell diff --git a/Makefile b/Makefile index 33945146deb422621461bed905fb39857b0ba898..5c7ac81383c9ff1ee0fdc0161c40001346cef6ad 100644 --- a/Makefile +++ b/Makefile @@ -156,6 +156,8 @@ mocks: FORCE mockery -dir=$(GOPATH)/src/github.com/ayufan/golang-kardianos-service -name=Interface mockery -dir=./common -name=Network mockery -dir=./helpers/docker -name=Client + mockery -dir=./common -name=Shell + mockery -dir=./shells -name=ShellWriter test-docker: make test-docker-image IMAGE=centos:6 TYPE=rpm diff --git a/mocks/Shell.go b/mocks/Shell.go new file mode 100644 index 0000000000000000000000000000000000000000..7a81e3f290dbfcbf73d7e25a420d3ad33e234fc8 --- /dev/null +++ b/mocks/Shell.go @@ -0,0 +1,47 @@ +package mocks + +import "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" +import "github.com/stretchr/testify/mock" + +type Shell struct { + mock.Mock +} + +func (m *Shell) GetName() string { + ret := m.Called() + + r0 := ret.Get(0).(string) + + return r0 +} +func (m *Shell) GetSupportedOptions() []string { + ret := m.Called() + + var r0 []string + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + + return r0 +} +func (m *Shell) GenerateScript(info common.ShellScriptInfo) (*common.ShellScript, error) { + ret := m.Called(info) + + var r0 *common.ShellScript + if ret.Get(0) != nil { + r0 = ret.Get(0).(*common.ShellScript) + } + r1 := ret.Error(1) + + return r0, r1 +} +func (m *Shell) GetFeatures(features *common.FeaturesInfo) { + m.Called(features) +} +func (m *Shell) IsDefault() bool { + ret := m.Called() + + r0 := ret.Get(0).(bool) + + return r0 +} diff --git a/mocks/ShellWriter.go b/mocks/ShellWriter.go new file mode 100644 index 0000000000000000000000000000000000000000..8e1912d8f5c4eec922ea39d96f6341f2eb433351 --- /dev/null +++ b/mocks/ShellWriter.go @@ -0,0 +1,65 @@ +package mocks + +import "github.com/stretchr/testify/mock" + +import "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" + +type ShellWriter struct { + mock.Mock +} + +func (m *ShellWriter) Variable(variable common.BuildVariable) { + m.Called(variable) +} +func (m *ShellWriter) Command(command string, arguments ...string) { + m.Called(command, arguments) +} +func (m *ShellWriter) Line(text string) { + m.Called(text) +} +func (m *ShellWriter) CheckForErrors() { + m.Called() +} +func (m *ShellWriter) IfDirectory(path string) { + m.Called(path) +} +func (m *ShellWriter) IfFile(file string) { + m.Called(file) +} +func (m *ShellWriter) Else() { + m.Called() +} +func (m *ShellWriter) EndIf() { + m.Called() +} +func (m *ShellWriter) Cd(path string) { + m.Called(path) +} +func (m *ShellWriter) RmDir(path string) { + m.Called(path) +} +func (m *ShellWriter) RmFile(path string) { + m.Called(path) +} +func (m *ShellWriter) Absolute(path string) string { + ret := m.Called(path) + + r0 := ret.Get(0).(string) + + return r0 +} +func (m *ShellWriter) Print(fmt string, arguments ...interface{}) { + m.Called(fmt, arguments) +} +func (m *ShellWriter) Notice(fmt string, arguments ...interface{}) { + m.Called(fmt, arguments) +} +func (m *ShellWriter) Warning(fmt string, arguments ...interface{}) { + m.Called(fmt, arguments) +} +func (m *ShellWriter) Error(fmt string, arguments ...interface{}) { + m.Called(fmt, arguments) +} +func (m *ShellWriter) EmptyLine() { + m.Called() +} diff --git a/shells/abstract.go b/shells/abstract.go index a0b184572f41baf77030bb1b817ed11b1bda3c16..397c964350af5fb5ccb21f469dca1a992d064928 100644 --- a/shells/abstract.go +++ b/shells/abstract.go @@ -1,6 +1,8 @@ package shells import ( + "errors" + "net/url" "path" "path/filepath" "strconv" @@ -31,8 +33,24 @@ func (b *AbstractShell) writeExports(w ShellWriter, info common.ShellScriptInfo) } } -func (b *AbstractShell) writeTLSCAInfo(w ShellWriter, build *common.Build, key string) { - if build.TLSCAChain != "" { +func (b *AbstractShell) writeTLSCAInfo(w ShellWriter, build *common.Build, key string, forRawUrl string) error { + if build.TLSCAChain == "" { + return errors.New("No TLSCAChain") + } + + runnerUrl, err := url.Parse(build.Runner.URL) + if err != nil { + return err + } + + forUrl, err := url.Parse(forRawUrl) + if err != nil { + return err + } + + // Define `key` only if forRawUrl matches + if strings.EqualFold(runnerUrl.Scheme, forUrl.Scheme) && + strings.EqualFold(runnerUrl.Host, forUrl.Host) { w.Variable(common.BuildVariable{ Key: key, Value: build.TLSCAChain, @@ -41,6 +59,7 @@ func (b *AbstractShell) writeTLSCAInfo(w ShellWriter, build *common.Build, key s File: true, }) } + return nil } func (b *AbstractShell) writeCloneCmd(w ShellWriter, build *common.Build, projectDir string) { @@ -179,8 +198,8 @@ func (b *AbstractShell) GeneratePreBuild(w ShellWriter, info common.ShellScriptI projectDir := build.FullProjectDir() gitDir := path.Join(build.FullProjectDir(), ".git") - b.writeTLSCAInfo(w, info.Build, "GIT_SSL_CAINFO") - b.writeTLSCAInfo(w, info.Build, "CI_SERVER_TLS_CA_FILE") + b.writeTLSCAInfo(w, info.Build, "GIT_SSL_CAINFO", build.GetBuildResponse.RepoURL) + b.writeTLSCAInfo(w, info.Build, "CI_SERVER_TLS_CA_FILE", build.Runner.URL) if build.AllowGitFetch { b.writeFetchCmd(w, build, projectDir, gitDir) @@ -299,7 +318,7 @@ func (b *AbstractShell) uploadArtifacts(w ShellWriter, options *archivingOptions func (b *AbstractShell) GeneratePostBuild(w ShellWriter, info common.ShellScriptInfo) { b.writeExports(w, info) b.writeCdBuildDir(w, info) - b.writeTLSCAInfo(w, info.Build, "CI_SERVER_TLS_CA_FILE") + b.writeTLSCAInfo(w, info.Build, "CI_SERVER_TLS_CA_FILE", info.Build.Runner.URL) // Parse options var options shellOptions diff --git a/shells/abstract_test.go b/shells/abstract_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6f87ac021b26cf0d115c6343174459217ee2577b --- /dev/null +++ b/shells/abstract_test.go @@ -0,0 +1,64 @@ +package shells + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" + "gitlab.com/gitlab-org/gitlab-ci-multi-runner/mocks" +) + +func TestWriteTLSCAInfo(t *testing.T) { + w := &mocks.ShellWriter{} + defer w.AssertExpectations(t) + + b := &AbstractShell{} + + build := &common.Build{ + GetBuildResponse: common.GetBuildResponse{ + TLSCAChain: "chain", + }, + Runner: &common.RunnerConfig{ + RunnerCredentials: common.RunnerCredentials{ + URL: "https://example.com:440/ci", + }, + }, + } + + expectVariable := func(key string) { + w.On("Variable", common.BuildVariable{ + Key: key, + Value: "chain", + Public: true, + Internal: true, + File: true, + }).Return().Once() + } + + expectVariable("KEY") + err := b.writeTLSCAInfo(w, build, "KEY", "https://example.com:440/ci") + assert.NoError(t, err) + + expectVariable("KEY2") + err = b.writeTLSCAInfo(w, build, "KEY2", "https://EXAMPLE.com:440/ci") + assert.NoError(t, err) + + expectVariable("KEY8") + err = b.writeTLSCAInfo(w, build, "KEY8", "https://user:password@EXAMPLE.com:440/ci") + assert.NoError(t, err) + + err = b.writeTLSCAInfo(w, build, "KEY3", "http://EXAMPLE.com:440/ci") + assert.NoError(t, err) + + err = b.writeTLSCAInfo(w, build, "KEY4", "http://EXAMPLE.com/ci") + assert.NoError(t, err) + + err = b.writeTLSCAInfo(w, build, "KEY5", "https://SERVER.com/") + assert.NoError(t, err) + + err = b.writeTLSCAInfo(w, build, "KEY6", "https://SERVER.com/") + assert.NoError(t, err) + + err = b.writeTLSCAInfo(w, build, "KEY7", "https://other-ServeR.com/") + assert.NoError(t, err) +}