From 0a5048a56b7ee4495585ecb7aa3d3e345a472694 Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Tue, 8 Nov 2022 21:13:43 +0530 Subject: [PATCH 1/4] refactor bootstrap process to use fluxcd/pkg/git Signed-off-by: Sanskar Jaiswal --- cmd/flux/bootstrap_bitbucket_server.go | 19 +- cmd/flux/bootstrap_git.go | 80 ++++-- cmd/flux/bootstrap_github.go | 20 +- cmd/flux/bootstrap_gitlab.go | 19 +- go.mod | 8 +- go.sum | 30 +- pkg/bootstrap/bootstrap_plain_git.go | 157 ++++++---- pkg/bootstrap/bootstrap_provider.go | 9 +- pkg/bootstrap/git/commit_options.go | 46 --- pkg/bootstrap/git/git.go | 52 ---- pkg/bootstrap/git/gogit/gogit.go | 286 ------------------- pkg/bootstrap/git/gogit/gogit_test.go | 80 ------ pkg/bootstrap/git/gogit/testdata/private.key | Bin 7533 -> 0 bytes pkg/bootstrap/options.go | 30 +- pkg/manifestgen/sourcesecret/sourcesecret.go | 4 +- 15 files changed, 233 insertions(+), 607 deletions(-) delete mode 100644 pkg/bootstrap/git/commit_options.go delete mode 100644 pkg/bootstrap/git/git.go delete mode 100644 pkg/bootstrap/git/gogit/gogit.go delete mode 100644 pkg/bootstrap/git/gogit/gogit_test.go delete mode 100644 pkg/bootstrap/git/gogit/testdata/private.key diff --git a/cmd/flux/bootstrap_bitbucket_server.go b/cmd/flux/bootstrap_bitbucket_server.go index af93f8f0d7..4b827498e7 100644 --- a/cmd/flux/bootstrap_bitbucket_server.go +++ b/cmd/flux/bootstrap_bitbucket_server.go @@ -22,13 +22,13 @@ import ( "os" "time" - "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" "github.com/spf13/cobra" "github.com/fluxcd/flux2/internal/flags" "github.com/fluxcd/flux2/internal/utils" "github.com/fluxcd/flux2/pkg/bootstrap" - "github.com/fluxcd/flux2/pkg/bootstrap/git/gogit" "github.com/fluxcd/flux2/pkg/bootstrap/provider" "github.com/fluxcd/flux2/pkg/manifestgen" "github.com/fluxcd/flux2/pkg/manifestgen/install" @@ -171,10 +171,16 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to create temporary working dir: %w", err) } defer os.RemoveAll(tmpDir) - gitClient := gogit.New(tmpDir, &http.BasicAuth{ - Username: user, - Password: bitbucketToken, + + gitClient, err := gogit.NewClient(tmpDir, &git.AuthOptions{ + Transport: git.HTTPS, + Username: user, + Password: bitbucketToken, + CAFile: caBundle, }) + if err != nil { + return err + } // Install manifest config installOptions := install.Options{ @@ -253,13 +259,12 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithProviderRepository(bServerArgs.owner, bServerArgs.repository, bServerArgs.personal), bootstrap.WithBranch(bootstrapArgs.branch), bootstrap.WithBootstrapTransportType("https"), - bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail), + bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), bootstrap.WithProviderTeamPermissions(mapTeamSlice(bServerArgs.teams, bServerDefaultPermission)), bootstrap.WithReadWriteKeyPermissions(bServerArgs.readWriteKey), bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions), bootstrap.WithLogger(logger), - bootstrap.WithCABundle(caBundle), bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID), } if bootstrapArgs.sshHostname != "" { diff --git a/cmd/flux/bootstrap_git.go b/cmd/flux/bootstrap_git.go index 8d975749c6..1721faf8cf 100644 --- a/cmd/flux/bootstrap_git.go +++ b/cmd/flux/bootstrap_git.go @@ -24,9 +24,6 @@ import ( "strings" "time" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/go-git/go-git/v5/plumbing/transport/ssh" "github.com/manifoldco/promptui" "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" @@ -34,11 +31,12 @@ import ( "github.com/fluxcd/flux2/internal/flags" "github.com/fluxcd/flux2/internal/utils" "github.com/fluxcd/flux2/pkg/bootstrap" - "github.com/fluxcd/flux2/pkg/bootstrap/git/gogit" "github.com/fluxcd/flux2/pkg/manifestgen" "github.com/fluxcd/flux2/pkg/manifestgen/install" "github.com/fluxcd/flux2/pkg/manifestgen/sourcesecret" "github.com/fluxcd/flux2/pkg/manifestgen/sync" + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" ) var bootstrapGitCmd = &cobra.Command{ @@ -116,10 +114,6 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { if err != nil { return err } - gitAuth, err := transportForURL(repositoryURL) - if err != nil { - return err - } ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() @@ -145,7 +139,28 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to create temporary working dir: %w", err) } defer os.RemoveAll(tmpDir) - gitClient := gogit.New(tmpDir, gitAuth) + + var caBundle []byte + if bootstrapArgs.caFile != "" { + var err error + caBundle, err = os.ReadFile(bootstrapArgs.caFile) + if err != nil { + return fmt.Errorf("unable to read TLS CA file: %w", err) + } + } + authOpts, err := getAuthOpts(repositoryURL, caBundle) + if err != nil { + return fmt.Errorf("failed to create authentication options for %s: %w", repositoryURL.String(), err) + } + + clientOpts := []gogit.ClientOption{gogit.WithDiskStorage()} + if authOpts.Transport == git.HTTP { + clientOpts = append(clientOpts, gogit.WithInsecureCredentialsOverHTTP()) + } + gitClient, err := gogit.NewClient(tmpDir, authOpts, clientOpts...) + if err != nil { + return fmt.Errorf("failed to create a Git client: %w", err) + } // Install manifest config installOptions := install.Options{ @@ -169,15 +184,6 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { installOptions.BaseURL = customBaseURL } - var caBundle []byte - if bootstrapArgs.caFile != "" { - var err error - caBundle, err = os.ReadFile(bootstrapArgs.caFile) - if err != nil { - return fmt.Errorf("unable to read TLS CA file: %w", err) - } - } - // Source generation and secret config secretOpts := sourcesecret.Options{ Name: bootstrapArgs.secretName, @@ -253,12 +259,11 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { bootstrapOpts := []bootstrap.GitOption{ bootstrap.WithRepositoryURL(gitArgs.url), bootstrap.WithBranch(bootstrapArgs.branch), - bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail), + bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions), bootstrap.WithPostGenerateSecretFunc(promptPublicKey), bootstrap.WithLogger(logger), - bootstrap.WithCABundle(caBundle), bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID), } @@ -272,28 +277,45 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { return bootstrap.Run(ctx, b, manifestsBase, installOptions, secretOpts, syncOpts, rootArgs.pollInterval, rootArgs.timeout) } -// transportForURL constructs a transport.AuthMethod based on the scheme +// getAuthOpts retruns a AuthOptions based on the scheme // of the given URL and the configured flags. If the protocol equals // "ssh" but no private key is configured, authentication using the local // SSH-agent is attempted. -func transportForURL(u *url.URL) (transport.AuthMethod, error) { +func getAuthOpts(u *url.URL, caBundle []byte) (*git.AuthOptions, error) { switch u.Scheme { case "http": if !gitArgs.insecureHttpAllowed { return nil, fmt.Errorf("scheme http is insecure, pass --allow-insecure-http=true to allow it") } - return &http.BasicAuth{ - Username: gitArgs.username, - Password: gitArgs.password, + return &git.AuthOptions{ + Transport: git.HTTP, + Username: gitArgs.username, + Password: gitArgs.password, }, nil case "https": - return &http.BasicAuth{ - Username: gitArgs.username, - Password: gitArgs.password, + return &git.AuthOptions{ + Transport: git.HTTPS, + Username: gitArgs.username, + Password: gitArgs.password, + CAFile: caBundle, }, nil case "ssh": if bootstrapArgs.privateKeyFile != "" { - return ssh.NewPublicKeysFromFile(u.User.Username(), bootstrapArgs.privateKeyFile, gitArgs.password) + pk, err := os.ReadFile(bootstrapArgs.privateKeyFile) + if err != nil { + return nil, err + } + kh, err := sourcesecret.ScanHostKey(u.Host) + if err != nil { + return nil, err + } + return &git.AuthOptions{ + Transport: git.SSH, + Username: u.User.Username(), + Password: gitArgs.password, + Identity: pk, + KnownHosts: kh, + }, nil } return nil, nil default: diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go index 34ad8e2fa1..faca1c7b41 100644 --- a/cmd/flux/bootstrap_github.go +++ b/cmd/flux/bootstrap_github.go @@ -22,13 +22,13 @@ import ( "os" "time" - "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" "github.com/spf13/cobra" "github.com/fluxcd/flux2/internal/flags" "github.com/fluxcd/flux2/internal/utils" "github.com/fluxcd/flux2/pkg/bootstrap" - "github.com/fluxcd/flux2/pkg/bootstrap/git/gogit" "github.com/fluxcd/flux2/pkg/bootstrap/provider" "github.com/fluxcd/flux2/pkg/manifestgen" "github.com/fluxcd/flux2/pkg/manifestgen/install" @@ -161,16 +161,21 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { return err } - // Lazy go-git repository tmpDir, err := manifestgen.MkdirTempAbs("", "flux-bootstrap-") if err != nil { return fmt.Errorf("failed to create temporary working dir: %w", err) } defer os.RemoveAll(tmpDir) - gitClient := gogit.New(tmpDir, &http.BasicAuth{ - Username: githubArgs.owner, - Password: ghToken, + + gitClient, err := gogit.NewClient(tmpDir, &git.AuthOptions{ + Transport: git.HTTPS, + Username: githubArgs.owner, + Password: ghToken, + CAFile: caBundle, }) + if err != nil { + return err + } // Install manifest config installOptions := install.Options{ @@ -239,13 +244,12 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithProviderRepository(githubArgs.owner, githubArgs.repository, githubArgs.personal), bootstrap.WithBranch(bootstrapArgs.branch), bootstrap.WithBootstrapTransportType("https"), - bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail), + bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), bootstrap.WithProviderTeamPermissions(mapTeamSlice(githubArgs.teams, ghDefaultPermission)), bootstrap.WithReadWriteKeyPermissions(githubArgs.readWriteKey), bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions), bootstrap.WithLogger(logger), - bootstrap.WithCABundle(caBundle), bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID), } if bootstrapArgs.sshHostname != "" { diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go index cb38cdaee1..55f5dc5828 100644 --- a/cmd/flux/bootstrap_gitlab.go +++ b/cmd/flux/bootstrap_gitlab.go @@ -24,13 +24,13 @@ import ( "strings" "time" - "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/gogit" "github.com/spf13/cobra" "github.com/fluxcd/flux2/internal/flags" "github.com/fluxcd/flux2/internal/utils" "github.com/fluxcd/flux2/pkg/bootstrap" - "github.com/fluxcd/flux2/pkg/bootstrap/git/gogit" "github.com/fluxcd/flux2/pkg/bootstrap/provider" "github.com/fluxcd/flux2/pkg/manifestgen" "github.com/fluxcd/flux2/pkg/manifestgen/install" @@ -178,10 +178,16 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("failed to create temporary working dir: %w", err) } defer os.RemoveAll(tmpDir) - gitClient := gogit.New(tmpDir, &http.BasicAuth{ - Username: gitlabArgs.owner, - Password: glToken, + + gitClient, err := gogit.NewClient(tmpDir, &git.AuthOptions{ + Transport: git.HTTPS, + Username: gitlabArgs.owner, + Password: glToken, + CAFile: caBundle, }) + if err != nil { + return err + } // Install manifest config installOptions := install.Options{ @@ -255,13 +261,12 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithProviderRepository(gitlabArgs.owner, gitlabArgs.repository, gitlabArgs.personal), bootstrap.WithBranch(bootstrapArgs.branch), bootstrap.WithBootstrapTransportType("https"), - bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail), + bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), bootstrap.WithProviderTeamPermissions(mapTeamSlice(gitlabArgs.teams, glDefaultPermission)), bootstrap.WithReadWriteKeyPermissions(gitlabArgs.readWriteKey), bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions), bootstrap.WithLogger(logger), - bootstrap.WithCABundle(caBundle), bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID), } if bootstrapArgs.sshHostname != "" { diff --git a/go.mod b/go.mod index 045d0e716c..973299179a 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,9 @@ module github.com/fluxcd/flux2 go 1.18 +// Use Flux's version of go-git, which allows clones with multi_ack and multi_ack_detailed. +replace github.com/go-git/go-git/v5 => github.com/fluxcd/go-git/v5 v5.0.0-20221019082644-b33dae782906 + require ( github.com/Masterminds/semver/v3 v3.1.1 github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 @@ -14,6 +17,8 @@ require ( github.com/fluxcd/kustomize-controller/api v0.30.0 github.com/fluxcd/notification-controller/api v0.28.0 github.com/fluxcd/pkg/apis/meta v0.18.0 + github.com/fluxcd/pkg/git v0.7.0 + github.com/fluxcd/pkg/git/gogit v0.2.0 github.com/fluxcd/pkg/kustomize v0.10.0 github.com/fluxcd/pkg/oci v0.15.0 github.com/fluxcd/pkg/runtime v0.24.0 @@ -87,7 +92,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect - github.com/cloudflare/circl v1.1.0 // indirect + github.com/cloudflare/circl v1.3.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -181,6 +186,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect + github.com/skeema/knownhosts v1.1.0 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/vbatts/tar-split v0.11.2 // indirect github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect diff --git a/go.sum b/go.sum index f1c3782f47..2e7a37320d 100644 --- a/go.sum +++ b/go.sum @@ -80,8 +80,7 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= 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.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= @@ -136,8 +135,9 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.3.0 h1:Anq00jxDtoyX3+aCaYUZ0vXC5r4k4epberfWGDXV1zE= +github.com/cloudflare/circl v1.3.0/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw= 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= @@ -200,8 +200,11 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg= github.com/fluxcd/go-git-providers v0.9.0 h1:iiiKe3dzRCgVkjEi8rfpvaWTZwuGRfb3RJFhjSNz+Uc= github.com/fluxcd/go-git-providers v0.9.0/go.mod h1:GcaDVP9RlamLKJp25Nwi7X5t0MyZV3FY+qy1GiRdbtk= +github.com/fluxcd/go-git/v5 v5.0.0-20221019082644-b33dae782906 h1:VFNX84BWt3r4YVFYLdNvryRwFBix2lea8EVT5V/xH7Y= +github.com/fluxcd/go-git/v5 v5.0.0-20221019082644-b33dae782906/go.mod h1:YpPgMNvxopDCZUuSFjkbcx/vWhCDvPsuoBCTTEd9dDc= github.com/fluxcd/go-git/v5 v5.0.0-20221104190732-329fd6659b10 h1:au798417R1iWtgcgKe3Dg495mexQmuxelL+NebAtexE= github.com/fluxcd/go-git/v5 v5.0.0-20221104190732-329fd6659b10/go.mod h1:w8bjt1WtWUxMEmlifjBJP9bK9QAG1Vw1Lw7RzchJFNk= github.com/fluxcd/helm-controller/api v0.26.0 h1:UCod+R1Oct2jg5cXHlVBC57Jy01lMdpl9MA+8UPogvY= @@ -220,6 +223,11 @@ github.com/fluxcd/pkg/apis/kustomize v0.7.0 h1:X2htBmJ91nGYv4d93gin665MFWKNGiNwU github.com/fluxcd/pkg/apis/kustomize v0.7.0/go.mod h1:Mu+KdktsEKWA4l/33CZdY5lB4hz51mqfcLzBZSwAqVg= github.com/fluxcd/pkg/apis/meta v0.18.0 h1:s0LeulWcQ4DxVX6805vgDTxlA6bAYk+Lq1QHSnNdqLM= github.com/fluxcd/pkg/apis/meta v0.18.0/go.mod h1:pYvXRFi1UKNNrGR34jw3uqOnMXw9X6dTkML8j5Z7tis= +github.com/fluxcd/pkg/git v0.7.0 h1:sQHRpFMcOzEdqlyGMjFv2LKMdcoE5xeUr2UcRrsLRG8= +github.com/fluxcd/pkg/git v0.7.0/go.mod h1:3deiLPws4DSQ3hqwtQd7Dt66GXTN/4RcT/yHAljXaHo= +github.com/fluxcd/pkg/git/gogit v0.2.0 h1:vhFzk2Pky4tDZwisx8+26YZumRDPxERnkV8l2dbLSoo= +github.com/fluxcd/pkg/git/gogit v0.2.0/go.mod h1:d1RIwl6DVdU8/2dBIhw6n7GNokIKqs+b9cKc/8tz7ew= +github.com/fluxcd/pkg/gittestserver v0.8.0 h1:YrYe63KScKlLxx0GAiQthx2XqHDx0vKitIIx4JnDtIo= github.com/fluxcd/pkg/kustomize v0.10.0 h1:EG5MbYrLtxeCiZxeFUgvyBhFZaXnKfeqqpg7O+J7o3s= github.com/fluxcd/pkg/kustomize v0.10.0/go.mod h1:awHID4OKe2/WAfTFg4u0fURXZPUkrIslSZNSPX9MEFQ= github.com/fluxcd/pkg/oci v0.15.0 h1:M8fiWveUPoUxZqvHc6om1/5tDYMOEdbJAURfKK7mGAA= @@ -251,14 +259,10 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= -github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= 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= @@ -283,6 +287,7 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -591,12 +596,12 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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.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.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= @@ -625,7 +630,7 @@ github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtb github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c= github.com/xanzy/go-gitlab v0.73.1 h1:UMagqUZLJdjss1SovIC+kJCH4k2AZWXl58gJd38Y/hI= github.com/xanzy/go-gitlab v0.73.1/go.mod h1:d/a0vswScO7Agg1CZNz15Ic6SSvBG9vfw8egL99t4kA= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w= github.com/xanzy/ssh-agent v0.3.2 h1:eKj4SX2Fe7mui28ZgnFW5fmTz1EIr7ugo5s6wDxdHBM= github.com/xanzy/ssh-agent v0.3.2/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -660,14 +665,13 @@ go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -749,7 +753,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v 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/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-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -809,7 +812,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -842,10 +844,8 @@ golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= diff --git a/pkg/bootstrap/bootstrap_plain_git.go b/pkg/bootstrap/bootstrap_plain_git.go index 4f82a72e49..70f2f49a4e 100644 --- a/pkg/bootstrap/bootstrap_plain_git.go +++ b/pkg/bootstrap/bootstrap_plain_git.go @@ -19,6 +19,7 @@ package bootstrap import ( "context" "fmt" + "io" "os" "path/filepath" "strings" @@ -40,21 +41,21 @@ import ( runclient "github.com/fluxcd/pkg/runtime/client" "github.com/fluxcd/flux2/internal/utils" - "github.com/fluxcd/flux2/pkg/bootstrap/git" "github.com/fluxcd/flux2/pkg/log" "github.com/fluxcd/flux2/pkg/manifestgen/install" "github.com/fluxcd/flux2/pkg/manifestgen/kustomization" "github.com/fluxcd/flux2/pkg/manifestgen/sourcesecret" "github.com/fluxcd/flux2/pkg/manifestgen/sync" "github.com/fluxcd/flux2/pkg/status" + "github.com/fluxcd/pkg/git" + "github.com/fluxcd/pkg/git/repository" ) type PlainGitBootstrapper struct { - url string - branch string - caBundle []byte + url string + branch string - author git.Author + signature git.Signature commitMessageAppendix string gpgKeyRing openpgp.EntityList @@ -66,9 +67,9 @@ type PlainGitBootstrapper struct { postGenerateSecret []PostGenerateSecretFunc - git git.Git - kube client.Client - logger log.Logger + gitClient repository.Client + kube client.Client + logger log.Logger } type GitOption interface { @@ -95,10 +96,10 @@ func (o postGenerateSecret) applyGit(b *PlainGitBootstrapper) { b.postGenerateSecret = append(b.postGenerateSecret, PostGenerateSecretFunc(o)) } -func NewPlainGitProvider(git git.Git, kube client.Client, opts ...GitOption) (*PlainGitBootstrapper, error) { +func NewPlainGitProvider(git repository.Client, kube client.Client, opts ...GitOption) (*PlainGitBootstrapper, error) { b := &PlainGitBootstrapper{ - git: git, - kube: kube, + gitClient: git, + kube: kube, } for _, opt := range opts { opt.applyGit(b) @@ -108,7 +109,7 @@ func NewPlainGitProvider(git git.Git, kube client.Client, opts ...GitOption) (*P func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options, _ sourcesecret.Options) error { // Clone if not already - if _, err := b.git.Status(); err != nil { + if _, err := b.gitClient.Head(); err != nil { if err != git.ErrNoGitRepository { return err } @@ -116,7 +117,17 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url) var cloned bool if err = retry(1, 2*time.Second, func() (err error) { - cloned, err = b.git.Clone(ctx, b.url, b.branch, b.caBundle) + _, err = b.gitClient.Clone(ctx, b.url, repository.CloneOptions{ + CheckoutStrategy: repository.CheckoutStrategy{ + Branch: b.branch, + }, + }) + if err != nil { + b.logger.Warningf(" clone failure: %s", err) + } + if err == nil { + cloned = true + } return }); err != nil { return fmt.Errorf("failed to clone repository: %w", err) @@ -134,28 +145,33 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest } b.logger.Successf("generated component manifests") - // Write manifest to Git repository - if err = b.git.Write(manifests.Path, strings.NewReader(manifests.Content)); err != nil { - return fmt.Errorf("failed to write manifest %q: %w", manifests.Path, err) + // Write generated files and make a commit + var signer *openpgp.Entity + if b.gpgKeyRing != nil { + signer, err = getOpenPgpEntity(b.gpgKeyRing, b.gpgPassphrase, b.gpgKeyID) + if err != nil { + return fmt.Errorf("failed to generate OpenPGP entity: %w", err) + } } - - // Git commit generated - gpgOpts := git.WithGpgSigningOption(b.gpgKeyRing, b.gpgPassphrase, b.gpgKeyID) commitMsg := fmt.Sprintf("Add Flux %s component manifests", options.Version) if b.commitMessageAppendix != "" { commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix } - commit, err := b.git.Commit(git.Commit{ - Author: b.author, + + commit, err := b.gitClient.Commit(git.Commit{ + Author: b.signature, Message: commitMsg, - }, gpgOpts) + }, repository.WithFiles(map[string]io.Reader{ + manifests.Path: strings.NewReader(manifests.Content), + }), repository.WithSigner(signer)) if err != nil && err != git.ErrNoStagedFiles { return fmt.Errorf("failed to commit sync manifests: %w", err) } + if err == nil { b.logger.Successf("committed sync manifests to %q (%q)", b.branch, commit) b.logger.Actionf("pushing component manifests to %q", b.url) - if err = b.git.Push(ctx, b.caBundle); err != nil { + if err = b.gitClient.Push(ctx); err != nil { return fmt.Errorf("failed to push manifests: %w", err) } } else { @@ -166,16 +182,16 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest if mustInstallManifests(ctx, b.kube, options.Namespace) { b.logger.Actionf("installing components in %q namespace", options.Namespace) - componentsYAML := filepath.Join(b.git.Path(), manifests.Path) + componentsYAML := filepath.Join(b.gitClient.Path(), manifests.Path) kfile := filepath.Join(filepath.Dir(componentsYAML), konfig.DefaultKustomizationFileName()) if _, err := os.Stat(kfile); err == nil { // Apply the components and their patches - if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.git.Path(), kfile); err != nil { + if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.gitClient.Path(), kfile); err != nil { return err } } else { // Apply the CRDs and controllers - if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.git.Path(), componentsYAML); err != nil { + if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.gitClient.Path(), componentsYAML); err != nil { return err } } @@ -237,12 +253,19 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options } // Clone if not already - if _, err := b.git.Status(); err != nil { + if _, err := b.gitClient.Head(); err != nil { if err == git.ErrNoGitRepository { b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url) var cloned bool if err = retry(1, 2*time.Second, func() (err error) { - cloned, err = b.git.Clone(ctx, b.url, b.branch, b.caBundle) + _, err = b.gitClient.Clone(ctx, b.url, repository.CloneOptions{ + CheckoutStrategy: repository.CheckoutStrategy{ + Branch: b.branch, + }, + }) + if err == nil { + cloned = true + } return }); err != nil { return fmt.Errorf("failed to clone repository: %w", err) @@ -260,41 +283,47 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options if err != nil { return fmt.Errorf("sync manifests generation failed: %w", err) } - if err = b.git.Write(manifests.Path, strings.NewReader(manifests.Content)); err != nil { - return fmt.Errorf("failed to write manifest %q: %w", manifests.Path, err) - } // Create secure Kustomize FS - fs, err := filesys.MakeFsOnDiskSecureBuild(b.git.Path()) + fs, err := filesys.MakeFsOnDiskSecureBuild(b.gitClient.Path()) if err != nil { return fmt.Errorf("failed to initialize Kustomize file system: %w", err) } + if err = fs.WriteFile(filepath.Join(b.gitClient.Path(), manifests.Path), []byte(manifests.Content)); err != nil { + return err + } + // Generate Kustomization kusManifests, err := kustomization.Generate(kustomization.Options{ FileSystem: fs, - BaseDir: b.git.Path(), + BaseDir: b.gitClient.Path(), TargetPath: filepath.Dir(manifests.Path), }) if err != nil { return fmt.Errorf("%s generation failed: %w", konfig.DefaultKustomizationFileName(), err) } - if err = b.git.Write(kusManifests.Path, strings.NewReader(kusManifests.Content)); err != nil { - return fmt.Errorf("failed to write manifest %q: %w", kusManifests.Path, err) - } b.logger.Successf("generated sync manifests") - // Git commit generated - gpgOpts := git.WithGpgSigningOption(b.gpgKeyRing, b.gpgPassphrase, b.gpgKeyID) + // Write generated files and make a commit + var signer *openpgp.Entity + if b.gpgKeyRing != nil { + signer, err = getOpenPgpEntity(b.gpgKeyRing, b.gpgPassphrase, b.gpgKeyID) + if err != nil { + return fmt.Errorf("failed to generate OpenPGP entity: %w", err) + } + } commitMsg := fmt.Sprintf("Add Flux sync manifests") if b.commitMessageAppendix != "" { commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix } - commit, err := b.git.Commit(git.Commit{ - Author: b.author, - Message: commitMsg, - }, gpgOpts) + commit, err := b.gitClient.Commit(git.Commit{ + Author: b.signature, + Message: commitMsg, + }, repository.WithFiles(map[string]io.Reader{ + kusManifests.Path: strings.NewReader(kusManifests.Content), + }), repository.WithSigner(signer)) if err != nil && err != git.ErrNoStagedFiles { return fmt.Errorf("failed to commit sync manifests: %w", err) } @@ -302,18 +331,22 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options if err == nil { b.logger.Successf("committed sync manifests to %q (%q)", b.branch, commit) b.logger.Actionf("pushing sync manifests to %q", b.url) - err = b.git.Push(ctx, b.caBundle) + err = b.gitClient.Push(ctx) if err != nil { if strings.HasPrefix(err.Error(), gogit.ErrNonFastForwardUpdate.Error()) { b.logger.Waitingf("git conflict detected, retrying with a fresh clone") - if err := os.RemoveAll(b.git.Path()); err != nil { + if err := os.RemoveAll(b.gitClient.Path()); err != nil { return fmt.Errorf("failed to remove tmp dir: %w", err) } - if err := os.Mkdir(b.git.Path(), 0o700); err != nil { + if err := os.Mkdir(b.gitClient.Path(), 0o700); err != nil { return fmt.Errorf("failed to recreate tmp dir: %w", err) } if err = retry(1, 2*time.Second, func() (err error) { - _, err = b.git.Clone(ctx, b.url, b.branch, b.caBundle) + _, err = b.gitClient.Clone(ctx, b.url, repository.CloneOptions{ + CheckoutStrategy: repository.CheckoutStrategy{ + Branch: b.branch, + }, + }) return }); err != nil { return fmt.Errorf("failed to clone repository: %w", err) @@ -328,7 +361,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options // Apply to cluster b.logger.Actionf("applying sync manifests") - if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.git.Path(), filepath.Join(b.git.Path(), kusManifests.Path)); err != nil { + if _, err := utils.Apply(ctx, b.restClientGetter, b.restClientOptions, b.gitClient.Path(), filepath.Join(b.gitClient.Path(), kusManifests.Path)); err != nil { return err } @@ -338,7 +371,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options } func (b *PlainGitBootstrapper) ReportKustomizationHealth(ctx context.Context, options sync.Options, pollInterval, timeout time.Duration) error { - head, err := b.git.Head() + head, err := b.gitClient.Head() if err != nil { return err } @@ -390,3 +423,31 @@ func (b *PlainGitBootstrapper) ReportComponentsHealth(ctx context.Context, insta b.logger.Successf("all components are healthy") return nil } + +func getOpenPgpEntity(keyRing openpgp.EntityList, passphrase, keyID string) (*openpgp.Entity, error) { + if len(keyRing) == 0 { + return nil, fmt.Errorf("empty GPG key ring") + } + + var entity *openpgp.Entity + if keyID != "" { + for _, ent := range keyRing { + if ent.PrimaryKey.KeyIdString() == keyID { + entity = ent + } + } + + if entity == nil { + return nil, fmt.Errorf("no GPG private key matching key id '%s' found", keyID) + } + } else { + entity = keyRing[0] + } + + err := entity.PrivateKey.Decrypt([]byte(passphrase)) + if err != nil { + return nil, fmt.Errorf("unable to decrypt GPG private key: %w", err) + } + + return entity, nil +} diff --git a/pkg/bootstrap/bootstrap_provider.go b/pkg/bootstrap/bootstrap_provider.go index 1d27cce0f6..6360092628 100644 --- a/pkg/bootstrap/bootstrap_provider.go +++ b/pkg/bootstrap/bootstrap_provider.go @@ -29,10 +29,10 @@ import ( "github.com/fluxcd/go-git-providers/gitprovider" - "github.com/fluxcd/flux2/pkg/bootstrap/git" "github.com/fluxcd/flux2/pkg/bootstrap/provider" "github.com/fluxcd/flux2/pkg/manifestgen/sourcesecret" "github.com/fluxcd/flux2/pkg/manifestgen/sync" + "github.com/fluxcd/pkg/git/repository" ) type GitProviderBootstrapper struct { @@ -62,11 +62,12 @@ type GitProviderBootstrapper struct { provider gitprovider.Client } -func NewGitProviderBootstrapper(git git.Git, provider gitprovider.Client, kube client.Client, opts ...GitProviderOption) (*GitProviderBootstrapper, error) { +func NewGitProviderBootstrapper(git repository.Client, provider gitprovider.Client, + kube client.Client, opts ...GitProviderOption) (*GitProviderBootstrapper, error) { b := &GitProviderBootstrapper{ PlainGitBootstrapper: &PlainGitBootstrapper{ - git: git, - kube: kube, + gitClient: git, + kube: kube, }, bootstrapTransportType: "https", syncTransportType: "ssh", diff --git a/pkg/bootstrap/git/commit_options.go b/pkg/bootstrap/git/commit_options.go deleted file mode 100644 index b30491f6fe..0000000000 --- a/pkg/bootstrap/git/commit_options.go +++ /dev/null @@ -1,46 +0,0 @@ -package git - -import ( - "github.com/ProtonMail/go-crypto/openpgp" -) - -// Option is a some configuration that modifies options for a commit. -type Option interface { - // ApplyToCommit applies this configuration to a given commit option. - ApplyToCommit(*CommitOptions) -} - -// CommitOptions contains options for making a commit. -type CommitOptions struct { - *GPGSigningInfo -} - -// GPGSigningInfo contains information for signing a commit. -type GPGSigningInfo struct { - KeyRing openpgp.EntityList - Passphrase string - KeyID string -} - -type GpgSigningOption struct { - *GPGSigningInfo -} - -func (w GpgSigningOption) ApplyToCommit(in *CommitOptions) { - in.GPGSigningInfo = w.GPGSigningInfo -} - -func WithGpgSigningOption(keyRing openpgp.EntityList, passphrase, keyID string) Option { - // Return nil if no path is set, even if other options are configured. - if len(keyRing) == 0 { - return GpgSigningOption{} - } - - return GpgSigningOption{ - GPGSigningInfo: &GPGSigningInfo{ - KeyRing: keyRing, - Passphrase: passphrase, - KeyID: keyID, - }, - } -} diff --git a/pkg/bootstrap/git/git.go b/pkg/bootstrap/git/git.go deleted file mode 100644 index 1a0f6d86b2..0000000000 --- a/pkg/bootstrap/git/git.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2021 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package git - -import ( - "context" - "errors" - "io" -) - -var ( - ErrNoGitRepository = errors.New("no git repository") - ErrNoStagedFiles = errors.New("no staged files") -) - -type Author struct { - Name string - Email string -} - -type Commit struct { - Author - Hash string - Message string -} - -// Git is an interface for basic Git operations on a single branch of a -// remote repository. -type Git interface { - Init(url, branch string) (bool, error) - Clone(ctx context.Context, url, branch string, caBundle []byte) (bool, error) - Write(path string, reader io.Reader) error - Commit(message Commit, options ...Option) (string, error) - Push(ctx context.Context, caBundle []byte) error - Status() (bool, error) - Head() (string, error) - Path() string -} diff --git a/pkg/bootstrap/git/gogit/gogit.go b/pkg/bootstrap/git/gogit/gogit.go deleted file mode 100644 index c1c6200a77..0000000000 --- a/pkg/bootstrap/git/gogit/gogit.go +++ /dev/null @@ -1,286 +0,0 @@ -/* -Copyright 2021 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gogit - -import ( - "context" - "fmt" - "io" - "os" - "path/filepath" - "strings" - "time" - - "github.com/ProtonMail/go-crypto/openpgp" - gogit "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/transport" - - "github.com/fluxcd/flux2/pkg/bootstrap/git" -) - -type GoGit struct { - path string - auth transport.AuthMethod - repository *gogit.Repository -} - -type CommitOptions struct { - GpgKeyPath string - GpgKeyPassphrase string - KeyID string -} - -func New(path string, auth transport.AuthMethod) *GoGit { - return &GoGit{ - path: path, - auth: auth, - } -} - -func (g *GoGit) Init(url, branch string) (bool, error) { - if g.repository != nil { - return false, nil - } - - r, err := gogit.PlainInit(g.path, false) - if err != nil { - return false, err - } - if _, err = r.CreateRemote(&config.RemoteConfig{ - Name: gogit.DefaultRemoteName, - URLs: []string{url}, - }); err != nil { - return false, err - } - branchRef := plumbing.NewBranchReferenceName(branch) - if err = r.CreateBranch(&config.Branch{ - Name: branch, - Remote: gogit.DefaultRemoteName, - Merge: branchRef, - }); err != nil { - return false, err - } - // PlainInit assumes the initial branch to always be master, we can - // overwrite this by setting the reference of the Storer to a new - // symbolic reference (as there are no commits yet) that points - // the HEAD to our new branch. - if err = r.Storer.SetReference(plumbing.NewSymbolicReference(plumbing.HEAD, branchRef)); err != nil { - return false, err - } - - g.repository = r - return true, nil -} - -func (g *GoGit) Clone(ctx context.Context, url, branch string, caBundle []byte) (bool, error) { - branchRef := plumbing.NewBranchReferenceName(branch) - r, err := gogit.PlainCloneContext(ctx, g.path, false, &gogit.CloneOptions{ - URL: url, - Auth: g.auth, - RemoteName: gogit.DefaultRemoteName, - ReferenceName: branchRef, - SingleBranch: true, - - NoCheckout: false, - Progress: nil, - Tags: gogit.NoTags, - CABundle: caBundle, - }) - if err != nil { - if err == transport.ErrEmptyRemoteRepository || isRemoteBranchNotFoundErr(err, branchRef.String()) { - return g.Init(url, branch) - } - return false, err - } - - g.repository = r - return true, nil -} - -func (g *GoGit) Write(path string, reader io.Reader) error { - if g.repository == nil { - return git.ErrNoGitRepository - } - - wt, err := g.repository.Worktree() - if err != nil { - return err - } - - f, err := wt.Filesystem.Create(path) - if err != nil { - return err - } - defer f.Close() - - _, err = io.Copy(f, reader) - return err -} - -func (g *GoGit) Commit(message git.Commit, opts ...git.Option) (string, error) { - if g.repository == nil { - return "", git.ErrNoGitRepository - } - - wt, err := g.repository.Worktree() - if err != nil { - return "", err - } - - status, err := wt.Status() - if err != nil { - return "", err - } - - // apply the options - options := &git.CommitOptions{} - for _, opt := range opts { - opt.ApplyToCommit(options) - } - - // go-git has [a bug](https://github.com/go-git/go-git/issues/253) - // whereby it thinks broken symlinks to absolute paths are - // modified. There's no circumstance in which we want to commit a - // change to a broken symlink: so, detect and skip those. - var changed bool - for file, _ := range status { - abspath := filepath.Join(g.path, file) - info, err := os.Lstat(abspath) - if err != nil { - return "", fmt.Errorf("checking if %s is a symlink: %w", file, err) - } - if info.Mode()&os.ModeSymlink > 0 { - // symlinks are OK; broken symlinks are probably a result - // of the bug mentioned above, but not of interest in any - // case. - if _, err := os.Stat(abspath); os.IsNotExist(err) { - continue - } - } - _, _ = wt.Add(file) - changed = true - } - - if !changed { - head, err := g.repository.Head() - if err != nil { - return "", err - } - return head.Hash().String(), git.ErrNoStagedFiles - } - - commitOpts := &gogit.CommitOptions{ - Author: &object.Signature{ - Name: message.Name, - Email: message.Email, - When: time.Now(), - }, - } - - if options.GPGSigningInfo != nil { - entity, err := getOpenPgpEntity(*options.GPGSigningInfo) - if err != nil { - return "", err - } - - commitOpts.SignKey = entity - } - - commit, err := wt.Commit(message.Message, commitOpts) - if err != nil { - return "", err - } - return commit.String(), nil -} - -func (g *GoGit) Push(ctx context.Context, caBundle []byte) error { - if g.repository == nil { - return git.ErrNoGitRepository - } - - return g.repository.PushContext(ctx, &gogit.PushOptions{ - RemoteName: gogit.DefaultRemoteName, - Auth: g.auth, - Progress: nil, - CABundle: caBundle, - }) -} - -func (g *GoGit) Status() (bool, error) { - if g.repository == nil { - return false, git.ErrNoGitRepository - } - wt, err := g.repository.Worktree() - if err != nil { - return false, err - } - status, err := wt.Status() - if err != nil { - return false, err - } - return status.IsClean(), nil -} - -func (g *GoGit) Head() (string, error) { - if g.repository == nil { - return "", git.ErrNoGitRepository - } - head, err := g.repository.Head() - if err != nil { - return "", err - } - return head.Hash().String(), nil -} - -func (g *GoGit) Path() string { - return g.path -} - -func isRemoteBranchNotFoundErr(err error, ref string) bool { - return strings.Contains(err.Error(), fmt.Sprintf("couldn't find remote ref %q", ref)) -} - -func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) { - if len(info.KeyRing) == 0 { - return nil, fmt.Errorf("empty GPG key ring") - } - - var entity *openpgp.Entity - if info.KeyID != "" { - for _, ent := range info.KeyRing { - if ent.PrimaryKey.KeyIdString() == info.KeyID { - entity = ent - } - } - - if entity == nil { - return nil, fmt.Errorf("no GPG private key matching key id '%s' found", info.KeyID) - } - } else { - entity = info.KeyRing[0] - } - - err := entity.PrivateKey.Decrypt([]byte(info.Passphrase)) - if err != nil { - return nil, fmt.Errorf("unable to decrypt GPG private key: %w", err) - } - - return entity, nil -} diff --git a/pkg/bootstrap/git/gogit/gogit_test.go b/pkg/bootstrap/git/gogit/gogit_test.go deleted file mode 100644 index 03e4545b5e..0000000000 --- a/pkg/bootstrap/git/gogit/gogit_test.go +++ /dev/null @@ -1,80 +0,0 @@ -//go:build unit -// +build unit - -package gogit - -import ( - "os" - "testing" - - "github.com/ProtonMail/go-crypto/openpgp" - "github.com/fluxcd/flux2/pkg/bootstrap/git" -) - -func TestGetOpenPgpEntity(t *testing.T) { - tests := []struct { - name string - keyPath string - passphrase string - id string - expectErr bool - }{ - { - name: "no default key id given", - keyPath: "testdata/private.key", - passphrase: "flux", - id: "", - expectErr: false, - }, - { - name: "key id given", - keyPath: "testdata/private.key", - passphrase: "flux", - id: "0619327DBD777415", - expectErr: false, - }, - { - name: "wrong key id", - keyPath: "testdata/private.key", - passphrase: "flux", - id: "0619327DBD777416", - expectErr: true, - }, - { - name: "wrong password", - keyPath: "testdata/private.key", - passphrase: "fluxe", - id: "0619327DBD777415", - expectErr: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var entityList openpgp.EntityList - if tt.keyPath != "" { - r, err := os.Open(tt.keyPath) - if err != nil { - t.Errorf("unexpected error: %s", err) - } - entityList, err = openpgp.ReadKeyRing(r) - if err != nil { - t.Errorf("unexpected error: %s", err) - } - } - gpgInfo := git.GPGSigningInfo{ - KeyRing: entityList, - Passphrase: tt.passphrase, - KeyID: tt.id, - } - - _, err := getOpenPgpEntity(gpgInfo) - if err != nil && !tt.expectErr { - t.Errorf("unexpected error: %s", err) - } - if err == nil && tt.expectErr { - t.Errorf("expected error when %s", tt.name) - } - }) - } -} diff --git a/pkg/bootstrap/git/gogit/testdata/private.key b/pkg/bootstrap/git/gogit/testdata/private.key deleted file mode 100644 index 9e56432c627b84d068b2fe3f9abd07a8fcb5368a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7533 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 diff --git a/pkg/bootstrap/options.go b/pkg/bootstrap/options.go index be6ce3e87f..c9ea0f8132 100644 --- a/pkg/bootstrap/options.go +++ b/pkg/bootstrap/options.go @@ -23,9 +23,9 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "github.com/ProtonMail/go-crypto/openpgp" + "github.com/fluxcd/pkg/git" runclient "github.com/fluxcd/pkg/runtime/client" - "github.com/fluxcd/flux2/pkg/bootstrap/git" "github.com/fluxcd/flux2/pkg/log" ) @@ -48,42 +48,28 @@ func (o branchOption) applyGitProvider(b *GitProviderBootstrapper) { o.applyGit(b.PlainGitBootstrapper) } -func WithAuthor(name, email string) Option { - return authorOption{ +func WithSignature(name, email string) Option { + return signatureOption{ Name: name, Email: email, } } -type authorOption git.Author +type signatureOption git.Signature -func (o authorOption) applyGit(b *PlainGitBootstrapper) { +func (o signatureOption) applyGit(b *PlainGitBootstrapper) { if o.Name != "" { - b.author.Name = o.Name + b.signature.Name = o.Name } if o.Email != "" { - b.author.Email = o.Email + b.signature.Email = o.Email } } -func (o authorOption) applyGitProvider(b *GitProviderBootstrapper) { +func (o signatureOption) applyGitProvider(b *GitProviderBootstrapper) { o.applyGit(b.PlainGitBootstrapper) } -func WithCABundle(b []byte) Option { - return caBundleOption(b) -} - -type caBundleOption []byte - -func (o caBundleOption) applyGit(b *PlainGitBootstrapper) { - b.caBundle = o -} - -func (o caBundleOption) applyGitProvider(b *GitProviderBootstrapper) { - b.caBundle = o -} - func WithCommitMessageAppendix(appendix string) Option { return commitMessageAppendixOption(appendix) } diff --git a/pkg/manifestgen/sourcesecret/sourcesecret.go b/pkg/manifestgen/sourcesecret/sourcesecret.go index 575af3df22..a5ab6c43dd 100644 --- a/pkg/manifestgen/sourcesecret/sourcesecret.go +++ b/pkg/manifestgen/sourcesecret/sourcesecret.go @@ -76,7 +76,7 @@ func Generate(options Options) (*manifestgen.Manifest, error) { var hostKey []byte if keypair != nil { - if hostKey, err = scanHostKey(options.SSHHostname); err != nil { + if hostKey, err = ScanHostKey(options.SSHHostname); err != nil { return nil, err } } @@ -194,7 +194,7 @@ func generateKeyPair(options Options) (*ssh.KeyPair, error) { return pair, nil } -func scanHostKey(host string) ([]byte, error) { +func ScanHostKey(host string) ([]byte, error) { if _, _, err := net.SplitHostPort(host); err != nil { // Assume we are dealing with a hostname without a port, // append the default SSH port as this is required for From 4ea253220a4600319a9f2bc599ecf5217ffaa8dc Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Wed, 9 Nov 2022 16:16:50 +0530 Subject: [PATCH 2/4] use fluxcd/go-git instead of go-git/go-git directly Signed-off-by: Sanskar Jaiswal --- go.mod | 7 ++----- go.sum | 19 ++++++++++++++----- pkg/bootstrap/bootstrap_plain_git.go | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 973299179a..351b716e79 100644 --- a/go.mod +++ b/go.mod @@ -2,15 +2,13 @@ module github.com/fluxcd/flux2 go 1.18 -// Use Flux's version of go-git, which allows clones with multi_ack and multi_ack_detailed. -replace github.com/go-git/go-git/v5 => github.com/fluxcd/go-git/v5 v5.0.0-20221019082644-b33dae782906 - require ( github.com/Masterminds/semver/v3 v3.1.1 github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 github.com/cyphar/filepath-securejoin v0.2.3 github.com/distribution/distribution/v3 v3.0.0-20221111170714-3b8fbf975279 github.com/fluxcd/go-git-providers v0.9.0 + github.com/fluxcd/go-git/v5 v5.0.0-20221104190732-329fd6659b10 github.com/fluxcd/helm-controller/api v0.26.0 github.com/fluxcd/image-automation-controller/api v0.26.1 github.com/fluxcd/image-reflector-controller/api v0.22.1 @@ -28,7 +26,6 @@ require ( github.com/fluxcd/pkg/untar v0.2.0 github.com/fluxcd/pkg/version v0.2.0 github.com/fluxcd/source-controller/api v0.31.0 - github.com/go-git/go-git/v5 v5.4.2 github.com/gonvenience/bunt v1.3.4 github.com/gonvenience/ytbx v1.4.4 github.com/google/go-cmp v0.5.9 @@ -111,7 +108,6 @@ require ( github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/fatih/color v1.13.0 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fluxcd/go-git/v5 v5.0.0-20221104190732-329fd6659b10 // indirect github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect github.com/fluxcd/pkg/apis/kustomize v0.7.0 // indirect github.com/fluxcd/pkg/tar v0.2.0 // indirect @@ -119,6 +115,7 @@ require ( github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect + github.com/go-git/go-git/v5 v5.4.2 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect diff --git a/go.sum b/go.sum index 2e7a37320d..1c2c25ffeb 100644 --- a/go.sum +++ b/go.sum @@ -80,7 +80,8 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +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.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= @@ -203,8 +204,6 @@ github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg= github.com/fluxcd/go-git-providers v0.9.0 h1:iiiKe3dzRCgVkjEi8rfpvaWTZwuGRfb3RJFhjSNz+Uc= github.com/fluxcd/go-git-providers v0.9.0/go.mod h1:GcaDVP9RlamLKJp25Nwi7X5t0MyZV3FY+qy1GiRdbtk= -github.com/fluxcd/go-git/v5 v5.0.0-20221019082644-b33dae782906 h1:VFNX84BWt3r4YVFYLdNvryRwFBix2lea8EVT5V/xH7Y= -github.com/fluxcd/go-git/v5 v5.0.0-20221019082644-b33dae782906/go.mod h1:YpPgMNvxopDCZUuSFjkbcx/vWhCDvPsuoBCTTEd9dDc= github.com/fluxcd/go-git/v5 v5.0.0-20221104190732-329fd6659b10 h1:au798417R1iWtgcgKe3Dg495mexQmuxelL+NebAtexE= github.com/fluxcd/go-git/v5 v5.0.0-20221104190732-329fd6659b10/go.mod h1:w8bjt1WtWUxMEmlifjBJP9bK9QAG1Vw1Lw7RzchJFNk= github.com/fluxcd/helm-controller/api v0.26.0 h1:UCod+R1Oct2jg5cXHlVBC57Jy01lMdpl9MA+8UPogvY= @@ -259,10 +258,14 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= +github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= +github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= 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= @@ -596,6 +599,7 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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.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= @@ -630,7 +634,7 @@ github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtb github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74/go.mod h1:RmMWU37GKR2s6pgrIEB4ixgpVCt/cf7dnJv3fuH1J1c= github.com/xanzy/go-gitlab v0.73.1 h1:UMagqUZLJdjss1SovIC+kJCH4k2AZWXl58gJd38Y/hI= github.com/xanzy/go-gitlab v0.73.1/go.mod h1:d/a0vswScO7Agg1CZNz15Ic6SSvBG9vfw8egL99t4kA= -github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xanzy/ssh-agent v0.3.2 h1:eKj4SX2Fe7mui28ZgnFW5fmTz1EIr7ugo5s6wDxdHBM= github.com/xanzy/ssh-agent v0.3.2/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -665,13 +669,14 @@ go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -753,6 +758,7 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v 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/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-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -812,6 +818,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -844,8 +851,10 @@ golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= diff --git a/pkg/bootstrap/bootstrap_plain_git.go b/pkg/bootstrap/bootstrap_plain_git.go index 70f2f49a4e..8f137bbc0a 100644 --- a/pkg/bootstrap/bootstrap_plain_git.go +++ b/pkg/bootstrap/bootstrap_plain_git.go @@ -26,7 +26,7 @@ import ( "time" "github.com/ProtonMail/go-crypto/openpgp" - gogit "github.com/go-git/go-git/v5" + gogit "github.com/fluxcd/go-git/v5" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" From f8da3a1b448fc1c4484cf71c2c93da9da1cbb557 Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Thu, 10 Nov 2022 22:45:22 +0530 Subject: [PATCH 3/4] make gpg signing more robust for bootstrap Signed-off-by: Sanskar Jaiswal --- pkg/bootstrap/bootstrap_plain_git.go | 13 ++++++++++++- pkg/bootstrap/options.go | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pkg/bootstrap/bootstrap_plain_git.go b/pkg/bootstrap/bootstrap_plain_git.go index 8f137bbc0a..4583fe2f1c 100644 --- a/pkg/bootstrap/bootstrap_plain_git.go +++ b/pkg/bootstrap/bootstrap_plain_git.go @@ -431,6 +431,14 @@ func getOpenPgpEntity(keyRing openpgp.EntityList, passphrase, keyID string) (*op var entity *openpgp.Entity if keyID != "" { + if strings.HasPrefix(keyID, "0x") { + keyID = strings.TrimPrefix(keyID, "0x") + } + if len(keyID) != 16 { + return nil, fmt.Errorf("invalid GPG key id length; expected %d, got %d", 16, len(keyID)) + } + keyID = strings.ToUpper(keyID) + for _, ent := range keyRing { if ent.PrimaryKey.KeyIdString() == keyID { entity = ent @@ -438,7 +446,10 @@ func getOpenPgpEntity(keyRing openpgp.EntityList, passphrase, keyID string) (*op } if entity == nil { - return nil, fmt.Errorf("no GPG private key matching key id '%s' found", keyID) + return nil, fmt.Errorf("no GPG keyring matching key id '%s' found", keyID) + } + if entity.PrivateKey == nil { + return nil, fmt.Errorf("keyring does not contain private key for key id '%s'", keyID) } } else { entity = keyRing[0] diff --git a/pkg/bootstrap/options.go b/pkg/bootstrap/options.go index c9ea0f8132..8b6ee790ae 100644 --- a/pkg/bootstrap/options.go +++ b/pkg/bootstrap/options.go @@ -155,7 +155,7 @@ func LoadEntityListFromPath(path string) (openpgp.EntityList, error) { } entityList, err := openpgp.ReadKeyRing(r) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to read GPG key ring: %w", err) } return entityList, nil } From 35e1b5cbb9f951601588ad02776e7bf64d348122 Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Mon, 14 Nov 2022 19:32:35 +0530 Subject: [PATCH 4/4] add aws codecommit example and validation; azure devops example Signed-off-by: Sanskar Jaiswal --- cmd/flux/bootstrap_git.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/cmd/flux/bootstrap_git.go b/cmd/flux/bootstrap_git.go index 1721faf8cf..f5909788b9 100644 --- a/cmd/flux/bootstrap_git.go +++ b/cmd/flux/bootstrap_git.go @@ -60,6 +60,12 @@ command will perform an upgrade if needed.`, # Run bootstrap for a Git repository with a private key and password flux bootstrap git --url=ssh://git@example.com/repository.git --private-key-file= --password= + + # Run bootstrap for a Git repository on AWS CodeCommit + flux bootstrap git --url=ssh://@git-codecommit..amazonaws.com/v1/repos/ --private-key-file= --password= + + # Run bootstrap for a Git repository on Azure Devops + flux bootstrap git --url=ssh://git@ssh.dev.azure.com/v3/// --ssh-key-algorithm=rsa --ssh-rsa-bits=4096 `, RunE: bootstrapGitCmdRun, } @@ -115,6 +121,23 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { return err } + if strings.Contains(repositoryURL.Hostname(), "git-codecommit") && strings.Contains(repositoryURL.Hostname(), "amazonaws.com") { + if repositoryURL.Scheme == string(git.SSH) { + if repositoryURL.User == nil { + return fmt.Errorf("invalid AWS CodeCommit url: ssh username should be specified in the url") + } + if repositoryURL.User.Username() == git.DefaultPublicKeyAuthUser { + return fmt.Errorf("invalid AWS CodeCommit url: ssh username should be the SSH key ID for the provided private key") + } + if bootstrapArgs.privateKeyFile == "" { + return fmt.Errorf("private key file is required for bootstrapping against AWS CodeCommit using ssh") + } + } + if repositoryURL.Scheme == string(git.HTTPS) && !bootstrapArgs.tokenAuth { + return fmt.Errorf("--token-auth=true must be specified for using a HTTPS AWS CodeCommit url") + } + } + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() @@ -154,7 +177,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { } clientOpts := []gogit.ClientOption{gogit.WithDiskStorage()} - if authOpts.Transport == git.HTTP { + if gitArgs.insecureHttpAllowed { clientOpts = append(clientOpts, gogit.WithInsecureCredentialsOverHTTP()) } gitClient, err := gogit.NewClient(tmpDir, authOpts, clientOpts...)