Skip to content

Conversation

aali309
Copy link
Contributor

@aali309 aali309 commented Aug 6, 2025

Problem Analysis
The ArgoCD operator fails to reconcile ArgoCD Custom Resources with long names due to Kubernetes' 63-character limit for label values. When the ArgoCD CR name exceeds approximately 40 characters, the generated secret names (like {cr-name}-cluster and {cr-name}-redis-initial-password) exceed 63 characters and are used as label values, causing Kubernetes validation failures.
Specific failure points:
Secret names like argocd-long-name-for-route-testiiiiiiiiiiiiiiiiiiiiiiiing-cluster (74+ characters)
Secret names like argocd-long-name-for-route-testiiiiiiiiiiiiiiiiiiiiiiiing-redis-initial-password (85+ characters)
These names are used in metadata.labels[app.kubernetes.io/name] fields, triggering the validation error

Root Cause
The operator was using generated resource names directly as Kubernetes label values without checking the 63-character RFC 1123 limit. Specifically:
Secret Creation: NewSecretWithName() function set secret.Labels[common.ArgoCDKeyName] = name where name could exceed 63 characters
Resource Naming: Generated names like {cr.Name}-cluster and {cr.Name}-redis-initial-password were used directly
Reference Inconsistency: Some code used hardcoded fmt.Sprintf() patterns while others used helper functions, creating potential mismatches

What type of PR is this?
These changes fixes length validation errors that occur when creating ArgoCD
instances with long names by implementing comprehensive truncation with hash
suffixes to ensure uniqueness while staying within Kubernetes limits.

/kind bug

What does this PR do / why we need it:

Have you updated the necessary documentation?

  • Documentation update is required by this PR.
  • Documentation has been updated.

Which issue(s) this PR fixes:

Fixes #?

How to test changes / Special notes to the reviewer:

aali309 added 3 commits August 6, 2025 00:56
…character limit

Signed-off-by: Atif Ali <atali@redhat.com>
Signed-off-by: Atif Ali <atali@redhat.com>
… 63 chars

Signed-off-by: Atif Ali <atali@redhat.com>
@aali309 aali309 marked this pull request as ready for review August 6, 2025 18:52
Copy link

@ranakan19 ranakan19 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should preserve the suffix of generated resources. In you current approach, a suffix is added and then the name is truncated, the suffix itself will cut off when the argocd cr name is already above 63 characters. This could make it difficult for users to search for resources using those suffixes.

A better approach would be to:

  1. Truncate the custom resource (CR) name first. We can store this truncated name as an annotation on the ArgoCD CR.
  2. Append the full suffix to the already-truncated name.

for example on applicationset:

truncatedCrName := cr.Annotations[truncatedNameKey]
...
svc.Spec.Selector = map[string]string{
		common.ArgoCDKeyName: nameWithSuffix(common.ApplicationSetServiceNameSuffix, truncatedCrName),
	}

So for the examples mentioned:
argocd-cr name: argocd-long-for-route-testing-long-very-long-very-very-long-name
truncated cr-name: argocd-long-for-route-testing-long-very(39 chars after removing the trailing -)
secrets would be: argocd-long-for-route-testing-long-very-cluster (47 characters)
and argocd-long-for-route-testing-long-very-redis-initial-password (62 characters)

To determine the correct truncation length, we need to find the maximum possible suffix length and subtract that from the Kubernetes limit of 63 characters. A common suffix, such as -redis-initial-password, is 23 characters long. Therefore, the truncated CR name should be limited to 40 characters (63 - 23 = 40). You can cross-check if there is indeed the longest suffix.

Feel free to use something other than annotation as well, whatever is easier.

…e field && remove specific hostname validation

Signed-off-by: Atif Ali <atali@redhat.com>
@aali309 aali309 requested a review from ranakan19 August 6, 2025 21:47
Signed-off-by: Atif Ali <atali@redhat.com>
@@ -943,7 +943,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoproj.ArgoCD) er
}

