From 5638e709291da89d2de823ad8a6a11ed1683af73 Mon Sep 17 00:00:00 2001 From: "gcp-cherry-pick-bot[bot]" <98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:48:32 -0400 Subject: [PATCH] fix: Parse hostname correctly from repoURL to fetch correct CA cert (#19488) (#19603) Signed-off-by: Siddhesh Ghadi Co-authored-by: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Co-authored-by: Jann Fischer --- .../application/v1alpha1/repository_types.go | 22 ++++++++++--------- pkg/apis/application/v1alpha1/types_test.go | 11 ++++++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/pkg/apis/application/v1alpha1/repository_types.go b/pkg/apis/application/v1alpha1/repository_types.go index 3a557813d87c6..e15f74d188429 100644 --- a/pkg/apis/application/v1alpha1/repository_types.go +++ b/pkg/apis/application/v1alpha1/repository_types.go @@ -3,6 +3,7 @@ package v1alpha1 import ( "fmt" "net/url" + "strings" "github.com/argoproj/argo-cd/v2/util/cert" "github.com/argoproj/argo-cd/v2/util/git" @@ -227,21 +228,22 @@ func getCAPath(repoURL string) string { } hostname := "" - // url.Parse() will happily parse most things thrown at it. When the URL - // is either https or oci, we use the parsed hostname to retrieve the cert, - // otherwise we'll use the parsed path (OCI repos are often specified as - // hostname, without protocol). - parsedURL, err := url.Parse(repoURL) + var parsedURL *url.URL + var err error + // Without schema in url, url.Parse() treats the url as differently + // and may incorrectly parses the hostname if url contains a path or port. + // To ensure proper parsing, prepend a dummy schema. + if !strings.Contains(repoURL, "://") { + parsedURL, err = url.Parse("protocol://" + repoURL) + } else { + parsedURL, err = url.Parse(repoURL) + } if err != nil { log.Warnf("Could not parse repo URL '%s': %v", repoURL, err) return "" } - if parsedURL.Scheme == "https" || parsedURL.Scheme == "oci" { - hostname = parsedURL.Host - } else if parsedURL.Scheme == "" { - hostname = parsedURL.Path - } + hostname = parsedURL.Hostname() if hostname == "" { log.Warnf("Could not get hostname for repository '%s'", repoURL) return "" diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go index 5a16a44876c27..50d92d1234804 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -3170,18 +3170,25 @@ func TestGetCAPath(t *testing.T) { "https://foo.example.com", "oci://foo.example.com", "foo.example.com", + "foo.example.com/charts", + "https://foo.example.com:5000", + "foo.example.com:5000", + "foo.example.com:5000/charts", + "ssh://foo.example.com", } invalidpath := []string{ "https://bar.example.com", "oci://bar.example.com", "bar.example.com", - "ssh://foo.example.com", - "git@example.com:organization/reponame.git", + "ssh://bar.example.com", + "git@foo.example.com:organization/reponame.git", + "ssh://git@foo.example.com:organization/reponame.git", "/some/invalid/thing", "../another/invalid/thing", "./also/invalid", "$invalid/as/well", "..", + "://invalid", } for _, str := range validcert {