Skip to content

Commit

Permalink
Merge pull request #14 from utilitywarehouse/as-git-url
Browse files Browse the repository at this point in the history
add support for git scp style URL
  • Loading branch information
asiyani authored Feb 27, 2023
2 parents e325513 + 8447282 commit 96c3c75
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ USER root
ENV ARGOCD_USER_ID=999

RUN adduser -S -H -u $ARGOCD_USER_ID argocd \
&& apk --no-cache add git git-lfs
&& apk --no-cache add git openssh-client git-lfs

COPY --from=build \
/usr/local/bin/kustomize \
Expand Down
47 changes: 33 additions & 14 deletions git-ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const (
)

var (
reKeyName = regexp.MustCompile(`#.*?argocd-voodoobox-plugin:\s*?(?P<keyName>\w+)`)
reRepoAddressWithSSH = regexp.MustCompile(`(?P<beginning>^\s*-\s*ssh:\/\/)(?P<domain>\w.+?)(?P<repoDetails>\/.*$)`)
reKeyName = regexp.MustCompile(`#.*?argocd-voodoobox-plugin:\s*?(?P<keyName>\w+)`)
reRepoURLWithSSH = regexp.MustCompile(`(?P<beginning>^\s*-\s*(?:ssh:\/\/)?)(?P<user>\w.+?@)?(?P<domain>\w.+?)(?P<repoDetails>[\/:].*$)`)
)

