Compare commits

...

18 Commits

Author SHA1 Message Date
gcp-cherry-pick-bot[bot]
2bc94af7bd fix(ui): code lint (#15150) (#15160)
Signed-off-by: ebuildy <ebuildy@gmail.com>
Co-authored-by: Thomas Decaux <ebuildy@gmail.com>
2023-08-22 14:20:40 -04:00
gcp-cherry-pick-bot[bot]
b9a32bb86e fix: windows build (#15154) (#15156)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-08-22 13:08:47 -04:00
github-actions[bot]
356e33ac29 Bump version to 2.8.1 (#15139)
Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: crenshaw-dev <crenshaw-dev@users.noreply.github.com>
2023-08-21 16:29:01 -04:00
pasha-codefresh
9ffef110da Merge pull request from GHSA-c8xw-vjgf-94hr
Signed-off-by: pashakostohrys <pavel@codefresh.io>
2023-08-21 16:15:09 -04:00
gcp-cherry-pick-bot[bot]
af721bbb63 docs(progressive syncs): specify which ConfigMap to use (#15119) (#15133)
Signed-off-by: Gaël Jourdan-Weil <gjourdanweil@gmail.com>
Co-authored-by: Gaël Jourdan-Weil <gjourdanweil@gmail.com>
2023-08-21 16:13:36 -04:00
gcp-cherry-pick-bot[bot]
91d249ec84 docs: ✏️ fix typo on configmap name for private certs (#9596) (#15131)
Signed-off-by: Gaël Jourdan-Weil <gael.jourdan-weil@kelkoogroup.com>
Co-authored-by: Gaël Jourdan-Weil <gael.jourdan-weil@kelkoogroup.com>
2023-08-21 16:13:06 -04:00
gcp-cherry-pick-bot[bot]
004ca26b9e docs: fix typo (#15083) (#15090)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-08-18 12:01:35 -04:00
gcp-cherry-pick-bot[bot]
2a17ca57ec docs: add docs for various annotations and labels (#14020) (#15112)
* docs: add docs for various annotations



* more info



* more docs



---------

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-08-18 11:22:37 -04:00
gcp-cherry-pick-bot[bot]
89495d72df docs: kubectl to synchronize argocd apps (#14881) (#15085)
We can use kubectl to synchronize argocd applications the same way we can use
the argocd cli or ui, however there's no documentation.

This PR adds documentation for kubectl.

Signed-off-by: Jordi Grant Esteve <jgrant.esteve@gmail.com>
Co-authored-by: selaci <selaci@users.noreply.github.com>
2023-08-18 11:20:13 -04:00
gcp-cherry-pick-bot[bot]
885bb57ae8 docs: fix link for argocd-repo-creds.yaml sample (#15091) (#15097)
Signed-off-by: SHIMADA Kento <shimada.kento8974@gmail.com>
Co-authored-by: SHIMADA Kento <shimada.kento8974@gmail.com>
2023-08-17 14:30:53 -04:00
gcp-cherry-pick-bot[bot]
d6d7b1452d docs: document permitOnlyProjectScopedClusters field (#15076) (#15082)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-08-16 15:44:30 -04:00
gcp-cherry-pick-bot[bot]
490c78b75f fix: bump ubuntu base image (#15020) (#15021) (#15023)
Latest version of the ubuntu image addresses CVE-2023-38408.

https://ubuntu.com/security/notices/USN-6242-1
https://github.com/docker-library/repo-info/blob/master/repos/ubuntu/remote/22.04.md

resolves #15020

Signed-off-by: Mason Cole <macole@beyondtrust.com>
Co-authored-by: Mason Cole <117116981+bt-macole@users.noreply.github.com>
2023-08-11 15:47:16 -04:00
Jason Meridth
092e55e279 chore(deps): upgrade nhooyr.io/websocket dependency (#15000) (#15008)
Upgrade from 1.8.6 to 1.8.7 due to high security issue

Was solved in dependency with https://github.com/nhooyr/websocket/pull/291

Signed-off-by: jmeridth <jmeridth@gmail.com>
2023-08-11 10:24:26 -04:00
gcp-cherry-pick-bot[bot]
fe526dd33c fix(actions): check if CronWorkflow has labels in create-workflow action (#14962) (#14974) (#14982)
Signed-off-by: Mickaël Canévet <mickael.canevet@gmail.com>
Co-authored-by: Mickaël Canévet <mickael.canevet@gmail.com>
2023-08-09 10:03:53 -04:00
gcp-cherry-pick-bot[bot]
cade0e970d fix(cmp): send sigterm to cmp commands before sigkill to allow for potential cleanup (#9180) (#14955) (#14958)
* fix: send sigterm to cmp commands before sigkill to allow for potential cleanup



* fix: unit test for runCommand in cmpserver to test cleanup modified



* fix: change unit test for plugin/runCommand to avoid bad trap along with lint fix



---------

Signed-off-by: Ashin Sabu <ashin.sabu@harness.io>
Co-authored-by: Ashin Sabu <139749674+ashinsabu3@users.noreply.github.com>
2023-08-08 11:37:55 -04:00
gcp-cherry-pick-bot[bot]
e58eaaf36f fix(ui): COPY JSON for ArgoCD version should include trailing newline (#5117) (#14917) (#14938)
Signed-off-by: Vipin M S <vipinachar2016@gmail.com>
Co-authored-by: Vipin M S <40431065+vipinachar@users.noreply.github.com>
2023-08-07 11:02:30 -04:00
gcp-cherry-pick-bot[bot]
0c4e249922 docs: Update helm.md - add missing syntax highlighting for YAML and Dockerfile blocks (#14911) (#14937)
Signed-off-by: JesseBot <jessebot@linux.com>
Co-authored-by: JesseBot <jessebot@linux.com>
2023-08-07 10:58:20 -04:00
gcp-cherry-pick-bot[bot]
8ea6650dd7 docs: Update Generators-Git.md (#14921) (#14934)
Remove a misleading symbol from the pattern for the path.Match function. The pipe symbol doesn't have any special meaning.

Signed-off-by: German Lashevich <german.lashevich@gmail.com>
Co-authored-by: German Lashevich <design.ber@gmail.com>
2023-08-07 10:49:02 -04:00
36 changed files with 457 additions and 65 deletions

View File

@@ -1,4 +1,4 @@
ARG BASE_IMAGE=docker.io/library/ubuntu:22.04@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5
ARG BASE_IMAGE=docker.io/library/ubuntu:22.04@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508
####################################################################################################
# Builder image
# Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image

View File

@@ -1 +1 @@
2.8.0
2.8.1

View File

@@ -97,6 +97,14 @@ func runCommand(ctx context.Context, command Command, path string, env []string)
<-ctx.Done()
// Kill by group ID to make sure child processes are killed. The - tells `kill` that it's a group ID.
// Since we didn't set Pgid in SysProcAttr, the group ID is the same as the process ID. https://pkg.go.dev/syscall#SysProcAttr
// Sending a TERM signal first to allow any potential cleanup if needed, and then sending a KILL signal
_ = sysCallTerm(-cmd.Process.Pid)
// modify cleanup timeout to allow process to cleanup
cleanupTimeout := 5 * time.Second
time.Sleep(cleanupTimeout)
_ = sysCallKill(-cmd.Process.Pid)
}()

View File

@@ -369,6 +369,28 @@ func TestRunCommandEmptyCommand(t *testing.T) {
assert.ErrorContains(t, err, "Command is empty")
}
// TestRunCommandContextTimeoutWithGracefulTermination makes sure that the process is given enough time to cleanup before sending SIGKILL.
func TestRunCommandContextTimeoutWithCleanup(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 900*time.Millisecond)
defer cancel()
// Use a subshell so there's a child command.
// This command sleeps for 4 seconds which is currently less than the 5 second delay between SIGTERM and SIGKILL signal and then exits successfully.
command := Command{
Command: []string{"sh", "-c"},
Args: []string{`(trap 'echo "cleanup completed"; exit' TERM; sleep 4)`},
}
before := time.Now()
output, err := runCommand(ctx, command, "", []string{})
after := time.Now()
assert.Error(t, err) // The command should time out, causing an error.
assert.Less(t, after.Sub(before), 1*time.Second)
// The command should still have completed the cleanup after termination.
assert.Contains(t, output, "cleanup completed")
}
func Test_getParametersAnnouncement_empty_command(t *testing.T) {
staticYAML := `
- name: static-a

View File

@@ -14,3 +14,7 @@ func newSysProcAttr(setpgid bool) *syscall.SysProcAttr {
func sysCallKill(pid int) error {
return syscall.Kill(pid, syscall.SIGKILL)
}
func sysCallTerm(pid int) error {
return syscall.Kill(pid, syscall.SIGTERM)
}

View File

@@ -14,3 +14,7 @@ func newSysProcAttr(setpgid bool) *syscall.SysProcAttr {
func sysCallKill(pid int) error {
return nil
}
func sysCallTerm(pid int) error {
return nil
}

View File

@@ -157,7 +157,7 @@ Or, a shorter way (using [path.Match](https://golang.org/pkg/path/#Match) syntax
```yaml
- path: /d/*
- path: /d/[f|g]
- path: /d/[fg]
exclude: true
```

View File

@@ -15,7 +15,7 @@ As an experimental feature, progressive syncs must be explicitly enabled, in one
1. Pass `--enable-progressive-syncs` to the ApplicationSet controller args.
1. Set `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS=true` in the ApplicationSet controller environment variables.
1. Set `applicationsetcontroller.enable.progressive.syncs: true` in the Argo CD ConfigMap.
1. Set `applicationsetcontroller.enable.progressive.syncs: true` in the Argo CD `argocd-cmd-params-cm` ConfigMap.
## Strategies

View File

@@ -12,7 +12,7 @@ All resources, including `Application` and `AppProject` specs, have to be instal
|-----------------------------------------------------------------------|------------------------------------------------------------------------------------|-----------|--------------------------------------------------------------------------------------|
| [`argocd-cm.yaml`](argocd-cm-yaml.md) | argocd-cm | ConfigMap | General Argo CD configuration |
| [`argocd-repositories.yaml`](argocd-repositories-yaml.md) | my-private-repo / istio-helm-repo / private-helm-repo / private-repo | Secrets | Sample repository connection details |
| [`argocd-repo-creds.yaml`](argocd-repo-creds.yaml) | argoproj-https-creds / argoproj-ssh-creds / github-creds / github-enterprise-creds | Secrets | Sample repository credential templates |
| [`argocd-repo-creds.yaml`](argocd-repo-creds-yaml.md) | argoproj-https-creds / argoproj-ssh-creds / github-creds / github-enterprise-creds | Secrets | Sample repository credential templates |
| [`argocd-cmd-params-cm.yaml`](argocd-cmd-params-cm-yaml.md) | argocd-cmd-params-cm | ConfigMap | Argo CD env variables configuration |
| [`argocd-secret.yaml`](argocd-secret-yaml.md) | argocd-secret | Secret | User Passwords, Certificates (deprecated), Signing Key, Dex secrets, Webhook secrets |
| [`argocd-rbac-cm.yaml`](argocd-rbac-cm-yaml.md) | argocd-rbac-cm | ConfigMap | RBAC Configuration |

View File

@@ -86,3 +86,8 @@ spec:
clusters:
- in-cluster
- cluster1
# By default, apps may sync to any cluster specified under the `destinations` field, even if they are not
# scoped to this project. Set the following field to `true` to restrict apps in this cluster to only clusters
# scoped to this project.
permitOnlyProjectScopedClusters: false

View File

@@ -0,0 +1,26 @@
# Annotations and Labels used by Argo CD
## Annotations
| Annotation key | Target resource(es) | Possible values | Description |
|--------------------------------------------|---------------------|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| argocd.argoproj.io/application-set-refresh | ApplicationSet | `"true"` | Added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconciliation. |
| argocd.argoproj.io/compare-options | any | [see compare options docs](compare-options.md) | Configures how an app's current state is compared to its desired state. |
| argocd.argoproj.io/hook | any | [see resource hooks docs](resource_hooks.md) | Used to configure [resource hooks](resource_hooks.md). |
| argocd.argoproj.io/hook-delete-policy | any | [see resource hooks docs](resource_hooks.md#hook-deletion-policies) | Used to set a [resource hook's deletion policy](resource_hooks.md#hook-deletion-policies). |
| argocd.argoproj.io/manifest-generate-paths | Application | [see scaling docs](../operator-manual/high_availability.md#webhook-and-manifest-paths-annotation) | Used to avoid unnecessary Application refreshes, especially in mono-repos. |
| argocd.argoproj.io/refresh | Application | `normal`, `hard` | Indicates that app needs to be refreshed. Removed by application controller after app is refreshed. Value `"hard"` means manifest cache and target cluster state cache should be invalidated before refresh. |
| argocd.argoproj.io/skip-reconcile | Application | `"true"` | Indicates to the Argo CD application controller that the Application should not be reconciled. See the [skip reconcile documentation](skip_reconcile.md) for use cases. |
| argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. |
| argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | |
| argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. |
| link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. |
| pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. |
| pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") |
## Labels
| Label key | Target resource(es) | Possible values | Description |
|--------------------------------|---------------------|---------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| argocd.argoproj.io/instance | Application | any | Recommended tracking label to [avoid conflicts with other tools which use `app.kubernetes.io/instance`](../faq.md#why-is-my-app-out-of-sync-even-after-syncing. |
| argocd.argoproj.io/secret-type | Secret | `cluster`, `repository`, `repo-creds` | Identifies certain types of Secrets used by Argo CD. See the [Declarative Setup docs](../operator-manual/declarative-setup.md) for details. |

View File

@@ -54,7 +54,7 @@ source:
Argo CD supports the equivalent of a values file directly in the Application manifest using the `source.helm.valuesObject` key.
```
```yaml
source:
helm:
valuesObject:
@@ -75,7 +75,7 @@ source:
Alternatively, values can be passed in as a string using the `source.helm.values` key.
```
```yaml
source:
helm:
values: |
@@ -254,7 +254,7 @@ One way to use this plugin is to prepare your own ArgoCD image where it is inclu
Example `Dockerfile`:
```
```dockerfile
FROM argoproj/argocd:v1.5.7
USER root
@@ -284,7 +284,7 @@ Some users find this pattern preferable to maintaining their own version of the
Below is an example of how to add Helm plugins when installing ArgoCD with the [official ArgoCD helm chart](https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd):
```
```yaml
repoServer:
volumes:
- name: gcp-credentials

View File

@@ -279,7 +279,7 @@ It is possible to add and remove TLS certificates using the ArgoCD web UI:
### Managing TLS certificates using declarative configuration
You can also manage TLS certificates in a declarative, self-managed ArgoCD setup. All TLS certificates are stored in the ConfigMap object `argocd-tls-cert-cm`.
You can also manage TLS certificates in a declarative, self-managed ArgoCD setup. All TLS certificates are stored in the ConfigMap object `argocd-tls-certs-cm`.
Please refer to the [Operator Manual](../../operator-manual/declarative-setup/#repositories-using-self-signed-tls-certificates-or-are-signed-by-custom-ca) for more information.
## Unknown SSH Hosts

View File

@@ -0,0 +1,144 @@
# Sync Applications with Kubectl
You can use "kubectl" to ask Argo CD to synchronize applications the same way you can use the CLI or UI. Many configurations like "force", "prune", "apply" and even synchronize a specific list of resources are equally supported. This is done by applying or patching the Argo CD application with a document that defines an "operation".
This "operation" defines how a synchronization should be done and for what resources these synchronization is to be done.
There are many configuration options that can be added to the "operation". Next, a few of them are explained. For more details, you can have a look at the CRD [applications.argoproj.io](https://github.com/argoproj/argo-cd/blob/master/manifests/crds/application-crd.yaml). Some of them are required, whereas others are optional.
To ask Argo CD to synchronize all resources of a given application, we can do:
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: <app-name>
namespace: <namespace>
spec:
...
operation:
initiatedBy:
username: <username>
sync:
syncStrategy:
hook: {}
```
```bash
$ kubectl apply -f <apply-file>
```
The most important part is the "sync" definition in the "operation" field. You can pass optional information like "info" or "initiatedBy". "info" allows you to add information about the operation in the form of a list. "initiatedBy" contains information about who initiated the operation request.
Or if you prefer, you also can patch:
```yaml
operation:
initiatedBy:
username: <username>
sync:
syncStrategy:
hook: {}
```
```bash
$ kubectl patch -n <namespace> app <app-name> --patch-file <patch-file> --type merge
```
Be aware that patches, specially with merge strategies, may not work the way you expect especially if you change sync strategies or options.
In these cases, "kubectl apply" gives better results.
Either with a "kubectl patch" or "kubectl apply", the state of the synchronization is reported in the "operationState" field in the application object.
```bash
$ kubectl get -n <namespace> get app <app-name> -o yaml
...
status:
operationState:
finishedAt: "2023-08-03T11:16:17Z"
message: successfully synced (all tasks run)
phase: Succeeded
```
# Apply and Hook synchronization strategies
There are two types of synchronization strategies: "hook", which is the default value, and "apply".
An "apply" sync strategy tells Argo CD to "kubectl apply", whereas a "hook" sync strategy informs Argo CD to submit any resource that's referenced in the operation. This way the synchronization of these resources will take into consideration any hook the resource has been annotated with.
```yaml
operation:
sync:
syncStrategy:
apply: {}
```
```yaml
operation:
sync:
syncStrategy:
hook: {}
```
Both strategies support "force". However, you need to be aware that a force operation deletes the resource when patch encounters a conflict after having retried 5 times.
```yaml
operation:
sync:
syncStrategy:
apply:
force: true
```
```yaml
operation:
sync:
syncStrategy:
hook:
force: true
```
# Prune
If you want to prune your resources before applying, you can instruct Argo CD to do so:
```yaml
operation:
sync:
prune: true
```
# List of resources
There's always the possibility to pass a list of resources. This list can be all resources the application manages or only a subset, for example resources that remained out of sync for some reason.
Only "kind" and "name" are required fields when referencing resources, but the fields "groups" and "namespace" can also be defined:
```yaml
operation:
sync:
resources:
- kind: Namespace
name: namespace-name
- kind: ServiceAccount
name: service-account-name
namespace: namespace-name
- group: networking.k8s.io
kind: NetworkPolicy
name: network-policy-name
namespace: namespace-name
```
# Sync Options
In an operation, you can also pass sync-options. Each of these options is passed as "name=value" pairs. For example:
```yaml
operations:
sync:
syncOptions:
- Validate=false
- Prune=false
```
For more information about sync options, please refer to [sync-options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/)

2
go.mod
View File

@@ -115,6 +115,7 @@ require (
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
gopkg.in/retry.v1 v1.0.3 // indirect
k8s.io/klog v1.0.0 // indirect
nhooyr.io/websocket v1.8.7 // indirect
)
require (
@@ -261,7 +262,6 @@ require (
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
k8s.io/kube-aggregator v0.24.2 // indirect
k8s.io/kubernetes v1.24.2 // indirect
nhooyr.io/websocket v1.8.6 // indirect
sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124 // indirect
sigs.k8s.io/kustomize/api v0.11.5 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.7 // indirect

3
go.sum
View File

@@ -1963,8 +1963,9 @@ modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
oras.land/oras-go/v2 v2.2.0 h1:E1fqITD56Eg5neZbxBtAdZVgDHD6wBabJo6xESTcQyo=
oras.land/oras-go/v2 v2.2.0/go.mod h1:pXjn0+KfarspMHHNR3A56j3tgvr+mxArHuI8qVn59v8=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

View File

@@ -5,7 +5,7 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.8.0
newTag: v2.8.1
resources:
- ./application-controller
- ./dex

View File

@@ -18880,7 +18880,7 @@ spec:
key: applicationsetcontroller.allowed.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -19168,7 +19168,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -19220,7 +19220,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -19439,7 +19439,7 @@ spec:
key: controller.kubectl.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -12,4 +12,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.8.0
newTag: v2.8.1

View File

@@ -12,7 +12,7 @@ patches:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.8.0
newTag: v2.8.1
resources:
- ../../base/application-controller
- ../../base/applicationset-controller

View File

@@ -20117,7 +20117,7 @@ spec:
key: applicationsetcontroller.allowed.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -20240,7 +20240,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -20310,7 +20310,7 @@ spec:
key: notificationscontroller.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -20624,7 +20624,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -20676,7 +20676,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -20965,7 +20965,7 @@ spec:
key: server.enable.proxy.extension
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -21211,7 +21211,7 @@ spec:
key: controller.kubectl.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -1635,7 +1635,7 @@ spec:
key: applicationsetcontroller.allowed.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1758,7 +1758,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1828,7 +1828,7 @@ spec:
key: notificationscontroller.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2142,7 +2142,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2194,7 +2194,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2483,7 +2483,7 @@ spec:
key: server.enable.proxy.extension
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2729,7 +2729,7 @@ spec:
key: controller.kubectl.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -19218,7 +19218,7 @@ spec:
key: applicationsetcontroller.allowed.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -19341,7 +19341,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -19411,7 +19411,7 @@ spec:
key: notificationscontroller.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -19681,7 +19681,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -19733,7 +19733,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -20020,7 +20020,7 @@ spec:
key: server.enable.proxy.extension
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -20266,7 +20266,7 @@ spec:
key: controller.kubectl.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -736,7 +736,7 @@ spec:
key: applicationsetcontroller.allowed.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -859,7 +859,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -929,7 +929,7 @@ spec:
key: notificationscontroller.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1199,7 +1199,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1251,7 +1251,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1538,7 +1538,7 @@ spec:
key: server.enable.proxy.extension
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -1784,7 +1784,7 @@ spec:
key: controller.kubectl.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.8.0
image: quay.io/argoproj/argocd:v2.8.1
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -167,6 +167,7 @@ nav:
- user-guide/selective_sync.md
- user-guide/sync-waves.md
- user-guide/sync_windows.md
- user-guide/sync-kubectl.md
- user-guide/skip_reconcile.md
- Generating Applications with ApplicationSet: user-guide/application-set.md
- user-guide/ci_automation.md
@@ -176,6 +177,7 @@ nav:
- user-guide/external-url.md
- user-guide/extra_info.md
- Notification subscriptions: user-guide/subscriptions.md
- user-guide/annotations-and-labels.md
- Command Reference: user-guide/commands/argocd.md
- Application Specification Reference: user-guide/application-specification.md
- Developer Guide:

View File

@@ -2,3 +2,6 @@ actionTests:
- action: create-workflow
inputPath: testdata/cronworkflow.yaml
expectedOutputPath: testdata/workflow.yaml
- action: create-workflow
inputPath: testdata/cronworkflow-without-label.yaml
expectedOutputPath: testdata/workflow-without-label.yaml

View File

@@ -50,7 +50,7 @@ if (obj.spec.workflowMetadata ~= nil) then
end
end
workflow.metadata.labels["workflows.argoproj.io/cron-workflow"] = obj.metadata.name
if (obj.metadata.labels["workflows.argoproj.io/controller-instanceid"] ~= nil) then
if (obj.metadata.labels ~= nil and obj.metadata.labels["workflows.argoproj.io/controller-instanceid"] ~= nil) then
workflow.metadata.labels["workflows.argoproj.io/controller-instanceid"] = obj.metadata.labels["workflows.argoproj.io/controller-instanceid"]
end
workflow.metadata.annotations["workflows.argoproj.io/scheduled-time"] = os.date("!%Y-%m-%dT%d:%H:%MZ")

View File

@@ -0,0 +1,31 @@
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
annotations:
cronworkflows.argoproj.io/last-used-schedule: CRON_TZ=America/Los_Angeles * * * * *
name: hello-world
namespace: default
spec:
concurrencyPolicy: Replace
failedJobsHistoryLimit: 4
schedule: '* * * * *'
startingDeadlineSeconds: 0
successfulJobsHistoryLimit: 4
suspend: true
timezone: America/Los_Angeles
workflowSpec:
entrypoint: whalesay
templates:
- container:
args:
- "\U0001F553 hello world. Scheduled on: {{workflow.scheduledTime}}"
command:
- cowsay
image: 'docker/whalesay:latest'
name: whalesay
workflowMetadata:
labels:
example: test
annotations:
another-example: another-test
finalizers: [test-finalizer]

View File

@@ -0,0 +1,26 @@
- k8sOperation: create
unstructuredObj:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
annotations:
another-example: another-test
labels:
example: test
name: hello-world-202306221736
namespace: default
ownerReferences:
- apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
name: hello-world
finalizers: [test-finalizer]
spec:
entrypoint: whalesay
templates:
- container:
args:
- "\U0001F553 hello world. Scheduled on: {{workflow.scheduledTime}}"
command:
- cowsay
image: 'docker/whalesay:latest'
name: whalesay

View File

@@ -6,6 +6,7 @@ import (
"net/http"
"time"
util_session "github.com/argoproj/argo-cd/v2/util/session"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
@@ -37,11 +38,12 @@ type terminalHandler struct {
allowedShells []string
namespace string
enabledNamespaces []string
sessionManager util_session.SessionManager
}
// NewHandler returns a new terminal handler.
func NewHandler(appLister applisters.ApplicationLister, namespace string, enabledNamespaces []string, db db.ArgoDB, enf *rbac.Enforcer, cache *servercache.Cache,
appResourceTree AppResourceTreeFn, allowedShells []string) *terminalHandler {
appResourceTree AppResourceTreeFn, allowedShells []string, sessionManager util_session.SessionManager) *terminalHandler {
return &terminalHandler{
appLister: appLister,
db: db,
@@ -51,6 +53,7 @@ func NewHandler(appLister applisters.ApplicationLister, namespace string, enable
allowedShells: allowedShells,
namespace: namespace,
enabledNamespaces: enabledNamespaces,
sessionManager: sessionManager,
}
}
@@ -222,7 +225,7 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fieldLog.Info("terminal session starting")
session, err := newTerminalSession(w, r, nil)
session, err := newTerminalSession(w, r, nil, s.sessionManager)
if err != nil {
http.Error(w, "Failed to start terminal session", http.StatusBadRequest)
return
@@ -282,6 +285,11 @@ type TerminalMessage struct {
Cols uint16 `json:"cols"`
}
// TerminalCommand is the struct for websocket commands,For example you need ask client to reconnect
type TerminalCommand struct {
Code int
}
// startProcess executes specified commands in the container and connects it up with the ptyHandler (a session)
func startProcess(k8sClient kubernetes.Interface, cfg *rest.Config, namespace, podName, containerName string, cmd []string, ptyHandler PtyHandler) error {
req := k8sClient.CoreV1().RESTClient().Post().

View File

@@ -3,6 +3,9 @@ package application
import (
"encoding/json"
"fmt"
"github.com/argoproj/argo-cd/v2/common"
httputil "github.com/argoproj/argo-cd/v2/util/http"
util_session "github.com/argoproj/argo-cd/v2/util/session"
"net/http"
"sync"
"time"
@@ -12,6 +15,11 @@ import (
"k8s.io/client-go/tools/remotecommand"
)
const (
ReconnectCode = 1
ReconnectMessage = "\nReconnect because the token was refreshed...\n"
)
var upgrader = func() websocket.Upgrader {
upgrader := websocket.Upgrader{}
upgrader.HandshakeTimeout = time.Second * 2
@@ -23,25 +31,40 @@ var upgrader = func() websocket.Upgrader {
// terminalSession implements PtyHandler
type terminalSession struct {
wsConn *websocket.Conn
sizeChan chan remotecommand.TerminalSize
doneChan chan struct{}
tty bool
readLock sync.Mutex
writeLock sync.Mutex
wsConn *websocket.Conn
sizeChan chan remotecommand.TerminalSize
doneChan chan struct{}
tty bool
readLock sync.Mutex
writeLock sync.Mutex
sessionManager util_session.SessionManager
token *string
}
// getToken get auth token from web socket request
func getToken(r *http.Request) (string, error) {
cookies := r.Cookies()
return httputil.JoinCookies(common.AuthCookieName, cookies)
}
// newTerminalSession create terminalSession
func newTerminalSession(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*terminalSession, error) {
func newTerminalSession(w http.ResponseWriter, r *http.Request, responseHeader http.Header, sessionManager util_session.SessionManager) (*terminalSession, error) {
token, err := getToken(r)
if err != nil {
return nil, err
}
conn, err := upgrader.Upgrade(w, r, responseHeader)
if err != nil {
return nil, err
}
session := &terminalSession{
wsConn: conn,
tty: true,
sizeChan: make(chan remotecommand.TerminalSize),
doneChan: make(chan struct{}),
wsConn: conn,
tty: true,
sizeChan: make(chan remotecommand.TerminalSize),
doneChan: make(chan struct{}),
sessionManager: sessionManager,
token: &token,
}
return session, nil
}
@@ -78,8 +101,40 @@ func (t *terminalSession) Next() *remotecommand.TerminalSize {
}
}
// reconnect send reconnect code to client and ask them init new ws session
func (t *terminalSession) reconnect() (int, error) {
reconnectCommand, _ := json.Marshal(TerminalCommand{
Code: ReconnectCode,
})
reconnectMessage, _ := json.Marshal(TerminalMessage{
Operation: "stdout",
Data: ReconnectMessage,
})
t.writeLock.Lock()
err := t.wsConn.WriteMessage(websocket.TextMessage, reconnectMessage)
if err != nil {
log.Errorf("write message err: %v", err)
return 0, err
}
err = t.wsConn.WriteMessage(websocket.TextMessage, reconnectCommand)
if err != nil {
log.Errorf("write message err: %v", err)
return 0, err
}
t.writeLock.Unlock()
return 0, nil
}
// Read called in a loop from remotecommand as long as the process is running
func (t *terminalSession) Read(p []byte) (int, error) {
// check if token still valid
_, newToken, err := t.sessionManager.VerifyToken(*t.token)
// err in case if token is revoked, newToken in case if refresh happened
if err != nil || newToken != "" {
// need to send reconnect code in case if token was refreshed
return t.reconnect()
}
t.readLock.Lock()
_, message, err := t.wsConn.ReadMessage()
t.readLock.Unlock()

View File

@@ -0,0 +1,46 @@
package application
import (
"encoding/json"
"github.com/gorilla/websocket"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func reconnect(w http.ResponseWriter, r *http.Request) {
var upgrader = websocket.Upgrader{}
c, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
ts := terminalSession{wsConn: c}
_, _ = ts.reconnect()
}
func TestReconnect(t *testing.T) {
s := httptest.NewServer(http.HandlerFunc(reconnect))
defer s.Close()
u := "ws" + strings.TrimPrefix(s.URL, "http")
// Connect to the server
ws, _, err := websocket.DefaultDialer.Dial(u, nil)
assert.NoError(t, err)
defer ws.Close()
_, p, _ := ws.ReadMessage()
var message TerminalMessage
err = json.Unmarshal(p, &message)
assert.NoError(t, err)
assert.Equal(t, message.Data, ReconnectMessage)
}

View File

@@ -977,7 +977,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
}
mux.Handle("/api/", handler)
terminal := application.NewHandler(a.appLister, a.Namespace, a.ApplicationNamespaces, a.db, a.enf, a.Cache, appResourceTreeFn, a.settings.ExecShells).
terminal := application.NewHandler(a.appLister, a.Namespace, a.ApplicationNamespaces, a.db, a.enf, a.Cache, appResourceTreeFn, a.settings.ExecShells, *a.sessionMgr).
WithFeatureFlagMiddleware(a.settingsMgr.GetSettings)
th := util_session.WithAuthMiddleware(a.DisableAuth, a.sessionMgr, terminal)
mux.Handle("/terminal", th)
@@ -990,6 +990,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
// will be added in mux.
registerExtensions(mux, a)
}
mustRegisterGWHandler(versionpkg.RegisterVersionServiceHandler, ctx, gwmux, conn)
mustRegisterGWHandler(clusterpkg.RegisterClusterServiceHandler, ctx, gwmux, conn)
mustRegisterGWHandler(applicationpkg.RegisterApplicationServiceHandler, ctx, gwmux, conn)

View File

@@ -14,7 +14,7 @@ FROM docker.io/library/registry:2.8@sha256:41f413c22d6156587e2a51f3e80c09808b8c7
FROM docker.io/bitnami/kubectl:1.27@sha256:670fe3f50d45c0511bb0f2af018e2fc082ac8cdfaea02dba4e32866296036926 as kubectl
FROM docker.io/library/ubuntu:22.04@sha256:ac58ff7fe25edc58bdf0067ca99df00014dbd032e2246d30a722fa348fd799a5
FROM docker.io/library/ubuntu:22.04@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install --fix-missing -y \

View File

@@ -72,7 +72,13 @@ export const PodTerminalViewer: React.FC<PodTerminalViewerProps> = ({
const onConnectionMessage = (e: MessageEvent) => {
const msg = JSON.parse(e.data);
connSubject.next(msg);
if (!msg?.Code) {
connSubject.next(msg);
} else {
// Do reconnect due to refresh token event
onConnectionClose();
setupConnection();
}
};
const onConnectionOpen = () => {

View File

@@ -105,7 +105,7 @@ export class VersionPanel extends React.Component<VersionPanelProps, {copyState:
}
private async onCopy(version: VersionMessage): Promise<void> {
const stringifiedVersion = JSON.stringify(version, undefined, 4);
const stringifiedVersion = JSON.stringify(version, undefined, 4) + '\n';
try {
await navigator.clipboard.writeText(stringifiedVersion);
this.setState({copyState: 'success'});