diff --git a/README.md b/README.md index 1575397a9..e20114ce0 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,9 @@ If you are using Azure Blob Storage for context file, you will need to pass [Azu ### Using Private Git Repository You can use `Personal Access Tokens` for Build Contexts from Private Repositories from [GitHub](https://blog.github.com/2012-09-21-easier-builds-and-deployments-using-git-over-https-and-oauth/). +You can either pass this in as part of the git URL (e.g., `git://TOKEN@github.com/acme/myproject.git#refs/heads/mybranch`) +or using the environment variable `GIT_USERNAME`. + ### Using Standard Input If running kaniko and using Standard Input build context, you will need to add the docker or kubernetes `-i, --interactive` flag. Once running, kaniko will then get the data from `STDIN` and create the build context as a compressed tar. diff --git a/pkg/buildcontext/git.go b/pkg/buildcontext/git.go index 7c2dddc6d..18d6e2ded 100644 --- a/pkg/buildcontext/git.go +++ b/pkg/buildcontext/git.go @@ -23,12 +23,17 @@ import ( "github.com/GoogleContainerTools/kaniko/pkg/constants" git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/transport" + "gopkg.in/src-d/go-git.v4/plumbing/transport/http" ) const ( gitPullMethodEnvKey = "GIT_PULL_METHOD" gitPullMethodHTTPS = "https" gitPullMethodHTTP = "http" + + gitAuthUsernameEnvKey = "GIT_USERNAME" + gitAuthPasswordEnvKey = "GIT_PASSWORD" ) var ( @@ -46,6 +51,7 @@ func (g *Git) UnpackTarFromBuildContext() (string, error) { parts := strings.Split(g.context, "#") options := git.CloneOptions{ URL: getGitPullMethod() + "://" + parts[0], + Auth: getGitAuth(), Progress: os.Stdout, } if len(parts) > 1 { @@ -55,6 +61,18 @@ func (g *Git) UnpackTarFromBuildContext() (string, error) { return directory, err } +func getGitAuth() transport.AuthMethod { + username := os.Getenv(gitAuthUsernameEnvKey) + password := os.Getenv(gitAuthPasswordEnvKey) + if username != "" || password != "" { + return &http.BasicAuth{ + Username: username, + Password: password, + } + } + return nil +} + func getGitPullMethod() string { gitPullMethod := os.Getenv(gitPullMethodEnvKey) if ok := supportedGitPullMethods[gitPullMethod]; !ok { diff --git a/pkg/buildcontext/git_test.go b/pkg/buildcontext/git_test.go index ccc53fcb9..aaa487c92 100644 --- a/pkg/buildcontext/git_test.go +++ b/pkg/buildcontext/git_test.go @@ -21,6 +21,8 @@ import ( "testing" "github.com/GoogleContainerTools/kaniko/testutil" + "gopkg.in/src-d/go-git.v4/plumbing/transport" + "gopkg.in/src-d/go-git.v4/plumbing/transport/http" ) func TestGetGitPullMethod(t *testing.T) { @@ -80,3 +82,88 @@ func TestGetGitPullMethod(t *testing.T) { }) } } + +func TestGetGitAuth(t *testing.T) { + tests := []struct { + testName string + setEnv func() (expectedValue transport.AuthMethod) + }{ + { + testName: "noEnv", + setEnv: func() (expectedValue transport.AuthMethod) { + expectedValue = nil + return + }, + }, + { + testName: "emptyUsernameEnv", + setEnv: func() (expectedValue transport.AuthMethod) { + _ = os.Setenv(gitAuthUsernameEnvKey, "") + expectedValue = nil + return + }, + }, + { + testName: "emptyPasswordEnv", + setEnv: func() (expectedValue transport.AuthMethod) { + _ = os.Setenv(gitAuthPasswordEnvKey, "") + expectedValue = nil + return + }, + }, + { + testName: "emptyEnv", + setEnv: func() (expectedValue transport.AuthMethod) { + _ = os.Setenv(gitAuthUsernameEnvKey, "") + _ = os.Setenv(gitAuthPasswordEnvKey, "") + expectedValue = nil + return + }, + }, + { + testName: "withUsername", + setEnv: func() (expectedValue transport.AuthMethod) { + username := "foo" + _ = os.Setenv(gitAuthUsernameEnvKey, username) + expectedValue = &http.BasicAuth{Username: username} + return + }, + }, + { + testName: "withPassword", + setEnv: func() (expectedValue transport.AuthMethod) { + pass := "super-secret-password-1234" + _ = os.Setenv(gitAuthPasswordEnvKey, pass) + expectedValue = &http.BasicAuth{Password: pass} + return + }, + }, + { + testName: "withUsernamePassword", + setEnv: func() (expectedValue transport.AuthMethod) { + username := "foo" + pass := "super-secret-password-1234" + _ = os.Setenv(gitAuthUsernameEnvKey, username) + _ = os.Setenv(gitAuthPasswordEnvKey, pass) + expectedValue = &http.BasicAuth{Username: username, Password: pass} + return + }, + }, + } + + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + // Make sure to unset environment vars to get a clean test each time + defer clearTestAuthEnv() + + expectedValue := tt.setEnv() + testutil.CheckDeepEqual(t, expectedValue, getGitAuth()) + }) + } + +} + +func clearTestAuthEnv() { + _ = os.Unsetenv(gitAuthUsernameEnvKey) + _ = os.Unsetenv(gitAuthPasswordEnvKey) +}