mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-04-01 22:38:46 +02:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bc94af7bd | ||
|
|
b9a32bb86e | ||
|
|
356e33ac29 | ||
|
|
9ffef110da | ||
|
|
af721bbb63 | ||
|
|
91d249ec84 | ||
|
|
004ca26b9e | ||
|
|
2a17ca57ec | ||
|
|
89495d72df | ||
|
|
885bb57ae8 | ||
|
|
d6d7b1452d | ||
|
|
490c78b75f | ||
|
|
092e55e279 | ||
|
|
fe526dd33c | ||
|
|
cade0e970d | ||
|
|
e58eaaf36f | ||
|
|
0c4e249922 | ||
|
|
8ea6650dd7 |
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -14,3 +14,7 @@ func newSysProcAttr(setpgid bool) *syscall.SysProcAttr {
|
||||
func sysCallKill(pid int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func sysCallTerm(pid int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
26
docs/user-guide/annotations-and-labels.md
Normal file
26
docs/user-guide/annotations-and-labels.md
Normal 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. |
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
144
docs/user-guide/sync-kubectl.md
Normal file
144
docs/user-guide/sync-kubectl.md
Normal 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
2
go.mod
@@ -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
3
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: v2.8.0
|
||||
newTag: v2.8.1
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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]
|
||||
26
resource_customizations/argoproj.io/CronWorkflow/actions/testdata/workflow-without-label.yaml
vendored
Normal file
26
resource_customizations/argoproj.io/CronWorkflow/actions/testdata/workflow-without-label.yaml
vendored
Normal 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
|
||||
@@ -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().
|
||||
|
||||
@@ -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()
|
||||
|
||||
46
server/application/websocket_test.go
Normal file
46
server/application/websocket_test.go
Normal 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)
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 = () => {
|
||||
|
||||
@@ -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'});
|
||||
|
||||
Reference in New Issue
Block a user