From 35a9e0cc6dfbd52ba4f97472bd57c3f18efa3c7d Mon Sep 17 00:00:00 2001 From: Victor Sollerhed Date: Mon, 23 Oct 2023 15:30:28 +0200 Subject: [PATCH 01/13] chore(deps): bump kustomize to v5.2.1 (#16054) * kustomize v5.2.1 checksums Signed-off-by: Victor Sollerhed * kustomize v5.2.1 tool-versions Signed-off-by: Victor Sollerhed --------- Signed-off-by: Victor Sollerhed --- .../checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 | 1 + hack/tool-versions.sh | 2 +- 7 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 diff --git a/hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..655910d278d31 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +b7aba749da75d33e6fea49a5098747d379abc45583ff5cd16e2356127a396549 kustomize_5.2.1_darwin_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..55f753b7cb4a5 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 @@ -0,0 +1 @@ +f6a5f3cffd45bac585a0c80b5ed855c2b72d932a1d6e8e7c87aae3be4eba5750 kustomize_5.2.1_darwin_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..a9cb3b79c77e8 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +88346543206b889f9287c0b92c70708040ecd5aad54dd33019c4d6579cd24de8 kustomize_5.2.1_linux_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..ff4078ddd85f3 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 @@ -0,0 +1 @@ +5566f7badece5a72d42075d8dffa6296a228966dd6ac2390de7afbb9675c3aaa kustomize_5.2.1_linux_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..b5b6c7e9f077c --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +82d732cf624b6fa67dfabe751e9a1510e2d08605996b1b130b4c0f5b835b130e kustomize_5.2.1_linux_ppc64le.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..565fb1df10d8e --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 @@ -0,0 +1 @@ +d94cb97a2776b4685ab41233dfd5f0b426f399d2fce87d2b69e1ce4907f3aad2 kustomize_5.2.1_linux_s390x.tar.gz diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 00dd572966182..842af77c8a2ac 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -14,5 +14,5 @@ helm3_version=3.13.1 kubectl_version=1.17.8 kubectx_version=0.6.3 -kustomize5_version=5.1.1 +kustomize5_version=5.2.1 protoc_version=3.17.3 From 9a922de9b290109b38c6fb171915f7de1293a965 Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Mon, 23 Oct 2023 06:32:35 -0700 Subject: [PATCH 02/13] fix: ensure appset don't attempt to remove application kind in patch requests (#16056) Signed-off-by: Alexander Matyushentsev --- applicationset/utils/createOrUpdate.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/applicationset/utils/createOrUpdate.go b/applicationset/utils/createOrUpdate.go index 096be5a9a97d3..274070c2ef5be 100644 --- a/applicationset/utils/createOrUpdate.go +++ b/applicationset/utils/createOrUpdate.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -78,6 +79,12 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f c return a.Namespace == b.Namespace && a.Name == b.Name && a.Server == b.Server }, ) + // make sure updated object has the same apiVersion & kind as original object + if objKind, ok := obj.(schema.ObjectKind); ok { + if existingKind, ok := existing.(schema.ObjectKind); ok { + existingKind.SetGroupVersionKind(objKind.GroupVersionKind()) + } + } if equality.DeepEqual(existing, obj) { return controllerutil.OperationResultNone, nil From c72a38861879ac3298279c5b429e68425d8d95b4 Mon Sep 17 00:00:00 2001 From: Ratan Gulati Date: Mon, 23 Oct 2023 19:11:36 +0530 Subject: [PATCH 03/13] feat(cli): Add examples to --help output for "gpg add" (#16020) * feat: Add examples to --help output for gpg add Signed-off-by: Ratan Gulati * Update gpg.go Signed-off-by: Ratan Gulati * feat: Add examples to --help output for gpg add Signed-off-by: Ratan Gulati * updated file Signed-off-by: Ratan Gulati --------- Signed-off-by: Ratan Gulati --- cmd/argocd/commands/gpg.go | 6 ++++++ docs/user-guide/commands/argocd_gpg_add.md | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/cmd/argocd/commands/gpg.go b/cmd/argocd/commands/gpg.go index 7a48a915bebec..3c0496d2f012a 100644 --- a/cmd/argocd/commands/gpg.go +++ b/cmd/argocd/commands/gpg.go @@ -14,6 +14,7 @@ import ( appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/util/errors" argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/templates" ) // NewGPGCommand returns a new instance of an `argocd repo` command @@ -109,6 +110,11 @@ func NewGPGAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ Use: "add", Short: "Adds a GPG public key to the server's keyring", + Example: templates.Examples(` + # Add a GPG public key to the server's keyring from a file. + argocd gpg add --from /path/to/keyfile + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_gpg_add.md b/docs/user-guide/commands/argocd_gpg_add.md index c3fb32369d86d..3ef5d4e6c72d5 100644 --- a/docs/user-guide/commands/argocd_gpg_add.md +++ b/docs/user-guide/commands/argocd_gpg_add.md @@ -8,6 +8,13 @@ Adds a GPG public key to the server's keyring argocd gpg add [flags] ``` +### Examples + +``` + # Add a GPG public key to the server's keyring from a file. + argocd gpg add --from /path/to/keyfile +``` + ### Options ``` From 20618b44eddd94977d19d8f6c4b773eb9ce1169f Mon Sep 17 00:00:00 2001 From: Shaurya Gulati Date: Mon, 23 Oct 2023 19:13:18 +0530 Subject: [PATCH 04/13] feat(cli): Add examples to --help output for "list PROJECT" (#16033) Signed-off-by: Shauryagulati --- cmd/argocd/commands/project_role.go | 9 +++++++++ docs/user-guide/commands/argocd_proj_role_list.md | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index ecc7d670ce42e..166d8f3979be2 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -395,6 +395,15 @@ func NewProjectRoleListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co var command = &cobra.Command{ Use: "list PROJECT", Short: "List all the roles in a project", + Example: templates.Examples(` + # This command will list all the roles in argocd-project in a default table format. + argocd list argocd-project + + # List the roles in the project in formats like json, yaml, wide, or name. + argocd list argocd-project --output json + + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index b535cf724add9..ea6e0099d4611 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -8,6 +8,16 @@ List all the roles in a project argocd proj role list PROJECT [flags] ``` +### Examples + +``` + # This command will list all the roles in argocd-project in a default table format. + argocd list argocd-project + + # List the roles in the project in formats like json, yaml, wide, or name. + argocd list argocd-project --output json +``` + ### Options ``` From 752004c8705578b450e04129a13f319a874b940b Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Mon, 23 Oct 2023 15:59:56 +0200 Subject: [PATCH 05/13] feat(cmp): Print stderr output from command even on success (#15921) (#15973) * feat(cmp): Print stderr output from command even on success Signed-off-by: Mathias Petermann * docs(cmp): Document logging from cmp sidecard for development purposes Signed-off-by: Mathias Petermann --------- Signed-off-by: Mathias Petermann --- cmpserver/plugin/plugin.go | 13 +++++++++---- docs/operator-manual/config-management-plugins.md | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cmpserver/plugin/plugin.go b/cmpserver/plugin/plugin.go index f03b73f24dcf6..ca1e7592218ea 100644 --- a/cmpserver/plugin/plugin.go +++ b/cmpserver/plugin/plugin.go @@ -120,11 +120,16 @@ func runCommand(ctx context.Context, command Command, path string, env []string) logCtx.Error(err.Error()) return strings.TrimSuffix(output, "\n"), err } + + logCtx = logCtx.WithFields(log.Fields{ + "stderr": stderr.String(), + "command": command, + }) if len(output) == 0 { - log.WithFields(log.Fields{ - "stderr": stderr.String(), - "command": command, - }).Warn("Plugin command returned zero output") + logCtx.Warn("Plugin command returned zero output") + } else { + // Log stderr even on successfull commands to help develop plugins + logCtx.Info("Plugin command successfull") } return strings.TrimSuffix(output, "\n"), nil diff --git a/docs/operator-manual/config-management-plugins.md b/docs/operator-manual/config-management-plugins.md index ee805b71cd604..b77a4bdd7ba21 100644 --- a/docs/operator-manual/config-management-plugins.md +++ b/docs/operator-manual/config-management-plugins.md @@ -44,6 +44,7 @@ spec: args: [-c, 'echo "Initializing..."'] # The generate command runs in the Application source directory each time manifests are generated. Standard output # must be ONLY valid Kubernetes Objects in either YAML or JSON. A non-zero exit code will fail manifest generation. + # To write log messages from the command, write them to stderr, it will always be displayed. # Error output will be sent to the UI, so avoid printing sensitive information (such as secrets). generate: command: [sh, -c] @@ -333,6 +334,7 @@ If you are actively developing a sidecar-installed CMP, keep a few things in min 3. CMP errors are cached by the repo-server in Redis. Restarting the repo-server Pod will not clear the cache. Always do a "Hard Refresh" when actively developing a CMP so you have the latest output. 4. Verify your sidecar has started properly by viewing the Pod and seeing that two containers are running `kubectl get pod -l app.kubernetes.io/component=repo-server -n argocd` +5. Write log message to stderr and set the `--loglevel=info` flag in the sidecar. This will print everything written to stderr, even on successfull command execution. ### Other Common Errors From 56a7bb79a4d66e5f0a7932d62aaef3f18d38ea08 Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Mon, 23 Oct 2023 08:40:13 -0700 Subject: [PATCH 06/13] fix: auto-sync fails with 'another operation is already in progress' error (#15638) Signed-off-by: Alexander Matyushentsev --- controller/appcontroller.go | 8 ++++++++ util/argo/argo.go | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 46e3ede0f3a3e..537f8d5a411e4 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + goerrors "errors" "fmt" "math" "net/http" @@ -1801,6 +1802,13 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * _, err := argo.SetAppOperation(appIf, app.Name, &op) setOpTime := time.Since(start) if err != nil { + if goerrors.Is(err, argo.ErrAnotherOperationInProgress) { + // skipping auto-sync because another operation is in progress and was not noticed due to stale data in informer + // it is safe to skip auto-sync because it is already running + logCtx.Warnf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) + return nil, 0 + } + logCtx.Errorf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: err.Error()}, setOpTime } diff --git a/util/argo/argo.go b/util/argo/argo.go index 9b08d3aeeb847..9187726ab17dc 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -35,6 +35,10 @@ const ( errDestinationMissing = "Destination server missing from app spec" ) +var ( + ErrAnotherOperationInProgress = status.Errorf(codes.FailedPrecondition, "another operation is already in progress") +) + // AugmentSyncMsg enrich the K8s message with user-relevant information func AugmentSyncMsg(res common.ResourceSyncResult, apiResourceInfoGetter func() ([]kube.APIResourceInfo, error)) (string, error) { switch res.Message { @@ -800,7 +804,7 @@ func SetAppOperation(appIf v1alpha1.ApplicationInterface, appName string, op *ar return nil, fmt.Errorf("error getting application %q: %w", appName, err) } if a.Operation != nil { - return nil, status.Errorf(codes.FailedPrecondition, "another operation is already in progress") + return nil, ErrAnotherOperationInProgress } a.Operation = op a.Status.OperationState = nil From f4e0d354548c101096b234363b5fcd7dce07017f Mon Sep 17 00:00:00 2001 From: May Zhang Date: Mon, 23 Oct 2023 14:44:49 -0700 Subject: [PATCH 07/13] fix: argocd notification controller app cluster permission issue (#16057) * if applicationNamespaces is not provided as input parameter, then use namespaced appClient Signed-off-by: May Zhang * fix go lint error Signed-off-by: May Zhang --------- Signed-off-by: May Zhang --- notification_controller/controller/controller.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index 1ad2ab361ab93..a08c0cc1f9714 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -61,7 +61,13 @@ func NewController( secretName string, configMapName string, ) *notificationController { - appClient := client.Resource(applications) + var appClient dynamic.ResourceInterface + namespaceableAppClient := client.Resource(applications) + appClient = namespaceableAppClient + if len(applicationNamespaces) == 0 { + appClient = namespaceableAppClient.Namespace(namespace) + } + appInformer := newInformer(appClient, namespace, applicationNamespaces, appLabelSelector) appProjInformer := newInformer(newAppProjClient(client, namespace), namespace, []string{namespace}, "") secretInformer := k8s.NewSecretInformer(k8sClient, namespace, secretName) @@ -74,7 +80,7 @@ func NewController( appInformer: appInformer, appProjInformer: appProjInformer, apiFactory: apiFactory} - res.ctrl = controller.NewController(appClient, appInformer, apiFactory, + res.ctrl = controller.NewController(namespaceableAppClient, appInformer, apiFactory, controller.WithSkipProcessing(func(obj v1.Object) (bool, string) { app, ok := (obj).(*unstructured.Unstructured) if !ok { From a43b799609a75f2376cfe14268d69b8ee6f2e8dd Mon Sep 17 00:00:00 2001 From: gdsoumya <44349253+gdsoumya@users.noreply.github.com> Date: Tue, 24 Oct 2023 06:45:53 +0530 Subject: [PATCH 08/13] feat: add write back to application informer (#15987) Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> --- controller/appcontroller.go | 34 +++++++++++++++++++++++++------- controller/appcontroller_test.go | 32 +++++++++++++++--------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 537f8d5a411e4..3b54c13d4eb43 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -1331,8 +1331,7 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta } kube.RetryUntilSucceed(context.Background(), updateOperationStateTimeout, "Update application operation state", logutils.NewLogrusLogger(logutils.NewWithCurrentConfig()), func() error { - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) - _, err = appClient.Patch(context.Background(), app.Name, types.MergePatchType, patchJSON, metav1.PatchOptions{}) + _, err := ctrl.PatchAppWithWriteBack(context.Background(), app.Name, app.Namespace, types.MergePatchType, patchJSON, metav1.PatchOptions{}) if err != nil { // Stop retrying updating deleted application if apierr.IsNotFound(err) { @@ -1370,6 +1369,27 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta } } +// writeBackToInformer writes a just recently updated App back into the informer cache. +// This prevents the situation where the controller operates on a stale app and repeats work +func (ctrl *ApplicationController) writeBackToInformer(app *appv1.Application) { + logCtx := log.WithFields(log.Fields{"application": app.Name, "appNamespace": app.Namespace, "project": app.Spec.Project, "informer-writeBack": true}) + err := ctrl.appInformer.GetStore().Update(app) + if err != nil { + logCtx.Errorf("failed to update informer store: %v", err) + return + } +} + +// PatchAppWithWriteBack patches an application and writes it back to the informer cache +func (ctrl *ApplicationController) PatchAppWithWriteBack(ctx context.Context, name, ns string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *appv1.Application, err error) { + patchedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ns).Patch(ctx, name, pt, data, opts, subresources...) + if err != nil { + return patchedApp, err + } + ctrl.writeBackToInformer(patchedApp) + return patchedApp, err +} + func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext bool) { patchMs := time.Duration(0) // time spent in doing patch/update calls setOpMs := time.Duration(0) // time spent in doing Operation patch calls in autosync @@ -1643,8 +1663,7 @@ func (ctrl *ApplicationController) normalizeApplication(orig, app *appv1.Applica if err != nil { logCtx.Errorf("error constructing app spec patch: %v", err) } else if modified { - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) - _, err = appClient.Patch(context.Background(), app.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + _, err := ctrl.PatchAppWithWriteBack(context.Background(), app.Name, app.Namespace, types.MergePatchType, patch, metav1.PatchOptions{}) if err != nil { logCtx.Errorf("Error persisting normalized application spec: %v", err) } else { @@ -1688,8 +1707,7 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new defer func() { patchMs = time.Since(start) }() - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(orig.Namespace) - _, err = appClient.Patch(context.Background(), orig.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + _, err = ctrl.PatchAppWithWriteBack(context.Background(), orig.Name, orig.Namespace, types.MergePatchType, patch, metav1.PatchOptions{}) if err != nil { logCtx.Warnf("Error updating application: %v", err) } else { @@ -1799,7 +1817,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * appIf := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) start := time.Now() - _, err := argo.SetAppOperation(appIf, app.Name, &op) + updatedApp, err := argo.SetAppOperation(appIf, app.Name, &op) setOpTime := time.Since(start) if err != nil { if goerrors.Is(err, argo.ErrAnotherOperationInProgress) { @@ -1811,6 +1829,8 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * logCtx.Errorf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: err.Error()}, setOpTime + } else { + ctrl.writeBackToInformer(updatedApp) } message := fmt.Sprintf("Initiated automated sync to '%s'", desiredCommitSHA) ctrl.auditLogger.LogAppEvent(app, argo.EventInfo{Reason: argo.EventReasonOperationStarted, Type: v1.EventTypeNormal}, message, "") diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 2129c88885fff..a47114f5c2527 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -625,7 +625,7 @@ func TestFinalizeAppDeletion(t *testing.T) { }) fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) _, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil @@ -675,7 +675,7 @@ func TestFinalizeAppDeletion(t *testing.T) { }) fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) objs, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil @@ -709,7 +709,7 @@ func TestFinalizeAppDeletion(t *testing.T) { }) fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) _, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil @@ -804,7 +804,7 @@ func TestNormalizeApplication(t *testing.T) { normalized = true } } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processAppRefreshQueueItem() assert.True(t, normalized) @@ -826,7 +826,7 @@ func TestNormalizeApplication(t *testing.T) { normalized = true } } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processAppRefreshQueueItem() assert.False(t, normalized) @@ -923,7 +923,7 @@ func TestSetOperationStateOnDeletedApp(t *testing.T) { patched := false fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, apierr.NewNotFound(schema.GroupResource{}, "my-app") + return true, &v1alpha1.Application{}, apierr.NewNotFound(schema.GroupResource{}, "my-app") }) ctrl.setOperationState(newFakeApp(), &v1alpha1.OperationState{Phase: synccommon.OperationSucceeded}) assert.True(t, patched) @@ -955,9 +955,9 @@ func TestSetOperationStateLogRetries(t *testing.T) { fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if !patched { patched = true - return true, nil, errors.New("fake error") + return true, &v1alpha1.Application{}, errors.New("fake error") } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.setOperationState(newFakeApp(), &v1alpha1.OperationState{Phase: synccommon.OperationSucceeded}) assert.True(t, patched) @@ -1273,7 +1273,7 @@ func TestUpdateReconciledAt(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) t.Run("UpdatedOnFullReconciliation", func(t *testing.T) { @@ -1347,7 +1347,7 @@ func TestFinalizeProjectDeletion_HasApplications(t *testing.T) { patched := false fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) err := ctrl.finalizeProjectDeletion(proj) @@ -1365,7 +1365,7 @@ func TestFinalizeProjectDeletion_DoesNotHaveApplications(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.AppProject{}, nil }) err := ctrl.finalizeProjectDeletion(proj) @@ -1390,7 +1390,7 @@ func TestProcessRequestedAppOperation_FailedNoRetries(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) @@ -1418,7 +1418,7 @@ func TestProcessRequestedAppOperation_InvalidDestination(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) }() @@ -1444,7 +1444,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) @@ -1487,7 +1487,7 @@ func TestProcessRequestedAppOperation_RunningPreviouslyFailed(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) @@ -1520,7 +1520,7 @@ func TestProcessRequestedAppOperation_HasRetriesTerminated(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) From f8cd449e36b9a9f977340b73ede92e7510e6ed4e Mon Sep 17 00:00:00 2001 From: Edith Puclla <58795858+edithturn@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:22:21 +0100 Subject: [PATCH 09/13] docs: add percona to list of Argo users (#16079) * Add Percona user Signed-off-by: Edith Puclla * Add Percona user Signed-off-by: Edith Puclla Add Percona in USERS --------- Signed-off-by: Edith Puclla --- USERS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/USERS.md b/USERS.md index 652a68c6e679f..6c4bc8e5e3eac 100644 --- a/USERS.md +++ b/USERS.md @@ -25,7 +25,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [AppDirect](https://www.appdirect.com) 1. [Arctiq Inc.](https://www.arctiq.ca) 1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/) -2. [Autodesk](https://www.autodesk.com) +1. [Autodesk](https://www.autodesk.com) 1. [Axual B.V.](https://axual.com) 1. [Back Market](https://www.backmarket.com) 1. [Baloise](https://www.baloise.com) @@ -210,6 +210,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Patreon](https://www.patreon.com/) 1. [PayPay](https://paypay.ne.jp/) 1. [Peloton Interactive](https://www.onepeloton.com/) +1. [Percona](https://percona.com/) 1. [PGS](https://www.pgs.com) 1. [Pigment](https://www.gopigment.com/) 1. [Pipefy](https://www.pipefy.com/) From 91875c01b8d11e6670bcc516920ceff57b52bc06 Mon Sep 17 00:00:00 2001 From: Rafal Date: Tue, 24 Oct 2023 17:58:05 +0200 Subject: [PATCH 10/13] fix(ui): Dark theme improvements (#15891) Signed-off-by: Rafal Pelczar --- ui/src/app/app.tsx | 4 +++- .../application-details.scss | 12 ++++++++++-- .../application-resource-tree.scss | 18 +++++++++++++++++- .../application-status-panel.scss | 4 +++- .../applications-list/applications-list.scss | 2 +- ui/src/app/applications/components/utils.scss | 7 ++++++- 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx index e38e28d91a9db..2cc63effeed2f 100644 --- a/ui/src/app/app.tsx +++ b/ui/src/app/app.tsx @@ -217,7 +217,9 @@ export class App extends React.Component< - {this.state.popupProps && } + services.viewPreferences.getPreferences()}> + {pref =>
{this.state.popupProps && }
} +
diff --git a/ui/src/app/applications/components/application-details/application-details.scss b/ui/src/app/applications/components/application-details/application-details.scss index a653063fdc102..af1ca3e9d07dc 100644 --- a/ui/src/app/applications/components/application-details/application-details.scss +++ b/ui/src/app/applications/components/application-details/application-details.scss @@ -1,5 +1,6 @@ @import 'node_modules/argo-ui/src/styles/config'; @import 'node_modules/foundation-sites/scss/util/util'; +@import 'node_modules/argo-ui/src/styles/theme'; @import '../../../shared/config.scss'; $header: 120px; @@ -211,9 +212,14 @@ $header: 120px; z-index: 1; padding: 5px; display: inline-block; - background-color: $argo-color-gray-1; box-shadow: 1px 1px 3px $argo-color-gray-5; position: absolute; + + @include themify($themes) { + background: themed('background-2'); + } + + a { padding: 5px; margin: 2px; @@ -255,7 +261,9 @@ $header: 120px; } .separator { - border-right: 1px solid $argo-color-gray-4; + @include themify($themes) { + border-right: 1px solid themed('border'); + } padding-top: 6px; padding-bottom: 6px; } diff --git a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss index f4c6ba0d0df9f..0cc459b0dc52b 100644 --- a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss +++ b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss @@ -79,6 +79,10 @@ border: 1px solid transparent; cursor: pointer; + .theme-dark & { + box-shadow: 1px 1px 1px $argo-color-gray-7; + } + .icon { font-size: 2em; } @@ -120,6 +124,10 @@ } margin-top: 9px; margin-left: 215px; + + .theme-dark & { + box-shadow: 1px 1px 1px $argo-color-gray-7; + } } &--podgroup--expansion { @@ -131,6 +139,10 @@ box-shadow: 1px 1px 1px $argo-color-gray-4; background-color: white; margin-left: 215px; + + .theme-dark & { + box-shadow: 1px 1px 1px $argo-color-gray-7; + } } &--pod { @@ -348,8 +360,12 @@ border-radius: 33px; left: -20px; top: -8px; - border: 4px solid white; text-align: center; + + @include themify($themes) { + border: 4px solid themed('background-2'); + } + i { color: $white-color; line-height: 56px; diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss index 9898db27d2ba6..e96c29624d5d1 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss @@ -101,7 +101,9 @@ } &:not(:first-child) { - border-left: 1px solid $argo-color-gray-3; + @include themify($themes) { + border-left: 1px solid themed('border'); + } } & { diff --git a/ui/src/app/applications/components/applications-list/applications-list.scss b/ui/src/app/applications/components/applications-list/applications-list.scss index fbe03245e94e6..6d359e59723e3 100644 --- a/ui/src/app/applications/components/applications-list/applications-list.scss +++ b/ui/src/app/applications/components/applications-list/applications-list.scss @@ -118,9 +118,9 @@ } &__search { - border: 1px solid $argo-color-gray-4; @include themify($themes) { background-color: themed('light-argo-gray-2'); + border: 1px solid themed('border'); } border-radius: 7px; position: relative; diff --git a/ui/src/app/applications/components/utils.scss b/ui/src/app/applications/components/utils.scss index 24d9c275bff62..245573df95d92 100644 --- a/ui/src/app/applications/components/utils.scss +++ b/ui/src/app/applications/components/utils.scss @@ -1,3 +1,5 @@ +@import 'node_modules/argo-ui/src/styles/theme'; + .propagation-policy-list { display: flex; justify-content: left; @@ -9,9 +11,12 @@ padding-right: 2em; label { - color: #6D7F8B; font-size: 15px; cursor: pointer; + + @include themify($themes) { + color: themed('light-argo-gray-6'); + } } input { From eab38b53ace0fb479462d9ae776f9c31567de4ee Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:43:11 -0400 Subject: [PATCH 11/13] docs(bounty): proposal for feature to hide annotations on secrets in UI (#15699) * docs(bounty): proposal for feature to hide annotations on secrets in the UI Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix file location Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .../feature-bounties/hide-annotations.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 docs/proposals/feature-bounties/hide-annotations.md diff --git a/docs/proposals/feature-bounties/hide-annotations.md b/docs/proposals/feature-bounties/hide-annotations.md new file mode 100644 index 0000000000000..47c9b943b8f71 --- /dev/null +++ b/docs/proposals/feature-bounties/hide-annotations.md @@ -0,0 +1,23 @@ +# Proposal: Allow Hiding Certain Annotations in the Argo CD Web UI + +Based on this issue: https://github.com/argoproj/argo-cd/issues/15693 + +Award amount: $100 + +## Solution + +!!! note + This is the proposed solution. The accepted PR may differ from this proposal. + +Add a new config item in argocd-cm: + +```yaml +hide.secret.annotations: | +- openshift.io/token-secret.value +``` + +This will hide the `openshift.io/token-secret.value` annotation from the UI. Behind the scenes, it would likely work the +same way as the `last-applied-configuration` annotation hiding works: https://github.com/argoproj/gitops-engine/blob/b0fffe419a0f0a40f9f2c0b6346b752ed6537385/pkg/diff/diff.go#L897 + +I considered whether we'd want to support hiding things besides annotations and in resources besides secrets, but +having reviewed existing issues, I think this narrow feature is sufficient. From 5d3bdb5bd01cd3836db4ae3172bbd2630c7a51c3 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:14:43 -0400 Subject: [PATCH 12/13] fix(docs): proj role list example (#16074) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- cmd/argocd/commands/project_role.go | 4 ++-- docs/user-guide/commands/argocd_proj_role_list.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index 166d8f3979be2..8dca406a9dc30 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -397,10 +397,10 @@ func NewProjectRoleListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co Short: "List all the roles in a project", Example: templates.Examples(` # This command will list all the roles in argocd-project in a default table format. - argocd list argocd-project + argocd proj role list PROJECT # List the roles in the project in formats like json, yaml, wide, or name. - argocd list argocd-project --output json + argocd proj role list PROJECT --output json `), diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index ea6e0099d4611..3cfd630ddc988 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -12,10 +12,10 @@ argocd proj role list PROJECT [flags] ``` # This command will list all the roles in argocd-project in a default table format. - argocd list argocd-project + argocd proj role list PROJECT # List the roles in the project in formats like json, yaml, wide, or name. - argocd list argocd-project --output json + argocd proj role list PROJECT --output json ``` ### Options From f37d24f6d8494f5905bc0485d079ea5070e25a2b Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Tue, 24 Oct 2023 13:41:22 -0700 Subject: [PATCH 13/13] feat: make git requests configurable (#15646) * feat: make git requests configurable Signed-off-by: Alexander Matyushentsev * docs: mention new settings in 'argocd-cmd-params-cm' configmap Signed-off-by: Alexander Matyushentsev * add comment about ignored error Signed-off-by: Alexander Matyushentsev --------- Signed-off-by: Alexander Matyushentsev --- .../operator-manual/argocd-cmd-params-cm.yaml | 4 ++++ .../argocd-repo-server-deployment.yaml | 12 ++++++++++ manifests/core-install.yaml | 12 ++++++++++ manifests/ha/install.yaml | 12 ++++++++++ manifests/ha/namespace-install.yaml | 12 ++++++++++ manifests/install.yaml | 12 ++++++++++ manifests/namespace-install.yaml | 12 ++++++++++ reposerver/metrics/githandlers.go | 24 +++++++++++++++++++ util/git/client.go | 8 +++++-- 9 files changed, 106 insertions(+), 2 deletions(-) diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index 7d38506d0b7ec..f9f8b3fc14d52 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -154,6 +154,10 @@ data: reposerver.streamed.manifest.max.extracted.size: "1G" # Enable git submodule support reposerver.enable.git.submodule: "true" + # Number of concurrent git ls-remote requests. Any value less than 1 means no limit. + reposerver.git.lsremote.parallelism.limit: "0" + # Git requests timeout. + reposerver.git.request.timeout: "15s" # Disable TLS on the HTTP endpoint dexserver.disable.tls: "false" diff --git a/manifests/base/repo-server/argocd-repo-server-deployment.yaml b/manifests/base/repo-server/argocd-repo-server-deployment.yaml index eb230e0f9b856..728c80c14bc2a 100644 --- a/manifests/base/repo-server/argocd-repo-server-deployment.yaml +++ b/manifests/base/repo-server/argocd-repo-server-deployment.yaml @@ -168,6 +168,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 8456f5c3ef430..86e636e12ef59 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -21042,6 +21042,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index a2e1e5b91b668..043083de6be84 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -22528,6 +22528,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index ea123ef2e50ef..524ec8ace3e6c 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2184,6 +2184,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/install.yaml b/manifests/install.yaml index 6783484ed0150..a08c3a5cd1302 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -21574,6 +21574,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 0490434f4046c..cfdf7756ff134 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1230,6 +1230,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/reposerver/metrics/githandlers.go b/reposerver/metrics/githandlers.go index cce632cf56813..09a0591002c52 100644 --- a/reposerver/metrics/githandlers.go +++ b/reposerver/metrics/githandlers.go @@ -1,11 +1,27 @@ package metrics import ( + "context" + "math" "time" + "golang.org/x/sync/semaphore" + + "github.com/argoproj/argo-cd/v2/util/env" "github.com/argoproj/argo-cd/v2/util/git" ) +var ( + lsRemoteParallelismLimit = env.ParseInt64FromEnv("ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT", 0, 0, math.MaxInt64) + lsRemoteParallelismLimitSemaphore *semaphore.Weighted +) + +func init() { + if lsRemoteParallelismLimit > 0 { + lsRemoteParallelismLimitSemaphore = semaphore.NewWeighted(lsRemoteParallelismLimit) + } +} + // NewGitClientEventHandlers creates event handlers that update Git related metrics func NewGitClientEventHandlers(metricsServer *MetricsServer) git.EventHandlers { return git.EventHandlers{ @@ -19,7 +35,15 @@ func NewGitClientEventHandlers(metricsServer *MetricsServer) git.EventHandlers { OnLsRemote: func(repo string) func() { startTime := time.Now() metricsServer.IncGitRequest(repo, GitRequestTypeLsRemote) + if lsRemoteParallelismLimitSemaphore != nil { + // The `Acquire` method returns either `nil` or error of the provided context. The + // context.Background() is never canceled, so it is safe to ignore the error. + _ = lsRemoteParallelismLimitSemaphore.Acquire(context.Background(), 1) + } return func() { + if lsRemoteParallelismLimitSemaphore != nil { + lsRemoteParallelismLimitSemaphore.Release(1) + } metricsServer.ObserveGitRequestDuration(repo, GitRequestTypeLsRemote, time.Since(startTime)) } }, diff --git a/util/git/client.go b/util/git/client.go index 6b8587c0b3660..6a8828d13f432 100644 --- a/util/git/client.go +++ b/util/git/client.go @@ -174,6 +174,10 @@ func NewClientExt(rawRepoURL string, root string, creds Creds, insecure bool, en return client, nil } +var ( + gitClientTimeout = env.ParseDurationFromEnv("ARGOCD_GIT_REQUEST_TIMEOUT", 15*time.Second, 0, math.MaxInt64) +) + // Returns a HTTP client object suitable for go-git to use using the following // pattern: // - If insecure is true, always returns a client with certificate verification @@ -185,8 +189,8 @@ func NewClientExt(rawRepoURL string, root string, creds Creds, insecure bool, en func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds, proxyURL string) *http.Client { // Default HTTP client var customHTTPClient = &http.Client{ - // 15 second timeout - Timeout: 15 * time.Second, + // 15 second timeout by default + Timeout: gitClientTimeout, // don't follow redirect CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse