mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-28 21:48:46 +01:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe80bdcfdc | ||
|
|
94c09dff59 | ||
|
|
3d9e4d439e | ||
|
|
4a955e25a0 | ||
|
|
4f99f251bf | ||
|
|
fd418cec0d | ||
|
|
dc291a629f | ||
|
|
e23a1c6026 | ||
|
|
aee88c6452 | ||
|
|
3f111cc640 | ||
|
|
596038fc0f | ||
|
|
471685feae | ||
|
|
42e1f29117 | ||
|
|
c089f9a5e5 | ||
|
|
1dc5e6aaf9 | ||
|
|
82726fcbcf | ||
|
|
e715e085aa | ||
|
|
7db5ab71b0 |
1
USERS.md
1
USERS.md
@@ -37,6 +37,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
||||
1. [Chargetrip](https://chargetrip.com)
|
||||
1. [Chime](https://www.chime.com)
|
||||
1. [Cisco ET&I](https://eti.cisco.com/)
|
||||
1. [Cobalt](https://www.cobalt.io/)
|
||||
1. [Codefresh](https://www.codefresh.io/)
|
||||
1. [Codility](https://www.codility.com/)
|
||||
1. [Commonbond](https://commonbond.co/)
|
||||
|
||||
@@ -162,8 +162,10 @@ func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent []
|
||||
}
|
||||
params["path"] = path.Dir(filePath)
|
||||
params["path.basename"] = path.Base(params["path"])
|
||||
params["path.filename"] = path.Base(filePath)
|
||||
params["path.basenameNormalized"] = sanitizeName(path.Base(params["path"]))
|
||||
for k, v := range strings.Split(strings.TrimSuffix(params["path"], params["path.basename"]), "/") {
|
||||
params["path.filenameNormalized"] = sanitizeName(path.Base(params["path.filename"]))
|
||||
for k, v := range strings.Split(params["path"], "/") {
|
||||
if len(v) > 0 {
|
||||
params["path["+strconv.Itoa(k)+"]"] = v
|
||||
}
|
||||
@@ -213,7 +215,7 @@ func (g *GitGenerator) generateParamsFromApps(requestedApps []string, _ *argopro
|
||||
params["path"] = a
|
||||
params["path.basename"] = path.Base(a)
|
||||
params["path.basenameNormalized"] = sanitizeName(path.Base(a))
|
||||
for k, v := range strings.Split(strings.TrimSuffix(params["path"], params["path.basename"]), "/") {
|
||||
for k, v := range strings.Split(params["path"], "/") {
|
||||
if len(v) > 0 {
|
||||
params["path["+strconv.Itoa(k)+"]"] = v
|
||||
}
|
||||
|
||||
@@ -47,6 +47,28 @@ func (a argoCDServiceMock) GetDirectories(ctx context.Context, repoURL string, r
|
||||
return args.Get(0).([]string), args.Error(1)
|
||||
}
|
||||
|
||||
func Test_generateParamsFromGitFile(t *testing.T) {
|
||||
params, err := (*GitGenerator)(nil).generateParamsFromGitFile("path/dir/file_name.yaml", []byte(`
|
||||
foo:
|
||||
bar: baz
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"foo.bar": "baz",
|
||||
"path": "path/dir",
|
||||
"path.basename": "dir",
|
||||
"path.filename": "file_name.yaml",
|
||||
"path.basenameNormalized": "dir",
|
||||
"path.filenameNormalized": "file-name.yaml",
|
||||
"path[0]": "path",
|
||||
"path[1]": "dir",
|
||||
},
|
||||
}, params)
|
||||
}
|
||||
|
||||
func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
@@ -68,9 +90,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "app_3", "path.basename": "app_3", "path.basenameNormalized": "app-3"},
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2", "path[0]": "app2"},
|
||||
{"path": "app_3", "path.basename": "app_3", "path.basenameNormalized": "app-3", "path[0]": "app_3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -85,8 +107,8 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path.basenameNormalized": "app2"},
|
||||
{"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path.basenameNormalized": "app3"},
|
||||
{"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path[1]": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path[2]": "app3", "path.basenameNormalized": "app3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -102,9 +124,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path.basenameNormalized": "app3"},
|
||||
{"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -120,9 +142,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
|
||||
},
|
||||
repoError: nil,
|
||||
expected: []map[string]string{
|
||||
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path.basenameNormalized": "app3"},
|
||||
{"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"},
|
||||
{"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"},
|
||||
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
@@ -238,7 +260,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "foo.bar@example.com",
|
||||
@@ -247,7 +272,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/staging",
|
||||
"path.basename": "staging",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "staging",
|
||||
"path.basenameNormalized": "staging",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
@@ -305,7 +333,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "john.doe@example.com",
|
||||
@@ -314,7 +345,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.json",
|
||||
"path.filenameNormalized": "config.json",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
@@ -353,7 +387,10 @@ cluster:
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "foo.bar@example.com",
|
||||
@@ -362,7 +399,10 @@ cluster:
|
||||
"path": "cluster-config/staging",
|
||||
"path.basename": "staging",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "staging",
|
||||
"path.basenameNormalized": "staging",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
@@ -393,7 +433,10 @@ cluster:
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
{
|
||||
"cluster.owner": "john.doe@example.com",
|
||||
@@ -402,7 +445,10 @@ cluster:
|
||||
"path": "cluster-config/production",
|
||||
"path.basename": "production",
|
||||
"path[0]": "cluster-config",
|
||||
"path[1]": "production",
|
||||
"path.basenameNormalized": "production",
|
||||
"path.filename": "config.yaml",
|
||||
"path.filenameNormalized": "config.yaml",
|
||||
},
|
||||
},
|
||||
expectedError: nil,
|
||||
|
||||
@@ -81,6 +81,7 @@ func NewCommand() *cobra.Command {
|
||||
redisClient *redis.Client
|
||||
disableTLS bool
|
||||
maxCombinedDirectoryManifestsSize string
|
||||
cmpTarExcludedGlobs []string
|
||||
)
|
||||
var command = cobra.Command{
|
||||
Use: cliName,
|
||||
@@ -113,6 +114,7 @@ func NewCommand() *cobra.Command {
|
||||
PauseGenerationOnFailureForRequests: getPauseGenerationOnFailureForRequests(),
|
||||
SubmoduleEnabled: getSubmoduleEnabled(),
|
||||
MaxCombinedDirectoryManifestsSize: maxCombinedDirectoryManifestsQuantity,
|
||||
CMPTarExcludedGlobs: cmpTarExcludedGlobs,
|
||||
}, askPassServer)
|
||||
errors.CheckError(err)
|
||||
|
||||
@@ -189,6 +191,7 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_REPO_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to")
|
||||
command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_TLS", false), "Disable TLS on the gRPC endpoint")
|
||||
command.Flags().StringVar(&maxCombinedDirectoryManifestsSize, "max-combined-directory-manifests-size", env.StringFromEnv("ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE", "10M"), "Max combined size of manifest files in a directory-type Application")
|
||||
command.Flags().StringArrayVar(&cmpTarExcludedGlobs, "plugin-tar-exclude", env.StringsFromEnv("ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS", []string{}, ";"), "Globs to filter when sending tarballs to plugins.")
|
||||
|
||||
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
|
||||
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {
|
||||
|
||||
@@ -152,7 +152,10 @@ func NewCommand() *cobra.Command {
|
||||
stats.RegisterStackDumper()
|
||||
stats.StartStatsTicker(10 * time.Minute)
|
||||
stats.RegisterHeapDumper("memprofile")
|
||||
|
||||
argocd := server.NewServer(context.Background(), argoCDOpts)
|
||||
argocd.Init(context.Background())
|
||||
lns, err := argocd.Listen()
|
||||
errors.CheckError(err)
|
||||
for {
|
||||
var closer func()
|
||||
ctx := context.Background()
|
||||
@@ -163,8 +166,7 @@ func NewCommand() *cobra.Command {
|
||||
log.Fatalf("failed to initialize tracing: %v", err)
|
||||
}
|
||||
}
|
||||
argocd := server.NewServer(ctx, argoCDOpts)
|
||||
argocd.Run(ctx, listenPort, metricsPort)
|
||||
argocd.Run(ctx, lns)
|
||||
cancel()
|
||||
if closer != nil {
|
||||
closer()
|
||||
|
||||
@@ -215,8 +215,13 @@ func StartLocalServer(clientOpts *apiclient.ClientOptions, ctxStr string, port *
|
||||
ListenHost: *address,
|
||||
RepoClientset: &forwardRepoClientset{namespace: namespace, context: ctxStr},
|
||||
})
|
||||
srv.Init(ctx)
|
||||
|
||||
go srv.Run(ctx, *port, 0)
|
||||
lns, err := srv.Listen()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go srv.Run(ctx, lns)
|
||||
clientOpts.ServerAddr = fmt.Sprintf("%s:%d", *address, *port)
|
||||
clientOpts.PlainText = true
|
||||
if !cache2.WaitForCacheSync(ctx.Done(), srv.Initialized) {
|
||||
|
||||
@@ -4,10 +4,10 @@ You can download the latest Argo CD version from [the latest release page of thi
|
||||
|
||||
## Linux and WSL
|
||||
|
||||
### ArchLinux User Repository ([AUR](https://aur.archlinux.org/packages/))
|
||||
### ArchLinux
|
||||
|
||||
```bash
|
||||
yay -Sy argocd-bin
|
||||
pacman -S argocd
|
||||
```
|
||||
|
||||
### Homebrew
|
||||
|
||||
@@ -65,13 +65,15 @@ The generator parameters are:
|
||||
- `{{path.basename}}`: For any directory path within the Git repository that matches the `path` wildcard, the right-most path name is extracted (e.g. `/directory/directory2` would produce `directory2`).
|
||||
- `{{path.basenameNormalized}}`: This field is the same as `path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `path.basename` of `directory_2` would produce `directory-2` here).
|
||||
|
||||
Whenever a new Helm chart/Kustomize YAML/Application/plain subfolder is added to the Git repository, the ApplicationSet controller will detect this change and automatically deploy the resulting manifests within new `Application` resources.
|
||||
**Note**: The right-most path name always becomes `{{path.basename}}`. For example, for `- path: /one/two/three/four`, `{{path.basename}}` is `four`.
|
||||
|
||||
Whenever a new Helm chart/Kustomize YAML/Application/plain subdirectory is added to the Git repository, the ApplicationSet controller will detect this change and automatically deploy the resulting manifests within new `Application` resources.
|
||||
|
||||
As with other generators, clusters *must* already be defined within Argo CD, in order to generate Applications for them.
|
||||
|
||||
### Exclude directories
|
||||
|
||||
The Git directory generator will automatically exclude folders that begin with `.` (such as `.git`).
|
||||
The Git directory generator will automatically exclude directories that begin with `.` (such as `.git`).
|
||||
|
||||
The Git directory generator also supports an `exclude` option in order to exclude directories in the repository from being scanned by the ApplicationSet controller:
|
||||
|
||||
@@ -205,7 +207,7 @@ Suppose you have a Git repository with the following directory structure:
|
||||
└── git-generator-files.yaml
|
||||
```
|
||||
|
||||
The folders are:
|
||||
The directories are:
|
||||
|
||||
- `guestbook` contains the Kubernetes resources for a simple guestbook application
|
||||
- `cluster-config` contains JSON/YAML files describing the individual engineering clusters: one for `dev` and one for `prod`.
|
||||
@@ -269,10 +271,16 @@ As with other generators, clusters *must* already be defined within Argo CD, in
|
||||
|
||||
In addition to the flattened key/value pairs from the configuration file, the following generator parameters are provided:
|
||||
|
||||
- `{{path}}`: The path to the folder containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json`
|
||||
- `{{path}}`: The path to the directory containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json`
|
||||
- `{{path[n]}}`: The path to the matching configuration file within the Git repository, split into array elements (`n` - array index). Example: `path[0]: clusters`, `path[1]: clusterA`
|
||||
- `{{path.basename}}`: Basename of the path to the folder containing the configuration file (e.g. `clusterA`, with the above example.)
|
||||
- `{{path.basename}}`: Basename of the path to the directory containing the configuration file (e.g. `clusterA`, with the above example.)
|
||||
- `{{path.basenameNormalized}}`: This field is the same as `path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `path.basename` of `directory_2` would produce `directory-2` here).
|
||||
- `{{path.filename}}`: The matched filename. e.g., `config.json` in the above example.
|
||||
- `{{path.filenameNormalized}}`: The matched filename with unsupported characters replaced with `-`.
|
||||
|
||||
**Note**: The right-most *directory* name always becomes `{{path.basename}}`. For example, from `- path: /one/two/three/four/config.json`, `{{path.basename}}` will be `four`.
|
||||
The filename can always be accessed using `{{path.filename}}`.
|
||||
|
||||
|
||||
## Webhook Configuration
|
||||
|
||||
|
||||
@@ -111,3 +111,5 @@ data:
|
||||
# for 300x memory expansion and N Applications running at the same time.
|
||||
# (example 10M max * 300 expansion * 10 Apps = 30G max theoretical memory usage).
|
||||
reposerver.max.combined.directory.manifests.size: '10M'
|
||||
# Paths to be excluded from the tarball streamed to plugins. Separate with ;
|
||||
reposerver.plugin.tar.exclusions: ""
|
||||
|
||||
@@ -22,6 +22,7 @@ argocd-repo-server [flags]
|
||||
--metrics-port int Start metrics server on given port (default 8084)
|
||||
--otlp-address string OpenTelemetry collector address to send traces to
|
||||
--parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit.
|
||||
--plugin-tar-exclude stringArray Globs to filter when sending tarballs to plugins.
|
||||
--port int Listen on given port for incoming connections (default 8081)
|
||||
--redis string Redis server hostname and port (e.g. argocd-redis:6379).
|
||||
--redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.
|
||||
|
||||
@@ -197,6 +197,7 @@ NOTES:
|
||||
* There is no need to set `redirectURI` in the `connectors.config` as shown in the dex documentation.
|
||||
Argo CD will automatically use the correct `redirectURI` for any OAuth2 connectors, to match the
|
||||
correct external callback URL (e.g. `https://argocd.example.com/api/dex/callback`)
|
||||
* When using a custom secret (e.g., `some_K8S_secret` above,) it *must* have the label `app.kubernetes.io/part-of: argocd`.
|
||||
|
||||
## OIDC Configuration with DEX
|
||||
|
||||
|
||||
@@ -234,3 +234,17 @@ If you don't need to set any environment variables, you can set an empty plugin
|
||||
Each CMP command will also independently timeout on the `ARGOCD_EXEC_TIMEOUT` set for the CMP sidecar. The default
|
||||
is 90s. So if you increase the repo server timeout greater than 90s, be sure to set `ARGOCD_EXEC_TIMEOUT` on the
|
||||
sidecar.
|
||||
|
||||
## Tarball stream filtering
|
||||
|
||||
In order to increase the speed of manifest generation, certain files and folders can be excluded from being sent to your
|
||||
plugin. We recommend excluding your `.git` folder if it isn't necessary. Use Go's
|
||||
[filepatch.Match](https://pkg.go.dev/path/filepath#Match) syntax.
|
||||
|
||||
You can set it one of three ways:
|
||||
1. The `--plugin-tar-exclude` argument on the repo server.
|
||||
2. The `reposerver.plugin.tar.exclusions` key if you are using `argocd-cmd-params-cm`
|
||||
3. Directly setting 'ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS' environment variable on the repo server.
|
||||
|
||||
For option 1, the flag can be repeated multiple times. For option 2 and 3, you can specify multiple globs by separating
|
||||
them with semicolons.
|
||||
14
go.mod
14
go.mod
@@ -17,7 +17,7 @@ require (
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.0.4
|
||||
github.com/casbin/casbin/v2 v2.39.1
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
@@ -60,7 +60,7 @@ require (
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d // indirect
|
||||
github.com/pquerna/cachecontrol v0.1.0 // indirect
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/r3labs/diff v1.1.0
|
||||
github.com/robfig/cron v1.2.0
|
||||
@@ -76,10 +76,10 @@ require (
|
||||
github.com/xanzy/go-gitlab v0.60.0
|
||||
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
golang.org/x/net v0.0.0-20220621193019-9d032be2e588
|
||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
|
||||
google.golang.org/grpc v1.45.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
@@ -202,7 +202,7 @@ require (
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
golang.org/x/exp v0.0.0-20210901193431-a062eea981d2 // indirect
|
||||
golang.org/x/mod v0.5.1-0.20210830214625-1b1db11ec8f4 // indirect
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff // indirect
|
||||
@@ -214,7 +214,7 @@ require (
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.2.2 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
k8s.io/apiserver v0.23.1
|
||||
|
||||
24
go.sum
24
go.sum
@@ -254,8 +254,9 @@ github.com/coredns/corefile-migration v1.0.14/go.mod h1:XnhgULOEouimnzgn0t4WPuFD
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
@@ -944,8 +945,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d h1:7gXyC293Lsm2YWgQ+0uaAFFFDO82ruiQSwc3ua+Vtlc=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
|
||||
github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
@@ -1343,8 +1344,10 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220621193019-9d032be2e588 h1:9ubFuySsnAJYGyJrZ3koiEv8FyqofCBdz3G9Mbf2YFc=
|
||||
golang.org/x/net v0.0.0-20220621193019-9d032be2e588/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1364,8 +1367,9 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb h1:8tDJ3aechhddbdPAxpycgXHJRMLpk/Ab+aa4OgdN5/g=
|
||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -1485,11 +1489,14 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1789,8 +1796,9 @@ gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.2
|
||||
newTag: v2.4.4
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -107,6 +107,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
|
||||
@@ -9385,7 +9385,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9603,13 +9603,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -9658,7 +9664,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -9845,7 +9851,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.2
|
||||
newTag: v2.4.4
|
||||
|
||||
@@ -11,7 +11,7 @@ patchesStrategicMerge:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.4.2
|
||||
newTag: v2.4.4
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -10320,7 +10320,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -10417,7 +10417,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -10457,7 +10457,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -10702,13 +10702,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10757,7 +10763,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -11004,7 +11010,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -11212,7 +11218,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1244,7 +1244,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1341,7 +1341,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1381,7 +1381,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1626,13 +1626,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1681,7 +1687,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1928,7 +1934,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2136,7 +2142,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -9692,7 +9692,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -9789,7 +9789,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -9829,7 +9829,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -10042,13 +10042,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -10097,7 +10103,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -10340,7 +10346,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -10542,7 +10548,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -616,7 +616,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -713,7 +713,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -753,7 +753,7 @@ spec:
|
||||
containers:
|
||||
- command:
|
||||
- argocd-notifications
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -966,13 +966,19 @@ spec:
|
||||
key: reposerver.max.combined.directory.manifests.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.plugin.tar.exclusions
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: HELM_CACHE_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_CONFIG_HOME
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1021,7 +1027,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1264,7 +1270,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -1466,7 +1472,7 @@ spec:
|
||||
key: otlp.address
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v2.4.2
|
||||
image: quay.io/argoproj/argocd:v2.4.4
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
||||
@@ -1542,6 +1542,19 @@ func isValidAction(action string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: same as validActions, refacotor to use rbacpolicy.ResourceApplications etc.
|
||||
var validResources = map[string]bool{
|
||||
"applications": true,
|
||||
"repositories": true,
|
||||
"clusters": true,
|
||||
"exec": true,
|
||||
"logs": true,
|
||||
}
|
||||
|
||||
func isValidResource(resource string) bool {
|
||||
return validResources[resource]
|
||||
}
|
||||
|
||||
func validatePolicy(proj string, role string, policy string) error {
|
||||
policyComponents := strings.Split(policy, ",")
|
||||
if len(policyComponents) != 6 || strings.Trim(policyComponents[0], " ") != "p" {
|
||||
@@ -1555,7 +1568,7 @@ func validatePolicy(proj string, role string, policy string) error {
|
||||
}
|
||||
// resource
|
||||
resource := strings.Trim(policyComponents[2], " ")
|
||||
if resource != "applications" && resource != "repositories" && resource != "clusters" {
|
||||
if !isValidResource(resource) {
|
||||
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', 'repositories' or 'clusters', not '%s'", policy, resource)
|
||||
}
|
||||
// action
|
||||
|
||||
@@ -2546,10 +2546,19 @@ func Test_validatePolicy_projIsNotRegex(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_validatePolicy_ValidResource(t *testing.T) {
|
||||
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
|
||||
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, applications, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, clusters, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, exec, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, logs, *, some-project/*, allow")
|
||||
assert.NoError(t, err)
|
||||
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, unknown, *, some-project/*, allow")
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestEnvsubst(t *testing.T) {
|
||||
|
||||
@@ -103,6 +103,7 @@ type RepoServerInitConstants struct {
|
||||
PauseGenerationOnFailureForRequests int
|
||||
SubmoduleEnabled bool
|
||||
MaxCombinedDirectoryManifestsSize resource.Quantity
|
||||
CMPTarExcludedGlobs []string
|
||||
}
|
||||
|
||||
// NewService returns a new instance of the Manifest service
|
||||
@@ -213,7 +214,7 @@ func (s *Service) ListApps(ctx context.Context, q *apiclient.ListAppsRequest) (*
|
||||
}
|
||||
|
||||
defer io.Close(closer)
|
||||
apps, err := discovery.Discover(ctx, gitClient.Root(), q.EnabledSourceTypes)
|
||||
apps, err := discovery.Discover(ctx, gitClient.Root(), q.EnabledSourceTypes, s.initConstants.CMPTarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -457,10 +458,15 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
|
||||
close(ch.errCh)
|
||||
close(ch.responseCh)
|
||||
}()
|
||||
|
||||
// GenerateManifests mutates the source (applies overrides). Those overrides shouldn't be reflected in the cache
|
||||
// key. Overrides will break the cache anyway, because changes to overrides will change the revision.
|
||||
appSourceCopy := q.ApplicationSource.DeepCopy()
|
||||
|
||||
var manifestGenResult *apiclient.ManifestResponse
|
||||
opContext, err := opContextSrc()
|
||||
if err == nil {
|
||||
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, WithCMPTarDoneChannel(ch.tarDoneCh))
|
||||
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs))
|
||||
}
|
||||
if err != nil {
|
||||
// If manifest generation error caching is enabled
|
||||
@@ -469,9 +475,9 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
|
||||
// Retrieve a new copy (if available) of the cached response: this ensures we are updating the latest copy of the cache,
|
||||
// rather than a copy of the cache that occurred before (a potentially lengthy) manifest generation.
|
||||
innerRes := &cache.CachedManifestResponse{}
|
||||
cacheErr := s.cache.GetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
|
||||
cacheErr := s.cache.GetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
|
||||
if cacheErr != nil && cacheErr != reposervercache.ErrCacheMiss {
|
||||
log.Warnf("manifest cache set error %s: %v", q.ApplicationSource.String(), cacheErr)
|
||||
log.Warnf("manifest cache set error %s: %v", appSourceCopy.String(), cacheErr)
|
||||
ch.errCh <- cacheErr
|
||||
return
|
||||
}
|
||||
@@ -485,9 +491,9 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
|
||||
// Update the cache to include failure information
|
||||
innerRes.NumberOfConsecutiveFailures++
|
||||
innerRes.MostRecentError = err.Error()
|
||||
cacheErr = s.cache.SetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
|
||||
cacheErr = s.cache.SetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
|
||||
if cacheErr != nil {
|
||||
log.Warnf("manifest cache set error %s: %v", q.ApplicationSource.String(), cacheErr)
|
||||
log.Warnf("manifest cache set error %s: %v", appSourceCopy.String(), cacheErr)
|
||||
ch.errCh <- cacheErr
|
||||
return
|
||||
}
|
||||
@@ -506,9 +512,9 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
|
||||
}
|
||||
manifestGenResult.Revision = commitSHA
|
||||
manifestGenResult.VerifyResult = opContext.verificationResult
|
||||
err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry)
|
||||
err = s.cache.SetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry)
|
||||
if err != nil {
|
||||
log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err)
|
||||
log.Warnf("manifest cache set error %s/%s: %v", appSourceCopy.String(), cacheKey, err)
|
||||
}
|
||||
ch.responseCh <- manifestGenCacheEntry.ManifestResponse
|
||||
}
|
||||
@@ -853,7 +859,8 @@ func getRepoCredential(repoCredentials []*v1alpha1.RepoCreds, repoURL string) *v
|
||||
|
||||
type GenerateManifestOpt func(*generateManifestOpt)
|
||||
type generateManifestOpt struct {
|
||||
cmpTarDoneCh chan<- bool
|
||||
cmpTarDoneCh chan<- bool
|
||||
cmpTarExcludedGlobs []string
|
||||
}
|
||||
|
||||
func newGenerateManifestOpt(opts ...GenerateManifestOpt) *generateManifestOpt {
|
||||
@@ -873,14 +880,23 @@ func WithCMPTarDoneChannel(ch chan<- bool) GenerateManifestOpt {
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateManifests generates manifests from a path
|
||||
// WithCMPTarExcludedGlobs defines globs for files to filter out when streaming the tarball
|
||||
// to a CMP sidecar.
|
||||
func WithCMPTarExcludedGlobs(excludedGlobs []string) GenerateManifestOpt {
|
||||
return func(o *generateManifestOpt) {
|
||||
o.cmpTarExcludedGlobs = excludedGlobs
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateManifests generates manifests from a path. Overrides are applied as a side effect on the given ApplicationSource.
|
||||
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) {
|
||||
opt := newGenerateManifestOpt(opts...)
|
||||
var targetObjs []*unstructured.Unstructured
|
||||
var dest *v1alpha1.ApplicationDestination
|
||||
|
||||
resourceTracking := argo.NewResourceTracking()
|
||||
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName, q.EnabledSourceTypes)
|
||||
|
||||
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName, q.EnabledSourceTypes, opt.cmpTarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -904,7 +920,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
|
||||
if q.ApplicationSource.Plugin != nil && q.ApplicationSource.Plugin.Name != "" {
|
||||
targetObjs, err = runConfigManagementPlugin(appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore))
|
||||
} else {
|
||||
targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh)
|
||||
targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("plugin sidecar failed. %s", err.Error())
|
||||
}
|
||||
@@ -992,7 +1008,7 @@ func mergeSourceParameters(source *v1alpha1.ApplicationSource, path, appName str
|
||||
overrides = append(overrides, filepath.Join(path, fmt.Sprintf(appSourceFile, appName)))
|
||||
}
|
||||
|
||||
var merged v1alpha1.ApplicationSource = *source.DeepCopy()
|
||||
var merged = *source.DeepCopy()
|
||||
|
||||
for _, filename := range overrides {
|
||||
info, err := os.Stat(filename)
|
||||
@@ -1038,7 +1054,7 @@ func mergeSourceParameters(source *v1alpha1.ApplicationSource, path, appName str
|
||||
}
|
||||
|
||||
// GetAppSourceType returns explicit application source type or examines a directory and determines its application source type
|
||||
func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, path, appName string, enableGenerateManifests map[string]bool) (v1alpha1.ApplicationSourceType, error) {
|
||||
func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, path, appName string, enableGenerateManifests map[string]bool, tarExcludedGlobs []string) (v1alpha1.ApplicationSourceType, error) {
|
||||
err := mergeSourceParameters(source, path, appName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error while parsing source parameters: %v", err)
|
||||
@@ -1055,7 +1071,7 @@ func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, p
|
||||
}
|
||||
return *appSourceType, nil
|
||||
}
|
||||
appType, err := discovery.AppType(ctx, path, enableGenerateManifests)
|
||||
appType, err := discovery.AppType(ctx, path, enableGenerateManifests, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -1459,7 +1475,7 @@ func getPluginEnvs(envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds gi
|
||||
return env, nil
|
||||
}
|
||||
|
||||
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool) ([]*unstructured.Unstructured, error) {
|
||||
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string) ([]*unstructured.Unstructured, error) {
|
||||
// compute variables.
|
||||
env, err := getPluginEnvs(envVars, q, creds, true)
|
||||
if err != nil {
|
||||
@@ -1467,14 +1483,14 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath st
|
||||
}
|
||||
|
||||
// detect config management plugin server (sidecar)
|
||||
conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath, env)
|
||||
conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath, env, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer io.Close(conn)
|
||||
|
||||
// generate manifests using commands provided in plugin config file in detected cmp-server sidecar
|
||||
cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh)
|
||||
cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error generating manifests in cmp: %s", err)
|
||||
}
|
||||
@@ -1492,7 +1508,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath st
|
||||
// generateManifestsCMP will send the appPath files to the cmp-server over a gRPC stream.
|
||||
// The cmp-server will generate the manifests. Returns a response object with the generated
|
||||
// manifests.
|
||||
func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool) (*pluginclient.ManifestResponse, error) {
|
||||
func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool, tarExcludedGlobs []string) (*pluginclient.ManifestResponse, error) {
|
||||
generateManifestStream, err := cmpClient.GenerateManifest(ctx, grpc_retry.Disable())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting generateManifestStream: %s", err)
|
||||
@@ -1500,7 +1516,7 @@ func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []s
|
||||
opts := []cmp.SenderOption{
|
||||
cmp.WithTarDoneChan(tarDoneCh),
|
||||
}
|
||||
err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, opts...)
|
||||
err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, tarExcludedGlobs, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error sending file to cmp-server: %s", err)
|
||||
}
|
||||
@@ -1518,7 +1534,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
|
||||
return err
|
||||
}
|
||||
|
||||
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName, q.EnabledSourceTypes)
|
||||
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName, q.EnabledSourceTypes, s.initConstants.CMPTarExcludedGlobs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1633,7 +1649,7 @@ func loadFileIntoIfExists(path pathutil.ResolvedFilePath, destination *string) e
|
||||
info, err := os.Stat(stringPath)
|
||||
|
||||
if err == nil && !info.IsDir() {
|
||||
bytes, err := ioutil.ReadFile(stringPath);
|
||||
bytes, err := ioutil.ReadFile(stringPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -133,6 +133,31 @@ func newServiceWithCommitSHA(root, revision string) *Service {
|
||||
return service
|
||||
}
|
||||
|
||||
// createSymlink creates a symlink with name linkName to file destName in
|
||||
// workingDir
|
||||
func createSymlink(t *testing.T, workingDir, destName, linkName string) error {
|
||||
oldWorkingDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if workingDir != "" {
|
||||
err = os.Chdir(workingDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := os.Chdir(oldWorkingDir); err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
err = os.Symlink(destName, linkName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestGenerateYamlManifestInDir(t *testing.T) {
|
||||
service := newService("../..")
|
||||
|
||||
@@ -1049,15 +1074,15 @@ func TestGenerateNullList(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIdentifyAppSourceTypeByAppDirWithKustomizations(t *testing.T) {
|
||||
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp", map[string]bool{})
|
||||
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp", map[string]bool{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
|
||||
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp", map[string]bool{})
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp", map[string]bool{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
|
||||
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp", map[string]bool{})
|
||||
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp", map[string]bool{}, []string{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
|
||||
}
|
||||
@@ -1122,19 +1147,20 @@ func TestListApps(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
|
||||
expectedApps := map[string]string{
|
||||
"Kustomization": "Kustomize",
|
||||
"app-parameters/multi": "Kustomize",
|
||||
"app-parameters/single-app-only": "Kustomize",
|
||||
"app-parameters/single-global": "Kustomize",
|
||||
"invalid-helm": "Helm",
|
||||
"in-bounds-values-file-link": "Helm",
|
||||
"invalid-kustomize": "Kustomize",
|
||||
"kustomization_yaml": "Kustomize",
|
||||
"kustomization_yml": "Kustomize",
|
||||
"my-chart": "Helm",
|
||||
"my-chart-2": "Helm",
|
||||
"out-of-bounds-values-file-link": "Helm",
|
||||
"values-files": "Helm",
|
||||
"Kustomization": "Kustomize",
|
||||
"app-parameters/multi": "Kustomize",
|
||||
"app-parameters/single-app-only": "Kustomize",
|
||||
"app-parameters/single-global": "Kustomize",
|
||||
"app-parameters/single-global-helm": "Helm",
|
||||
"invalid-helm": "Helm",
|
||||
"in-bounds-values-file-link": "Helm",
|
||||
"invalid-kustomize": "Kustomize",
|
||||
"kustomization_yaml": "Kustomize",
|
||||
"kustomization_yml": "Kustomize",
|
||||
"my-chart": "Helm",
|
||||
"my-chart-2": "Helm",
|
||||
"out-of-bounds-values-file-link": "Helm",
|
||||
"values-files": "Helm",
|
||||
}
|
||||
assert.Equal(t, expectedApps, res.Apps)
|
||||
}
|
||||
@@ -1486,6 +1512,35 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Single global override Helm", func(t *testing.T) {
|
||||
runWithTempTestdata(t, "single-global-helm", func(t *testing.T, path string) {
|
||||
service := newService(".")
|
||||
manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
|
||||
Repo: &argoappv1.Repository{},
|
||||
ApplicationSource: &argoappv1.ApplicationSource{
|
||||
Path: path,
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
resourceByKindName := make(map[string]*unstructured.Unstructured)
|
||||
for _, manifest := range manifests.Manifests {
|
||||
var un unstructured.Unstructured
|
||||
err := yaml.Unmarshal([]byte(manifest), &un)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un
|
||||
}
|
||||
deployment, ok := resourceByKindName["Deployment/guestbook-ui"]
|
||||
require.True(t, ok)
|
||||
containers, ok, _ := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers")
|
||||
require.True(t, ok)
|
||||
image, ok, _ := unstructured.NestedString(containers[0].(map[string]interface{}), "image")
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.2", image)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Application specific override", func(t *testing.T) {
|
||||
service := newService(".")
|
||||
runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) {
|
||||
@@ -1545,6 +1600,28 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
|
||||
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.1", image)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Override info does not appear in cache key", func(t *testing.T) {
|
||||
service := newService(".")
|
||||
runWithTempTestdata(t, "single-global", func(t *testing.T, path string) {
|
||||
source := &argoappv1.ApplicationSource{
|
||||
Path: path,
|
||||
}
|
||||
sourceCopy := source.DeepCopy() // make a copy in case GenerateManifest mutates it.
|
||||
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
|
||||
Repo: &argoappv1.Repository{},
|
||||
ApplicationSource: sourceCopy,
|
||||
AppName: "test",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
res := &cache.CachedManifestResponse{}
|
||||
// Try to pull from the cache with a `source` that does not include any overrides. Overrides should not be
|
||||
// part of the cache key, because you can't get the overrides without a repo operation. And avoiding repo
|
||||
// operations is the point of the cache.
|
||||
err = service.cache.GetManifests(mock.Anything, source, &argoappv1.ClusterInfo{}, "", "", "", "test", res)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) {
|
||||
@@ -1956,7 +2033,12 @@ func Test_getPotentiallyValidManifests(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("circular link should throw an error", func(t *testing.T) {
|
||||
require.DirExists(t, "./testdata/circular-link")
|
||||
const testDir = "./testdata/circular-link"
|
||||
require.DirExists(t, testDir)
|
||||
require.NoError(t, createSymlink(t, testDir, "a.json", "b.json"))
|
||||
defer os.Remove(path.Join(testDir, "a.json"))
|
||||
require.NoError(t, createSymlink(t, testDir, "b.json", "a.json"))
|
||||
defer os.Remove(path.Join(testDir, "b.json"))
|
||||
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", false, "", "", resource.MustParse("0"))
|
||||
assert.Empty(t, manifests)
|
||||
assert.Error(t, err)
|
||||
@@ -2051,7 +2133,12 @@ func Test_findManifests(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("circular link should throw an error", func(t *testing.T) {
|
||||
require.DirExists(t, "./testdata/circular-link")
|
||||
const testDir = "./testdata/circular-link"
|
||||
require.DirExists(t, testDir)
|
||||
require.NoError(t, createSymlink(t, testDir, "a.json", "b.json"))
|
||||
defer os.Remove(path.Join(testDir, "a.json"))
|
||||
require.NoError(t, createSymlink(t, testDir, "b.json", "a.json"))
|
||||
defer os.Remove(path.Join(testDir, "b.json"))
|
||||
manifests, err := findManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", nil, noRecurse, nil, resource.MustParse("0"))
|
||||
assert.Empty(t, manifests)
|
||||
assert.Error(t, err)
|
||||
|
||||
4
reposerver/repository/testdata/app-parameters/single-global-helm/.argocd-source.yaml
vendored
Normal file
4
reposerver/repository/testdata/app-parameters/single-global-helm/.argocd-source.yaml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
helm:
|
||||
parameters:
|
||||
- name: image.tag
|
||||
value: '0.2'
|
||||
2
reposerver/repository/testdata/app-parameters/single-global-helm/Chart.yaml
vendored
Normal file
2
reposerver/repository/testdata/app-parameters/single-global-helm/Chart.yaml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
name: my-chart
|
||||
version: 1.1.0
|
||||
18
reposerver/repository/testdata/app-parameters/single-global-helm/templates/deployment.yaml
vendored
Normal file
18
reposerver/repository/testdata/app-parameters/single-global-helm/templates/deployment.yaml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: guestbook-ui
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook-ui
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: guestbook-ui
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/heptio-images/ks-guestbook-demo:{{.Values.image.tag}}
|
||||
name: guestbook-ui
|
||||
ports:
|
||||
- containerPort: 81
|
||||
2
reposerver/repository/testdata/app-parameters/single-global-helm/values.yaml
vendored
Normal file
2
reposerver/repository/testdata/app-parameters/single-global-helm/values.yaml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
image:
|
||||
tag: 0.1
|
||||
0
reposerver/repository/testdata/circular-link/.keep
vendored
Normal file
0
reposerver/repository/testdata/circular-link/.keep
vendored
Normal file
@@ -1 +0,0 @@
|
||||
b.json
|
||||
@@ -1 +0,0 @@
|
||||
a.json
|
||||
172
server/server.go
172
server/server.go
@@ -282,11 +282,97 @@ func (a *ArgoCDServer) healthCheck(r *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Listeners struct {
|
||||
Main net.Listener
|
||||
Metrics net.Listener
|
||||
GatewayConn *grpc.ClientConn
|
||||
}
|
||||
|
||||
func (l *Listeners) Close() error {
|
||||
if l.Main != nil {
|
||||
if err := l.Main.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
l.Main = nil
|
||||
}
|
||||
if l.Metrics != nil {
|
||||
if err := l.Metrics.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
l.Metrics = nil
|
||||
}
|
||||
if l.GatewayConn != nil {
|
||||
if err := l.GatewayConn.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
l.GatewayConn = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func startListener(host string, port int) (net.Listener, error) {
|
||||
var conn net.Listener
|
||||
var realErr error
|
||||
_ = wait.ExponentialBackoff(backoff, func() (bool, error) {
|
||||
conn, realErr = net.Listen("tcp", fmt.Sprintf("%s:%d", host, port))
|
||||
if realErr != nil {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
return conn, realErr
|
||||
}
|
||||
|
||||
func (a *ArgoCDServer) Listen() (*Listeners, error) {
|
||||
mainLn, err := startListener(a.ListenHost, a.ListenPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metricsLn, err := startListener(a.ListenHost, a.MetricsPort)
|
||||
if err != nil {
|
||||
io.Close(mainLn)
|
||||
return nil, err
|
||||
}
|
||||
var dOpts []grpc.DialOption
|
||||
dOpts = append(dOpts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(apiclient.MaxGRPCMessageSize)))
|
||||
dOpts = append(dOpts, grpc.WithUserAgent(fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, common.GetVersion().Version)))
|
||||
dOpts = append(dOpts, grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()))
|
||||
dOpts = append(dOpts, grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()))
|
||||
if a.useTLS() {
|
||||
// The following sets up the dial Options for grpc-gateway to talk to gRPC server over TLS.
|
||||
// grpc-gateway is just translating HTTP/HTTPS requests as gRPC requests over localhost,
|
||||
// so we need to supply the same certificates to establish the connections that a normal,
|
||||
// external gRPC client would need.
|
||||
tlsConfig := a.settings.TLSConfig()
|
||||
if a.TLSConfigCustomizer != nil {
|
||||
a.TLSConfigCustomizer(tlsConfig)
|
||||
}
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
dCreds := credentials.NewTLS(tlsConfig)
|
||||
dOpts = append(dOpts, grpc.WithTransportCredentials(dCreds))
|
||||
} else {
|
||||
dOpts = append(dOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
}
|
||||
conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", a.ListenPort), dOpts...)
|
||||
if err != nil {
|
||||
io.Close(mainLn)
|
||||
io.Close(metricsLn)
|
||||
return nil, err
|
||||
}
|
||||
return &Listeners{Main: mainLn, Metrics: metricsLn, GatewayConn: conn}, nil
|
||||
}
|
||||
|
||||
// Init starts informers used by the API server
|
||||
func (a *ArgoCDServer) Init(ctx context.Context) {
|
||||
go a.projInformer.Run(ctx.Done())
|
||||
go a.appInformer.Run(ctx.Done())
|
||||
}
|
||||
|
||||
// Run runs the API Server
|
||||
// We use k8s.io/code-generator/cmd/go-to-protobuf to generate the .proto files from the API types.
|
||||
// k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of
|
||||
// golang/protobuf).
|
||||
func (a *ArgoCDServer) Run(ctx context.Context, port int, metricsPort int) {
|
||||
func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) {
|
||||
a.userStateStorage.Init(ctx)
|
||||
|
||||
grpcS, appResourceTreeFn := a.newGRPCServer()
|
||||
@@ -294,10 +380,10 @@ func (a *ArgoCDServer) Run(ctx context.Context, port int, metricsPort int) {
|
||||
var httpS *http.Server
|
||||
var httpsS *http.Server
|
||||
if a.useTLS() {
|
||||
httpS = newRedirectServer(port, a.RootPath)
|
||||
httpsS = a.newHTTPServer(ctx, port, grpcWebS, appResourceTreeFn)
|
||||
httpS = newRedirectServer(a.ListenPort, a.RootPath)
|
||||
httpsS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn)
|
||||
} else {
|
||||
httpS = a.newHTTPServer(ctx, port, grpcWebS, appResourceTreeFn)
|
||||
httpS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn)
|
||||
}
|
||||
if a.RootPath != "" {
|
||||
httpS.Handler = withRootPath(httpS.Handler, a)
|
||||
@@ -311,26 +397,13 @@ func (a *ArgoCDServer) Run(ctx context.Context, port int, metricsPort int) {
|
||||
httpsS.Handler = &bug21955Workaround{handler: httpsS.Handler}
|
||||
}
|
||||
|
||||
metricsServ := metrics.NewMetricsServer(a.ListenHost, metricsPort)
|
||||
metricsServ := metrics.NewMetricsServer(a.ListenHost, a.MetricsPort)
|
||||
if a.RedisClient != nil {
|
||||
cacheutil.CollectMetrics(a.RedisClient, metricsServ)
|
||||
}
|
||||
|
||||
// Start listener
|
||||
var conn net.Listener
|
||||
var realErr error
|
||||
_ = wait.ExponentialBackoff(backoff, func() (bool, error) {
|
||||
conn, realErr = net.Listen("tcp", fmt.Sprintf("%s:%d", a.ListenHost, port))
|
||||
if realErr != nil {
|
||||
a.log.Warnf("failed listen: %v", realErr)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
errors.CheckError(realErr)
|
||||
|
||||
// CMux is used to support servicing gRPC and HTTP1.1+JSON on the same port
|
||||
tcpm := cmux.New(conn)
|
||||
tcpm := cmux.New(listeners.Main)
|
||||
var tlsm cmux.CMux
|
||||
var grpcL net.Listener
|
||||
var httpL net.Listener
|
||||
@@ -360,10 +433,7 @@ func (a *ArgoCDServer) Run(ctx context.Context, port int, metricsPort int) {
|
||||
|
||||
// Start the muxed listeners for our servers
|
||||
log.Infof("argocd %s serving on port %d (url: %s, tls: %v, namespace: %s, sso: %v)",
|
||||
common.GetVersion(), port, a.settings.URL, a.useTLS(), a.Namespace, a.settings.IsSSOConfigured())
|
||||
|
||||
go a.projInformer.Run(ctx.Done())
|
||||
go a.appInformer.Run(ctx.Done())
|
||||
common.GetVersion(), a.ListenPort, a.settings.URL, a.useTLS(), a.Namespace, a.settings.IsSSOConfigured())
|
||||
|
||||
go func() { a.checkServeErr("grpcS", grpcS.Serve(grpcL)) }()
|
||||
go func() { a.checkServeErr("httpS", httpS.Serve(httpL)) }()
|
||||
@@ -374,17 +444,13 @@ func (a *ArgoCDServer) Run(ctx context.Context, port int, metricsPort int) {
|
||||
go a.watchSettings()
|
||||
go a.rbacPolicyLoader(ctx)
|
||||
go func() { a.checkServeErr("tcpm", tcpm.Serve()) }()
|
||||
go func() { a.checkServeErr("metrics", metricsServ.ListenAndServe()) }()
|
||||
go func() { a.checkServeErr("metrics", metricsServ.Serve(listeners.Metrics)) }()
|
||||
if !cache.WaitForCacheSync(ctx.Done(), a.projInformer.HasSynced, a.appInformer.HasSynced) {
|
||||
log.Fatal("Timed out waiting for project cache to sync")
|
||||
}
|
||||
|
||||
a.stopCh = make(chan struct{})
|
||||
<-a.stopCh
|
||||
errors.CheckError(conn.Close())
|
||||
if err := metricsServ.Shutdown(ctx); err != nil {
|
||||
log.Fatalf("Failed to gracefully shutdown metrics server: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ArgoCDServer) Initialized() bool {
|
||||
@@ -702,7 +768,7 @@ func compressHandler(handler http.Handler) http.Handler {
|
||||
|
||||
// newHTTPServer returns the HTTP server to serve HTTP/HTTPS requests. This is implemented
|
||||
// using grpc-gateway as a proxy to the gRPC server.
|
||||
func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn) *http.Server {
|
||||
func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn, conn *grpc.ClientConn) *http.Server {
|
||||
endpoint := fmt.Sprintf("localhost:%d", port)
|
||||
mux := http.NewServeMux()
|
||||
httpS := http.Server{
|
||||
@@ -718,26 +784,6 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
},
|
||||
},
|
||||
}
|
||||
var dOpts []grpc.DialOption
|
||||
dOpts = append(dOpts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(apiclient.MaxGRPCMessageSize)))
|
||||
dOpts = append(dOpts, grpc.WithUserAgent(fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, common.GetVersion().Version)))
|
||||
dOpts = append(dOpts, grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()))
|
||||
dOpts = append(dOpts, grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()))
|
||||
if a.useTLS() {
|
||||
// The following sets up the dial Options for grpc-gateway to talk to gRPC server over TLS.
|
||||
// grpc-gateway is just translating HTTP/HTTPS requests as gRPC requests over localhost,
|
||||
// so we need to supply the same certificates to establish the connections that a normal,
|
||||
// external gRPC client would need.
|
||||
tlsConfig := a.settings.TLSConfig()
|
||||
if a.TLSConfigCustomizer != nil {
|
||||
a.TLSConfigCustomizer(tlsConfig)
|
||||
}
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
dCreds := credentials.NewTLS(tlsConfig)
|
||||
dOpts = append(dOpts, grpc.WithTransportCredentials(dCreds))
|
||||
} else {
|
||||
dOpts = append(dOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
}
|
||||
|
||||
// HTTP 1.1+JSON Server
|
||||
// grpc-ecosystem/grpc-gateway is used to proxy HTTP requests to the corresponding gRPC call
|
||||
@@ -790,17 +836,17 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
|
||||
terminalHandler.ServeHTTP(writer, request)
|
||||
})
|
||||
|
||||
mustRegisterGWHandler(versionpkg.RegisterVersionServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(clusterpkg.RegisterClusterServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(applicationpkg.RegisterApplicationServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(repositorypkg.RegisterRepositoryServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(repocredspkg.RegisterRepoCredsServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(sessionpkg.RegisterSessionServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(settingspkg.RegisterSettingsServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(projectpkg.RegisterProjectServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(accountpkg.RegisterAccountServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(certificatepkg.RegisterCertificateServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(gpgkeypkg.RegisterGPGKeyServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
|
||||
mustRegisterGWHandler(versionpkg.RegisterVersionServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(clusterpkg.RegisterClusterServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(applicationpkg.RegisterApplicationServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(repositorypkg.RegisterRepositoryServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(repocredspkg.RegisterRepoCredsServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(sessionpkg.RegisterSessionServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(settingspkg.RegisterSettingsServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(projectpkg.RegisterProjectServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(accountpkg.RegisterAccountServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(certificatepkg.RegisterCertificateServiceHandler, ctx, gwmux, conn)
|
||||
mustRegisterGWHandler(gpgkeypkg.RegisterGPGKeyServiceHandler, ctx, gwmux, conn)
|
||||
|
||||
// Swagger UI
|
||||
swagger.ServeSwaggerUI(mux, assets.SwaggerJSON, "/swagger-ui", a.RootPath)
|
||||
@@ -968,11 +1014,11 @@ func isMainJsBundle(url *url.URL) bool {
|
||||
return mainJsBundleRegex.Match([]byte(filename))
|
||||
}
|
||||
|
||||
type registerFunc func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) error
|
||||
type registerFunc func(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error
|
||||
|
||||
// mustRegisterGWHandler is a convenience function to register a gateway handler
|
||||
func mustRegisterGWHandler(register registerFunc, ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) {
|
||||
err := register(ctx, mux, endpoint, opts)
|
||||
func mustRegisterGWHandler(register registerFunc, ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) {
|
||||
err := register(ctx, mux, conn)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -29,20 +29,17 @@ func TestUserAgent(t *testing.T) {
|
||||
|
||||
s, closer := fakeServer()
|
||||
defer closer()
|
||||
lns, err := s.Listen()
|
||||
assert.NoError(t, err)
|
||||
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
type testData struct {
|
||||
userAgent string
|
||||
errorMsg string
|
||||
@@ -72,7 +69,7 @@ func TestUserAgent(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
opts := apiclient.ClientOptions{
|
||||
ServerAddr: fmt.Sprintf("localhost:%d", port),
|
||||
ServerAddr: fmt.Sprintf("localhost:%d", s.ListenPort),
|
||||
PlainText: true,
|
||||
UserAgent: test.userAgent,
|
||||
}
|
||||
@@ -99,25 +96,21 @@ func Test_StaticHeaders(t *testing.T) {
|
||||
{
|
||||
s, closer := fakeServer()
|
||||
defer closer()
|
||||
lns, err := s.Listen()
|
||||
assert.NoError(t, err)
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", s.ListenPort)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
@@ -134,23 +127,19 @@ func Test_StaticHeaders(t *testing.T) {
|
||||
s.ContentSecurityPolicy = "frame-ancestors 'none';"
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
lns, err := s.Listen()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", s.ListenPort)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
@@ -167,23 +156,22 @@ func Test_StaticHeaders(t *testing.T) {
|
||||
s.ContentSecurityPolicy = ""
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
lns, err := s.Listen()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
s.Init(ctx)
|
||||
go s.Run(ctx, lns)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", s.ListenPort), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", s.ListenPort)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
|
||||
@@ -41,8 +41,13 @@ func fakeServer() (*ArgoCDServer, func()) {
|
||||
kubeclientset := fake.NewSimpleClientset(cm, secret)
|
||||
appClientSet := apps.NewSimpleClientset()
|
||||
redis, closer := test.NewInMemoryRedis()
|
||||
port, err := test.GetFreePort()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
argoCDOpts := ArgoCDServerOpts{
|
||||
ListenPort: port,
|
||||
Namespace: test.FakeArgoCDNamespace,
|
||||
KubeClientset: kubeclientset,
|
||||
AppClientset: appClientSet,
|
||||
@@ -61,7 +66,8 @@ func fakeServer() (*ArgoCDServer, func()) {
|
||||
),
|
||||
RedisClient: redis,
|
||||
}
|
||||
return NewServer(context.Background(), argoCDOpts), closer
|
||||
srv := NewServer(context.Background(), argoCDOpts)
|
||||
return srv, closer
|
||||
}
|
||||
|
||||
func TestEnforceProjectToken(t *testing.T) {
|
||||
|
||||
@@ -141,8 +141,9 @@ export const PodTerminalViewer: React.FC<PodTerminalViewerProps> = ({selectedNod
|
||||
|
||||
function setupConnection() {
|
||||
const {name = '', namespace = ''} = selectedNode || {};
|
||||
const url = `${location.host}${appContext.baseHref}`.replace(/\/$/, '');
|
||||
webSocket = new WebSocket(
|
||||
`${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/terminal?pod=${name}&container=${AppUtils.getContainerName(
|
||||
`${location.protocol === 'https:' ? 'wss' : 'ws'}://${url}/terminal?pod=${name}&container=${AppUtils.getContainerName(
|
||||
podState,
|
||||
activeContainer
|
||||
)}&appName=${applicationName}&projectName=${projectName}&namespace=${namespace}`
|
||||
|
||||
@@ -29,11 +29,11 @@ func IsManifestGenerationEnabled(sourceType v1alpha1.ApplicationSourceType, enab
|
||||
return enabled
|
||||
}
|
||||
|
||||
func Discover(ctx context.Context, repoPath string, enableGenerateManifests map[string]bool) (map[string]string, error) {
|
||||
func Discover(ctx context.Context, repoPath string, enableGenerateManifests map[string]bool, tarExcludedGlobs []string) (map[string]string, error) {
|
||||
apps := make(map[string]string)
|
||||
|
||||
// Check if it is CMP
|
||||
conn, _, err := DetectConfigManagementPlugin(ctx, repoPath, []string{})
|
||||
conn, _, err := DetectConfigManagementPlugin(ctx, repoPath, []string{}, tarExcludedGlobs)
|
||||
if err == nil {
|
||||
// Found CMP
|
||||
io.Close(conn)
|
||||
@@ -65,8 +65,8 @@ func Discover(ctx context.Context, repoPath string, enableGenerateManifests map[
|
||||
return apps, err
|
||||
}
|
||||
|
||||
func AppType(ctx context.Context, path string, enableGenerateManifests map[string]bool) (string, error) {
|
||||
apps, err := Discover(ctx, path, enableGenerateManifests)
|
||||
func AppType(ctx context.Context, path string, enableGenerateManifests map[string]bool, tarExcludedGlobs []string) (string, error) {
|
||||
apps, err := Discover(ctx, path, enableGenerateManifests, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func AppType(ctx context.Context, path string, enableGenerateManifests map[strin
|
||||
// 3. check isSupported(path)?
|
||||
// 4.a if no then close connection
|
||||
// 4.b if yes then return conn for detected plugin
|
||||
func DetectConfigManagementPlugin(ctx context.Context, repoPath string, env []string) (io.Closer, pluginclient.ConfigManagementPluginServiceClient, error) {
|
||||
func DetectConfigManagementPlugin(ctx context.Context, repoPath string, env []string, tarExcludedGlobs []string) (io.Closer, pluginclient.ConfigManagementPluginServiceClient, error) {
|
||||
var conn io.Closer
|
||||
var cmpClient pluginclient.ConfigManagementPluginServiceClient
|
||||
|
||||
@@ -106,7 +106,7 @@ func DetectConfigManagementPlugin(ctx context.Context, repoPath string, env []st
|
||||
continue
|
||||
}
|
||||
|
||||
isSupported, err := matchRepositoryCMP(ctx, repoPath, cmpClient, env)
|
||||
isSupported, err := matchRepositoryCMP(ctx, repoPath, cmpClient, env, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
log.Errorf("repository %s is not the match because %v", repoPath, err)
|
||||
continue
|
||||
@@ -131,13 +131,13 @@ func DetectConfigManagementPlugin(ctx context.Context, repoPath string, env []st
|
||||
// matchRepositoryCMP will send the repoPath to the cmp-server. The cmp-server will
|
||||
// inspect the files and return true if the repo is supported for manifest generation.
|
||||
// Will return false otherwise.
|
||||
func matchRepositoryCMP(ctx context.Context, repoPath string, client pluginclient.ConfigManagementPluginServiceClient, env []string) (bool, error) {
|
||||
func matchRepositoryCMP(ctx context.Context, repoPath string, client pluginclient.ConfigManagementPluginServiceClient, env []string, tarExcludedGlobs []string) (bool, error) {
|
||||
matchRepoStream, err := client.MatchRepository(ctx, grpc_retry.Disable())
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error getting stream client: %s", err)
|
||||
}
|
||||
|
||||
err = cmp.SendRepoStream(ctx, repoPath, repoPath, matchRepoStream, env)
|
||||
err = cmp.SendRepoStream(ctx, repoPath, repoPath, matchRepoStream, env, tarExcludedGlobs)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error sending stream: %s", err)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func TestDiscover(t *testing.T) {
|
||||
apps, err := Discover(context.Background(), "./testdata", map[string]bool{})
|
||||
apps, err := Discover(context.Background(), "./testdata", map[string]bool{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, map[string]string{
|
||||
"foo": "Kustomize",
|
||||
@@ -19,15 +19,15 @@ func TestDiscover(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAppType(t *testing.T) {
|
||||
appType, err := AppType(context.Background(), "./testdata/foo", map[string]bool{})
|
||||
appType, err := AppType(context.Background(), "./testdata/foo", map[string]bool{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Kustomize", appType)
|
||||
|
||||
appType, err = AppType(context.Background(), "./testdata/baz", map[string]bool{})
|
||||
appType, err = AppType(context.Background(), "./testdata/baz", map[string]bool{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Helm", appType)
|
||||
|
||||
appType, err = AppType(context.Background(), "./testdata", map[string]bool{})
|
||||
appType, err = AppType(context.Background(), "./testdata", map[string]bool{}, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Directory", appType)
|
||||
}
|
||||
@@ -37,15 +37,15 @@ func TestAppType_Disabled(t *testing.T) {
|
||||
string(v1alpha1.ApplicationSourceTypeKustomize): false,
|
||||
string(v1alpha1.ApplicationSourceTypeHelm): false,
|
||||
}
|
||||
appType, err := AppType(context.Background(), "./testdata/foo", enableManifestGeneration)
|
||||
appType, err := AppType(context.Background(), "./testdata/foo", enableManifestGeneration, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Directory", appType)
|
||||
|
||||
appType, err = AppType(context.Background(), "./testdata/baz", enableManifestGeneration)
|
||||
appType, err = AppType(context.Background(), "./testdata/baz", enableManifestGeneration, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Directory", appType)
|
||||
|
||||
appType, err = AppType(context.Background(), "./testdata", enableManifestGeneration)
|
||||
appType, err = AppType(context.Background(), "./testdata", enableManifestGeneration, []string{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Directory", appType)
|
||||
}
|
||||
|
||||
@@ -84,11 +84,11 @@ func WithTarDoneChan(ch chan<- bool) SenderOption {
|
||||
|
||||
// SendRepoStream will compress the files under the given repoPath and send
|
||||
// them using the plugin stream sender.
|
||||
func SendRepoStream(ctx context.Context, appPath, repoPath string, sender StreamSender, env []string, opts ...SenderOption) error {
|
||||
func SendRepoStream(ctx context.Context, appPath, repoPath string, sender StreamSender, env []string, excludedGlobs []string, opts ...SenderOption) error {
|
||||
opt := newSenderOption(opts...)
|
||||
|
||||
// compress all files in appPath in tgz
|
||||
tgz, checksum, err := compressFiles(repoPath)
|
||||
tgz, checksum, err := compressFiles(repoPath, excludedGlobs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error compressing repo files: %w", err)
|
||||
}
|
||||
@@ -162,11 +162,10 @@ func closeAndDelete(f *os.File) {
|
||||
}
|
||||
|
||||
// compressFiles will create a tgz file with all contents of appPath
|
||||
// directory excluding the .git folder. Returns the file alongside
|
||||
// its sha256 hash to be used as checksum. It is the responsibility
|
||||
// of the caller to close the file.
|
||||
func compressFiles(appPath string) (*os.File, string, error) {
|
||||
excluded := []string{".git"}
|
||||
// directory excluding globs in the excluded array. Returns the file
|
||||
// alongside its sha256 hash to be used as checksum. It is the
|
||||
// responsibility of the caller to close the file.
|
||||
func compressFiles(appPath string, excluded []string) (*os.File, string, error) {
|
||||
appName := filepath.Base(appPath)
|
||||
tempDir, err := files.CreateTempDir(os.TempDir())
|
||||
if err != nil {
|
||||
|
||||
@@ -60,7 +60,7 @@ func TestReceiveApplicationStream(t *testing.T) {
|
||||
close(streamMock.messages)
|
||||
os.RemoveAll(workdir)
|
||||
}()
|
||||
go streamMock.sendFile(context.Background(), t, appDir, streamMock, []string{"env1", "env2"})
|
||||
go streamMock.sendFile(context.Background(), t, appDir, streamMock, []string{"env1", "env2"}, []string{"DUMMY.md", "dum*"})
|
||||
|
||||
// when
|
||||
env, err := cmp.ReceiveRepoStream(context.Background(), streamMock, workdir)
|
||||
@@ -77,16 +77,18 @@ func TestReceiveApplicationStream(t *testing.T) {
|
||||
}
|
||||
assert.Contains(t, names, "README.md")
|
||||
assert.Contains(t, names, "applicationset")
|
||||
assert.NotContains(t, names, "DUMMY.md")
|
||||
assert.NotContains(t, names, "dummy")
|
||||
assert.NotNil(t, env)
|
||||
})
|
||||
}
|
||||
|
||||
func (m *streamMock) sendFile(ctx context.Context, t *testing.T, basedir string, sender cmp.StreamSender, env []string) {
|
||||
func (m *streamMock) sendFile(ctx context.Context, t *testing.T, basedir string, sender cmp.StreamSender, env []string, excludedGlobs []string) {
|
||||
t.Helper()
|
||||
defer func() {
|
||||
m.done <- true
|
||||
}()
|
||||
err := cmp.SendRepoStream(ctx, basedir, basedir, sender, env)
|
||||
err := cmp.SendRepoStream(ctx, basedir, basedir, sender, env, excludedGlobs)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
||||
1
util/cmp/testdata/app/DUMMY.md
vendored
Normal file
1
util/cmp/testdata/app/DUMMY.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This file is used to test the tar stream exclusions.
|
||||
1
util/cmp/testdata/app/dummy/DUMMY2.md
vendored
Normal file
1
util/cmp/testdata/app/dummy/DUMMY2.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
This is another file that should get excluded because the entire directory is excluded.
|
||||
7
util/env/env.go
vendored
7
util/env/env.go
vendored
@@ -126,6 +126,13 @@ func StringFromEnv(env string, defaultValue string) string {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func StringsFromEnv(env string, defaultValue []string, separator string) []string {
|
||||
if str := os.Getenv(env); str != "" {
|
||||
return strings.Split(str, separator)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// ParseBoolFromEnv retrieves a boolean value from given environment envVar.
|
||||
// Returns default value if envVar is not set.
|
||||
//
|
||||
|
||||
@@ -326,6 +326,16 @@ func (m *nativeGitClient) IsLFSEnabled() bool {
|
||||
return m.enableLfs
|
||||
}
|
||||
|
||||
func (m *nativeGitClient) fetch(revision string) error {
|
||||
var err error
|
||||
if revision != "" {
|
||||
err = m.runCredentialedCmd("git", "fetch", "origin", revision, "--tags", "--force")
|
||||
} else {
|
||||
err = m.runCredentialedCmd("git", "fetch", "origin", "--tags", "--force")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Fetch fetches latest updates from origin
|
||||
func (m *nativeGitClient) Fetch(revision string) error {
|
||||
if m.OnFetch != nil {
|
||||
@@ -334,11 +344,19 @@ func (m *nativeGitClient) Fetch(revision string) error {
|
||||
}
|
||||
|
||||
var err error
|
||||
if revision != "" {
|
||||
err = m.runCredentialedCmd("git", "fetch", "origin", revision, "--tags", "--force")
|
||||
} else {
|
||||
err = m.runCredentialedCmd("git", "fetch", "origin", "--tags", "--force")
|
||||
|
||||
err = m.fetch(revision)
|
||||
if err != nil {
|
||||
errMsg := strings.ReplaceAll(err.Error(), "\n", "")
|
||||
if strings.Contains(errMsg, "try running 'git remote prune origin'") {
|
||||
// Prune any deleted refs, then try fetching again
|
||||
if err := m.runCredentialedCmd("git", "remote", "prune", "origin"); err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.fetch(revision)
|
||||
}
|
||||
}
|
||||
|
||||
// When we have LFS support enabled, check for large files and fetch them too.
|
||||
if err == nil && m.IsLFSEnabled() {
|
||||
largeFiles, err := m.LsLargeFiles()
|
||||
@@ -349,6 +367,7 @@ func (m *nativeGitClient) Fetch(revision string) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
94
util/git/client_test.go
Normal file
94
util/git/client_test.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_nativeGitClient_Fetch(t *testing.T) {
|
||||
tempDir, err := os.MkdirTemp("", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd := exec.Command("git", "init")
|
||||
cmd.Dir = tempDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd = exec.Command("git", "commit", "-m", "Initial commit", "--allow-empty")
|
||||
cmd.Dir = tempDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client.Fetch("")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_nativeGitClient_Fetch_Prune(t *testing.T) {
|
||||
tempDir, err := os.MkdirTemp("", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd := exec.Command("git", "init")
|
||||
cmd.Dir = tempDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd = exec.Command("git", "commit", "-m", "Initial commit", "--allow-empty")
|
||||
cmd.Dir = tempDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create branch
|
||||
cmd = exec.Command("git", "branch", "test/foo")
|
||||
cmd.Dir = tempDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client.Fetch("")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Delete branch
|
||||
cmd = exec.Command("git", "branch", "-d", "test/foo")
|
||||
cmd.Dir = tempDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create branch that conflicts with previous branch name
|
||||
cmd = exec.Command("git", "branch", "test/foo/bar")
|
||||
cmd.Dir = tempDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client.Fetch("")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -3,7 +3,10 @@ package session
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -456,3 +459,125 @@ func TestFailedAttemptsExpiry(t *testing.T) {
|
||||
|
||||
os.Setenv(envLoginFailureWindowSeconds, "")
|
||||
}
|
||||
|
||||
func oidcMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.RequestURI {
|
||||
case "/.well-known/openid-configuration":
|
||||
_, err := io.WriteString(w, fmt.Sprintf(`
|
||||
{
|
||||
"issuer": "%[1]s",
|
||||
"authorization_endpoint": "%[1]s/auth",
|
||||
"token_endpoint": "%[1]s/token",
|
||||
"jwks_uri": "%[1]s/keys",
|
||||
"userinfo_endpoint": "%[1]s/userinfo",
|
||||
"device_authorization_endpoint": "%[1]s/device/code",
|
||||
"grant_types_supported": ["authorization_code"],
|
||||
"response_types_supported": ["code"],
|
||||
"subject_types_supported": ["public"],
|
||||
"id_token_signing_alg_values_supported": ["RS512"],
|
||||
"code_challenge_methods_supported": ["S256", "plain"],
|
||||
"scopes_supported": ["openid"],
|
||||
"token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post"],
|
||||
"claims_supported": ["sub", "aud", "exp"]
|
||||
}`, url))
|
||||
require.NoError(t, err)
|
||||
default:
|
||||
w.WriteHeader(404)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getOIDCTestServer(t *testing.T) *httptest.Server {
|
||||
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Start with a placeholder. We need the server URL before setting up the real handler.
|
||||
}))
|
||||
ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
oidcMockHandler(t, ts.URL)(w, r)
|
||||
})
|
||||
return ts
|
||||
}
|
||||
|
||||
func getKubeClientWithConfig(config map[string]string) *fake.Clientset {
|
||||
return fake.NewSimpleClientset(&corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "argocd-cm",
|
||||
Namespace: "argocd",
|
||||
Labels: map[string]string{
|
||||
"app.kubernetes.io/part-of": "argocd",
|
||||
},
|
||||
},
|
||||
Data: config,
|
||||
}, &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "argocd-secret",
|
||||
Namespace: "argocd",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"server.secretkey": []byte("Hello, world!"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// privateKey is an RSA key used only for tests.
|
||||
var privateKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA2KHkp2fe0ReHqAt9BimWEec2ryWZIyg9jvB3BdP3mzFf0bOt
|
||||
WlHm1FAETFxH4h5jYASUaaWEwRNNyGlT1GhTp+jOMC4xhOSb5/SnI2dt2EITkudQ
|
||||
FKsSFUdJAndqOzkjrP2pL4fi4b7JWhuLDO36ufAP4l2m3tnAseGSSTIccWvzLFFU
|
||||
s3wsHOHxOcJGCP1Z7rizxl6mTKYL/Z+GHqN17OJslDf901uPXsUeDCYL2iigGPhD
|
||||
Ao6k8POsfbpqLG7poCDTK50FLnS5qEocjxt+J4ZjBEWTU/DOFXWYstzfbhm8OZPQ
|
||||
pSSEiBCxpg+zjtkQfCyZxXB5RQ84CY78fXOI9QIDAQABAoIBAG8jL0FLIp62qZvm
|
||||
uO9ualUo/37/lP7aaCpq50UQJ9lwjS3yNh8+IWQO4QWj2iUBXg4mi1Vf2ymKk78b
|
||||
eixgkXp1D0Lcj/8ToYBwnUami04FKDGXhhf0Y8SS27vuM4vKlqjrQd7modkangYi
|
||||
V0X82UKHDD8fuLpfkGIxzXDLypfMzjMuVpSntnWaf2YX3VR/0/66yEp9GejftF2k
|
||||
wqhGoWM6r68pN5XuCqWd5PRluSoDy/o4BAFMhYCSfp9PjgZE8aoeWHgYzlZ3gUyn
|
||||
r+HaDDNWbibhobXk/9h8lwAJ6KCZ5RZ+HFfh0HuwIxmocT9OCFgy/S0g1p+o3m9K
|
||||
VNd5AMkCgYEA5fbS5UK7FBzuLoLgr1hktmbLJhpt8y8IPHNABHcUdE+O4/1xTQNf
|
||||
pMUwkKjGG1MtrGjLOIoMGURKKn8lR1GMZueOTSKY0+mAWUGvSzl6vwtJwvJruT8M
|
||||
otEO03o0tPnRKGxbFjqxkp2b6iqJ8MxCRZ3lSidc4mdi7PHzv9lwgvsCgYEA8Siq
|
||||
7weCri9N6y+tIdORAXgRzcW54BmJyqB147c72RvbMacb6rN28KXpM3qnRXyp3Llb
|
||||
yh81TW3FH10GqrjATws7BK8lP9kkAw0Z/7kNiS1NgH3pUbO+5H2kAa/6QW35nzRe
|
||||
Jw2lyfYGWqYO4hYXH14ML1kjgS1hgd3XHOQ64M8CgYAKcjDYSzS2UC4dnMJaFLjW
|
||||
dErsGy09a7iDDnUs/r/GHMsP3jZkWi/hCzgOiiwdl6SufUAl/FdaWnjH/2iRGco3
|
||||
7nLPXC/3CFdVNp+g2iaSQRADtAFis9N+HeL/hkCYq/RtUqa8lsP0NgacF3yWnKCy
|
||||
Ct8chDc67ZlXzBHXeCgdOwKBgHHGFPbWXUHeUW1+vbiyvrupsQSanznp8oclMtkv
|
||||
Dk48hSokw9fzuU6Jh77gw9/Vk7HtxS9Tj+squZA1bDrJFPl1u+9WzkUUJZhG6xgp
|
||||
bwhj1iejv5rrKUlVOTYOlwudXeJNa4oTNz9UEeVcaLMjZt9GmIsSC90a0uDZD26z
|
||||
AlAjAoGAEoqm2DcNN7SrH6aVFzj1EVOrNsHYiXj/yefspeiEmf27PSAslP+uF820
|
||||
SDpz4h+Bov5qTKkzcxuu1QWtA4M0K8Iy6IYLwb83DZEm1OsAf4i0pODz21PY/I+O
|
||||
VHzjB10oYgaInHZgMUdyb6F571UdiYSB6a/IlZ3ngj5touy3VIM=
|
||||
-----END RSA PRIVATE KEY-----`)
|
||||
|
||||
func TestSessionManager_VerifyToken(t *testing.T) {
|
||||
t.Run("HS256 is supported", func(t *testing.T) {
|
||||
oidcTestServer := getOIDCTestServer(t)
|
||||
defer oidcTestServer.Close()
|
||||
dexConfig := map[string]string{
|
||||
"url": "",
|
||||
"oidc.config": fmt.Sprintf(`
|
||||
name: Test
|
||||
issuer: %s
|
||||
clientID: xxx
|
||||
clientSecret: yyy
|
||||
requestedScopes: ["oidc"]`, oidcTestServer.URL),
|
||||
}
|
||||
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(dexConfig), "argocd")
|
||||
mgr := NewSessionManager(settingsMgr, getProjLister(), "", NewUserStateStorage(nil))
|
||||
mgr.verificationDelayNoiseEnabled = false
|
||||
// Use test server's client to avoid TLS issues.
|
||||
mgr.client = oidcTestServer.Client()
|
||||
|
||||
claims := jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"test-client"}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24))}
|
||||
claims.Issuer = oidcTestServer.URL
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims)
|
||||
key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey)
|
||||
require.NoError(t, err)
|
||||
tokenString, err := token.SignedString(key)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = mgr.VerifyToken(tokenString)
|
||||
assert.NotContains(t, err.Error(), "oidc: id token signed with unsupported algorithm")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Appl
|
||||
return err
|
||||
}
|
||||
var cachedManifests cache.CachedManifestResponse
|
||||
if err := a.repoCache.GetManifests(change.shaBefore, &app.Spec.Source, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests); err == nil {
|
||||
if err := a.repoCache.GetManifests(change.shaBefore, &app.Spec.Source, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = a.repoCache.SetManifests(change.shaAfter, &app.Spec.Source, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user