-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from utilitywarehouse/as-git-url
add support for git scp style URL
- Loading branch information
Showing
3 changed files
with
119 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
|
@@ -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 = "" | ||
} | ||
|
@@ -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 { | ||
|
@@ -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") | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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", | ||
|
@@ -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 | ||
|