Skip to content

Commit

Permalink
fix: Allow to delete repos with invalid urls (#20921)
Browse files Browse the repository at this point in the history
Fixes #20921

Normalization of repo url is attempted during repo deletion before comparison with existing repos. Before this change, it'd fail on invalid urls and return "", resulting in permission denied. This ended up in a state where people can add repos with invalid urls but couldn't delete them. Return raw repo url if url parsing failed. Add a test to validate the deletion can be performed and make sure it fails without the main change.

This needs to be cherry-picked to v2.11-2.13

Signed-off-by: Andrii Korotkov <[email protected]>
  • Loading branch information
andrii-korotkov-verkada committed Nov 27, 2024
1 parent 8bce61e commit 6ccd0fc
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
33 changes: 33 additions & 0 deletions server/repository/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
fakeapps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake"
appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions"
Expand Down Expand Up @@ -1119,3 +1120,35 @@ func TestGetRepository(t *testing.T) {
})
}
}

func TestDeleteRepository(t *testing.T) {
repositories := map[string]string{
"valid": "https://bitbucket.org/workspace/repo.git",
// Check a wrongly formatter repo as well, see https://github.com/argoproj/argo-cd/issues/20921
"invalid": "git clone https://bitbucket.org/workspace/repo.git",
}

kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret)
settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace)

for name, repo := range repositories {
t.Run(name, func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil)

repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)

db := &dbmocks.ArgoDB{}
db.On("DeleteRepository", context.TODO(), repo, "default").Return(nil)
db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: repo, Project: "default"}}, nil)
db.On("GetRepository", context.TODO(), repo, "default").Return(&appsv1.Repository{Repo: repo, Project: "default"}, nil)
appLister, projLister := newAppAndProjLister(defaultProj)

s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr)
resp, err := s.DeleteRepository(context.TODO(), &repository.RepoQuery{Repo: repo, AppProject: "default"})
require.NoError(t, err)
assert.Equal(t, repositorypkg.RepoResponse{}, *resp)
})
}
}
20 changes: 17 additions & 3 deletions util/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ func IsTruncatedCommitSHA(sha string) bool {

// SameURL returns whether or not the two repository URLs are equivalent in location
func SameURL(leftRepo, rightRepo string) bool {
normalLeft := NormalizeGitURL(leftRepo)
normalRight := NormalizeGitURL(rightRepo)
normalLeft := NormalizeGitURLAllowInvalid(leftRepo)
normalRight := NormalizeGitURLAllowInvalid(rightRepo)
return normalLeft != "" && normalRight != "" && normalLeft == normalRight
}

Expand All @@ -45,6 +45,16 @@ func SameURL(leftRepo, rightRepo string) bool {
// Prefer using SameURL() over this function when possible. This algorithm may change over time
// and should not be considered stable from release to release
func NormalizeGitURL(repo string) string {
return normalizeGitURL(repo, false)
}

// Similar to NormalizeGitURL, except returning a not fully normalized string when the url is invalid.
// Needed to allow a deletion of repos with invalid urls. See https://github.com/argoproj/argo-cd/issues/20921.
func NormalizeGitURLAllowInvalid(repo string) string {
return normalizeGitURL(repo, true)
}

func normalizeGitURL(repo string, allowInvalid bool) string {
repo = strings.ToLower(strings.TrimSpace(repo))
if yes, _ := IsSSHURL(repo); yes {
if !strings.HasPrefix(repo, "ssh://") {
Expand All @@ -57,7 +67,11 @@ func NormalizeGitURL(repo string) string {
repo = strings.TrimSuffix(repo, ".git")
repoURL, err := url.Parse(repo)
if err != nil {
return ""
if allowInvalid {
return repo
} else {
return ""
}
}
normalized := repoURL.String()
return strings.TrimPrefix(normalized, "ssh://")
Expand Down

0 comments on commit 6ccd0fc

Please sign in to comment.