Skip to content

Commit 0c393e6

Browse files
committed
fix: limit number of resources in appset status (argoproj#24690)
Signed-off-by: Alexander Matyushentsev <[email protected]>
1 parent 28510cd commit 0c393e6

16 files changed

+158
-11
lines changed

applicationset/controllers/applicationset_controller.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ type ApplicationSetReconciler struct {
100100
GlobalPreservedAnnotations []string
101101
GlobalPreservedLabels []string
102102
Metrics *metrics.ApplicationsetMetrics
103+
MaxResourcesStatusCount int
103104
}
104105

105106
// +kubebuilder:rbac:groups=argoproj.io,resources=applicationsets,verbs=get;list;watch;create;update;patch;delete
@@ -1398,6 +1399,11 @@ func (r *ApplicationSetReconciler) updateResourcesStatus(ctx context.Context, lo
13981399
sort.Slice(statuses, func(i, j int) bool {
13991400
return statuses[i].Name < statuses[j].Name
14001401
})
1402+
1403+
if r.MaxResourcesStatusCount > 0 && len(statuses) > r.MaxResourcesStatusCount {
1404+
logCtx.Warnf("Truncating ApplicationSet %s resource status from %d to max allowed %d entries", appset.Name, len(statuses), r.MaxResourcesStatusCount)
1405+
statuses = statuses[:r.MaxResourcesStatusCount]
1406+
}
14011407
appset.Status.Resources = statuses
14021408
// DefaultRetry will retry 5 times with a backoff factor of 1, jitter of 0.1 and a duration of 10ms
14031409
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {

applicationset/controllers/applicationset_controller_test.go

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6410,10 +6410,11 @@ func TestUpdateResourceStatus(t *testing.T) {
64106410
require.NoError(t, err)
64116411

64126412
for _, cc := range []struct {
6413-
name string
6414-
appSet v1alpha1.ApplicationSet
6415-
apps []v1alpha1.Application
6416-
expectedResources []v1alpha1.ResourceStatus
6413+
name string
6414+
appSet v1alpha1.ApplicationSet
6415+
apps []v1alpha1.Application
6416+
expectedResources []v1alpha1.ResourceStatus
6417+
maxResourcesStatusCount int
64176418
}{
64186419
{
64196420
name: "handles an empty application list",
@@ -6577,6 +6578,73 @@ func TestUpdateResourceStatus(t *testing.T) {
65776578
apps: []v1alpha1.Application{},
65786579
expectedResources: nil,
65796580
},
6581+
{
6582+
name: "truncates resources status list to",
6583+
appSet: v1alpha1.ApplicationSet{
6584+
ObjectMeta: metav1.ObjectMeta{
6585+
Name: "name",
6586+
Namespace: "argocd",
6587+
},
6588+
Status: v1alpha1.ApplicationSetStatus{
6589+
Resources: []v1alpha1.ResourceStatus{
6590+
{
6591+
Name: "app1",
6592+
Status: v1alpha1.SyncStatusCodeOutOfSync,
6593+
Health: &v1alpha1.HealthStatus{
6594+
Status: health.HealthStatusProgressing,
6595+
Message: "this is progressing",
6596+
},
6597+
},
6598+
{
6599+
Name: "app2",
6600+
Status: v1alpha1.SyncStatusCodeOutOfSync,
6601+
Health: &v1alpha1.HealthStatus{
6602+
Status: health.HealthStatusProgressing,
6603+
Message: "this is progressing",
6604+
},
6605+
},
6606+
},
6607+
},
6608+
},
6609+
apps: []v1alpha1.Application{
6610+
{
6611+
ObjectMeta: metav1.ObjectMeta{
6612+
Name: "app1",
6613+
},
6614+
Status: v1alpha1.ApplicationStatus{
6615+
Sync: v1alpha1.SyncStatus{
6616+
Status: v1alpha1.SyncStatusCodeSynced,
6617+
},
6618+
Health: v1alpha1.AppHealthStatus{
6619+
Status: health.HealthStatusHealthy,
6620+
},
6621+
},
6622+
},
6623+
{
6624+
ObjectMeta: metav1.ObjectMeta{
6625+
Name: "app2",
6626+
},
6627+
Status: v1alpha1.ApplicationStatus{
6628+
Sync: v1alpha1.SyncStatus{
6629+
Status: v1alpha1.SyncStatusCodeSynced,
6630+
},
6631+
Health: v1alpha1.AppHealthStatus{
6632+
Status: health.HealthStatusHealthy,
6633+
},
6634+
},
6635+
},
6636+
},
6637+
expectedResources: []v1alpha1.ResourceStatus{
6638+
{
6639+
Name: "app1",
6640+
Status: v1alpha1.SyncStatusCodeSynced,
6641+
Health: &v1alpha1.HealthStatus{
6642+
Status: health.HealthStatusHealthy,
6643+
},
6644+
},
6645+
},
6646+
maxResourcesStatusCount: 1,
6647+
},
65806648
} {
65816649
t.Run(cc.name, func(t *testing.T) {
65826650
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
@@ -6587,13 +6655,14 @@ func TestUpdateResourceStatus(t *testing.T) {
65876655
argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset)
65886656

65896657
r := ApplicationSetReconciler{
6590-
Client: client,
6591-
Scheme: scheme,
6592-
Recorder: record.NewFakeRecorder(1),
6593-
Generators: map[string]generators.Generator{},
6594-
ArgoDB: argodb,
6595-
KubeClientset: kubeclientset,
6596-
Metrics: metrics,
6658+
Client: client,
6659+
Scheme: scheme,
6660+
Recorder: record.NewFakeRecorder(1),
6661+
Generators: map[string]generators.Generator{},
6662+
ArgoDB: argodb,
6663+
KubeClientset: kubeclientset,
6664+
Metrics: metrics,
6665+
MaxResourcesStatusCount: cc.maxResourcesStatusCount,
65976666
}
65986667

65996668
err := r.updateResourcesStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps)

cmd/argocd-applicationset-controller/commands/applicationset_controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ func NewCommand() *cobra.Command {
7979
enableScmProviders bool
8080
webhookParallelism int
8181
tokenRefStrictMode bool
82+
maxResourcesStatusCount int
8283
)
8384
scheme := runtime.NewScheme()
8485
_ = clientgoscheme.AddToScheme(scheme)
@@ -231,6 +232,7 @@ func NewCommand() *cobra.Command {
231232
GlobalPreservedAnnotations: globalPreservedAnnotations,
232233
GlobalPreservedLabels: globalPreservedLabels,
233234
Metrics: &metrics,
235+
MaxResourcesStatusCount: maxResourcesStatusCount,
234236
}).SetupWithManager(mgr, enableProgressiveSyncs, maxConcurrentReconciliations); err != nil {
235237
log.Error(err, "unable to create controller", "controller", "ApplicationSet")
236238
os.Exit(1)
@@ -275,6 +277,7 @@ func NewCommand() *cobra.Command {
275277
command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently")
276278
command.Flags().StringSliceVar(&metricsAplicationsetLabels, "metrics-applicationset-labels", []string{}, "List of Application labels that will be added to the argocd_applicationset_labels metric")
277279
command.Flags().BoolVar(&enableGitHubAPIMetrics, "enable-github-api-metrics", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_GITHUB_API_METRICS", false), "Enable GitHub API metrics for generators that use the GitHub API")
280+
command.Flags().IntVar(&maxResourcesStatusCount, "max-resources-status-count", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT", 0, 0, math.MaxInt), "Max number of resources stored in appset status.")
278281

279282
return &command
280283
}

docs/operator-manual/argocd-cmd-params-cm.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ data:
292292
applicationsetcontroller.global.preserved.labels: "acme.com/label1,acme.com/label2"
293293
# Enable GitHub API metrics for generators that use GitHub API
294294
applicationsetcontroller.enable.github.api.metrics: "false"
295+
# The maximum number of resources stored in the status of an ApplicationSet. This is a safeguard to prevent the status from growing too large.
296+
applicationsetcontroller.status.max.resources.count: "5000"
295297

296298
## Argo CD Notifications Controller Properties
297299
# Set the logging level. One of: debug|info|warn|error (default "info")

docs/operator-manual/server-commands/argocd-applicationset-controller.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ spec:
187187
name: argocd-cmd-params-cm
188188
key: applicationsetcontroller.requeue.after
189189
optional: true
190+
- name: ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT
191+
valueFrom:
192+
configMapKeyRef:
193+
name: argocd-cmd-params-cm
194+
key: applicationsetcontroller.status.max.resources.count
195+
optional: true
190196
volumeMounts:
191197
- mountPath: /app/config/ssh
192198
name: ssh-known-hosts

manifests/core-install-with-hydrator.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

manifests/core-install.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

manifests/ha/install-with-hydrator.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

manifests/ha/install.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)