svc.Spec.Selector = map[string]string{
common.ArgoCDKeyName: nameWithSuffix(common.ApplicationSetServiceNameSuffix, cr),
common.ArgoCDKeyName: argoutil.TruncateWithHash(nameWithSuffix(common.ApplicationSetServiceNameSuffix, cr)),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will still truncate the suffix

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually no, looking further you have the truncated CR logic in nameWithSuffix.
So is TruncateWithHash needed here if nameWithSuffix already takes care of having the name under 63 chars?
It is a little confusing with the names, maybe you could consider renaming them so its clearer what the function is doing?

Copy link

@ranakan19 ranakan19 Aug 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also another function with the same name - https://github.com/argoproj-labs/argocd-operator/blob/master/controllers/argoutil/resource.go#L118 - so should definitely rename nameWithSuffix you are adding.


// Truncate the name to stay within 63 character limit
fullName := fmt.Sprintf("%s-%s", cr.Name, name)
roleBinding.Name = truncateWithHash(fullName)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is using https://github.com/argoproj-labs/argocd-operator/blob/master/controllers/argocd/rolebinding.go#L28, which looks redundant, Could this be replaced with argoutil.TruncateWithHash() instead? And thus removing the function from rolebinding.go, would need to replace its occurance in tests as well.

Signed-off-by: Atif Ali <atali@redhat.com>
@aali309 aali309 requested a review from ranakan19 August 21, 2025 23:52
Copy link

@ranakan19 ranakan19 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for making these changes! I had a few follow-ups we can consider:

  1. We could consolidate and remove the redundant truncateWithHash() function.
  2. The function nameWithSuffix might be clearer if renamed. (and there is an existing function with the same name)
  3. Some tests seem to be missing — I see coverage for routes and secrets, but since the changes affect multiple k8s resources, it may help to add tests for a long-name Argo CD instance in the relevant resource files. If not kuttl tests, unit tests would also work (e.g., networkpolicies_test.go).
  4. Not blocking, but it could be nice to add tests for the new functions TruncateCRName(), GetTruncatedCRName(), and nameWithSuffix().
  5. I noticed that references to argoutil.TruncateWithHash() in networkpolicies.go may truncate the suffix when the Argo CD instance name is long. To keep things consistent, might consider using the nameWithSuffix approach, since it preserves the suffix.

@aali309
Copy link
Contributor Author

aali309 commented Aug 22, 2025

  • The function nameWithSuffix might be clearer if renamed. (and there is an existing function with the same name)

On your 2nd point, the function already existed in the codebase, and renaming it is a separate concern that should be addressed in another PR. I will create another follow up PR for this once this is merged.

Signed-off-by: Atif Ali <atali@redhat.com>
@@ -325,7 +326,7 @@ func TestReconcileArgoCD_reconcileRoleBinding_forSourceNamespaces(t *testing.T)
expectedName := getRoleBindingNameForSourceNamespaces(a.Name, sourceNamespace)

// Verify the name is truncated to 63 characters
assert.LessOrEqual(t, len(expectedName), maxLabelLength, "RoleBinding name should not exceed maxLabelLength")
assert.LessOrEqual(t, len(expectedName), 63, "RoleBinding name should not exceed maxLabelLength")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason to remove the maxLabelLength usage here? Its better to not hardcode it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was doing some testing, forgot to restore it

Signed-off-by: Atif Ali <atali@redhat.com>
Signed-off-by: Atif Ali <atali@redhat.com>
Signed-off-by: Atif Ali <atali@redhat.com>
Signed-off-by: Atif Ali <atali@redhat.com>
Signed-off-by: Atif Ali <atali@redhat.com>
@aali309 aali309 requested a review from ranakan19 September 2, 2025 20:03
@@ -943,7 +943,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoproj.ArgoCD) er
}

svc.Spec.Selector = map[string]string{
common.ArgoCDKeyName: nameWithSuffix(common.ApplicationSetServiceNameSuffix, cr),
common.ArgoCDKeyName: argoutil.TruncateWithHash(fmt.Sprintf("%s-%s", cr.Name, common.ApplicationSetServiceNameSuffix)),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
common.ArgoCDKeyName: argoutil.TruncateWithHash(fmt.Sprintf("%s-%s", cr.Name, common.ApplicationSetServiceNameSuffix)),
common.ArgoCDKeyName: nameWithSuffix(common.ApplicationSetServiceNameSuffix, cr),

This should be keeping the suffix as well.
For the long argocd name - argocd-long-name-for-route-testiiiiiiiiiiiiiiiiiiiiiiiing the selector with your current changes would have the value argocd-long-name-for-route-testiiiiiiiiiiiiiiiii-2a814fa2e3b158 instead of the expected argocd-long-name-for-r-2a814fa2e3b158-applicationset-controller
Correct me if wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I actually missed this!

Copy link

@ranakan19 ranakan19 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you for adding tests, left a few comments to address.

Signed-off-by: Atif Ali <atali@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants