mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
* Git GitHub App auth Signed-off-by: Slava Markeyev <slavamarkeyev@gmail.com>
This commit is contained in:
parent
594c827b66
commit
13b9b92c99
30 changed files with 1902 additions and 587 deletions
1
USERS.md
1
USERS.md
|
|
@ -64,6 +64,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
1. [MOO Print](https://www.moo.com/)
|
||||
1. [MTN Group](https://www.mtn.com/)
|
||||
1. [New Relic](https://newrelic.com/)
|
||||
1. [Nextdoor](https://nextdoor.com/)
|
||||
1. [Nikkei](https://www.nikkei.co.jp/nikkeiinfo/en/)
|
||||
1. [Octadesk](https://octadesk.com)
|
||||
1. [openEuler](https://openeuler.org)
|
||||
|
|
|
|||
|
|
@ -2809,6 +2809,32 @@
|
|||
"description": "Whether helm-oci support should be enabled for this repo.",
|
||||
"name": "enableOci",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Github App Private Key PEM data.",
|
||||
"name": "githubAppPrivateKey",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "Github App ID of the app used to access the repo.",
|
||||
"name": "githubAppID",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "Github App Installation ID of the installed GitHub App.",
|
||||
"name": "githubAppInstallationID",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Github App Enterprise base url if empty will default to https://api.github.com.",
|
||||
"name": "githubAppEnterpriseBaseUrl",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
|
@ -5612,6 +5638,24 @@
|
|||
"type": "object",
|
||||
"title": "RepoCreds holds a repository credentials definition",
|
||||
"properties": {
|
||||
"githubAppEnterpriseBaseUrl": {
|
||||
"type": "string",
|
||||
"title": "Github App Enterprise base url if empty will default to https://api.github.com"
|
||||
},
|
||||
"githubAppID": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "Github App ID of the app used to access the repo"
|
||||
},
|
||||
"githubAppInstallationID": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "Github App Installation ID of the installed GitHub App"
|
||||
},
|
||||
"githubAppPrivateKey": {
|
||||
"type": "string",
|
||||
"title": "Github App Private Key PEM data"
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"title": "Password for authenticating at the repo server"
|
||||
|
|
@ -5668,6 +5712,24 @@
|
|||
"type": "boolean",
|
||||
"title": "Whether helm-oci support should be enabled for this repo"
|
||||
},
|
||||
"githubAppEnterpriseBaseUrl": {
|
||||
"type": "string",
|
||||
"title": "Github App Enterprise base url if empty will default to https://api.github.com"
|
||||
},
|
||||
"githubAppID": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "Github App ID of the app used to access the repo"
|
||||
},
|
||||
"githubAppInstallationID": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "Github App Installation ID of the installed GitHub App"
|
||||
},
|
||||
"githubAppPrivateKey": {
|
||||
"type": "string",
|
||||
"title": "Github App Private Key PEM data"
|
||||
},
|
||||
"inheritedCreds": {
|
||||
"type": "boolean",
|
||||
"title": "Whether credentials were inherited from a credential set"
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
|||
|
||||
// For better readability and easier formatting
|
||||
var repoAddExamples = ` # Add a Git repository via SSH using a private key for authentication, ignoring the server's host key:
|
||||
argocd repo add git@git.example.com:repos/repo --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa
|
||||
argocd repo add git@git.example.com:repos/repo --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa
|
||||
|
||||
# Add a Git repository via SSH on a non-default port - need to use ssh:// style URLs here
|
||||
argocd repo add ssh://git@git.example.com:2222/repos/repo --ssh-private-key-path ~/id_rsa
|
||||
# Add a Git repository via SSH on a non-default port - need to use ssh:// style URLs here
|
||||
argocd repo add ssh://git@git.example.com:2222/repos/repo --ssh-private-key-path ~/id_rsa
|
||||
|
||||
# Add a private Git repository via HTTPS using username/password and TLS client certificates:
|
||||
argocd repo add https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key
|
||||
|
|
@ -65,6 +65,12 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
|||
|
||||
# Add a private Helm OCI-based repository named 'stable' via HTTPS
|
||||
argocd repo add helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type helm --name stable --enable-oci --username test --password test
|
||||
|
||||
# Add a private Git repository on GitHub.com via GitHub App
|
||||
argocd repo add https://git.example.com/repos/repo --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem
|
||||
|
||||
# Add a private Git repository on GitHub Enterprise via GitHub App
|
||||
argocd repo add https://ghe.example.com/repos/repo --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem --github-app-enterprise-base-url https://ghe.example.com/api/v3
|
||||
`
|
||||
|
||||
var command = &cobra.Command{
|
||||
|
|
@ -116,6 +122,18 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
|||
}
|
||||
}
|
||||
|
||||
// Specifying github-app-private-key-path is only valid for HTTPS repositories
|
||||
if repoOpts.GithubAppPrivateKeyPath != "" {
|
||||
if git.IsHTTPSURL(repoOpts.Repo.Repo) {
|
||||
githubAppPrivateKey, err := ioutil.ReadFile(repoOpts.GithubAppPrivateKeyPath)
|
||||
errors.CheckError(err)
|
||||
repoOpts.Repo.GithubAppPrivateKey = string(githubAppPrivateKey)
|
||||
} else {
|
||||
err := fmt.Errorf("--github-app-private-key-path is only supported for HTTPS repositories")
|
||||
errors.CheckError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set repository connection properties only when creating repository, not
|
||||
// when creating repository credentials.
|
||||
// InsecureIgnoreHostKey is deprecated and only here for backwards compat
|
||||
|
|
@ -123,6 +141,9 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
|||
repoOpts.Repo.Insecure = repoOpts.InsecureSkipServerVerification
|
||||
repoOpts.Repo.EnableLFS = repoOpts.EnableLfs
|
||||
repoOpts.Repo.EnableOCI = repoOpts.EnableOci
|
||||
repoOpts.Repo.GithubAppId = repoOpts.GithubAppId
|
||||
repoOpts.Repo.GithubAppInstallationId = repoOpts.GithubAppInstallationId
|
||||
repoOpts.Repo.GitHubAppEnterpriseBaseURL = repoOpts.GitHubAppEnterpriseBaseURL
|
||||
|
||||
if repoOpts.Repo.Type == "helm" && repoOpts.Repo.Name == "" {
|
||||
errors.CheckError(fmt.Errorf("Must specify --name for repos of type 'helm'"))
|
||||
|
|
@ -145,16 +166,20 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
|||
// are high that we do not have the given URL pointing to a valid Git
|
||||
// repo anyway.
|
||||
repoAccessReq := repositorypkg.RepoAccessQuery{
|
||||
Repo: repoOpts.Repo.Repo,
|
||||
Type: repoOpts.Repo.Type,
|
||||
Name: repoOpts.Repo.Name,
|
||||
Username: repoOpts.Repo.Username,
|
||||
Password: repoOpts.Repo.Password,
|
||||
SshPrivateKey: repoOpts.Repo.SSHPrivateKey,
|
||||
TlsClientCertData: repoOpts.Repo.TLSClientCertData,
|
||||
TlsClientCertKey: repoOpts.Repo.TLSClientCertKey,
|
||||
Insecure: repoOpts.Repo.IsInsecure(),
|
||||
EnableOci: repoOpts.Repo.EnableOCI,
|
||||
Repo: repoOpts.Repo.Repo,
|
||||
Type: repoOpts.Repo.Type,
|
||||
Name: repoOpts.Repo.Name,
|
||||
Username: repoOpts.Repo.Username,
|
||||
Password: repoOpts.Repo.Password,
|
||||
SshPrivateKey: repoOpts.Repo.SSHPrivateKey,
|
||||
TlsClientCertData: repoOpts.Repo.TLSClientCertData,
|
||||
TlsClientCertKey: repoOpts.Repo.TLSClientCertKey,
|
||||
Insecure: repoOpts.Repo.IsInsecure(),
|
||||
EnableOci: repoOpts.Repo.EnableOCI,
|
||||
GithubAppPrivateKey: repoOpts.Repo.GithubAppPrivateKey,
|
||||
GithubAppID: repoOpts.Repo.GithubAppId,
|
||||
GithubAppInstallationID: repoOpts.Repo.GithubAppInstallationId,
|
||||
GithubAppEnterpriseBaseUrl: repoOpts.Repo.GitHubAppEnterpriseBaseURL,
|
||||
}
|
||||
_, err := repoIf.ValidateAccess(context.Background(), &repoAccessReq)
|
||||
errors.CheckError(err)
|
||||
|
|
|
|||
|
|
@ -39,11 +39,12 @@ func NewRepoCredsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
|
|||
// NewRepoCredsAddCommand returns a new instance of an `argocd repocreds add` command
|
||||
func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
var (
|
||||
repo appsv1.RepoCreds
|
||||
upsert bool
|
||||
sshPrivateKeyPath string
|
||||
tlsClientCertPath string
|
||||
tlsClientCertKeyPath string
|
||||
repo appsv1.RepoCreds
|
||||
upsert bool
|
||||
sshPrivateKeyPath string
|
||||
tlsClientCertPath string
|
||||
tlsClientCertKeyPath string
|
||||
githubAppPrivateKeyPath string
|
||||
)
|
||||
|
||||
// For better readability and easier formatting
|
||||
|
|
@ -52,6 +53,12 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma
|
|||
|
||||
# Add credentials with SSH private key authentication to use for all repositories under ssh://git@git.example.com/repos
|
||||
argocd repocreds add ssh://git@git.example.com/repos/ --ssh-private-key-path ~/.ssh/id_rsa
|
||||
|
||||
# Add credentials with GitHub App authentication to use for all repositories under https://github.com/repos
|
||||
argocd repocreds add https://github.com/repos/ --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem
|
||||
|
||||
# Add credentials with GitHub App authentication to use for all repositories under https://ghe.example.com/repos
|
||||
argocd repocreds add https://ghe.example.com/repos/ --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem --github-app-enterprise-base-url https://ghe.example.com/api/v3
|
||||
`
|
||||
|
||||
var command = &cobra.Command{
|
||||
|
|
@ -103,6 +110,18 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma
|
|||
}
|
||||
}
|
||||
|
||||
// Specifying github-app-private-key-path is only valid for HTTPS repositories
|
||||
if githubAppPrivateKeyPath != "" {
|
||||
if git.IsHTTPSURL(repo.URL) {
|
||||
githubAppPrivateKey, err := ioutil.ReadFile(githubAppPrivateKeyPath)
|
||||
errors.CheckError(err)
|
||||
repo.GithubAppPrivateKey = string(githubAppPrivateKey)
|
||||
} else {
|
||||
err := fmt.Errorf("--github-app-private-key-path is only supported for HTTPS repositories")
|
||||
errors.CheckError(err)
|
||||
}
|
||||
}
|
||||
|
||||
conn, repoIf := argocdclient.NewClientOrDie(clientOpts).NewRepoCredsClientOrDie()
|
||||
defer io.Close(conn)
|
||||
|
||||
|
|
@ -127,6 +146,10 @@ func NewRepoCredsAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma
|
|||
command.Flags().StringVar(&sshPrivateKeyPath, "ssh-private-key-path", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)")
|
||||
command.Flags().StringVar(&tlsClientCertPath, "tls-client-cert-path", "", "path to the TLS client cert (must be PEM format)")
|
||||
command.Flags().StringVar(&tlsClientCertKeyPath, "tls-client-cert-key-path", "", "path to the TLS client cert's key path (must be PEM format)")
|
||||
command.Flags().Int64Var(&repo.GithubAppId, "github-app-id", 0, "id of the GitHub Application")
|
||||
command.Flags().Int64Var(&repo.GithubAppInstallationId, "github-app-installation-id", 0, "installation id of the GitHub Application")
|
||||
command.Flags().StringVar(&githubAppPrivateKeyPath, "github-app-private-key-path", "", "private key of the GitHub Application")
|
||||
command.Flags().StringVar(&repo.GitHubAppEnterpriseBaseURL, "github-app-enterprise-base-url", "", "base url to use when using GitHub Enterprise (e.g. https://ghe.example.com/api/v3")
|
||||
command.Flags().BoolVar(&upsert, "upsert", false, "Override an existing repository with the same name even if the spec differs")
|
||||
return command
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ type RepoOptions struct {
|
|||
TlsClientCertKeyPath string
|
||||
EnableLfs bool
|
||||
EnableOci bool
|
||||
GithubAppId int64
|
||||
GithubAppInstallationId int64
|
||||
GithubAppPrivateKeyPath string
|
||||
GitHubAppEnterpriseBaseURL string
|
||||
}
|
||||
|
||||
func AddRepoFlags(command *cobra.Command, opts *RepoOptions) {
|
||||
|
|
@ -31,4 +35,8 @@ func AddRepoFlags(command *cobra.Command, opts *RepoOptions) {
|
|||
command.Flags().BoolVar(&opts.InsecureSkipServerVerification, "insecure-skip-server-verification", false, "disables server certificate and host key checks")
|
||||
command.Flags().BoolVar(&opts.EnableLfs, "enable-lfs", false, "enable git-lfs (Large File Support) on this repository")
|
||||
command.Flags().BoolVar(&opts.EnableOci, "enable-oci", false, "enable helm-oci (Helm OCI-Based Repository)")
|
||||
command.Flags().Int64Var(&opts.GithubAppId, "github-app-id", 0, "id of the GitHub Application")
|
||||
command.Flags().Int64Var(&opts.GithubAppInstallationId, "github-app-installation-id", 0, "installation id of the GitHub Application")
|
||||
command.Flags().StringVar(&opts.GithubAppPrivateKeyPath, "github-app-private-key-path", "", "private key of the GitHub Application")
|
||||
command.Flags().StringVar(&opts.GitHubAppEnterpriseBaseURL, "github-app-enterprise-base-url", "", "base url to use when using GitHub Enterprise (e.g. https://ghe.example.com/api/v3")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ const (
|
|||
RevisionHistoryLimit = 10
|
||||
// ChangePasswordSSOTokenMaxAge is the max token age for password change operation
|
||||
ChangePasswordSSOTokenMaxAge = time.Minute * 5
|
||||
// GithubAppCredsExpirationDuration is the default time used to cache the GitHub app credentials
|
||||
GithubAppCredsExpirationDuration = time.Minute * 60
|
||||
)
|
||||
|
||||
// Dex related constants
|
||||
|
|
@ -184,6 +186,8 @@ const (
|
|||
EnvControllerShard = "ARGOCD_CONTROLLER_SHARD"
|
||||
// EnvEnableGRPCTimeHistogramEnv enables gRPC metrics collection
|
||||
EnvEnableGRPCTimeHistogramEnv = "ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM"
|
||||
// EnvGithubAppCredsExpirationDuration controls the caching of Github app credentials. This value is in minutes (default: 60)
|
||||
EnvGithubAppCredsExpirationDuration = "ARGOCD_GITHUB_APP_CREDS_EXPIRATION_DURATION"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
BIN
docs/assets/repo-add-github-app.png
Normal file
BIN
docs/assets/repo-add-github-app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 60 KiB |
|
|
@ -156,7 +156,7 @@ Repository credentials are stored in secret. Use following steps to configure a
|
|||
|
||||
1. Create secret which contains repository credentials. Consider using [bitnami-labs/sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) to store encrypted secret
|
||||
definition as a Kubernetes manifest.
|
||||
2. Register repository in the `argocd-cm` config map. Each repository must have `url` field and, depending on whether you connect using HTTPS or SSH, `usernameSecret` and `passwordSecret` (for HTTPS) or `sshPrivateKeySecret` (for SSH).
|
||||
2. Register repository in the `argocd-cm` config map. Each repository must have `url` field and, depending on whether you connect using HTTPS, SSH, or GitHub App, `usernameSecret` and `passwordSecret` (for HTTPS), `sshPrivateKeySecret` (for SSH), `githubAppPrivateKeySecret` (for GitHub App).
|
||||
|
||||
Example for HTTPS:
|
||||
|
||||
|
|
@ -199,6 +199,37 @@ data:
|
|||
key: sshPrivateKey
|
||||
```
|
||||
|
||||
> v1.9 or later
|
||||
|
||||
Example for GitHub App:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: argocd-cm
|
||||
namespace: argocd
|
||||
labels:
|
||||
app.kubernetes.io/name: argocd-cm
|
||||
app.kubernetes.io/part-of: argocd
|
||||
data:
|
||||
repositories: |
|
||||
- url: https://github.com/argoproj/my-private-repository
|
||||
githubAppID: 1
|
||||
githubAppInstallationID: 2
|
||||
githubAppPrivateKeySecret:
|
||||
name: my-secret
|
||||
key: githubAppPrivateKey
|
||||
|
||||
- url: https://ghe.example.com/argoproj/my-private-repository
|
||||
githubAppID: 1
|
||||
githubAppInstallationID: 2
|
||||
githubAppEnterpriseBaseUrl: https://ghe.example.com/api/v3
|
||||
githubAppPrivateKeySecret:
|
||||
name: my-secret
|
||||
key: githubAppPrivateKey
|
||||
```
|
||||
|
||||
!!! tip
|
||||
The Kubernetes documentation has [instructions for creating a secret containing a private key](https://kubernetes.io/docs/concepts/configuration/secret/#use-case-pod-with-ssh-keys).
|
||||
|
||||
|
|
@ -233,6 +264,19 @@ data:
|
|||
sshPrivateKeySecret:
|
||||
name: my-secret
|
||||
key: sshPrivateKey
|
||||
- url: https://github.com/argoproj
|
||||
githubAppID: 1
|
||||
githubAppInstallationID: 2
|
||||
githubAppPrivateKeySecret:
|
||||
name: my-secret
|
||||
key: githubAppPrivateKey
|
||||
- url: https://ghe.example.com/argoproj
|
||||
githubAppID: 1
|
||||
githubAppInstallationID: 2
|
||||
githubAppEnterpriseBaseUrl: https://ghe.example.com/api/v3
|
||||
githubAppPrivateKeySecret:
|
||||
name: my-secret
|
||||
key: githubAppPrivateKey
|
||||
```
|
||||
|
||||
Argo CD will only use the credentials if you omit `usernameSecret`, `passwordSecret`, and `sshPrivateKeySecret` fields (`insecureIgnoreHostKey` is ignored) or if your repository is not listed in `repositories`.
|
||||
|
|
@ -341,6 +385,13 @@ The following keys are valid to refer to credential secrets:
|
|||
* `usernameSecret` and `passwordSecret` refer to secrets where username and/or password are stored for accessing the repositories
|
||||
* `tlsClientCertData` and `tlsClientCertKey` refer to secrets where a TLS client certificate (`tlsClientCertData`) and the corresponding private key `tlsClientCertKey` are stored for accessing the repositories
|
||||
|
||||
#### GitHub App repositories
|
||||
|
||||
* `githubAppPrivateKeySecret` refers to the secret where the GitHub App private key is stored for accessing the repositories
|
||||
* `githubAppID` refers to the GitHub Application ID for the application you created.
|
||||
* `githubAppInstallationID` refers to the Installation ID of the GitHub app you created and installed.
|
||||
* `githubAppEnterpriseBaseUrl` refers to the base api URL for GitHub Enterprise (e.g. `https://ghe.example.com/api/v3`)
|
||||
* `tlsClientCertData` and `tlsClientCertKey` refer to secrets where a TLS client certificate (`tlsClientCertData`) and the corresponding private key `tlsClientCertKey` are stored for accessing GitHub Enterprise if custom certificates are used.
|
||||
|
||||
### Repositories using self-signed TLS certificates (or are signed by custom CA)
|
||||
|
||||
|
|
|
|||
|
|
@ -36,19 +36,23 @@ argocd-util config repo REPOURL [flags]
|
|||
### Options
|
||||
|
||||
```
|
||||
--enable-lfs enable git-lfs (Large File Support) on this repository
|
||||
--enable-oci enable helm-oci (Helm OCI-Based Repository)
|
||||
-h, --help help for repo
|
||||
--insecure-ignore-host-key disables SSH strict host key checking (deprecated, use --insecure-skip-server-verification instead)
|
||||
--insecure-skip-server-verification disables server certificate and host key checks
|
||||
--name string name of the repository, mandatory for repositories of type helm
|
||||
-o, --output string Output format. One of: json|yaml (default "yaml")
|
||||
--password string password to the repository
|
||||
--ssh-private-key-path string path to the private ssh key (e.g. ~/.ssh/id_rsa)
|
||||
--tls-client-cert-key-path string path to the TLS client cert's key path (must be PEM format)
|
||||
--tls-client-cert-path string path to the TLS client cert (must be PEM format)
|
||||
--type string type of the repository, "git" or "helm" (default "git")
|
||||
--username string username to the repository
|
||||
--enable-lfs enable git-lfs (Large File Support) on this repository
|
||||
--enable-oci enable helm-oci (Helm OCI-Based Repository)
|
||||
--github-app-enterprise-base-url string base url to use when using GitHub Enterprise (e.g. https://ghe.example.com/api/v3
|
||||
--github-app-id int id of the GitHub Application
|
||||
--github-app-installation-id int installation id of the GitHub Application
|
||||
--github-app-private-key-path string private key of the GitHub Application
|
||||
-h, --help help for repo
|
||||
--insecure-ignore-host-key disables SSH strict host key checking (deprecated, use --insecure-skip-server-verification instead)
|
||||
--insecure-skip-server-verification disables server certificate and host key checks
|
||||
--name string name of the repository, mandatory for repositories of type helm
|
||||
-o, --output string Output format. One of: json|yaml (default "yaml")
|
||||
--password string password to the repository
|
||||
--ssh-private-key-path string path to the private ssh key (e.g. ~/.ssh/id_rsa)
|
||||
--tls-client-cert-key-path string path to the TLS client cert's key path (must be PEM format)
|
||||
--tls-client-cert-path string path to the TLS client cert (must be PEM format)
|
||||
--type string type of the repository, "git" or "helm" (default "git")
|
||||
--username string username to the repository
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ argocd repo add REPOURL [flags]
|
|||
|
||||
```
|
||||
# Add a Git repository via SSH using a private key for authentication, ignoring the server's host key:
|
||||
argocd repo add git@git.example.com:repos/repo --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa
|
||||
argocd repo add git@git.example.com:repos/repo --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa
|
||||
|
||||
# Add a Git repository via SSH on a non-default port - need to use ssh:// style URLs here
|
||||
argocd repo add ssh://git@git.example.com:2222/repos/repo --ssh-private-key-path ~/id_rsa
|
||||
# Add a Git repository via SSH on a non-default port - need to use ssh:// style URLs here
|
||||
argocd repo add ssh://git@git.example.com:2222/repos/repo --ssh-private-key-path ~/id_rsa
|
||||
|
||||
# Add a private Git repository via HTTPS using username/password and TLS client certificates:
|
||||
argocd repo add https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key
|
||||
|
|
@ -30,24 +30,34 @@ argocd repo add REPOURL [flags]
|
|||
# Add a private Helm OCI-based repository named 'stable' via HTTPS
|
||||
argocd repo add helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type helm --name stable --enable-oci --username test --password test
|
||||
|
||||
# Add a private Git repository on GitHub.com via GitHub App
|
||||
argocd repo add https://git.example.com/repos/repo --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem
|
||||
|
||||
# Add a private Git repository on GitHub Enterprise via GitHub App
|
||||
argocd repo add https://ghe.example.com/repos/repo --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem --github-app-enterprise-base-url https://ghe.example.com/api/v3
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--enable-lfs enable git-lfs (Large File Support) on this repository
|
||||
--enable-oci enable helm-oci (Helm OCI-Based Repository)
|
||||
-h, --help help for add
|
||||
--insecure-ignore-host-key disables SSH strict host key checking (deprecated, use --insecure-skip-server-verification instead)
|
||||
--insecure-skip-server-verification disables server certificate and host key checks
|
||||
--name string name of the repository, mandatory for repositories of type helm
|
||||
--password string password to the repository
|
||||
--ssh-private-key-path string path to the private ssh key (e.g. ~/.ssh/id_rsa)
|
||||
--tls-client-cert-key-path string path to the TLS client cert's key path (must be PEM format)
|
||||
--tls-client-cert-path string path to the TLS client cert (must be PEM format)
|
||||
--type string type of the repository, "git" or "helm" (default "git")
|
||||
--upsert Override an existing repository with the same name even if the spec differs
|
||||
--username string username to the repository
|
||||
--enable-lfs enable git-lfs (Large File Support) on this repository
|
||||
--enable-oci enable helm-oci (Helm OCI-Based Repository)
|
||||
--github-app-enterprise-base-url string base url to use when using GitHub Enterprise (e.g. https://ghe.example.com/api/v3
|
||||
--github-app-id int id of the GitHub Application
|
||||
--github-app-installation-id int installation id of the GitHub Application
|
||||
--github-app-private-key-path string private key of the GitHub Application
|
||||
-h, --help help for add
|
||||
--insecure-ignore-host-key disables SSH strict host key checking (deprecated, use --insecure-skip-server-verification instead)
|
||||
--insecure-skip-server-verification disables server certificate and host key checks
|
||||
--name string name of the repository, mandatory for repositories of type helm
|
||||
--password string password to the repository
|
||||
--ssh-private-key-path string path to the private ssh key (e.g. ~/.ssh/id_rsa)
|
||||
--tls-client-cert-key-path string path to the TLS client cert's key path (must be PEM format)
|
||||
--tls-client-cert-path string path to the TLS client cert (must be PEM format)
|
||||
--type string type of the repository, "git" or "helm" (default "git")
|
||||
--upsert Override an existing repository with the same name even if the spec differs
|
||||
--username string username to the repository
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
|
|
|||
|
|
@ -15,18 +15,28 @@ argocd repocreds add REPOURL [flags]
|
|||
# Add credentials with SSH private key authentication to use for all repositories under ssh://git@git.example.com/repos
|
||||
argocd repocreds add ssh://git@git.example.com/repos/ --ssh-private-key-path ~/.ssh/id_rsa
|
||||
|
||||
# Add credentials with GitHub App authentication to use for all repositories under https://github.com/repos
|
||||
argocd repocreds add https://github.com/repos/ --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem
|
||||
|
||||
# Add credentials with GitHub App authentication to use for all repositories under https://ghe.example.com/repos
|
||||
argocd repocreds add https://ghe.example.com/repos/ --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem --github-app-enterprise-base-url https://ghe.example.com/api/v3
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for add
|
||||
--password string password to the repository
|
||||
--ssh-private-key-path string path to the private ssh key (e.g. ~/.ssh/id_rsa)
|
||||
--tls-client-cert-key-path string path to the TLS client cert's key path (must be PEM format)
|
||||
--tls-client-cert-path string path to the TLS client cert (must be PEM format)
|
||||
--upsert Override an existing repository with the same name even if the spec differs
|
||||
--username string username to the repository
|
||||
--github-app-enterprise-base-url string base url to use when using GitHub Enterprise (e.g. https://ghe.example.com/api/v3
|
||||
--github-app-id int id of the GitHub Application
|
||||
--github-app-installation-id int installation id of the GitHub Application
|
||||
--github-app-private-key-path string private key of the GitHub Application
|
||||
-h, --help help for add
|
||||
--password string password to the repository
|
||||
--ssh-private-key-path string path to the private ssh key (e.g. ~/.ssh/id_rsa)
|
||||
--tls-client-cert-key-path string path to the TLS client cert's key path (must be PEM format)
|
||||
--tls-client-cert-path string path to the TLS client cert (must be PEM format)
|
||||
--upsert Override an existing repository with the same name even if the spec differs
|
||||
--username string username to the repository
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
|
|
|||
|
|
@ -116,6 +116,42 @@ The Argo CD UI don't support configuring SSH credentials. The SSH credentials ca
|
|||
argocd repo add git@github.com:argoproj/argocd-example-apps.git --ssh-private-key-path ~/.ssh/id_rsa
|
||||
```
|
||||
|
||||
### GitHub App Credential
|
||||
|
||||
Private repositories that are hosted on GitHub.com or GitHub Enterprise can be accessed using credentials from a GitHub Application. Consult the [GitHub documentation](https://docs.github.com/en/developers/apps/about-apps#about-github-apps) on how to create an application.
|
||||
|
||||
!!!note
|
||||
Ensure your application has at least `Read-only` permissions to the `Contents` of the repository. This is the minimum requirement.
|
||||
|
||||
> previous to v1.9
|
||||
|
||||
GitHub App credentials are not supported.
|
||||
|
||||
> v1.9 or later
|
||||
|
||||
You can configure access to your Git repository hosted by GitHub.com or GitHub Enterprise using the GitHub App method by either using the CLI or the UI.
|
||||
|
||||
Using the CLI:
|
||||
|
||||
```
|
||||
argocd repo add https://github.com/argoproj/argocd-example-apps.git --github-app-id 1 --github-app-installation-id 2 --github-app-private-key-path test.private-key.pem
|
||||
```
|
||||
|
||||
Using the UI:
|
||||
|
||||
1. Navigate to `Settings/Repositories`
|
||||
|
||||

|
||||
|
||||
1. Click `Connect Repo using GitHub App` button, enter the URL, App Id, Installation Id, and the app's private key.
|
||||
|
||||

|
||||
|
||||
1. Click `Connect` to test the connection and have the repository added
|
||||
|
||||
!!!note
|
||||
When pasting GitHub App private key in the UI, make sure there are no unintended line breaks or additional characters in the text area
|
||||
|
||||
## Credential templates
|
||||
|
||||
> previous to v1.4
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -10,6 +10,7 @@ require (
|
|||
github.com/argoproj/gitops-engine v0.2.1-0.20210218233004-354817a103ee
|
||||
github.com/argoproj/pkg v0.2.0
|
||||
github.com/bombsimon/logrusr v1.0.0
|
||||
github.com/bradleyfalzon/ghinstallation v1.1.1
|
||||
github.com/casbin/casbin v1.9.1
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible
|
||||
|
|
|
|||
6
go.sum
6
go.sum
|
|
@ -118,6 +118,8 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
|
|||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/bombsimon/logrusr v1.0.0 h1:CTCkURYAt5nhCCnKH9eLShYayj2/8Kn/4Qg3QfiU+Ro=
|
||||
github.com/bombsimon/logrusr v1.0.0/go.mod h1:Jq0nHtvxabKE5EMwAAdgTaz7dfWE8C4i11NOltxGQpc=
|
||||
github.com/bradleyfalzon/ghinstallation v1.1.1 h1:pmBXkxgM1WeF8QYvDLT5kuQiHMcmf+X015GI0KM/E3I=
|
||||
github.com/bradleyfalzon/ghinstallation v1.1.1/go.mod h1:vyCmHTciHx/uuyN82Zc3rXN3X2KTK8nUTCrTMwAhcug=
|
||||
github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E=
|
||||
github.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=
|
||||
github.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog=
|
||||
|
|
@ -352,8 +354,12 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts=
|
||||
github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
|
||||
github.com/google/go-jsonnet v0.17.0 h1:/9NIEfhK1NQRKl3sP2536b2+x5HnZMdql7x3yK/l8JY=
|
||||
github.com/google/go-jsonnet v0.17.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
|
|
|
|||
|
|
@ -322,10 +322,18 @@ type RepoAccessQuery struct {
|
|||
// The name of the repo
|
||||
Name string `protobuf:"bytes,10,opt,name=name,proto3" json:"name,omitempty"`
|
||||
// Whether helm-oci support should be enabled for this repo
|
||||
EnableOci bool `protobuf:"varint,11,opt,name=enableOci,proto3" json:"enableOci,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
EnableOci bool `protobuf:"varint,11,opt,name=enableOci,proto3" json:"enableOci,omitempty"`
|
||||
// Github App Private Key PEM data
|
||||
GithubAppPrivateKey string `protobuf:"bytes,12,opt,name=githubAppPrivateKey,proto3" json:"githubAppPrivateKey,omitempty"`
|
||||
// Github App ID of the app used to access the repo
|
||||
GithubAppID int64 `protobuf:"varint,13,opt,name=githubAppID,proto3" json:"githubAppID,omitempty"`
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
GithubAppInstallationID int64 `protobuf:"varint,14,opt,name=githubAppInstallationID,proto3" json:"githubAppInstallationID,omitempty"`
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
GithubAppEnterpriseBaseUrl string `protobuf:"bytes,15,opt,name=githubAppEnterpriseBaseUrl,proto3" json:"githubAppEnterpriseBaseUrl,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *RepoAccessQuery) Reset() { *m = RepoAccessQuery{} }
|
||||
|
|
@ -431,6 +439,34 @@ func (m *RepoAccessQuery) GetEnableOci() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (m *RepoAccessQuery) GetGithubAppPrivateKey() string {
|
||||
if m != nil {
|
||||
return m.GithubAppPrivateKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RepoAccessQuery) GetGithubAppID() int64 {
|
||||
if m != nil {
|
||||
return m.GithubAppID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *RepoAccessQuery) GetGithubAppInstallationID() int64 {
|
||||
if m != nil {
|
||||
return m.GithubAppInstallationID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *RepoAccessQuery) GetGithubAppEnterpriseBaseUrl() string {
|
||||
if m != nil {
|
||||
return m.GithubAppEnterpriseBaseUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RepoResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
|
@ -601,69 +637,74 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptor_8d38260443475705 = []byte{
|
||||
// 989 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0x1b, 0xc5,
|
||||
0x1b, 0xd6, 0x26, 0xa9, 0x9b, 0x4c, 0x9a, 0xfc, 0xdc, 0x69, 0x7f, 0x95, 0x71, 0xdd, 0x34, 0x9a,
|
||||
0x96, 0x2a, 0x44, 0x65, 0x17, 0x1b, 0x90, 0x50, 0x11, 0x42, 0x89, 0x83, 0x4a, 0x44, 0xa4, 0xc2,
|
||||
0x56, 0x45, 0x02, 0x09, 0xa1, 0xc9, 0xfa, 0xb5, 0xbd, 0x64, 0xbd, 0x33, 0xcc, 0x8c, 0x8d, 0xac,
|
||||
0xa8, 0x17, 0x4e, 0xe5, 0x08, 0x88, 0x1b, 0x17, 0x24, 0x0e, 0x7c, 0x0b, 0xae, 0x1c, 0x91, 0xf8,
|
||||
0x02, 0x28, 0xe2, 0xc2, 0xb7, 0x40, 0x33, 0xb3, 0xff, 0x1c, 0xdb, 0xdb, 0x54, 0x84, 0xdc, 0x66,
|
||||
0x9e, 0x99, 0x79, 0x9f, 0xe7, 0x7d, 0xe6, 0xdd, 0x77, 0x07, 0x11, 0x09, 0x62, 0x04, 0xc2, 0x13,
|
||||
0xc0, 0x99, 0x0c, 0x15, 0x13, 0xe3, 0xc2, 0xd0, 0xe5, 0x82, 0x29, 0x86, 0x51, 0x8e, 0xd4, 0xaf,
|
||||
0xf7, 0x58, 0x8f, 0x19, 0xd8, 0xd3, 0x23, 0xbb, 0xa3, 0xde, 0xe8, 0x31, 0xd6, 0x8b, 0xc0, 0xa3,
|
||||
0x3c, 0xf4, 0x68, 0x1c, 0x33, 0x45, 0x55, 0xc8, 0x62, 0x99, 0xac, 0x92, 0xa3, 0xb7, 0xa4, 0x1b,
|
||||
0x32, 0xb3, 0x1a, 0x30, 0x01, 0xde, 0xa8, 0xe9, 0xf5, 0x20, 0x06, 0x41, 0x15, 0x74, 0x92, 0x3d,
|
||||
0xfb, 0xbd, 0x50, 0xf5, 0x87, 0x87, 0x6e, 0xc0, 0x06, 0x1e, 0x15, 0x86, 0xe2, 0x0b, 0x33, 0x78,
|
||||
0x35, 0xe8, 0x78, 0xfc, 0xa8, 0xa7, 0x0f, 0x4b, 0x8f, 0x72, 0x1e, 0x85, 0x81, 0x09, 0xee, 0x8d,
|
||||
0x9a, 0x34, 0xe2, 0x7d, 0x3a, 0x1d, 0x6a, 0xb7, 0x2c, 0x94, 0x49, 0xe5, 0xb9, 0x29, 0x93, 0x77,
|
||||
0xd1, 0x9a, 0x0f, 0x9c, 0xed, 0x70, 0x2e, 0x3f, 0x1a, 0x82, 0x18, 0x63, 0x8c, 0x96, 0xf4, 0xa6,
|
||||
0x9a, 0xb3, 0xe9, 0x6c, 0xad, 0xf8, 0x66, 0x8c, 0xeb, 0x68, 0x59, 0xc0, 0x28, 0x94, 0x21, 0x8b,
|
||||
0x6b, 0x0b, 0x06, 0xcf, 0xe6, 0xa4, 0x89, 0x2e, 0xef, 0x70, 0xbe, 0x1f, 0x77, 0x99, 0x3e, 0xaa,
|
||||
0xc6, 0x1c, 0xd2, 0xa3, 0x7a, 0xac, 0x31, 0x4e, 0x55, 0x3f, 0x39, 0x66, 0xc6, 0xe4, 0x18, 0x5d,
|
||||
0x4b, 0x38, 0xf7, 0x40, 0xd1, 0x30, 0x4a, 0x98, 0x3b, 0xa8, 0x22, 0xd9, 0x50, 0x04, 0x36, 0xc0,
|
||||
0x6a, 0xeb, 0xc0, 0xcd, 0xf3, 0x73, 0xd3, 0xfc, 0xcc, 0xe0, 0xf3, 0xa0, 0xe3, 0xf2, 0xa3, 0x9e,
|
||||
0xab, 0xad, 0x72, 0x0b, 0x56, 0xb9, 0xa9, 0x55, 0xee, 0x4e, 0x0e, 0x3e, 0x36, 0x31, 0xfd, 0x24,
|
||||
0x36, 0x79, 0x07, 0x55, 0xd3, 0x84, 0x7d, 0x90, 0x9c, 0xc5, 0x12, 0xf0, 0x2b, 0xe8, 0x52, 0xa8,
|
||||
0x60, 0x20, 0x6b, 0xce, 0xe6, 0xe2, 0xd6, 0x6a, 0xeb, 0x9a, 0x5b, 0xb0, 0x29, 0x49, 0xce, 0xb7,
|
||||
0x3b, 0x48, 0x1b, 0xad, 0xe8, 0xe3, 0xf3, 0xbd, 0x22, 0xe8, 0x4a, 0x97, 0x69, 0x42, 0xe8, 0x0a,
|
||||
0x90, 0x36, 0xf1, 0x65, 0x7f, 0x02, 0x23, 0xbf, 0x2e, 0xa0, 0xff, 0x19, 0x11, 0x41, 0x00, 0xb2,
|
||||
0xdc, 0xf7, 0xa1, 0x04, 0x11, 0xd3, 0x01, 0xa4, 0xbe, 0xa7, 0x73, 0xbd, 0xc6, 0xa9, 0x94, 0x5f,
|
||||
0x31, 0xd1, 0xa9, 0x2d, 0xda, 0xb5, 0x74, 0x8e, 0xef, 0xa2, 0x35, 0x29, 0xfb, 0x1f, 0x8a, 0x70,
|
||||
0x44, 0x15, 0x7c, 0x00, 0xe3, 0xda, 0x92, 0xd9, 0x30, 0x09, 0xea, 0x08, 0x61, 0x2c, 0x21, 0x18,
|
||||
0x0a, 0xa8, 0x5d, 0x32, 0x2a, 0xb3, 0x39, 0xbe, 0x8f, 0xae, 0xaa, 0x48, 0xb6, 0xa3, 0x10, 0x62,
|
||||
0xd5, 0x06, 0xa1, 0xf6, 0xa8, 0xa2, 0xb5, 0x8a, 0x89, 0x32, 0xbd, 0x80, 0xb7, 0x51, 0x75, 0x02,
|
||||
0xd4, 0x94, 0x97, 0xcd, 0xe6, 0x29, 0x3c, 0x2b, 0x92, 0x95, 0xc9, 0x22, 0x31, 0x39, 0x22, 0x8b,
|
||||
0x99, 0xfc, 0x1a, 0x68, 0x05, 0x62, 0x7a, 0x18, 0xc1, 0xa3, 0x20, 0xac, 0xad, 0x1a, 0x79, 0x39,
|
||||
0x40, 0xd6, 0xd1, 0x15, 0x6d, 0x60, 0x7a, 0x83, 0xe4, 0x67, 0x07, 0x5d, 0xd5, 0x40, 0x5b, 0x00,
|
||||
0x55, 0xe0, 0xc3, 0x97, 0x43, 0x90, 0x0a, 0x7f, 0x52, 0xf0, 0x74, 0xb5, 0xf5, 0xde, 0xbf, 0xa8,
|
||||
0x27, 0x3f, 0x2b, 0x88, 0xe4, 0x6a, 0x6e, 0xa0, 0xca, 0x90, 0x4b, 0x10, 0x2a, 0xb9, 0xe0, 0x64,
|
||||
0xa6, 0x65, 0x07, 0x02, 0x3a, 0xf2, 0x51, 0x1c, 0x8d, 0xcd, 0xbd, 0x2c, 0xfb, 0x39, 0x40, 0x62,
|
||||
0xab, 0xf2, 0x09, 0xef, 0x5c, 0x88, 0xca, 0xd6, 0xdf, 0xeb, 0x96, 0xd0, 0x82, 0x8f, 0x41, 0x8c,
|
||||
0xc2, 0x00, 0xf0, 0x37, 0x0e, 0x5a, 0x3a, 0x08, 0xa5, 0xc2, 0xff, 0x2f, 0x16, 0x7a, 0x56, 0xd6,
|
||||
0xf5, 0xfd, 0x73, 0x91, 0xa0, 0x19, 0xc8, 0xed, 0xaf, 0xff, 0xf8, 0xeb, 0xfb, 0x85, 0x1b, 0xf8,
|
||||
0xba, 0xe9, 0x89, 0xa3, 0x66, 0xde, 0x80, 0x42, 0x90, 0xcf, 0x16, 0x1c, 0xfc, 0xcc, 0x41, 0x8b,
|
||||
0x0f, 0x61, 0xae, 0x94, 0xf3, 0x71, 0x83, 0xdc, 0x31, 0x32, 0x6e, 0xe1, 0x9b, 0xb3, 0x64, 0x78,
|
||||
0xc7, 0x7a, 0xf6, 0x14, 0x7f, 0xe7, 0xa0, 0xaa, 0x16, 0xed, 0x17, 0xd6, 0x2e, 0xc0, 0xa2, 0x46,
|
||||
0x99, 0x45, 0xf8, 0x33, 0xb4, 0x6c, 0x35, 0x75, 0xe7, 0x6a, 0xa9, 0x4e, 0xc2, 0x5d, 0x49, 0xb6,
|
||||
0x4c, 0x48, 0x82, 0x37, 0x4b, 0xd2, 0xf5, 0x84, 0x0e, 0x39, 0xb0, 0xe1, 0x75, 0x37, 0xc4, 0x2f,
|
||||
0x9d, 0x0e, 0x9f, 0xfd, 0x14, 0xea, 0x8d, 0x59, 0x4b, 0xd9, 0xc7, 0x77, 0x26, 0x3a, 0xaa, 0x29,
|
||||
0xbe, 0x75, 0xd0, 0xda, 0x43, 0x50, 0x79, 0xe7, 0xc7, 0xb7, 0x67, 0x44, 0x2e, 0xfe, 0x15, 0xea,
|
||||
0x64, 0xfe, 0x86, 0x4c, 0xc0, 0xdb, 0x46, 0xc0, 0x9b, 0xe4, 0xb5, 0xd9, 0x02, 0x6c, 0xe7, 0x37,
|
||||
0x71, 0x9e, 0xf8, 0x07, 0x46, 0x4a, 0xc7, 0x46, 0x78, 0xe0, 0x6c, 0xe3, 0x91, 0x91, 0xf4, 0x3e,
|
||||
0x44, 0x83, 0x76, 0x9f, 0x0a, 0x35, 0xd7, 0xe6, 0x8d, 0x22, 0x9c, 0x6f, 0xcf, 0x44, 0xb8, 0x46,
|
||||
0xc4, 0x16, 0xbe, 0x57, 0xe6, 0x42, 0x1f, 0xa2, 0x41, 0x60, 0x69, 0x7e, 0x70, 0x50, 0xc5, 0xb6,
|
||||
0x2b, 0x7c, 0xeb, 0x34, 0xe3, 0x44, 0x1b, 0x3b, 0xaf, 0x8f, 0xe0, 0x65, 0x23, 0xb0, 0x41, 0x66,
|
||||
0x16, 0xda, 0x03, 0xd3, 0x30, 0xf4, 0x17, 0xf9, 0xa3, 0x83, 0xaa, 0x29, 0x7f, 0x7a, 0xf6, 0x82,
|
||||
0x14, 0x92, 0xe7, 0x2b, 0xc4, 0x3f, 0x39, 0xa8, 0x62, 0xfb, 0xe7, 0xb4, 0xa8, 0x89, 0xbe, 0x7a,
|
||||
0x5e, 0xa2, 0x9a, 0xf6, 0x5e, 0xeb, 0x25, 0xd5, 0x6d, 0x74, 0x3c, 0xcd, 0x2d, 0xfc, 0xc5, 0x41,
|
||||
0xd5, 0x54, 0xcb, 0x7c, 0x0b, 0xff, 0x13, 0xb5, 0xee, 0x8b, 0xa9, 0xc5, 0x14, 0x55, 0xf6, 0x20,
|
||||
0x02, 0x05, 0xf3, 0xca, 0xbe, 0x76, 0x1a, 0xce, 0x0a, 0xfe, 0x9e, 0x6d, 0xaa, 0xdb, 0x65, 0x4d,
|
||||
0x55, 0xbb, 0xd1, 0x47, 0x55, 0x4b, 0x51, 0x30, 0xe3, 0x85, 0xc9, 0xee, 0x9c, 0x81, 0x0c, 0x1f,
|
||||
0xa3, 0xf5, 0x8f, 0x69, 0x14, 0x6a, 0x5b, 0xed, 0xd3, 0x0a, 0xdf, 0x9c, 0xea, 0x1e, 0xf9, 0x93,
|
||||
0xab, 0x84, 0xad, 0x65, 0xd8, 0xee, 0x93, 0xbb, 0x65, 0xdf, 0xf2, 0x28, 0xa1, 0xb2, 0x4e, 0xee,
|
||||
0xee, 0xfe, 0x76, 0xb2, 0xe1, 0xfc, 0x7e, 0xb2, 0xe1, 0xfc, 0x79, 0xb2, 0xe1, 0x7c, 0xfa, 0xc6,
|
||||
0x19, 0x9e, 0xf9, 0x81, 0x79, 0x18, 0x15, 0xde, 0xe4, 0x87, 0x15, 0xf3, 0x28, 0x7f, 0xfd, 0x9f,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x11, 0x28, 0x6f, 0x6f, 0xad, 0x0c, 0x00, 0x00,
|
||||
// 1063 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4d, 0x6f, 0x1c, 0x45,
|
||||
0x13, 0xd6, 0xd8, 0xce, 0xc6, 0x6e, 0x7f, 0x64, 0xd3, 0xce, 0x9b, 0x77, 0xd8, 0x38, 0x8e, 0xd5,
|
||||
0x09, 0x91, 0xb1, 0xc2, 0x4c, 0x6c, 0x40, 0x8a, 0x82, 0x00, 0xf9, 0x23, 0x0a, 0x16, 0x96, 0x02,
|
||||
0x13, 0x19, 0x09, 0x24, 0x84, 0xda, 0xb3, 0xe5, 0xdd, 0xc1, 0xb3, 0xd3, 0x4d, 0x77, 0xef, 0xa2,
|
||||
0x95, 0x95, 0x0b, 0xa7, 0x70, 0xe0, 0x00, 0x88, 0x1b, 0x17, 0x24, 0x0e, 0xfc, 0x14, 0x8e, 0x48,
|
||||
0xfc, 0x01, 0x64, 0x71, 0xe1, 0x5f, 0xa0, 0xee, 0x9e, 0xaf, 0xf5, 0xee, 0x4e, 0x1c, 0x61, 0x7c,
|
||||
0xeb, 0x7e, 0xaa, 0xba, 0xea, 0xa9, 0x67, 0xaa, 0x6b, 0x66, 0x10, 0x91, 0x20, 0x7a, 0x20, 0x7c,
|
||||
0x01, 0x9c, 0xc9, 0x48, 0x31, 0xd1, 0x2f, 0x2d, 0x3d, 0x2e, 0x98, 0x62, 0x18, 0x15, 0x48, 0xe3,
|
||||
0x5a, 0x8b, 0xb5, 0x98, 0x81, 0x7d, 0xbd, 0xb2, 0x1e, 0x8d, 0xa5, 0x16, 0x63, 0xad, 0x18, 0x7c,
|
||||
0xca, 0x23, 0x9f, 0x26, 0x09, 0x53, 0x54, 0x45, 0x2c, 0x91, 0xa9, 0x95, 0x1c, 0x3d, 0x90, 0x5e,
|
||||
0xc4, 0x8c, 0x35, 0x64, 0x02, 0xfc, 0xde, 0xba, 0xdf, 0x82, 0x04, 0x04, 0x55, 0xd0, 0x4c, 0x7d,
|
||||
0x76, 0x5b, 0x91, 0x6a, 0x77, 0x0f, 0xbc, 0x90, 0x75, 0x7c, 0x2a, 0x4c, 0x8a, 0x2f, 0xcc, 0xe2,
|
||||
0xf5, 0xb0, 0xe9, 0xf3, 0xa3, 0x96, 0x3e, 0x2c, 0x7d, 0xca, 0x79, 0x1c, 0x85, 0x26, 0xb8, 0xdf,
|
||||
0x5b, 0xa7, 0x31, 0x6f, 0xd3, 0xe1, 0x50, 0x5b, 0x55, 0xa1, 0x4c, 0x29, 0x2f, 0x2c, 0x99, 0xbc,
|
||||
0x87, 0xe6, 0x03, 0xe0, 0x6c, 0x93, 0x73, 0xf9, 0x51, 0x17, 0x44, 0x1f, 0x63, 0x34, 0xa5, 0x9d,
|
||||
0x5c, 0x67, 0xc5, 0x59, 0x9d, 0x09, 0xcc, 0x1a, 0x37, 0xd0, 0xb4, 0x80, 0x5e, 0x24, 0x23, 0x96,
|
||||
0xb8, 0x13, 0x06, 0xcf, 0xf7, 0x64, 0x1d, 0x5d, 0xde, 0xe4, 0x7c, 0x37, 0x39, 0x64, 0xfa, 0xa8,
|
||||
0xea, 0x73, 0xc8, 0x8e, 0xea, 0xb5, 0xc6, 0x38, 0x55, 0xed, 0xf4, 0x98, 0x59, 0x93, 0x63, 0xb4,
|
||||
0x98, 0xe6, 0xdc, 0x01, 0x45, 0xa3, 0x38, 0xcd, 0xdc, 0x44, 0x35, 0xc9, 0xba, 0x22, 0xb4, 0x01,
|
||||
0x66, 0x37, 0xf6, 0xbc, 0xa2, 0x3e, 0x2f, 0xab, 0xcf, 0x2c, 0x3e, 0x0f, 0x9b, 0x1e, 0x3f, 0x6a,
|
||||
0x79, 0x5a, 0x2a, 0xaf, 0x24, 0x95, 0x97, 0x49, 0xe5, 0x6d, 0x16, 0xe0, 0x53, 0x13, 0x33, 0x48,
|
||||
0x63, 0x93, 0x77, 0x50, 0x3d, 0x2b, 0x38, 0x00, 0xc9, 0x59, 0x22, 0x01, 0xbf, 0x86, 0x2e, 0x45,
|
||||
0x0a, 0x3a, 0xd2, 0x75, 0x56, 0x26, 0x57, 0x67, 0x37, 0x16, 0xbd, 0x92, 0x4c, 0x69, 0x71, 0x81,
|
||||
0xf5, 0x20, 0xdb, 0x68, 0x46, 0x1f, 0x1f, 0xaf, 0x15, 0x41, 0x73, 0x87, 0x4c, 0x27, 0x84, 0x43,
|
||||
0x01, 0xd2, 0x16, 0x3e, 0x1d, 0x0c, 0x60, 0xe4, 0xdb, 0x29, 0x74, 0xc5, 0x90, 0x08, 0x43, 0x90,
|
||||
0xd5, 0xba, 0x77, 0x25, 0x88, 0x84, 0x76, 0x20, 0xd3, 0x3d, 0xdb, 0x6b, 0x1b, 0xa7, 0x52, 0x7e,
|
||||
0xc5, 0x44, 0xd3, 0x9d, 0xb4, 0xb6, 0x6c, 0x8f, 0xef, 0xa0, 0x79, 0x29, 0xdb, 0x1f, 0x8a, 0xa8,
|
||||
0x47, 0x15, 0x7c, 0x00, 0x7d, 0x77, 0xca, 0x38, 0x0c, 0x82, 0x3a, 0x42, 0x94, 0x48, 0x08, 0xbb,
|
||||
0x02, 0xdc, 0x4b, 0x86, 0x65, 0xbe, 0xc7, 0xf7, 0xd0, 0x55, 0x15, 0xcb, 0xed, 0x38, 0x82, 0x44,
|
||||
0x6d, 0x83, 0x50, 0x3b, 0x54, 0x51, 0xb7, 0x66, 0xa2, 0x0c, 0x1b, 0xf0, 0x1a, 0xaa, 0x0f, 0x80,
|
||||
0x3a, 0xe5, 0x65, 0xe3, 0x3c, 0x84, 0xe7, 0x4d, 0x32, 0x33, 0xd8, 0x24, 0xa6, 0x46, 0x64, 0x31,
|
||||
0x53, 0xdf, 0x12, 0x9a, 0x81, 0x84, 0x1e, 0xc4, 0xf0, 0x24, 0x8c, 0xdc, 0x59, 0x43, 0xaf, 0x00,
|
||||
0xf0, 0x7d, 0xb4, 0x68, 0x9b, 0x63, 0x93, 0xf3, 0x52, 0x9d, 0x73, 0x26, 0xc0, 0x28, 0x13, 0x5e,
|
||||
0x41, 0xb3, 0x39, 0xbc, 0xbb, 0xe3, 0xce, 0xaf, 0x38, 0xab, 0x93, 0x41, 0x19, 0xc2, 0x0f, 0xd0,
|
||||
0xff, 0x8b, 0x6d, 0x22, 0x15, 0x8d, 0x63, 0xd3, 0x40, 0xbb, 0x3b, 0xee, 0x82, 0xf1, 0x1e, 0x67,
|
||||
0xc6, 0xef, 0xa2, 0x46, 0x6e, 0x7a, 0x94, 0x28, 0x10, 0x5c, 0x44, 0x12, 0xb6, 0xa8, 0x84, 0x7d,
|
||||
0x11, 0xbb, 0x57, 0x0c, 0xa9, 0x0a, 0x0f, 0xb2, 0x80, 0xe6, 0x74, 0x3b, 0x64, 0xfd, 0x48, 0x7e,
|
||||
0x71, 0xd0, 0x55, 0x0d, 0x6c, 0x0b, 0xa0, 0x0a, 0x02, 0xf8, 0xb2, 0x0b, 0x52, 0xe1, 0x4f, 0x4a,
|
||||
0x1d, 0x32, 0xbb, 0xf1, 0xe8, 0x5f, 0xdc, 0x8e, 0x20, 0x6f, 0xef, 0xb4, 0xd1, 0xae, 0xa3, 0x5a,
|
||||
0x97, 0x4b, 0x10, 0x2a, 0x6d, 0xd7, 0x74, 0xa7, 0x1f, 0x42, 0x28, 0xa0, 0x29, 0x9f, 0x24, 0x71,
|
||||
0xdf, 0x74, 0xd9, 0x74, 0x50, 0x00, 0x24, 0xb1, 0x2c, 0xf7, 0x79, 0xf3, 0x42, 0x58, 0x6e, 0xfc,
|
||||
0xbd, 0x60, 0x13, 0x5a, 0xf0, 0x29, 0x88, 0x5e, 0x14, 0x02, 0xfe, 0xc6, 0x41, 0x53, 0x7b, 0x91,
|
||||
0x54, 0xf8, 0x7f, 0xe5, 0x6b, 0x9b, 0x5f, 0xd2, 0xc6, 0xee, 0xb9, 0x50, 0xd0, 0x19, 0xc8, 0xad,
|
||||
0xaf, 0xff, 0xf8, 0xeb, 0x87, 0x89, 0xeb, 0xf8, 0x9a, 0x99, 0xf0, 0xbd, 0xf5, 0x62, 0x9c, 0x46,
|
||||
0x20, 0x9f, 0x4f, 0x38, 0xf8, 0xb9, 0x83, 0x26, 0x1f, 0xc3, 0x58, 0x2a, 0xe7, 0xa3, 0x06, 0xb9,
|
||||
0x6d, 0x68, 0xdc, 0xc4, 0x37, 0x46, 0xd1, 0xf0, 0x8f, 0xf5, 0xee, 0x19, 0xfe, 0xde, 0x41, 0x75,
|
||||
0x4d, 0x3a, 0x28, 0xd9, 0x2e, 0x40, 0xa2, 0xa5, 0x2a, 0x89, 0xf0, 0x67, 0x68, 0xda, 0x72, 0x3a,
|
||||
0x1c, 0xcb, 0xa5, 0x3e, 0x08, 0x1f, 0x4a, 0xb2, 0x6a, 0x42, 0x12, 0xbc, 0x52, 0x51, 0xae, 0x2f,
|
||||
0x74, 0xc8, 0x8e, 0x0d, 0xaf, 0x67, 0x3b, 0x7e, 0xe5, 0x74, 0xf8, 0xfc, 0x15, 0xd7, 0x58, 0x1a,
|
||||
0x65, 0xca, 0x2f, 0xdf, 0x99, 0xd2, 0x51, 0x9d, 0xe2, 0x3b, 0x07, 0xcd, 0x3f, 0x06, 0x55, 0xbc,
|
||||
0xc7, 0xf0, 0xad, 0x11, 0x91, 0xcb, 0xef, 0xb8, 0x06, 0x19, 0xef, 0x90, 0x13, 0x78, 0xdb, 0x10,
|
||||
0x78, 0x8b, 0xdc, 0x1f, 0x4d, 0xc0, 0xbe, 0xc7, 0x4c, 0x9c, 0xfd, 0x60, 0xcf, 0x50, 0x69, 0xda,
|
||||
0x08, 0x0f, 0x9d, 0x35, 0xdc, 0x33, 0x94, 0xde, 0x87, 0xb8, 0xb3, 0xdd, 0xa6, 0x42, 0x8d, 0x95,
|
||||
0x79, 0xb9, 0x0c, 0x17, 0xee, 0x39, 0x09, 0xcf, 0x90, 0x58, 0xc5, 0x77, 0xab, 0x54, 0x68, 0x43,
|
||||
0xdc, 0x09, 0x6d, 0x9a, 0x1f, 0x1d, 0x54, 0xb3, 0xe3, 0x0a, 0xdf, 0x3c, 0x9d, 0x71, 0x60, 0x8c,
|
||||
0x9d, 0xd7, 0x25, 0x78, 0xd5, 0x10, 0x5c, 0x22, 0x23, 0x1b, 0xed, 0xa1, 0x19, 0x18, 0xfa, 0x46,
|
||||
0xfe, 0xe4, 0xa0, 0x7a, 0x96, 0x3f, 0x3b, 0x7b, 0x41, 0x0c, 0xc9, 0x8b, 0x19, 0xe2, 0x9f, 0x1d,
|
||||
0x54, 0xb3, 0xf3, 0x73, 0x98, 0xd4, 0xc0, 0x5c, 0x3d, 0x2f, 0x52, 0xeb, 0xf6, 0xb9, 0x36, 0x2a,
|
||||
0xba, 0xdb, 0xf0, 0x78, 0x56, 0x48, 0xf8, 0xab, 0x83, 0xea, 0x19, 0x97, 0xf1, 0x12, 0xfe, 0x27,
|
||||
0x6c, 0xbd, 0x97, 0x63, 0x8b, 0x29, 0xaa, 0xed, 0x40, 0x0c, 0x0a, 0xc6, 0xb5, 0xbd, 0x7b, 0x1a,
|
||||
0xce, 0x1b, 0xfe, 0xae, 0x1d, 0xaa, 0x6b, 0x55, 0x43, 0x55, 0xab, 0xd1, 0x46, 0x75, 0x9b, 0xa2,
|
||||
0x24, 0xc6, 0x4b, 0x27, 0xbb, 0x7d, 0x86, 0x64, 0xf8, 0x18, 0x2d, 0x7c, 0x4c, 0xe3, 0x48, 0xcb,
|
||||
0x6a, 0x3f, 0x14, 0xf1, 0x8d, 0xa1, 0xe9, 0x51, 0x7c, 0x40, 0x56, 0x64, 0xdb, 0x30, 0xd9, 0xee,
|
||||
0x91, 0x3b, 0x55, 0x77, 0xb9, 0x97, 0xa6, 0xb2, 0x4a, 0x6e, 0x6d, 0xfd, 0x76, 0xb2, 0xec, 0xfc,
|
||||
0x7e, 0xb2, 0xec, 0xfc, 0x79, 0xb2, 0xec, 0x7c, 0xfa, 0xe6, 0x19, 0x7e, 0x5a, 0x42, 0xf3, 0x99,
|
||||
0x57, 0xfa, 0xc3, 0x38, 0xa8, 0x99, 0x5f, 0x8c, 0x37, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x2b,
|
||||
0xf1, 0xe2, 0xa9, 0x7b, 0x0d, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
|
@ -1474,6 +1515,30 @@ func (m *RepoAccessQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
i -= len(m.XXX_unrecognized)
|
||||
copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
if len(m.GithubAppEnterpriseBaseUrl) > 0 {
|
||||
i -= len(m.GithubAppEnterpriseBaseUrl)
|
||||
copy(dAtA[i:], m.GithubAppEnterpriseBaseUrl)
|
||||
i = encodeVarintRepository(dAtA, i, uint64(len(m.GithubAppEnterpriseBaseUrl)))
|
||||
i--
|
||||
dAtA[i] = 0x7a
|
||||
}
|
||||
if m.GithubAppInstallationID != 0 {
|
||||
i = encodeVarintRepository(dAtA, i, uint64(m.GithubAppInstallationID))
|
||||
i--
|
||||
dAtA[i] = 0x70
|
||||
}
|
||||
if m.GithubAppID != 0 {
|
||||
i = encodeVarintRepository(dAtA, i, uint64(m.GithubAppID))
|
||||
i--
|
||||
dAtA[i] = 0x68
|
||||
}
|
||||
if len(m.GithubAppPrivateKey) > 0 {
|
||||
i -= len(m.GithubAppPrivateKey)
|
||||
copy(dAtA[i:], m.GithubAppPrivateKey)
|
||||
i = encodeVarintRepository(dAtA, i, uint64(len(m.GithubAppPrivateKey)))
|
||||
i--
|
||||
dAtA[i] = 0x62
|
||||
}
|
||||
if m.EnableOci {
|
||||
i--
|
||||
if m.EnableOci {
|
||||
|
|
@ -1826,6 +1891,20 @@ func (m *RepoAccessQuery) Size() (n int) {
|
|||
if m.EnableOci {
|
||||
n += 2
|
||||
}
|
||||
l = len(m.GithubAppPrivateKey)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovRepository(uint64(l))
|
||||
}
|
||||
if m.GithubAppID != 0 {
|
||||
n += 1 + sovRepository(uint64(m.GithubAppID))
|
||||
}
|
||||
if m.GithubAppInstallationID != 0 {
|
||||
n += 1 + sovRepository(uint64(m.GithubAppInstallationID))
|
||||
}
|
||||
l = len(m.GithubAppEnterpriseBaseUrl)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovRepository(uint64(l))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
|
|
@ -2733,6 +2812,108 @@ func (m *RepoAccessQuery) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
}
|
||||
m.EnableOci = bool(v != 0)
|
||||
case 12:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GithubAppPrivateKey", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowRepository
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthRepository
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthRepository
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.GithubAppPrivateKey = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 13:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GithubAppID", wireType)
|
||||
}
|
||||
m.GithubAppID = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowRepository
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.GithubAppID |= int64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 14:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GithubAppInstallationID", wireType)
|
||||
}
|
||||
m.GithubAppInstallationID = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowRepository
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.GithubAppInstallationID |= int64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 15:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field GithubAppEnterpriseBaseUrl", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowRepository
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthRepository
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthRepository
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.GithubAppEnterpriseBaseUrl = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipRepository(dAtA[iNdEx:])
|
||||
|
|
|
|||
|
|
@ -62,7 +62,13 @@ API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application
|
|||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,JWTToken,IssuedAt
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,KustomizeOptions,BinaryPath
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,KustomizeOptions,BuildOptions
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,RepoCreds,GitHubAppEnterpriseBaseURL
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,RepoCreds,GithubAppId
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,RepoCreds,GithubAppInstallationId
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,Repository,EnableLFS
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,Repository,GitHubAppEnterpriseBaseURL
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,Repository,GithubAppId
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,Repository,GithubAppInstallationId
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,ResourceActionDefinition,ActionLua
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,ResourceActions,ActionDiscoveryLua
|
||||
API rule violation: names_match,github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1,ResourceOverride,Actions
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -737,6 +737,18 @@ message RepoCreds {
|
|||
|
||||
// TLS client cert key for authenticating at the repo server
|
||||
optional string tlsClientCertKey = 6;
|
||||
|
||||
// Github App Private Key PEM data
|
||||
optional string githubAppPrivateKey = 7;
|
||||
|
||||
// Github App ID of the app used to access the repo
|
||||
optional int64 githubAppID = 8;
|
||||
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
optional int64 githubAppInstallationID = 9;
|
||||
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
optional string githubAppEnterpriseBaseUrl = 10;
|
||||
}
|
||||
|
||||
// RepositoryList is a collection of Repositories.
|
||||
|
|
@ -791,6 +803,18 @@ message Repository {
|
|||
|
||||
// Whether helm-oci support should be enabled for this repo
|
||||
optional bool enableOCI = 14;
|
||||
|
||||
// Github App Private Key PEM data
|
||||
optional string githubAppPrivateKey = 15;
|
||||
|
||||
// Github App ID of the app used to access the repo
|
||||
optional int64 githubAppID = 16;
|
||||
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
optional int64 githubAppInstallationID = 17;
|
||||
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
optional string githubAppEnterpriseBaseUrl = 18;
|
||||
}
|
||||
|
||||
// A RepositoryCertificate is either SSH known hosts entry or TLS certificate
|
||||
|
|
|
|||
|
|
@ -2686,6 +2686,34 @@ func schema_pkg_apis_application_v1alpha1_RepoCreds(ref common.ReferenceCallback
|
|||
Format: "",
|
||||
},
|
||||
},
|
||||
"githubAppPrivateKey": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App Private Key PEM data",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"githubAppID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App ID of the app used to access the repo",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"githubAppInstallationID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App Installation ID of the installed GitHub App",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"githubAppEnterpriseBaseUrl": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App Enterprise base url if empty will default to https://api.github.com",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"url"},
|
||||
},
|
||||
|
|
@ -2834,6 +2862,34 @@ func schema_pkg_apis_application_v1alpha1_Repository(ref common.ReferenceCallbac
|
|||
Format: "",
|
||||
},
|
||||
},
|
||||
"githubAppPrivateKey": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App Private Key PEM data",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"githubAppID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App ID of the app used to access the repo",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"githubAppInstallationID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App Installation ID of the installed GitHub App",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"githubAppEnterpriseBaseUrl": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Github App Enterprise base url if empty will default to https://api.github.com",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"repo"},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1372,6 +1372,14 @@ type RepoCreds struct {
|
|||
TLSClientCertData string `json:"tlsClientCertData,omitempty" protobuf:"bytes,5,opt,name=tlsClientCertData"`
|
||||
// TLS client cert key for authenticating at the repo server
|
||||
TLSClientCertKey string `json:"tlsClientCertKey,omitempty" protobuf:"bytes,6,opt,name=tlsClientCertKey"`
|
||||
// Github App Private Key PEM data
|
||||
GithubAppPrivateKey string `json:"githubAppPrivateKey,omitempty" protobuf:"bytes,7,opt,name=githubAppPrivateKey"`
|
||||
// Github App ID of the app used to access the repo
|
||||
GithubAppId int64 `json:"githubAppID,omitempty" protobuf:"bytes,8,opt,name=githubAppID"`
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
GithubAppInstallationId int64 `json:"githubAppInstallationID,omitempty" protobuf:"bytes,9,opt,name=githubAppInstallationID"`
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
GitHubAppEnterpriseBaseURL string `json:"githubAppEnterpriseBaseUrl,omitempty" protobuf:"bytes,10,opt,name=githubAppEnterpriseBaseUrl"`
|
||||
}
|
||||
|
||||
// Repository is a repository holding application configurations
|
||||
|
|
@ -1406,6 +1414,14 @@ type Repository struct {
|
|||
InheritedCreds bool `json:"inheritedCreds,omitempty" protobuf:"bytes,13,opt,name=inheritedCreds"`
|
||||
// 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"`
|
||||
// Github App ID of the app used to access the repo
|
||||
GithubAppId int64 `json:"githubAppID,omitempty" protobuf:"bytes,16,opt,name=githubAppID"`
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
GithubAppInstallationId int64 `json:"githubAppInstallationID,omitempty" protobuf:"bytes,17,opt,name=githubAppInstallationID"`
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
GitHubAppEnterpriseBaseURL string `json:"githubAppEnterpriseBaseUrl,omitempty" protobuf:"bytes,18,opt,name=githubAppEnterpriseBaseUrl"`
|
||||
}
|
||||
|
||||
// IsInsecure returns true if receiver has been configured to skip server verification
|
||||
|
|
@ -1420,7 +1436,7 @@ func (repo *Repository) IsLFSEnabled() bool {
|
|||
|
||||
// HasCredentials returns true when the receiver has been configured any credentials
|
||||
func (m *Repository) HasCredentials() bool {
|
||||
return m.Username != "" || m.Password != "" || m.SSHPrivateKey != "" || m.TLSClientCertData != ""
|
||||
return m.Username != "" || m.Password != "" || m.SSHPrivateKey != "" || m.TLSClientCertData != "" || m.GithubAppPrivateKey != ""
|
||||
}
|
||||
|
||||
func (repo *Repository) CopyCredentialsFromRepo(source *Repository) {
|
||||
|
|
@ -1440,6 +1456,18 @@ func (repo *Repository) CopyCredentialsFromRepo(source *Repository) {
|
|||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1461,6 +1489,18 @@ func (repo *Repository) CopyCredentialsFrom(source *RepoCreds) {
|
|||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1474,6 +1514,9 @@ func (repo *Repository) GetGitCreds() git.Creds {
|
|||
if repo.SSHPrivateKey != "" {
|
||||
return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure())
|
||||
}
|
||||
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())
|
||||
}
|
||||
return git.NopCreds{}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,12 +110,15 @@ func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.R
|
|||
}
|
||||
// remove secrets
|
||||
item := appsv1.Repository{
|
||||
Repo: repo.Repo,
|
||||
Type: rType,
|
||||
Name: repo.Name,
|
||||
Username: repo.Username,
|
||||
Insecure: repo.IsInsecure(),
|
||||
EnableLFS: repo.EnableLFS,
|
||||
Repo: repo.Repo,
|
||||
Type: rType,
|
||||
Name: repo.Name,
|
||||
Username: repo.Username,
|
||||
Insecure: repo.IsInsecure(),
|
||||
EnableLFS: repo.EnableLFS,
|
||||
GithubAppId: repo.GithubAppId,
|
||||
GithubAppInstallationId: repo.GithubAppInstallationId,
|
||||
GitHubAppEnterpriseBaseURL: repo.GitHubAppEnterpriseBaseURL,
|
||||
}
|
||||
|
||||
item.ConnectionState = s.getConnectionState(ctx, item.Repo, q.ForceRefresh)
|
||||
|
|
@ -371,16 +374,20 @@ func (s *Server) ValidateAccess(ctx context.Context, q *repositorypkg.RepoAccess
|
|||
}
|
||||
|
||||
repo := &appsv1.Repository{
|
||||
Repo: q.Repo,
|
||||
Type: q.Type,
|
||||
Name: q.Name,
|
||||
Username: q.Username,
|
||||
Password: q.Password,
|
||||
SSHPrivateKey: q.SshPrivateKey,
|
||||
Insecure: q.Insecure,
|
||||
TLSClientCertData: q.TlsClientCertData,
|
||||
TLSClientCertKey: q.TlsClientCertKey,
|
||||
EnableOCI: q.EnableOci,
|
||||
Repo: q.Repo,
|
||||
Type: q.Type,
|
||||
Name: q.Name,
|
||||
Username: q.Username,
|
||||
Password: q.Password,
|
||||
SSHPrivateKey: q.SshPrivateKey,
|
||||
Insecure: q.Insecure,
|
||||
TLSClientCertData: q.TlsClientCertData,
|
||||
TLSClientCertKey: q.TlsClientCertKey,
|
||||
EnableOCI: q.EnableOci,
|
||||
GithubAppPrivateKey: q.GithubAppPrivateKey,
|
||||
GithubAppId: q.GithubAppID,
|
||||
GithubAppInstallationId: q.GithubAppInstallationID,
|
||||
GitHubAppEnterpriseBaseURL: q.GithubAppEnterpriseBaseUrl,
|
||||
}
|
||||
|
||||
var repoCreds *appsv1.RepoCreds
|
||||
|
|
|
|||
|
|
@ -65,6 +65,14 @@ message RepoAccessQuery {
|
|||
string name = 10;
|
||||
// Whether helm-oci support should be enabled for this repo
|
||||
bool enableOci = 11;
|
||||
// Github App Private Key PEM data
|
||||
string githubAppPrivateKey = 12;
|
||||
// Github App ID of the app used to access the repo
|
||||
int64 githubAppID = 13;
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
int64 githubAppInstallationID = 14;
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
string githubAppEnterpriseBaseUrl = 15;
|
||||
}
|
||||
|
||||
message RepoResponse {}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import * as React from 'react';
|
|||
import {Form, FormApi, Text, TextArea} from 'react-form';
|
||||
import {RouteComponentProps} from 'react-router';
|
||||
|
||||
import {CheckboxField, ConnectionStateIcon, DataLoader, EmptyState, ErrorNotification, Page, Repo} from '../../../shared/components';
|
||||
import {CheckboxField, ConnectionStateIcon, DataLoader, EmptyState, ErrorNotification, NumberField, Page, Repo} from '../../../shared/components';
|
||||
import {Spinner} from '../../../shared/components';
|
||||
import {AppContext} from '../../../shared/context';
|
||||
import * as models from '../../../shared/models';
|
||||
|
|
@ -33,6 +33,20 @@ interface NewHTTPSRepoParams {
|
|||
enableLfs: boolean;
|
||||
}
|
||||
|
||||
interface NewGitHubAppRepoParams {
|
||||
type: string;
|
||||
name: string;
|
||||
url: string;
|
||||
githubAppPrivateKey: string;
|
||||
githubAppId: bigint;
|
||||
githubAppInstallationId: bigint;
|
||||
githubAppEnterpriseBaseURL: string;
|
||||
tlsClientCertData: string;
|
||||
tlsClientCertKey: string;
|
||||
insecure: boolean;
|
||||
enableLfs: boolean;
|
||||
}
|
||||
|
||||
interface NewSSHRepoCredsParams {
|
||||
url: string;
|
||||
sshPrivateKey: string;
|
||||
|
|
@ -46,6 +60,16 @@ interface NewHTTPSRepoCredsParams {
|
|||
tlsClientCertKey: string;
|
||||
}
|
||||
|
||||
interface NewGitHubAppRepoCredsParams {
|
||||
url: string;
|
||||
githubAppPrivateKey: string;
|
||||
githubAppId: bigint;
|
||||
githubAppInstallationId: bigint;
|
||||
githubAppEnterpriseBaseURL: string;
|
||||
tlsClientCertData: string;
|
||||
tlsClientCertKey: string;
|
||||
}
|
||||
|
||||
export class ReposList extends React.Component<RouteComponentProps<any>, {connecting: boolean}> {
|
||||
public static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
|
|
@ -55,6 +79,7 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
|
||||
private formApiSSH: FormApi;
|
||||
private formApiHTTPS: FormApi;
|
||||
private formApiGitHubApp: FormApi;
|
||||
private credsTemplate: boolean;
|
||||
private repoLoader: DataLoader;
|
||||
private credsLoader: DataLoader;
|
||||
|
|
@ -82,6 +107,11 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
title: 'Connect Repo using HTTPS',
|
||||
action: () => (this.showConnectHTTPSRepo = true)
|
||||
},
|
||||
{
|
||||
iconClassName: 'fa fa-plus',
|
||||
title: 'Connect Repo using GitHub App',
|
||||
action: () => (this.showConnectGitHubAppRepo = true)
|
||||
},
|
||||
{
|
||||
iconClassName: 'fa fa-redo',
|
||||
title: 'Refresh list',
|
||||
|
|
@ -155,6 +185,9 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
<button className='argo-button argo-button--base' onClick={() => (this.showConnectHTTPSRepo = true)}>
|
||||
Connect Repo using HTTPS
|
||||
</button>
|
||||
<button className='argo-button argo-button--base' onClick={() => (this.showConnectGitHubAppRepo = true)}>
|
||||
Connect Repo using GitHub App
|
||||
</button>{' '}
|
||||
</EmptyState>
|
||||
)
|
||||
}
|
||||
|
|
@ -334,6 +367,95 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
)}
|
||||
</Form>
|
||||
</SlidingPanel>
|
||||
<SlidingPanel
|
||||
isShown={this.showConnectGitHubAppRepo}
|
||||
onClose={() => (this.showConnectGitHubAppRepo = false)}
|
||||
header={
|
||||
<div>
|
||||
<button
|
||||
className='argo-button argo-button--base'
|
||||
onClick={() => {
|
||||
this.credsTemplate = false;
|
||||
this.formApiGitHubApp.submitForm(null);
|
||||
}}>
|
||||
<Spinner show={this.state.connecting} style={{marginRight: '5px'}} />
|
||||
Connect
|
||||
</button>{' '}
|
||||
<button
|
||||
className='argo-button argo-button--base'
|
||||
onClick={() => {
|
||||
this.credsTemplate = true;
|
||||
this.formApiGitHubApp.submitForm(null);
|
||||
}}>
|
||||
Save as credentials template
|
||||
</button>{' '}
|
||||
<button onClick={() => (this.showConnectGitHubAppRepo = false)} className='argo-button argo-button--base-o'>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
}>
|
||||
<h4>Connect repo using GitHub App</h4>
|
||||
<Form
|
||||
onSubmit={params => this.connectGitHubAppRepo(params as NewGitHubAppRepoParams)}
|
||||
getApi={api => (this.formApiGitHubApp = api)}
|
||||
defaultValues={{type: 'git', ghType: 'GitHub'}}
|
||||
validateError={(params: NewGitHubAppRepoParams) => ({
|
||||
url: (!params.url && 'Repo URL is required') || (this.credsTemplate && !this.isHTTPSUrl(params.url) && 'Not a valid HTTPS URL'),
|
||||
githubAppId: !params.githubAppId && 'GitHub App ID is required',
|
||||
githubAppInstallationId: !params.githubAppInstallationId && 'GitHub App installation ID is required',
|
||||
githubAppPrivateKey: !params.githubAppPrivateKey && 'GitHub App private Key is required'
|
||||
})}>
|
||||
{formApi => (
|
||||
<form onSubmit={formApi.submitForm} role='form' className='repos-list width-control'>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='Type' field='ghType' component={FormSelect} componentProps={{options: ['GitHub', 'GitHub Enterprise']}} />
|
||||
</div>
|
||||
{formApi.getFormState().values.type === 'GitHub Enterprise' && (
|
||||
<React.Fragment>
|
||||
<div className='argo-form-row'>
|
||||
<FormField
|
||||
formApi={formApi}
|
||||
label='GitHub Enterprise Base URL (e.g. https://ghe.example.com/api/v3)'
|
||||
field='githubAppEnterpriseBaseURL'
|
||||
component={Text}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='Repository URL' field='url' component={Text} />
|
||||
</div>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='GitHub App ID' field='githubAppId' component={NumberField} />
|
||||
</div>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='GitHub App Installation ID' field='githubAppInstallationId' component={NumberField} />
|
||||
</div>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='GitHub App private key' field='githubAppPrivateKey' component={TextArea} />
|
||||
</div>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='Skip server verification' field='insecure' component={CheckboxField} />
|
||||
<HelpIcon title='This setting is ignored when creating as credential template.' />
|
||||
</div>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='Enable LFS support (Git only)' field='enableLfs' component={CheckboxField} />
|
||||
<HelpIcon title='This setting is ignored when creating as credential template.' />
|
||||
</div>
|
||||
{formApi.getFormState().values.ghType === 'GitHub Enterprise' && (
|
||||
<React.Fragment>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='TLS client certificate (optional)' field='tlsClientCertData' component={TextArea} />
|
||||
</div>
|
||||
<div className='argo-form-row'>
|
||||
<FormField formApi={formApi} label='TLS client certificate key (optional)' field='tlsClientCertKey' component={TextArea} />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
</SlidingPanel>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
|
@ -377,6 +499,12 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
this.formApiHTTPS.resetAll();
|
||||
}
|
||||
|
||||
// Empty all fields in SSH repository form
|
||||
private clearConnectGitHubAppForm() {
|
||||
this.credsTemplate = false;
|
||||
this.formApiGitHubApp.resetAll();
|
||||
}
|
||||
|
||||
// Connect a new repository or create a repository credentials for SSH repositories
|
||||
private async connectSSHRepo(params: NewSSHRepoParams) {
|
||||
if (this.credsTemplate) {
|
||||
|
|
@ -425,6 +553,35 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
}
|
||||
}
|
||||
|
||||
// Connect a new repository or create a repository credentials for GitHub App repositories
|
||||
private async connectGitHubAppRepo(params: NewGitHubAppRepoParams) {
|
||||
if (this.credsTemplate) {
|
||||
this.createGitHubAppCreds({
|
||||
url: params.url,
|
||||
githubAppPrivateKey: params.githubAppPrivateKey,
|
||||
githubAppId: params.githubAppId,
|
||||
githubAppInstallationId: params.githubAppInstallationId,
|
||||
githubAppEnterpriseBaseURL: params.githubAppEnterpriseBaseURL,
|
||||
tlsClientCertData: params.tlsClientCertData,
|
||||
tlsClientCertKey: params.tlsClientCertKey
|
||||
});
|
||||
} else {
|
||||
this.setState({connecting: true});
|
||||
try {
|
||||
await services.repos.createGitHubApp(params);
|
||||
this.repoLoader.reload();
|
||||
this.showConnectGitHubAppRepo = false;
|
||||
} catch (e) {
|
||||
this.appContext.apis.notifications.show({
|
||||
content: <ErrorNotification title='Unable to connect GitHub app repository' e={e} />,
|
||||
type: NotificationType.Error
|
||||
});
|
||||
} finally {
|
||||
this.setState({connecting: false});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async createHTTPSCreds(params: NewHTTPSRepoCredsParams) {
|
||||
try {
|
||||
await services.repocreds.createHTTPS(params);
|
||||
|
|
@ -451,6 +608,19 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
}
|
||||
}
|
||||
|
||||
private async createGitHubAppCreds(params: NewGitHubAppRepoCredsParams) {
|
||||
try {
|
||||
await services.repocreds.createGitHubApp(params);
|
||||
this.credsLoader.reload();
|
||||
this.showConnectGitHubAppRepo = false;
|
||||
} catch (e) {
|
||||
this.appContext.apis.notifications.show({
|
||||
content: <ErrorNotification title='Unable to create GitHub App credentials' e={e} />,
|
||||
type: NotificationType.Error
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a repository from the configuration
|
||||
private async disconnectRepo(repo: string) {
|
||||
const confirmed = await this.appContext.apis.popup.confirm('Disconnect repository', `Are you sure you want to disconnect '${repo}'?`);
|
||||
|
|
@ -489,6 +659,16 @@ export class ReposList extends React.Component<RouteComponentProps<any>, {connec
|
|||
this.appContext.router.history.push(`${this.props.match.url}?addSSHRepo=${val}`);
|
||||
}
|
||||
|
||||
// Whether to show the GitHub App repository connection dialogue on the page
|
||||
private get showConnectGitHubAppRepo() {
|
||||
return new URLSearchParams(this.props.location.search).get('addGitHubAppRepo') === 'true';
|
||||
}
|
||||
|
||||
private set showConnectGitHubAppRepo(val: boolean) {
|
||||
this.clearConnectGitHubAppForm();
|
||||
this.appContext.router.history.push(`${this.props.match.url}?addGitHubAppRepo=${val}`);
|
||||
}
|
||||
|
||||
private get appContext(): AppContext {
|
||||
return this.context as AppContext;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,49 @@ export class RepositoriesService {
|
|||
.then(res => res.body as models.Repository);
|
||||
}
|
||||
|
||||
public createGitHubApp({
|
||||
type,
|
||||
name,
|
||||
url,
|
||||
githubAppPrivateKey,
|
||||
githubAppId,
|
||||
githubAppInstallationId,
|
||||
githubAppEnterpriseBaseURL,
|
||||
tlsClientCertData,
|
||||
tlsClientCertKey,
|
||||
insecure,
|
||||
enableLfs
|
||||
}: {
|
||||
type: string;
|
||||
name: string;
|
||||
url: string;
|
||||
githubAppPrivateKey: string;
|
||||
githubAppId: bigint;
|
||||
githubAppInstallationId: bigint;
|
||||
githubAppEnterpriseBaseURL: string;
|
||||
tlsClientCertData: string;
|
||||
tlsClientCertKey: string;
|
||||
insecure: boolean;
|
||||
enableLfs: boolean;
|
||||
}): Promise<models.Repository> {
|
||||
return requests
|
||||
.post('/repositories')
|
||||
.send({
|
||||
type,
|
||||
name,
|
||||
repo: url,
|
||||
githubAppPrivateKey,
|
||||
githubAppId,
|
||||
githubAppInstallationId,
|
||||
githubAppEnterpriseBaseURL,
|
||||
tlsClientCertData,
|
||||
tlsClientCertKey,
|
||||
insecure,
|
||||
enableLfs
|
||||
})
|
||||
.then(res => res.body as models.Repository);
|
||||
}
|
||||
|
||||
public delete(url: string): Promise<models.Repository> {
|
||||
return requests
|
||||
.delete(`/repositories/${encodeURIComponent(url)}`)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,29 @@ export class RepoCredsService {
|
|||
.then(res => res.body as models.RepoCreds);
|
||||
}
|
||||
|
||||
public createGitHubApp({
|
||||
url,
|
||||
githubAppPrivateKey,
|
||||
githubAppId,
|
||||
githubAppInstallationId,
|
||||
githubAppEnterpriseBaseURL,
|
||||
tlsClientCertData,
|
||||
tlsClientCertKey
|
||||
}: {
|
||||
url: string;
|
||||
githubAppPrivateKey: string;
|
||||
githubAppId: bigint;
|
||||
githubAppInstallationId: bigint;
|
||||
githubAppEnterpriseBaseURL: string;
|
||||
tlsClientCertData: string;
|
||||
tlsClientCertKey: string;
|
||||
}): Promise<models.RepoCreds> {
|
||||
return requests
|
||||
.post('/repocreds')
|
||||
.send({url, githubAppPrivateKey, githubAppId, githubAppInstallationId, githubAppEnterpriseBaseURL, tlsClientCertData, tlsClientCertKey})
|
||||
.then(res => res.body as models.RepoCreds);
|
||||
}
|
||||
|
||||
public delete(url: string): Promise<models.RepoCreds> {
|
||||
return requests
|
||||
.delete(`/repocreds/${encodeURIComponent(url)}`)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ const (
|
|||
tlsClientCertData = "tlsClientCertData"
|
||||
// The name of the key storing the TLS client cert key in the secret
|
||||
tlsClientCertKey = "tlsClientCertKey"
|
||||
// The name of the key storing the GitHub App private key in the secret
|
||||
githubAppPrivateKey = "githubAppPrivateKey"
|
||||
)
|
||||
|
||||
func (db *db) CreateRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) {
|
||||
|
|
@ -59,15 +61,21 @@ func (db *db) CreateRepository(ctx context.Context, r *appsv1.Repository) (*apps
|
|||
if r.SSHPrivateKey != "" {
|
||||
data[sshPrivateKey] = []byte(r.SSHPrivateKey)
|
||||
}
|
||||
if r.GithubAppPrivateKey != "" {
|
||||
data[githubAppPrivateKey] = []byte(r.GithubAppPrivateKey)
|
||||
}
|
||||
|
||||
repoInfo := settings.Repository{
|
||||
URL: r.Repo,
|
||||
Type: r.Type,
|
||||
Name: r.Name,
|
||||
InsecureIgnoreHostKey: r.IsInsecure(),
|
||||
Insecure: r.IsInsecure(),
|
||||
EnableLFS: r.EnableLFS,
|
||||
EnableOci: r.EnableOCI,
|
||||
URL: r.Repo,
|
||||
Type: r.Type,
|
||||
Name: r.Name,
|
||||
InsecureIgnoreHostKey: r.IsInsecure(),
|
||||
Insecure: r.IsInsecure(),
|
||||
EnableLFS: r.EnableLFS,
|
||||
EnableOci: r.EnableOCI,
|
||||
GithubAppId: r.GithubAppId,
|
||||
GithubAppInstallationId: r.GithubAppInstallationId,
|
||||
GithubAppEnterpriseBaseURL: r.GitHubAppEnterpriseBaseURL,
|
||||
}
|
||||
err = db.updateRepositorySecrets(&repoInfo, r)
|
||||
if err != nil {
|
||||
|
|
@ -166,34 +174,42 @@ func (db *db) listRepositories(ctx context.Context, repoType *string) ([]*appsv1
|
|||
|
||||
func (db *db) credentialsToRepository(repoInfo settings.Repository) (*appsv1.Repository, error) {
|
||||
repo := &appsv1.Repository{
|
||||
Repo: repoInfo.URL,
|
||||
Type: repoInfo.Type,
|
||||
Name: repoInfo.Name,
|
||||
InsecureIgnoreHostKey: repoInfo.InsecureIgnoreHostKey,
|
||||
Insecure: repoInfo.Insecure,
|
||||
EnableLFS: repoInfo.EnableLFS,
|
||||
EnableOCI: repoInfo.EnableOci,
|
||||
Repo: repoInfo.URL,
|
||||
Type: repoInfo.Type,
|
||||
Name: repoInfo.Name,
|
||||
InsecureIgnoreHostKey: repoInfo.InsecureIgnoreHostKey,
|
||||
Insecure: repoInfo.Insecure,
|
||||
EnableLFS: repoInfo.EnableLFS,
|
||||
EnableOCI: repoInfo.EnableOci,
|
||||
GithubAppId: repoInfo.GithubAppId,
|
||||
GithubAppInstallationId: repoInfo.GithubAppInstallationId,
|
||||
GitHubAppEnterpriseBaseURL: repoInfo.GithubAppEnterpriseBaseURL,
|
||||
}
|
||||
err := db.unmarshalFromSecretsStr(map[*string]*apiv1.SecretKeySelector{
|
||||
&repo.Username: repoInfo.UsernameSecret,
|
||||
&repo.Password: repoInfo.PasswordSecret,
|
||||
&repo.SSHPrivateKey: repoInfo.SSHPrivateKeySecret,
|
||||
&repo.TLSClientCertData: repoInfo.TLSClientCertDataSecret,
|
||||
&repo.TLSClientCertKey: repoInfo.TLSClientCertKeySecret,
|
||||
&repo.Username: repoInfo.UsernameSecret,
|
||||
&repo.Password: repoInfo.PasswordSecret,
|
||||
&repo.SSHPrivateKey: repoInfo.SSHPrivateKeySecret,
|
||||
&repo.TLSClientCertData: repoInfo.TLSClientCertDataSecret,
|
||||
&repo.TLSClientCertKey: repoInfo.TLSClientCertKeySecret,
|
||||
&repo.GithubAppPrivateKey: repoInfo.GithubAppPrivateKeySecret,
|
||||
}, make(map[string]*apiv1.Secret))
|
||||
return repo, err
|
||||
}
|
||||
|
||||
func (db *db) credentialsToRepositoryCredentials(repoInfo settings.RepositoryCredentials) (*appsv1.RepoCreds, error) {
|
||||
creds := &appsv1.RepoCreds{
|
||||
URL: repoInfo.URL,
|
||||
URL: repoInfo.URL,
|
||||
GithubAppId: repoInfo.GithubAppId,
|
||||
GithubAppInstallationId: repoInfo.GithubAppInstallationId,
|
||||
GitHubAppEnterpriseBaseURL: repoInfo.GithubAppEnterpriseBaseURL,
|
||||
}
|
||||
err := db.unmarshalFromSecretsStr(map[*string]*apiv1.SecretKeySelector{
|
||||
&creds.Username: repoInfo.UsernameSecret,
|
||||
&creds.Password: repoInfo.PasswordSecret,
|
||||
&creds.SSHPrivateKey: repoInfo.SSHPrivateKeySecret,
|
||||
&creds.TLSClientCertData: repoInfo.TLSClientCertDataSecret,
|
||||
&creds.TLSClientCertKey: repoInfo.TLSClientCertKeySecret,
|
||||
&creds.Username: repoInfo.UsernameSecret,
|
||||
&creds.Password: repoInfo.PasswordSecret,
|
||||
&creds.SSHPrivateKey: repoInfo.SSHPrivateKeySecret,
|
||||
&creds.TLSClientCertData: repoInfo.TLSClientCertDataSecret,
|
||||
&creds.TLSClientCertKey: repoInfo.TLSClientCertKeySecret,
|
||||
&creds.GithubAppPrivateKey: repoInfo.GithubAppPrivateKeySecret,
|
||||
}, make(map[string]*apiv1.Secret))
|
||||
return creds, err
|
||||
}
|
||||
|
|
@ -241,11 +257,12 @@ func (db *db) DeleteRepository(ctx context.Context, repoURL string) error {
|
|||
return status.Errorf(codes.NotFound, "repo '%s' not found", repoURL)
|
||||
}
|
||||
err = db.updateRepositorySecrets(&repos[index], &appsv1.Repository{
|
||||
SSHPrivateKey: "",
|
||||
Password: "",
|
||||
Username: "",
|
||||
TLSClientCertData: "",
|
||||
TLSClientCertKey: "",
|
||||
SSHPrivateKey: "",
|
||||
Password: "",
|
||||
Username: "",
|
||||
TLSClientCertData: "",
|
||||
TLSClientCertKey: "",
|
||||
GithubAppPrivateKey: "",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -301,7 +318,10 @@ func (db *db) CreateRepositoryCredentials(ctx context.Context, r *appsv1.RepoCre
|
|||
}
|
||||
|
||||
repoInfo := settings.RepositoryCredentials{
|
||||
URL: r.URL,
|
||||
URL: r.URL,
|
||||
GithubAppId: r.GithubAppId,
|
||||
GithubAppInstallationId: r.GithubAppInstallationId,
|
||||
GithubAppEnterpriseBaseURL: r.GitHubAppEnterpriseBaseURL,
|
||||
}
|
||||
|
||||
err = db.updateCredentialsSecret(&repoInfo, r)
|
||||
|
|
@ -357,11 +377,12 @@ func (db *db) DeleteRepositoryCredentials(ctx context.Context, name string) erro
|
|||
return status.Errorf(codes.NotFound, "repository credentials '%s' not found", name)
|
||||
}
|
||||
err = db.updateCredentialsSecret(&repos[index], &appsv1.RepoCreds{
|
||||
SSHPrivateKey: "",
|
||||
Password: "",
|
||||
Username: "",
|
||||
TLSClientCertData: "",
|
||||
TLSClientCertKey: "",
|
||||
SSHPrivateKey: "",
|
||||
Password: "",
|
||||
Username: "",
|
||||
TLSClientCertData: "",
|
||||
TLSClientCertKey: "",
|
||||
GithubAppPrivateKey: "",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -372,12 +393,16 @@ func (db *db) DeleteRepositoryCredentials(ctx context.Context, name string) erro
|
|||
|
||||
func (db *db) updateCredentialsSecret(credsInfo *settings.RepositoryCredentials, c *appsv1.RepoCreds) error {
|
||||
r := &appsv1.Repository{
|
||||
Repo: c.URL,
|
||||
Username: c.Username,
|
||||
Password: c.Password,
|
||||
SSHPrivateKey: c.SSHPrivateKey,
|
||||
TLSClientCertData: c.TLSClientCertData,
|
||||
TLSClientCertKey: c.TLSClientCertKey,
|
||||
Repo: c.URL,
|
||||
Username: c.Username,
|
||||
Password: c.Password,
|
||||
SSHPrivateKey: c.SSHPrivateKey,
|
||||
TLSClientCertData: c.TLSClientCertData,
|
||||
TLSClientCertKey: c.TLSClientCertKey,
|
||||
GithubAppPrivateKey: c.GithubAppPrivateKey,
|
||||
GithubAppId: c.GithubAppId,
|
||||
GithubAppInstallationId: c.GithubAppInstallationId,
|
||||
GitHubAppEnterpriseBaseURL: c.GitHubAppEnterpriseBaseURL,
|
||||
}
|
||||
secretsData := make(map[string]map[string][]byte)
|
||||
|
||||
|
|
@ -386,6 +411,7 @@ func (db *db) updateCredentialsSecret(credsInfo *settings.RepositoryCredentials,
|
|||
credsInfo.SSHPrivateKeySecret = setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.SSHPrivateKeySecret, r.SSHPrivateKey, sshPrivateKey)
|
||||
credsInfo.TLSClientCertDataSecret = setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.TLSClientCertDataSecret, r.TLSClientCertData, tlsClientCertData)
|
||||
credsInfo.TLSClientCertKeySecret = setSecretData(credSecretPrefix, r.Repo, secretsData, credsInfo.TLSClientCertKeySecret, r.TLSClientCertKey, tlsClientCertKey)
|
||||
credsInfo.GithubAppPrivateKeySecret = setSecretData(repoSecretPrefix, r.Repo, secretsData, credsInfo.GithubAppPrivateKeySecret, r.GithubAppPrivateKey, githubAppPrivateKey)
|
||||
for k, v := range secretsData {
|
||||
err := db.upsertSecret(k, v)
|
||||
if err != nil {
|
||||
|
|
@ -403,6 +429,7 @@ func (db *db) updateRepositorySecrets(repoInfo *settings.Repository, r *appsv1.R
|
|||
repoInfo.SSHPrivateKeySecret = setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.SSHPrivateKeySecret, r.SSHPrivateKey, sshPrivateKey)
|
||||
repoInfo.TLSClientCertDataSecret = setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.TLSClientCertDataSecret, r.TLSClientCertData, tlsClientCertData)
|
||||
repoInfo.TLSClientCertKeySecret = setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.TLSClientCertKeySecret, r.TLSClientCertKey, tlsClientCertKey)
|
||||
repoInfo.GithubAppPrivateKeySecret = setSecretData(repoSecretPrefix, r.Repo, secretsData, repoInfo.GithubAppPrivateKeySecret, r.GithubAppPrivateKey, githubAppPrivateKey)
|
||||
for k, v := range secretsData {
|
||||
err := db.upsertSecret(k, v)
|
||||
if err != nil {
|
||||
|
|
@ -462,7 +489,7 @@ func (db *db) upsertSecret(name string, data map[string][]byte) error {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
for _, key := range []string{username, password, sshPrivateKey, tlsClientCertData, tlsClientCertKey} {
|
||||
for _, key := range []string{username, password, sshPrivateKey, tlsClientCertData, tlsClientCertKey, githubAppPrivateKey} {
|
||||
if secret.Data == nil {
|
||||
secret.Data = make(map[string][]byte)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,16 +131,16 @@ func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds) *http.Client
|
|||
var err error
|
||||
cert := tls.Certificate{}
|
||||
|
||||
// If we aren't called with HTTPSCreds, then we just return an empty cert
|
||||
httpsCreds, ok := creds.(HTTPSCreds)
|
||||
// If we aren't called with GenericHTTPSCreds, then we just return an empty cert
|
||||
httpsCreds, ok := creds.(GenericHTTPSCreds)
|
||||
if !ok {
|
||||
return &cert, nil
|
||||
}
|
||||
|
||||
// If the creds contain client certificate data, we return a TLS.Certificate
|
||||
// populated with the cert and its key.
|
||||
if httpsCreds.clientCertData != "" && httpsCreds.clientCertKey != "" {
|
||||
cert, err = tls.X509KeyPair([]byte(httpsCreds.clientCertData), []byte(httpsCreds.clientCertKey))
|
||||
if httpsCreds.HasClientCert() {
|
||||
cert, err = tls.X509KeyPair([]byte(httpsCreds.GetClientCertData()), []byte(httpsCreds.GetClientCertKey()))
|
||||
if err != nil {
|
||||
log.Errorf("Could not load Client Certificate: %v", err)
|
||||
return &cert, nil
|
||||
|
|
@ -218,6 +218,13 @@ func newAuth(repoURL string, creds Creds) (transport.AuthMethod, error) {
|
|||
case HTTPSCreds:
|
||||
auth := githttp.BasicAuth{Username: creds.username, Password: creds.password}
|
||||
return &auth, nil
|
||||
case GitHubAppCreds:
|
||||
token, err := creds.getAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
auth := githttp.BasicAuth{Username: "x-access-token", Password: token}
|
||||
return &auth, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,43 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
gocache "github.com/patrickmn/go-cache"
|
||||
|
||||
argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
|
||||
"github.com/bradleyfalzon/ghinstallation"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
|
||||
certutil "github.com/argoproj/argo-cd/util/cert"
|
||||
)
|
||||
|
||||
// In memory cache for storing github APP api token credentials
|
||||
var (
|
||||
githubAppTokenCache *gocache.Cache
|
||||
)
|
||||
|
||||
func init() {
|
||||
githubAppCredsExp := common.GithubAppCredsExpirationDuration
|
||||
if exp := os.Getenv(common.EnvGithubAppCredsExpirationDuration); exp != "" {
|
||||
if qps, err := strconv.Atoi(exp); err != nil {
|
||||
githubAppCredsExp = time.Duration(qps) * time.Minute
|
||||
}
|
||||
}
|
||||
|
||||
githubAppTokenCache = gocache.New(githubAppCredsExp, 1*time.Minute)
|
||||
}
|
||||
|
||||
type Creds interface {
|
||||
Environ() (io.Closer, []string, error)
|
||||
}
|
||||
|
|
@ -32,6 +57,13 @@ func (c NopCreds) Environ() (io.Closer, []string, error) {
|
|||
return NopCloser{}, nil, nil
|
||||
}
|
||||
|
||||
type GenericHTTPSCreds interface {
|
||||
HasClientCert() bool
|
||||
GetClientCertData() string
|
||||
GetClientCertKey() string
|
||||
Environ() (io.Closer, []string, error)
|
||||
}
|
||||
|
||||
// HTTPS creds implementation
|
||||
type HTTPSCreds struct {
|
||||
// Username for authentication
|
||||
|
|
@ -46,7 +78,7 @@ type HTTPSCreds struct {
|
|||
clientCertKey string
|
||||
}
|
||||
|
||||
func NewHTTPSCreds(username string, password string, clientCertData string, clientCertKey string, insecure bool) HTTPSCreds {
|
||||
func NewHTTPSCreds(username string, password string, clientCertData string, clientCertKey string, insecure bool) GenericHTTPSCreds {
|
||||
return HTTPSCreds{
|
||||
username,
|
||||
password,
|
||||
|
|
@ -71,7 +103,7 @@ func (c HTTPSCreds) Environ() (io.Closer, []string, error) {
|
|||
// In case the repo is configured for using a TLS client cert, we need to make
|
||||
// sure git client will use it. The certificate's key must not be password
|
||||
// protected.
|
||||
if c.clientCertData != "" && c.clientCertKey != "" {
|
||||
if c.HasClientCert() {
|
||||
var certFile, keyFile *os.File
|
||||
|
||||
// We need to actually create two temp files, one for storing cert data and
|
||||
|
|
@ -116,6 +148,18 @@ func (c HTTPSCreds) Environ() (io.Closer, []string, error) {
|
|||
return httpCloser, env, nil
|
||||
}
|
||||
|
||||
func (g HTTPSCreds) HasClientCert() bool {
|
||||
return g.clientCertData != "" && g.clientCertKey != ""
|
||||
}
|
||||
|
||||
func (c HTTPSCreds) GetClientCertData() string {
|
||||
return c.clientCertData
|
||||
}
|
||||
|
||||
func (c HTTPSCreds) GetClientCertKey() string {
|
||||
return c.clientCertKey
|
||||
}
|
||||
|
||||
// SSH implementation
|
||||
type SSHCreds struct {
|
||||
sshPrivateKey string
|
||||
|
|
@ -179,3 +223,143 @@ func (c SSHCreds) Environ() (io.Closer, []string, error) {
|
|||
env = append(env, []string{fmt.Sprintf("GIT_SSH_COMMAND=%s", strings.Join(args, " "))}...)
|
||||
return sshPrivateKeyFile(file.Name()), env, nil
|
||||
}
|
||||
|
||||
// GitHubAppCreds to authenticate as GitHub application
|
||||
type GitHubAppCreds struct {
|
||||
appID int64
|
||||
appInstallId int64
|
||||
privateKey string
|
||||
baseURL string
|
||||
repoURL string
|
||||
clientCertData string
|
||||
clientCertKey string
|
||||
insecure bool
|
||||
}
|
||||
|
||||
// NewGitHubAppCreds provide github app credentials
|
||||
func NewGitHubAppCreds(appID int64, appInstallId int64, privateKey string, baseURL string, repoURL string, clientCertData string, clientCertKey string, insecure bool) GenericHTTPSCreds {
|
||||
return GitHubAppCreds{appID: appID, appInstallId: appInstallId, privateKey: privateKey, baseURL: baseURL, repoURL: repoURL, clientCertData: clientCertData, clientCertKey: clientCertKey, insecure: insecure}
|
||||
}
|
||||
|
||||
func (g GitHubAppCreds) Environ() (io.Closer, []string, error) {
|
||||
token, err := g.getAccessToken()
|
||||
if err != nil {
|
||||
return NopCloser{}, nil, err
|
||||
}
|
||||
|
||||
env := []string{fmt.Sprintf("GIT_ASKPASS=%s", "git-ask-pass.sh"), "GIT_USERNAME=x-access-token", fmt.Sprintf("GIT_PASSWORD=%s", token)}
|
||||
httpCloser := authFilePaths(make([]string, 0))
|
||||
|
||||
// GIT_SSL_NO_VERIFY is used to tell git not to validate the server's cert at
|
||||
// all.
|
||||
if g.insecure {
|
||||
env = append(env, "GIT_SSL_NO_VERIFY=true")
|
||||
}
|
||||
|
||||
// In case the repo is configured for using a TLS client cert, we need to make
|
||||
// sure git client will use it. The certificate's key must not be password
|
||||
// protected.
|
||||
if g.HasClientCert() {
|
||||
var certFile, keyFile *os.File
|
||||
|
||||
// We need to actually create two temp files, one for storing cert data and
|
||||
// another for storing the key. If we fail to create second fail, the first
|
||||
// must be removed.
|
||||
certFile, err := ioutil.TempFile(argoio.TempDir, "")
|
||||
if err == nil {
|
||||
defer certFile.Close()
|
||||
keyFile, err = ioutil.TempFile(argoio.TempDir, "")
|
||||
if err != nil {
|
||||
removeErr := os.Remove(certFile.Name())
|
||||
if removeErr != nil {
|
||||
log.Errorf("Could not remove previously created tempfile %s: %v", certFile.Name(), removeErr)
|
||||
}
|
||||
return NopCloser{}, nil, err
|
||||
}
|
||||
defer keyFile.Close()
|
||||
} else {
|
||||
return NopCloser{}, nil, err
|
||||
}
|
||||
|
||||
// We should have both temp files by now
|
||||
httpCloser = authFilePaths([]string{certFile.Name(), keyFile.Name()})
|
||||
|
||||
_, err = certFile.WriteString(g.clientCertData)
|
||||
if err != nil {
|
||||
httpCloser.Close()
|
||||
return NopCloser{}, nil, err
|
||||
}
|
||||
// GIT_SSL_CERT is the full path to a client certificate to be used
|
||||
env = append(env, fmt.Sprintf("GIT_SSL_CERT=%s", certFile.Name()))
|
||||
|
||||
_, err = keyFile.WriteString(g.clientCertKey)
|
||||
if err != nil {
|
||||
httpCloser.Close()
|
||||
return NopCloser{}, nil, err
|
||||
}
|
||||
// GIT_SSL_KEY is the full path to a client certificate's key to be used
|
||||
env = append(env, fmt.Sprintf("GIT_SSL_KEY=%s", keyFile.Name()))
|
||||
|
||||
}
|
||||
return httpCloser, env, nil
|
||||
}
|
||||
|
||||
// getAccessToken fetches GitHub token using the app id, install id, and private key.
|
||||
// the token is then cached for re-use.
|
||||
func (g GitHubAppCreds) getAccessToken() (string, error) {
|
||||
// Timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Compute hash of creds for lookup in cache
|
||||
h := sha256.New()
|
||||
_, err := h.Write([]byte(fmt.Sprintf("%s %d %d %s", g.privateKey, g.appID, g.appInstallId, g.baseURL)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
key := fmt.Sprintf("%x", h.Sum(nil))
|
||||
|
||||
// Check cache for GitHub transport which helps fetch an API token
|
||||
t, found := githubAppTokenCache.Get(key)
|
||||
if found {
|
||||
itr := t.(*ghinstallation.Transport)
|
||||
// This method caches the token and if it's expired retrieves a new one
|
||||
return itr.Token(ctx)
|
||||
}
|
||||
|
||||
// GitHub API url
|
||||
baseUrl := "https://api.github.com"
|
||||
if g.baseURL != "" {
|
||||
baseUrl = strings.TrimSuffix(g.baseURL, "/")
|
||||
}
|
||||
|
||||
// Create a new GitHub transport
|
||||
c := GetRepoHTTPClient(baseUrl, g.insecure, g)
|
||||
itr, err := ghinstallation.New(c.Transport,
|
||||
g.appID,
|
||||
g.appInstallId,
|
||||
[]byte(g.privateKey),
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
itr.BaseURL = baseUrl
|
||||
|
||||
// Add transport to cache
|
||||
githubAppTokenCache.Set(key, itr, time.Minute*60)
|
||||
|
||||
return itr.Token(ctx)
|
||||
}
|
||||
|
||||
func (g GitHubAppCreds) HasClientCert() bool {
|
||||
return g.clientCertData != "" && g.clientCertKey != ""
|
||||
}
|
||||
|
||||
func (g GitHubAppCreds) GetClientCertData() string {
|
||||
return g.clientCertData
|
||||
}
|
||||
|
||||
func (g GitHubAppCreds) GetClientCertKey() string {
|
||||
return g.clientCertKey
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,6 +177,14 @@ type Repository struct {
|
|||
TLSClientCertKeySecret *apiv1.SecretKeySelector `json:"tlsClientCertKeySecret,omitempty"`
|
||||
// Whether the repo is helm-oci enabled. Git only.
|
||||
EnableOci bool `json:"enableOci,omitempty"`
|
||||
// Github App Private Key PEM data
|
||||
GithubAppPrivateKeySecret *apiv1.SecretKeySelector `json:"githubAppPrivateKeySecret,omitempty"`
|
||||
// Github App ID of the app used to access the repo
|
||||
GithubAppId int64 `json:"githubAppID,omitempty"`
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
GithubAppInstallationId int64 `json:"githubAppInstallationID,omitempty"`
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
GithubAppEnterpriseBaseURL string `json:"githubAppEnterpriseBaseUrl,omitempty"`
|
||||
}
|
||||
|
||||
// Credential template for accessing repositories
|
||||
|
|
@ -193,6 +201,14 @@ type RepositoryCredentials struct {
|
|||
TLSClientCertDataSecret *apiv1.SecretKeySelector `json:"tlsClientCertDataSecret,omitempty"`
|
||||
// Name of the secret storing the TLS client cert's key data
|
||||
TLSClientCertKeySecret *apiv1.SecretKeySelector `json:"tlsClientCertKeySecret,omitempty"`
|
||||
// Github App Private Key PEM data
|
||||
GithubAppPrivateKeySecret *apiv1.SecretKeySelector `json:"githubAppPrivateKeySecret,omitempty"`
|
||||
// Github App ID of the app used to access the repo
|
||||
GithubAppId int64 `json:"githubAppID,omitempty"`
|
||||
// Github App Installation ID of the installed GitHub App
|
||||
GithubAppInstallationId int64 `json:"githubAppInstallationID,omitempty"`
|
||||
// Github App Enterprise base url if empty will default to https://api.github.com
|
||||
GithubAppEnterpriseBaseURL string `json:"githubAppEnterpriseBaseUrl,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
|||
Loading…
Reference in a new issue