func setupGitSSH(ctx context.Context, cwd string, app applicationInfo) (string, error) {
Expand Down Expand Up @@ -154,25 +154,22 @@ func updateRepoBaseAddresses(in io.Reader) (map[string]string, []byte, error) {
keyName = s[reKeyName.SubexpIndex("keyName")]
}

case keyName != "" && !reRepoAddressWithSSH.MatchString(l):
return nil, nil, fmt.Errorf("found key reference in comment but next remote base url doesn't contain ssh://")
case keyName != "" && !reRepoURLWithSSH.MatchString(l):
return nil, nil, fmt.Errorf("found key reference in comment but next remote base url is not a valid SSH URL")

// referencing key is not mandatory since only 1 key can be used for all private base
// case keyName == "" && reRepoAddressWithSSH.MatchString(l):
// return nil, nil, fmt.Errorf("found remote base url with ssh protocol without referenced key comment above")

case keyName != "" && reRepoAddressWithSSH.MatchString(l):
case keyName != "" && reRepoURLWithSSH.MatchString(l):
// If Key if found replace domain
sections := reRepoAddressWithSSH.FindStringSubmatch(l)
if len(sections) != 4 {
new, domain, err := replaceDomainWithConfigHostName(l, keyName)
if err != nil {
return nil, nil, fmt.Errorf("error parsing remote base url")
}
domain := sections[reRepoAddressWithSSH.SubexpIndex("domain")]
keyedDomains[keyName] = domain

l = sections[reRepoAddressWithSSH.SubexpIndex("beginning")] +
keyName + "_" + strings.ReplaceAll(domain, ".", "_") +
sections[reRepoAddressWithSSH.SubexpIndex("repoDetails")]
l = new
keyedDomains[keyName] = domain

keyName = ""
}
Expand All @@ -184,6 +181,28 @@ func updateRepoBaseAddresses(in io.Reader) (map[string]string, []byte, error) {
return keyedDomains, out, nil
}

func replaceDomainWithConfigHostName(original string, keyName string) (string, string, error) {
sections := reRepoURLWithSSH.FindStringSubmatch(original)
if len(sections) != 4 && len(sections) != 5 {
return "", "", fmt.Errorf("error parsing remote base url")
}

// URL should be either ssh:// or [email protected]
// need to do check because in our regex both are optional
if !strings.Contains(sections[reRepoURLWithSSH.SubexpIndex("beginning")], "ssh://") &&
sections[reRepoURLWithSSH.SubexpIndex("user")] == "" {
return "", "", fmt.Errorf("private remote URL should either contain ssh:// or user@ i.e. git@domain")
}

domain := sections[reRepoURLWithSSH.SubexpIndex("domain")]
newURL := sections[reRepoURLWithSSH.SubexpIndex("beginning")] +
sections[reRepoURLWithSSH.SubexpIndex("user")] +
keyName + "_" + strings.ReplaceAll(domain, ".", "_") +
sections[reRepoURLWithSSH.SubexpIndex("repoDetails")]

return newURL, domain, nil
}

func constructSSHConfig(keyFilePaths map[string]string, keyedDomain map[string]string) ([]byte, error) {
if len(keyFilePaths) == 1 {
for _, keyFilePath := range keyFilePaths {
Expand All @@ -198,8 +217,8 @@ func constructSSHConfig(keyFilePaths map[string]string, keyedDomain map[string]s
return nil, fmt.Errorf("unable to find path for key:%s, please make sure all referenced keys are added to git ssh secret", keyName)
}

keyedDomain := keyName + "_" + strings.ReplaceAll(domain, ".", "_")
hostFragments = append(hostFragments, fmt.Sprintf(hostFragment, keyedDomain, domain, keyFilePath))
host := keyName + "_" + strings.ReplaceAll(domain, ".", "_")
hostFragments = append(hostFragments, fmt.Sprintf(hostFragment, host, domain, keyFilePath))
}
if len(hostFragments) == 0 {
return nil, fmt.Errorf("keys are not referenced, please reference keys on remote base url in kustomize file")
Expand Down
87 changes: 85 additions & 2 deletions git-ssh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,16 @@ resources:
# argocd-voodoobox-plugin: key_a
- ssh://github.com/org/repo1//manifests/lab-foo?ref=master
# argocd-voodoobox-plugin:keyD
- ssh://github.com/org/repo3//manifests/lab-zoo?ref=dev
- ssh://git@github.com/org/repo3//manifests/lab-zoo?ref=dev
# argocd-voodoobox-plugin: sshKeyB
- ssh://gitlab.io/org/repo2//manifests/lab-bar?ref=main
# argocd-voodoobox-plugin: key_c
- ssh://bitbucket.org/org/repo3//manifests/lab-zoo?ref=dev
# scp github url with git suffix
# argocd-voodoobox-plugin: key_e
- ssh://[email protected]:someorg/somerepo.git/somedir
# argocd-voodoobox-plugin: key_f
- [email protected]:owner/repo
`)},
wantOut: []byte(`apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
Expand All @@ -51,17 +56,24 @@ resources:
# argocd-voodoobox-plugin: key_a
- ssh://key_a_github_com/org/repo1//manifests/lab-foo?ref=master
# argocd-voodoobox-plugin:keyD
- ssh://keyD_github_com/org/repo3//manifests/lab-zoo?ref=dev
- ssh://git@keyD_github_com/org/repo3//manifests/lab-zoo?ref=dev
# argocd-voodoobox-plugin: sshKeyB
- ssh://sshKeyB_gitlab_io/org/repo2//manifests/lab-bar?ref=main
# argocd-voodoobox-plugin: key_c
- ssh://key_c_bitbucket_org/org/repo3//manifests/lab-zoo?ref=dev
# scp github url with git suffix
# argocd-voodoobox-plugin: key_e
- ssh://git@key_e_github_com:someorg/somerepo.git/somedir
# argocd-voodoobox-plugin: key_f
- git@key_f_github_com:owner/repo
`),
wantKeyMap: map[string]string{
"key_a": "github.com",
"sshKeyB": "gitlab.io",
"key_c": "bitbucket.org",
"keyD": "github.com",
"key_e": "github.com",
"key_f": "github.com",
},
}, {
name: "valid-with-empty-line",
Expand Down Expand Up @@ -197,6 +209,77 @@ resources:
}
}

func Test_replaceDomainWithConfigHostName(t *testing.T) {
type args struct {
original string
keyName string
}
tests := []struct {
name string
args args
url string
domain string
wantErr bool
}{
{
"empty",
args{"", ""},
"", "", true,
}, {
"non-ssh",
args{" - github.com/org/open1//manifests/lab-foo?ref=master", "keyA"},
"", "", true,
}, {
"valid",
args{" - ssh://github.com/org/repo1//manifests/lab-foo?ref=master", "keyB"},
" - ssh://keyB_github_com/org/repo1//manifests/lab-foo?ref=master", "github.com", false,
}, {
"valid with git user",
args{" - ssh://[email protected]/org/repo3//manifests/lab-zoo?ref=dev", "keyC"},
" - ssh://git@keyC_github_com/org/repo3//manifests/lab-zoo?ref=dev", "github.com", false,
}, {
"valid with diff user",
args{" - ssh://[email protected]/org/repo3//manifests/lab-zoo?ref=dev", "keyC"},
" - ssh://user1@keyC_github_com/org/repo3//manifests/lab-zoo?ref=dev", "github.com", false,
}, {
"valid diff domain",
args{" - ssh://gitlab.io/org/repo2//manifests/lab-bar?ref=main", "keyD"},
" - ssh://keyD_gitlab_io/org/repo2//manifests/lab-bar?ref=main", "gitlab.io", false,
}, {
"valid diff domain2",
args{" - ssh://bitbucket.org/org/repo3//manifests/lab-zoo?ref=dev", "keyE"},
" - ssh://keyE_bitbucket_org/org/repo3//manifests/lab-zoo?ref=dev", "bitbucket.org", false,
}, {
"valid with :",
args{" - ssh://[email protected]:someorg/somerepo.git/somedir", "keyF"},
" - ssh://git@keyF_github_com:someorg/somerepo.git/somedir", "github.com", false,
}, {
"valid without ssh",
args{" - [email protected]:someorg/somerepo.git/somedir", "keyG"},
" - git@keyG_github_com:someorg/somerepo.git/somedir", "github.com", false,
}, {
"valid without ssh and diff user",
args{" - [email protected]:someorg/somerepo.git/somedir", "keyG"},
" - bob@keyG_github_com:someorg/somerepo.git/somedir", "github.com", false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1, err := replaceDomainWithConfigHostName(tt.args.original, tt.args.keyName)
if (err != nil) != tt.wantErr {
t.Errorf("replaceDomainWithConfigHostName() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.url {
t.Errorf("replaceDomainWithConfigHostName() got = %v, want %v", got, tt.url)
}
if got1 != tt.domain {
t.Errorf("replaceDomainWithConfigHostName() got1 = %v, want %v", got1, tt.domain)
}
})
}
}

func Test_constructSSHConfig(t *testing.T) {
type args struct {
keyFilePaths map[string]string
Expand Down

0 comments on commit 96c3c75

Please sign in to comment.