-
Notifications
You must be signed in to change notification settings - Fork 991
fix: Truncate Kubernetes resource names and labels to comply with 63-… #1813
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…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>
There was a problem hiding this 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:
- Truncate the custom resource (CR) name first. We can store this truncated name as an annotation on the ArgoCD CR.
- 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>
Signed-off-by: Atif Ali <atali@redhat.com>
controllers/argocd/applicationset.go
Outdated
@@ -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)), |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
controllers/argocd/rolebinding.go
Outdated
|
||
// Truncate the name to stay within 63 character limit | ||
fullName := fmt.Sprintf("%s-%s", cr.Name, name) | ||
roleBinding.Name = truncateWithHash(fullName) |
There was a problem hiding this comment.
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>
There was a problem hiding this 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:
- We could consolidate and remove the redundant truncateWithHash() function.
- The function nameWithSuffix might be clearer if renamed. (and there is an existing function with the same name)
- 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).
- Not blocking, but it could be nice to add tests for the new functions TruncateCRName(), GetTruncatedCRName(), and nameWithSuffix().
- 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.
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") |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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>
controllers/argocd/applicationset.go
Outdated
@@ -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)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this 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>
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?
Which issue(s) this PR fixes:
Fixes #?
How to test changes / Special notes to the reviewer: