@@ -3,15 +3,18 @@ package argocd
33import (
44 "context"
55 "fmt"
6+ "net/url"
67 "strconv"
78 "strings"
89
910 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
11+ "github.com/argoproj/argo-cd/v2/util/cert"
1012 "github.com/argoproj/argo-cd/v2/util/db"
1113 "github.com/argoproj/argo-cd/v2/util/settings"
1214
1315 "github.com/argoproj-labs/argocd-image-updater/ext/git"
1416 "github.com/argoproj-labs/argocd-image-updater/pkg/kube"
17+ "github.com/argoproj-labs/argocd-image-updater/pkg/log"
1518)
1619
1720// getGitCredsSource returns git credentials source that loads credentials from the secret or from Argo CD settings
@@ -43,7 +46,69 @@ func getCredsFromArgoCD(wbc *WriteBackConfig, kubeClient *kube.KubernetesClient)
4346 if ! repo .HasCredentials () {
4447 return nil , fmt .Errorf ("credentials for '%s' are not configured in Argo CD settings" , wbc .GitRepo )
4548 }
46- return repo .GetGitCreds (git.NoopCredsStore {}), nil
49+ creds := GetGitCreds (repo , wbc .GitCreds )
50+ return creds , nil
51+ }
52+
53+ // GetGitCreds returns the credentials from a repository configuration used to authenticate at a Git repository
54+ // This is a slightly modified version of upstream's Repository.GetGitCreds method. We need it so it does not return the upstream type.
55+ // TODO(jannfis): Can be removed once we have the change to the git client's getGitAskPassEnv upstream.
56+ func GetGitCreds (repo * v1alpha1.Repository , store git.CredsStore ) git.Creds {
57+ if repo == nil {
58+ return git.NopCreds {}
59+ }
60+ if repo .Password != "" {
61+ return git .NewHTTPSCreds (repo .Username , repo .Password , repo .TLSClientCertData , repo .TLSClientCertKey , repo .IsInsecure (), repo .Proxy , store , repo .ForceHttpBasicAuth )
62+ }
63+ if repo .SSHPrivateKey != "" {
64+ return git .NewSSHCreds (repo .SSHPrivateKey , getCAPath (repo .Repo ), repo .IsInsecure (), store , repo .Proxy )
65+ }
66+ if repo .GithubAppPrivateKey != "" && repo .GithubAppId != 0 && repo .GithubAppInstallationId != 0 {
67+ return git .NewGitHubAppCreds (repo .GithubAppId , repo .GithubAppInstallationId , repo .GithubAppPrivateKey , repo .GitHubAppEnterpriseBaseURL , repo .Repo , repo .TLSClientCertData , repo .TLSClientCertKey , repo .IsInsecure (), repo .Proxy , store )
68+ }
69+ if repo .GCPServiceAccountKey != "" {
70+ return git .NewGoogleCloudCreds (repo .GCPServiceAccountKey , store )
71+ }
72+ return git.NopCreds {}
73+ }
74+
75+ // Taken from upstream Argo CD.
76+ // TODO(jannfis): Can be removed once we have the change to the git client's getGitAskPassEnv upstream.
77+ func getCAPath (repoURL string ) string {
78+ // For git ssh protocol url without ssh://, url.Parse() will fail to parse.
79+ // However, no warn log is output since ssh scheme url is a possible format.
80+ if ok , _ := git .IsSSHURL (repoURL ); ok {
81+ return ""
82+ }
83+
84+ hostname := ""
85+ // url.Parse() will happily parse most things thrown at it. When the URL
86+ // is either https or oci, we use the parsed hostname to retrieve the cert,
87+ // otherwise we'll use the parsed path (OCI repos are often specified as
88+ // hostname, without protocol).
89+ parsedURL , err := url .Parse (repoURL )
90+ if err != nil {
91+ log .Warnf ("Could not parse repo URL '%s': %v" , repoURL , err )
92+ return ""
93+ }
94+ if parsedURL .Scheme == "https" || parsedURL .Scheme == "oci" {
95+ hostname = parsedURL .Host
96+ } else if parsedURL .Scheme == "" {
97+ hostname = parsedURL .Path
98+ }
99+
100+ if hostname == "" {
101+ log .Warnf ("Could not get hostname for repository '%s'" , repoURL )
102+ return ""
103+ }
104+
105+ caPath , err := cert .GetCertBundlePathForRepository (hostname )
106+ if err != nil {
107+ log .Warnf ("Could not get cert bundle path for repository '%s': %v" , repoURL , err )
108+ return ""
109+ }
110+
111+ return caPath
47112}
48113
49114// getCredsFromSecret loads repository credentials from secret
0 commit comments