-
Notifications
You must be signed in to change notification settings - Fork 5.2k
/
repository_types.go
302 lines (278 loc) · 14.5 KB
/
repository_types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
package v1alpha1
import (
"net/url"
"github.com/argoproj/argo-cd/v2/util/cert"
"github.com/argoproj/argo-cd/v2/util/git"
"github.com/argoproj/argo-cd/v2/util/helm"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// RepoCreds holds the definition for repository credentials
type RepoCreds struct {
// URL is the URL that this credentials matches to
URL string `json:"url" protobuf:"bytes,1,opt,name=url"`
// Username for authenticating at the repo server
Username string `json:"username,omitempty" protobuf:"bytes,2,opt,name=username"`
// Password for authenticating at the repo server
Password string `json:"password,omitempty" protobuf:"bytes,3,opt,name=password"`
// SSHPrivateKey contains the private key data for authenticating at the repo server using SSH (only Git repos)
SSHPrivateKey string `json:"sshPrivateKey,omitempty" protobuf:"bytes,4,opt,name=sshPrivateKey"`
// TLSClientCertData specifies the TLS client cert data for authenticating at the repo server
TLSClientCertData string `json:"tlsClientCertData,omitempty" protobuf:"bytes,5,opt,name=tlsClientCertData"`
// TLSClientCertKey specifies the TLS client cert key for authenticating at the repo server
TLSClientCertKey string `json:"tlsClientCertKey,omitempty" protobuf:"bytes,6,opt,name=tlsClientCertKey"`
// GithubAppPrivateKey specifies the private key PEM data for authentication via GitHub app
GithubAppPrivateKey string `json:"githubAppPrivateKey,omitempty" protobuf:"bytes,7,opt,name=githubAppPrivateKey"`
// GithubAppId specifies the Github App ID of the app used to access the repo for GitHub app authentication
GithubAppId int64 `json:"githubAppID,omitempty" protobuf:"bytes,8,opt,name=githubAppID"`
// GithubAppInstallationId specifies the ID of the installed GitHub App for GitHub app authentication
GithubAppInstallationId int64 `json:"githubAppInstallationID,omitempty" protobuf:"bytes,9,opt,name=githubAppInstallationID"`
// GithubAppEnterpriseBaseURL specifies the GitHub API URL for GitHub app authentication. If empty will default to https://api.github.com
GitHubAppEnterpriseBaseURL string `json:"githubAppEnterpriseBaseUrl,omitempty" protobuf:"bytes,10,opt,name=githubAppEnterpriseBaseUrl"`
// EnableOCI specifies whether helm-oci support should be enabled for this repo
EnableOCI bool `json:"enableOCI,omitempty" protobuf:"bytes,11,opt,name=enableOCI"`
// Type specifies the type of the repoCreds. Can be either "git" or "helm. "git" is assumed if empty or absent.
Type string `json:"type,omitempty" protobuf:"bytes,12,opt,name=type"`
}
// Repository is a repository holding application configurations
type Repository struct {
// Repo contains the URL to the remote repository
Repo string `json:"repo" protobuf:"bytes,1,opt,name=repo"`
// Username contains the user name used for authenticating at the remote repository
Username string `json:"username,omitempty" protobuf:"bytes,2,opt,name=username"`
// Password contains the password or PAT used for authenticating at the remote repository
Password string `json:"password,omitempty" protobuf:"bytes,3,opt,name=password"`
// SSHPrivateKey contains the PEM data for authenticating at the repo server. Only used with Git repos.
SSHPrivateKey string `json:"sshPrivateKey,omitempty" protobuf:"bytes,4,opt,name=sshPrivateKey"`
// ConnectionState contains information about the current state of connection to the repository server
ConnectionState ConnectionState `json:"connectionState,omitempty" protobuf:"bytes,5,opt,name=connectionState"`
// InsecureIgnoreHostKey should not be used anymore, Insecure is favoured
// Used only for Git repos
InsecureIgnoreHostKey bool `json:"insecureIgnoreHostKey,omitempty" protobuf:"bytes,6,opt,name=insecureIgnoreHostKey"`
// Insecure specifies whether the connection to the repository ignores any errors when verifying TLS certificates or SSH host keys
Insecure bool `json:"insecure,omitempty" protobuf:"bytes,7,opt,name=insecure"`
// EnableLFS specifies whether git-lfs support should be enabled for this repo. Only valid for Git repositories.
EnableLFS bool `json:"enableLfs,omitempty" protobuf:"bytes,8,opt,name=enableLfs"`
// TLSClientCertData contains a certificate in PEM format for authenticating at the repo server
TLSClientCertData string `json:"tlsClientCertData,omitempty" protobuf:"bytes,9,opt,name=tlsClientCertData"`
// TLSClientCertKey contains a private key in PEM format for authenticating at the repo server
TLSClientCertKey string `json:"tlsClientCertKey,omitempty" protobuf:"bytes,10,opt,name=tlsClientCertKey"`
// Type specifies the type of the repo. Can be either "git" or "helm. "git" is assumed if empty or absent.
Type string `json:"type,omitempty" protobuf:"bytes,11,opt,name=type"`
// Name specifies a name to be used for this repo. Only used with Helm repos
Name string `json:"name,omitempty" protobuf:"bytes,12,opt,name=name"`
// Whether credentials were inherited from a credential set
InheritedCreds bool `json:"inheritedCreds,omitempty" protobuf:"bytes,13,opt,name=inheritedCreds"`
// EnableOCI specifies whether helm-oci support should be enabled for this repo
EnableOCI bool `json:"enableOCI,omitempty" protobuf:"bytes,14,opt,name=enableOCI"`
// Github App Private Key PEM data
GithubAppPrivateKey string `json:"githubAppPrivateKey,omitempty" protobuf:"bytes,15,opt,name=githubAppPrivateKey"`
// GithubAppId specifies the ID of the GitHub app used to access the repo
GithubAppId int64 `json:"githubAppID,omitempty" protobuf:"bytes,16,opt,name=githubAppID"`
// GithubAppInstallationId specifies the installation ID of the GitHub App used to access the repo
GithubAppInstallationId int64 `json:"githubAppInstallationID,omitempty" protobuf:"bytes,17,opt,name=githubAppInstallationID"`
// GithubAppEnterpriseBaseURL specifies the base URL of GitHub Enterprise installation. If empty will default to https://api.github.com
GitHubAppEnterpriseBaseURL string `json:"githubAppEnterpriseBaseUrl,omitempty" protobuf:"bytes,18,opt,name=githubAppEnterpriseBaseUrl"`
// Proxy specifies the HTTP/HTTPS proxy used to access the repo
Proxy string `json:"proxy,omitempty" protobuf:"bytes,19,opt,name=proxy"`
// Reference between project and repository that allow you automatically to be added as item inside SourceRepos project entity
Project string `json:"project,omitempty" protobuf:"bytes,20,opt,name=project"`
}
// IsInsecure returns true if the repository has been configured to skip server verification
func (repo *Repository) IsInsecure() bool {
return repo.InsecureIgnoreHostKey || repo.Insecure
}
// IsLFSEnabled returns true if LFS support is enabled on repository
func (repo *Repository) IsLFSEnabled() bool {
return repo.EnableLFS
}
// HasCredentials returns true when the repository has been configured with any credentials
func (m *Repository) HasCredentials() bool {
return m.Username != "" || m.Password != "" || m.SSHPrivateKey != "" || m.TLSClientCertData != "" || m.GithubAppPrivateKey != ""
}
// CopyCredentialsFromRepo copies all credential information from source repository to receiving repository
func (repo *Repository) CopyCredentialsFromRepo(source *Repository) {
if source != nil {
if repo.Username == "" {
repo.Username = source.Username
}
if repo.Password == "" {
repo.Password = source.Password
}
if repo.SSHPrivateKey == "" {
repo.SSHPrivateKey = source.SSHPrivateKey
}
if repo.TLSClientCertData == "" {
repo.TLSClientCertData = source.TLSClientCertData
}
if repo.TLSClientCertKey == "" {
repo.TLSClientCertKey = source.TLSClientCertKey
}
if repo.GithubAppPrivateKey == "" {
repo.GithubAppPrivateKey = source.GithubAppPrivateKey
}
if repo.GithubAppId == 0 {
repo.GithubAppId = source.GithubAppId
}
if repo.GithubAppInstallationId == 0 {
repo.GithubAppInstallationId = source.GithubAppInstallationId
}
if repo.GitHubAppEnterpriseBaseURL == "" {
repo.GitHubAppEnterpriseBaseURL = source.GitHubAppEnterpriseBaseURL
}
}
}
// CopyCredentialsFrom copies credentials from given credential template to receiving repository
func (repo *Repository) CopyCredentialsFrom(source *RepoCreds) {
if source != nil {
if repo.Username == "" {
repo.Username = source.Username
}
if repo.Password == "" {
repo.Password = source.Password
}
if repo.SSHPrivateKey == "" {
repo.SSHPrivateKey = source.SSHPrivateKey
}
if repo.TLSClientCertData == "" {
repo.TLSClientCertData = source.TLSClientCertData
}
if repo.TLSClientCertKey == "" {
repo.TLSClientCertKey = source.TLSClientCertKey
}
if repo.GithubAppPrivateKey == "" {
repo.GithubAppPrivateKey = source.GithubAppPrivateKey
}
if repo.GithubAppId == 0 {
repo.GithubAppId = source.GithubAppId
}
if repo.GithubAppInstallationId == 0 {
repo.GithubAppInstallationId = source.GithubAppInstallationId
}
if repo.GitHubAppEnterpriseBaseURL == "" {
repo.GitHubAppEnterpriseBaseURL = source.GitHubAppEnterpriseBaseURL
}
}
}
// GetGitCreds returns the credentials from a repository configuration used to authenticate at a Git repository
func (repo *Repository) GetGitCreds(store git.CredsStore) git.Creds {
if repo == nil {
return git.NopCreds{}
}
if repo.Password != "" {
return git.NewHTTPSCreds(repo.Username, repo.Password, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, store)
}
if repo.SSHPrivateKey != "" {
return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure(), store)
}
if repo.GithubAppPrivateKey != "" && repo.GithubAppId != 0 && repo.GithubAppInstallationId != 0 {
return git.NewGitHubAppCreds(repo.GithubAppId, repo.GithubAppInstallationId, repo.GithubAppPrivateKey, repo.GitHubAppEnterpriseBaseURL, repo.Repo, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), store)
}
return git.NopCreds{}
}
// GetHelmCreds returns the credentials from a repository configuration used to authenticate at a Helm repository
func (repo *Repository) GetHelmCreds() helm.Creds {
return helm.Creds{
Username: repo.Username,
Password: repo.Password,
CAPath: getCAPath(repo.Repo),
CertData: []byte(repo.TLSClientCertData),
KeyData: []byte(repo.TLSClientCertKey),
InsecureSkipVerify: repo.Insecure,
}
}
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 receive the cert,
// otherwise we'll use the parsed path (OCI repos are often specified as
// hostname, without protocol).
if parsedURL, err := url.Parse(repoURL); err == nil {
if parsedURL.Scheme == "https" || parsedURL.Scheme == "oci" {
hostname = parsedURL.Host
} else if parsedURL.Scheme == "" {
hostname = parsedURL.Path
}
} else {
log.Warnf("Could not parse repo URL '%s': %v", repoURL, err)
}
if hostname != "" {
if caPath, err := cert.GetCertBundlePathForRepository(hostname); err == nil {
return caPath
} else {
log.Warnf("Could not get cert bundle path for repository '%s': %v", repoURL, err)
}
}
return ""
}
// CopySettingsFrom copies all repository settings from source to receiver
func (m *Repository) CopySettingsFrom(source *Repository) {
if source != nil {
m.EnableLFS = source.EnableLFS
m.InsecureIgnoreHostKey = source.InsecureIgnoreHostKey
m.Insecure = source.Insecure
m.InheritedCreds = source.InheritedCreds
}
}
// Repositories defines a list of Repository configurations
type Repositories []*Repository
// Filter returns a list of repositories, which only contain items matched by the supplied predicate method
func (r Repositories) Filter(predicate func(r *Repository) bool) Repositories {
var res Repositories
for i := range r {
repo := r[i]
if predicate(repo) {
res = append(res, repo)
}
}
return res
}
// RepositoryList is a collection of Repositories.
type RepositoryList struct {
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items Repositories `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// RepositoryList is a collection of Repositories.
type RepoCredsList struct {
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []RepoCreds `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// A RepositoryCertificate is either SSH known hosts entry or TLS certificate
type RepositoryCertificate struct {
// ServerName specifies the DNS name of the server this certificate is intended for
ServerName string `json:"serverName" protobuf:"bytes,1,opt,name=serverName"`
// CertType specifies the type of the certificate - currently one of "https" or "ssh"
CertType string `json:"certType" protobuf:"bytes,2,opt,name=certType"`
// CertSubType specifies the sub type of the cert, i.e. "ssh-rsa"
CertSubType string `json:"certSubType" protobuf:"bytes,3,opt,name=certSubType"`
// CertData contains the actual certificate data, dependent on the certificate type
CertData []byte `json:"certData" protobuf:"bytes,4,opt,name=certData"`
// CertInfo will hold additional certificate info, depdendent on the certificate type (e.g. SSH fingerprint, X509 CommonName)
CertInfo string `json:"certInfo" protobuf:"bytes,5,opt,name=certInfo"`
}
// RepositoryCertificateList is a collection of RepositoryCertificates
type RepositoryCertificateList struct {
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of certificates to be processed
Items []RepositoryCertificate `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// GnuPGPublicKey is a representation of a GnuPG public key
type GnuPGPublicKey struct {
// KeyID specifies the key ID, in hexadecimal string format
KeyID string `json:"keyID" protobuf:"bytes,1,opt,name=keyID"`
// Fingerprint is the fingerprint of the key
Fingerprint string `json:"fingerprint,omitempty" protobuf:"bytes,2,opt,name=fingerprint"`
// Owner holds the owner identification, e.g. a name and e-mail address
Owner string `json:"owner,omitempty" protobuf:"bytes,3,opt,name=owner"`
// Trust holds the level of trust assigned to this key
Trust string `json:"trust,omitempty" protobuf:"bytes,4,opt,name=trust"`
// SubType holds the key's sub type (e.g. rsa4096)
SubType string `json:"subType,omitempty" protobuf:"bytes,5,opt,name=subType"`
// KeyData holds the raw key data, in base64 encoded format
KeyData string `json:"keyData,omitempty" protobuf:"bytes,6,opt,name=keyData"`
}
// GnuPGPublicKeyList is a collection of GnuPGPublicKey objects
type GnuPGPublicKeyList struct {
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []GnuPGPublicKey `json:"items" protobuf:"bytes,2,rep,name=items"`
}