Skip to content

Commit 3bf1c43

Browse files
tls support for git provider in git cli
1 parent a8e6e8b commit 3bf1c43

File tree

15 files changed

+822
-577
lines changed

15 files changed

+822
-577
lines changed

api/GrpcHandler.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ func (impl *GrpcHandlerImpl) SaveGitProvider(ctx context.Context, req *pb.GitPro
8181
SshPrivateKey: req.SshPrivateKey,
8282
AuthMode: sql.AuthMode(req.AuthMode),
8383
Active: req.Active,
84+
CaCert: req.CaCert,
85+
TlsCert: req.TlsCert,
86+
TlsKey: req.TlsKey,
8487
}
8588

8689
_, err := impl.repositoryManager.SaveGitProvider(gitProvider)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.20
55
require (
66
github.com/caarlos0/env v3.5.0+incompatible
77
github.com/devtron-labs/common-lib v0.0.18-0.20240520062828-c6c38c3f135e
8-
github.com/devtron-labs/protos v0.0.3-0.20240130061723-7b2e12ab0abb
8+
github.com/devtron-labs/protos v0.0.3-0.20240613123522-f9b02995eb55
99
github.com/gammazero/workerpool v0.0.0-20200206003619-019d125201ab
1010
github.com/go-git/go-git/v5 v5.11.0
1111
github.com/go-pg/pg v6.15.1+incompatible

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ github.com/devtron-labs/common-lib v0.0.18-0.20240520062828-c6c38c3f135e h1:feRK
3131
github.com/devtron-labs/common-lib v0.0.18-0.20240520062828-c6c38c3f135e/go.mod h1:deAcJ5IjUjM6ozZQLJEgPWDUA0mKa632LBsKx8uM9TE=
3232
github.com/devtron-labs/protos v0.0.3-0.20240130061723-7b2e12ab0abb h1:CkfQQgZc950/hTPqtQSiHV2RmZgkBLGCzwR02FZYjAU=
3333
github.com/devtron-labs/protos v0.0.3-0.20240130061723-7b2e12ab0abb/go.mod h1:pjLjgoa1GzbkOkvbMyP4SAKsaiK7eG6GoQCNauG03JA=
34+
github.com/devtron-labs/protos v0.0.3-0.20240613123522-f9b02995eb55 h1:yB2S48rk6eNzva8tdxhWbpQ3jsJH+EhMKKE8bgGxdzk=
35+
github.com/devtron-labs/protos v0.0.3-0.20240613123522-f9b02995eb55/go.mod h1:ypUknVph8Ph4dxSlrFoouf7wLedQxHku2LQwgRrdgS4=
3436
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
3537
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
3638
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=

internals/sql/GitProviderRepository.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ type GitProvider struct {
3838
AccessToken string `sql:"access_token"`
3939
AuthMode AuthMode `sql:"auth_mode,notnull"`
4040
Active bool `sql:"active,notnull"`
41+
TlsCert string `sql:"tls_cert"`
42+
TlsKey string `sql:"tls_key"`
43+
CaCert string `sql:"ca_cert"`
4144
//models.AuditLog
4245
}
4346

pkg/RepoManages.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ func (impl RepoManagerImpl) updatePipelineMaterialCommit(gitCtx git.GitContext,
196196
}
197197

198198
gitCtx = gitCtx.WithCredentials(material.GitProvider.UserName, material.GitProvider.Password).
199+
WithTLSData(material.GitProvider.CaCert, material.GitProvider.TlsKey, material.GitProvider.TlsCert).
200+
WithGitProviderId(material.GitProviderId).
199201
WithCloningMode(impl.configuration.CloningMode)
200202

201203
fetchCount := impl.configuration.GitHistoryCount
@@ -352,6 +354,8 @@ func (impl RepoManagerImpl) checkoutMaterial(gitCtx git.GitContext, material *sq
352354
}
353355

354356
gitCtx = gitCtx.WithCredentials(userName, password).
357+
WithTLSData(material.GitProvider.CaCert, material.GitProvider.TlsKey, material.GitProvider.TlsCert).
358+
WithGitProviderId(material.GitProviderId).
355359
WithCloningMode(impl.configuration.CloningMode)
356360

357361
checkoutPath, _, _, err := impl.repositoryManager.GetCheckoutLocationFromGitUrl(material, gitCtx.CloningMode)
@@ -639,6 +643,8 @@ func (impl RepoManagerImpl) GetLatestCommitForBranch(gitCtx git.GitContext, pipe
639643
userName, password, err := git.GetUserNamePassword(gitMaterial.GitProvider)
640644

641645
gitCtx = gitCtx.WithCredentials(userName, password).
646+
WithTLSData(gitMaterial.GitProvider.CaCert, gitMaterial.GitProvider.TlsKey, gitMaterial.GitProvider.TlsCert).
647+
WithGitProviderId(gitMaterial.GitProviderId).
642648
WithCloningMode(impl.configuration.CloningMode)
643649

644650
updated, repo, err := impl.repositoryManager.Fetch(gitCtx, gitMaterial.Url, gitMaterial.CheckoutLocation)
@@ -708,6 +714,8 @@ func (impl RepoManagerImpl) GetCommitMetadataForPipelineMaterial(gitCtx git.GitC
708714
}
709715

710716
gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password).
717+
WithTLSData(gitMaterial.GitProvider.CaCert, gitMaterial.GitProvider.TlsKey, gitMaterial.GitProvider.TlsCert).
718+
WithGitProviderId(gitMaterial.GitProviderId).
711719
WithCloningMode(impl.configuration.CloningMode)
712720
// validate checkout status of gitMaterial
713721
if !gitMaterial.CheckoutStatus {
@@ -764,6 +772,8 @@ func (impl RepoManagerImpl) GetReleaseChanges(gitCtx git.GitContext, request *Re
764772
}()
765773

766774
gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password).
775+
WithTLSData(gitMaterial.GitProvider.CaCert, gitMaterial.GitProvider.TlsKey, gitMaterial.GitProvider.TlsCert).
776+
WithGitProviderId(gitMaterial.GitProviderId).
767777
WithCloningMode(impl.configuration.CloningMode)
768778

769779
gitChanges, err := impl.repositoryManagerAnalytics.ChangesSinceByRepositoryForAnalytics(gitCtx, gitMaterial.CheckoutLocation, request.OldCommit, request.NewCommit)

pkg/git/Bean.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,9 @@ type IteratorRequest struct {
333333
FromCommitHash string
334334
ToCommitHash string
335335
}
336+
337+
type TlsPathInfo struct {
338+
CaCertPath string
339+
TlsKeyPath string
340+
TlsCertPath string
341+
}

pkg/git/GitBaseManager.go

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,18 @@ func (impl *GitManagerBaseImpl) Fetch(gitCtx GitContext, rootDir string) (respon
110110
impl.logger.Debugw("git fetch ", "location", rootDir)
111111
cmd, cancel := impl.createCmdWithContext(gitCtx, "git", "-C", rootDir, "fetch", "origin", "--tags", "--force")
112112
defer cancel()
113-
output, errMsg, err := impl.runCommandWithCred(cmd, gitCtx.Username, gitCtx.Password)
113+
tlsPathInfo, err := createFilesForTlsData(gitCtx)
114+
if err != nil {
115+
//making it non-blocking
116+
impl.logger.Errorw("error encountered in createFilesForTlsData", "err", err)
117+
}
118+
defer impl.deleteTlsFiles(tlsPathInfo)
119+
output, errMsg, err := impl.runCommandWithCred(cmd, gitCtx.Username, gitCtx.Password, tlsPathInfo)
114120
if strings.Contains(output, LOCK_REF_MESSAGE) {
115121
impl.logger.Info("error in fetch, pruning local refs and retrying", "rootDir", rootDir)
116122
// running git remote prune origin and retrying fetch. gitHub issue - https://github.com/devtron-labs/devtron/issues/4605
117123
pruneCmd, pruneCmdCancel := impl.createCmdWithContext(gitCtx, "git", "-C", rootDir, "remote", "prune", "origin")
118-
pruneOutput, pruneMsg, pruneErr := impl.runCommandWithCred(pruneCmd, gitCtx.Username, gitCtx.Password)
124+
pruneOutput, pruneMsg, pruneErr := impl.runCommandWithCred(pruneCmd, gitCtx.Username, gitCtx.Password, tlsPathInfo)
119125
defer pruneCmdCancel()
120126
if pruneErr != nil {
121127
impl.logger.Errorw("error in pruning local refs that do not exist at remote")
@@ -125,7 +131,7 @@ func (impl *GitManagerBaseImpl) Fetch(gitCtx GitContext, rootDir string) (respon
125131
retryFetchCmd, retryFetchCancel := impl.createCmdWithContext(gitCtx, "git", "-C", rootDir, "fetch", "origin", "--tags", "--force")
126132
defer retryFetchCancel()
127133

128-
output, errMsg, err = impl.runCommandWithCred(retryFetchCmd, gitCtx.Username, gitCtx.Password)
134+
output, errMsg, err = impl.runCommandWithCred(retryFetchCmd, gitCtx.Username, gitCtx.Password, tlsPathInfo)
129135
}
130136
impl.logger.Debugw("fetch output", "root", rootDir, "opt", output, "errMsg", errMsg, "error", err)
131137
return output, errMsg, err
@@ -165,12 +171,33 @@ func (impl *GitManagerBaseImpl) LogMergeBase(gitCtx GitContext, rootDir, from st
165171
return commits, nil
166172
}
167173

168-
func (impl *GitManagerBaseImpl) runCommandWithCred(cmd *exec.Cmd, userName, password string) (response, errMsg string, err error) {
174+
func (impl *GitManagerBaseImpl) runCommandWithCred(cmd *exec.Cmd, userName, password string, tlsPathInfo *TlsPathInfo) (response, errMsg string, err error) {
169175
cmd.Env = append(os.Environ(),
170176
fmt.Sprintf("GIT_ASKPASS=%s", GIT_ASK_PASS),
171177
fmt.Sprintf("GIT_USERNAME=%s", userName),
172178
fmt.Sprintf("GIT_PASSWORD=%s", password),
173179
)
180+
if tlsPathInfo != nil {
181+
if tlsPathInfo.TlsKeyPath != "" && tlsPathInfo.TlsCertPath != "" {
182+
cmd.Env = append(cmd.Env,
183+
fmt.Sprintf("GIT_SSL_KEY=%s", tlsPathInfo.TlsKeyPath),
184+
fmt.Sprintf("GIT_SSL_CERT=%s", tlsPathInfo.TlsCertPath))
185+
}
186+
if tlsPathInfo.CaCertPath != "" {
187+
cmd.Env = append(cmd.Env, fmt.Sprintf("GIT_SSL_CAINFO=%s", tlsPathInfo.CaCertPath))
188+
}
189+
}
190+
return impl.runCommand(cmd)
191+
}
192+
193+
func (impl *GitManagerBaseImpl) runCommandWithTlsData(cmd *exec.Cmd, tlsPathInfo *TlsPathInfo) (response, errMsg string, err error) {
194+
if tlsPathInfo != nil {
195+
cmd.Env = append(os.Environ(),
196+
fmt.Sprintf("GIT_SSL_CAINFO=%s", tlsPathInfo.CaCertPath),
197+
fmt.Sprintf("GIT_SSL_KEY=%s", tlsPathInfo.TlsKeyPath),
198+
fmt.Sprintf("GIT_SSL_CERT=%s", tlsPathInfo.TlsCertPath),
199+
)
200+
}
174201
return impl.runCommand(cmd)
175202
}
176203

@@ -296,8 +323,13 @@ func (impl *GitManagerBaseImpl) FetchDiffStatBetweenCommits(gitCtx GitContext, o
296323
}
297324
cmd, cancel := impl.createCmdWithContext(gitCtx, "git", "-C", rootDir, "diff", "--numstat", oldHash, newHash)
298325
defer cancel()
299-
300-
output, errMsg, err := impl.runCommandWithCred(cmd, gitCtx.Username, gitCtx.Password)
326+
tlsPathInfo, err := createFilesForTlsData(gitCtx)
327+
if err != nil {
328+
//making it non-blocking
329+
impl.logger.Errorw("error encountered in createFilesForTlsData", "err", err)
330+
}
331+
defer impl.deleteTlsFiles(tlsPathInfo)
332+
output, errMsg, err := impl.runCommandWithCred(cmd, gitCtx.Username, gitCtx.Password, tlsPathInfo)
301333
impl.logger.Debugw("root", rootDir, "opt", output, "errMsg", errMsg, "error", err)
302334
if err != nil || len(errMsg) > 0 {
303335
impl.logger.Errorw("error in fetching fileStat diff btw commits: ", "oldHash", oldHash, "newHash", newHash, "checkoutPath", rootDir, "errorMsg", errMsg, "err", err)
@@ -333,6 +365,63 @@ func (impl *GitManagerBaseImpl) getCommandTimeout(command string) int {
333365
func (impl *GitManagerBaseImpl) ExecuteCustomCommand(gitContext GitContext, name string, arg ...string) (response, errMsg string, err error) {
334366
cmd, cancel := impl.createCmdWithContext(gitContext, name, arg...)
335367
defer cancel()
336-
output, errMsg, err := impl.runCommandWithCred(cmd, gitContext.Username, gitContext.Password)
368+
tlsPathInfo, err := createFilesForTlsData(gitContext)
369+
if err != nil {
370+
//making it non-blocking
371+
impl.logger.Errorw("error encountered in createFilesForTlsData", "err", err)
372+
}
373+
defer impl.deleteTlsFiles(tlsPathInfo)
374+
output, errMsg, err := impl.runCommandWithCred(cmd, gitContext.Username, gitContext.Password, tlsPathInfo)
337375
return output, errMsg, err
338376
}
377+
378+
func createFilesForTlsData(gitContext GitContext) (*TlsPathInfo, error) {
379+
var tlsKeyFilePath string
380+
var tlsCertFilePath string
381+
var caCertFilePath string
382+
var err error
383+
if gitContext.TLSKey != "" && gitContext.TLSCertificate != "" {
384+
tlsKeyFilePath, err = CreateTlsPathFilesWithData(gitContext.GitProviderId, gitContext.TLSKey, TLS_KEY_FILE_NAME)
385+
if err != nil {
386+
return nil, err
387+
}
388+
tlsCertFilePath, err = CreateTlsPathFilesWithData(gitContext.GitProviderId, gitContext.TLSCertificate, TLS_CERT_FILE_NAME)
389+
if err != nil {
390+
return nil, err
391+
}
392+
}
393+
if gitContext.CACert != "" {
394+
caCertFilePath, err = CreateTlsPathFilesWithData(gitContext.GitProviderId, gitContext.CACert, CA_CERT_FILE_NAME)
395+
if err != nil {
396+
return nil, err
397+
}
398+
}
399+
return BuildTlsInfoPath(caCertFilePath, tlsKeyFilePath, tlsCertFilePath), nil
400+
401+
}
402+
403+
func (impl *GitManagerBaseImpl) deleteTlsFiles(pathInfo *TlsPathInfo) {
404+
if pathInfo == nil {
405+
return
406+
}
407+
if pathInfo.TlsKeyPath != "" {
408+
err := DeleteAFileIfExists(pathInfo.TlsKeyPath)
409+
if err != nil {
410+
impl.logger.Errorw("error in deleting file", "tlsKeyPath", pathInfo.TlsKeyPath, "err", err)
411+
}
412+
}
413+
414+
if pathInfo.TlsCertPath != "" {
415+
err := DeleteAFileIfExists(pathInfo.TlsCertPath)
416+
if err != nil {
417+
impl.logger.Errorw("error in deleting file", "TlsCertPath", pathInfo.TlsCertPath, "err", err)
418+
}
419+
}
420+
if pathInfo.CaCertPath != "" {
421+
err := DeleteAFileIfExists(pathInfo.CaCertPath)
422+
if err != nil {
423+
impl.logger.Errorw("error in deleting file", "CaCertPath", pathInfo.CaCertPath, "err", err)
424+
}
425+
}
426+
return
427+
}

pkg/git/GitContextUtils.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ type GitContext struct {
2626
Username string
2727
Password string
2828
CloningMode string
29+
CACert string
30+
TLSKey string
31+
TLSCertificate string
32+
GitProviderId int
2933
}
3034

3135
func (gitCtx GitContext) WithCredentials(Username string, Password string) GitContext {
@@ -34,6 +38,18 @@ func (gitCtx GitContext) WithCredentials(Username string, Password string) GitCo
3438
return gitCtx
3539
}
3640

41+
func (gitCtx GitContext) WithTLSData(caData string, tlsKey string, tlsCertificate string) GitContext {
42+
gitCtx.CACert = caData
43+
gitCtx.TLSKey = tlsKey
44+
gitCtx.TLSCertificate = tlsCertificate
45+
return gitCtx
46+
}
47+
48+
func (gitCtx GitContext) WithGitProviderId(gitProviderId int) GitContext {
49+
gitCtx.GitProviderId = gitProviderId
50+
return gitCtx
51+
}
52+
3753
func BuildGitContext(ctx context.Context) GitContext {
3854
return GitContext{
3955
Context: ctx,

pkg/git/Util.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ import (
3030
const (
3131
GIT_BASE_DIR = "/git-base/"
3232
SSH_PRIVATE_KEY_DIR = GIT_BASE_DIR + "ssh-keys/"
33+
TLS_FILES_DIR = GIT_BASE_DIR + "tls-files/"
3334
SSH_PRIVATE_KEY_FILE_NAME = "ssh_pvt_key"
35+
TLS_KEY_FILE_NAME = "tls_key"
36+
TLS_CERT_FILE_NAME = "tls_cert"
37+
CA_CERT_FILE_NAME = "ca_cert"
3438
CLONE_TIMEOUT_SEC = 600
3539
FETCH_TIMEOUT_SEC = 30
3640
GITHUB_PROVIDER = "github.com"
@@ -122,6 +126,36 @@ func CreateOrUpdateSshPrivateKeyOnDisk(gitProviderId int, sshPrivateKeyContent s
122126
return nil
123127
}
124128

129+
func CreateTlsPathFilesWithData(gitProviderId int, content string, fileName string) (string, error) {
130+
tlsFolderPath := path.Join(TLS_FILES_DIR, strconv.Itoa(gitProviderId))
131+
tlsFilePath := path.Join(tlsFolderPath, fileName)
132+
133+
// if file exists then delete file
134+
if _, err := os.Stat(tlsFilePath); os.IsExist(err) {
135+
os.Remove(tlsFilePath)
136+
}
137+
// create dirs
138+
err := os.MkdirAll(tlsFolderPath, 0755)
139+
if err != nil {
140+
return "", err
141+
}
142+
143+
// create file with content
144+
err = ioutil.WriteFile(tlsFilePath, []byte(content), 0600)
145+
if err != nil {
146+
return "", err
147+
}
148+
return tlsFilePath, nil
149+
}
150+
151+
func DeleteAFileIfExists(path string) error {
152+
if _, err := os.Stat(path); os.IsExist(err) {
153+
err = os.Remove(path)
154+
return err
155+
}
156+
return nil
157+
}
158+
125159
// sample commitDiff :=4\t3\tModels/models.go\n2\t2\tRepository/Repository.go\n0\t2\main.go
126160
func getFileStat(commitDiff string) (FileStats, error) {
127161
filestat := FileStats{}

pkg/git/Watcher.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ func (impl GitWatcherImpl) pollGitMaterialAndNotify(material *sql.GitMaterial) e
194194
}
195195
gitCtx := BuildGitContext(context.Background()).
196196
WithCredentials(userName, password).
197+
WithTLSData(gitProvider.CaCert, gitProvider.TlsKey, gitProvider.TlsCert).
198+
WithGitProviderId(gitProvider.Id).
197199
WithCloningMode(impl.configuration.CloningMode)
198200

199201
updated, repo, err := impl.FetchAndUpdateMaterial(gitCtx, material, location)

0 commit comments

Comments
 (0)