From 161a7c5d87bdd64086149c0b050de7c11b0a1ded Mon Sep 17 00:00:00 2001 From: Jake Heath <76011913+jakeyheath@users.noreply.github.com> Date: Fri, 15 Jul 2022 14:34:57 -0700 Subject: [PATCH] feat: allowing fogg to run with a github app token (#679) --- util/module_storage.go | 41 +++++++++++++++++++++++++++++++++++-- util/module_storage_test.go | 14 +++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/util/module_storage.go b/util/module_storage.go index db6438941..4559b58c6 100644 --- a/util/module_storage.go +++ b/util/module_storage.go @@ -112,17 +112,54 @@ func convertSSHToGithubHTTPURL(sURL, token string) string { return fmt.Sprintf("git::%s", u.String()) } +// Changes a URL to use the git protocol over HTTPS instead of SSH. +// If the URL was not a remote URL or an git/SSH protocol, +// it will return the path that was passed in. If it does +// convert it properly, it will add Github credentials to the path +func convertSSHToGithubAppHTTPURL(sURL, token string) string { + // only detect the remote destinations + s, err := getter.Detect(sURL, token, []getter.Detector{ + &getter.GitLabDetector{}, + &getter.GitHubDetector{}, + &getter.GitDetector{}, + &getter.BitBucketDetector{}, + &getter.S3Detector{}, + &getter.GCSDetector{}, + }) + if err != nil { + logrus.Debug(err) + return sURL + } + + splits := strings.Split(s, "git::ssh://git@") + if len(splits) != 2 { + return sURL + } + u, err := url.Parse(fmt.Sprintf("https://%s", splits[1])) + if err != nil { + logrus.Debug(err) + return sURL + } + u.User = url.UserPassword("x-access-token", token) + + // we want to force the git protocol + return fmt.Sprintf("git::%s", u.String()) +} + func MakeDownloader(src string) (*Downloader, error) { type HTTPAuth struct { - GithubToken *string + GithubToken *string + GithubAppToken *string } var httpAuth HTTPAuth err := envconfig.Process("fogg", &httpAuth) if err != nil { - return nil, errs.WrapUser(err, "unable to get env FOGG_GITHUBTOKEN flag") + return nil, errs.WrapUser(err, "unable to parse Github tokens") } if httpAuth.GithubToken != nil { src = convertSSHToGithubHTTPURL(src, *httpAuth.GithubToken) + } else if httpAuth.GithubAppToken != nil { + src = convertSSHToGithubAppHTTPURL(src, *httpAuth.GithubAppToken) } return &Downloader{Source: src}, nil } diff --git a/util/module_storage_test.go b/util/module_storage_test.go index ba1596a92..c74f6bd40 100644 --- a/util/module_storage_test.go +++ b/util/module_storage_test.go @@ -61,6 +61,20 @@ func TestMakeDownloader(t *testing.T) { r.Equal(fmt.Sprintf("git::https://%s@github.com/chanzuckerberg/test-repo//terraform/modules/eks-airflow?ref=v0.80.0", creds), downloader.Source) } +func TestMakeDownloaderGithubApp(t *testing.T) { + r := require.New(t) + creds := "REDACTED" + downloader, err := MakeDownloader("git@github.com:chanzuckerberg/test-repo//terraform/modules/eks-airflow?ref=v0.80.0") + r.NoError(err) + r.Equal("git@github.com:chanzuckerberg/test-repo//terraform/modules/eks-airflow?ref=v0.80.0", downloader.Source) + + os.Setenv("FOGG_GITHUBAPPTOKEN", creds) + defer os.Unsetenv("FOGG_GITHUBAPPTOKEN") + downloader, err = MakeDownloader("git@github.com:chanzuckerberg/test-repo//terraform/modules/eks-airflow?ref=v0.80.0") + r.NoError(err) + r.Equal(fmt.Sprintf("git::https://x-access-token:%s@github.com/chanzuckerberg/test-repo//terraform/modules/eks-airflow?ref=v0.80.0", creds), downloader.Source) +} + func TestConvertSSHToHTTP(t *testing.T) { r := require.New(t)