@@ -3,15 +3,18 @@ package argocd
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "net/url"
6
7
"strconv"
7
8
"strings"
8
9
9
10
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
11
+ "github.com/argoproj/argo-cd/v2/util/cert"
10
12
"github.com/argoproj/argo-cd/v2/util/db"
11
13
"github.com/argoproj/argo-cd/v2/util/settings"
12
14
13
15
"github.com/argoproj-labs/argocd-image-updater/ext/git"
14
16
"github.com/argoproj-labs/argocd-image-updater/pkg/kube"
17
+ "github.com/argoproj-labs/argocd-image-updater/pkg/log"
15
18
)
16
19
17
20
// 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)
43
46
if ! repo .HasCredentials () {
44
47
return nil , fmt .Errorf ("credentials for '%s' are not configured in Argo CD settings" , wbc .GitRepo )
45
48
}
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
47
112
}
48
113
49
114
// getCredsFromSecret loads repository credentials from secret
0 commit comments