fix(controller): handle long rule names in bootstrap annotation keys#224
fix(controller): handle long rule names in bootstrap annotation keys#224vishnukothakapu wants to merge 1 commit into
Conversation
✅ Deploy Preview for node-readiness-controller canceled.
|
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: vishnukothakapu The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Welcome @vishnukothakapu! |
|
Hi @vishnukothakapu. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
538cca4 to
d42de51
Compare
|
Thanks for catching this. My only thoughts on this is that it takes away the human observability on this when a bootsrap-rule is done. :/ |
| // 20 (prefix) + 32 (hash) = 52 characters. | ||
| namePart = hex.EncodeToString(hash[:16]) | ||
| } | ||
| return fmt.Sprintf("%s%s", bootstrapAnnotationPrefix, namePart) |
There was a problem hiding this comment.
should we go with a hybrid approach something like below
availableSpace := maxK8sAnnotationNameLen - len(bootstrapAnnotationPrefix)
const hashLen = 8
humanPartLen := availableSpace - hashLen - 1
hashBytes := sha256.Sum256([]byte(ruleName))
shortHash := hex.EncodeToString(hashBytes[:])[:hashLen]
namePart := fmt.Sprintf("%s-%s", ruleName[:humanPartLen], shortHash)
return fmt.Sprintf("%s%s", bootstrapAnnotationPrefix, namePart)this way we keep the ruleName
There was a problem hiding this comment.
we have a lot of options to handle this. I added some different approach as well. We could discuss further over the meeting, feel free to join if you are available, @vishnukothakapu
|
The annotation restrictions are Hashing the rule name is one option, couple of alternatives to consider:
We need to evaluate the pros/cons on the implementation. @vishnukothakapu Do you want to evaluate the alternatives and propose a plan here? |
Good point. I agree the full hash reduces readability during debugging. I’ll explore the hybrid approach with a readable prefix + short hash and compare it with the other alternatives discussed.
Thanks @ajaysundark , these are good points. I’ll evaluate the tradeoffs between the current hashing approach, the hybrid readable-prefix approach, and the single annotation JSON payload design, then propose a direction based on readability, implementation complexity, and backward compatibility. |
|
/assign @vishnukothakapu |
|
Hi @AvineshTripathi & @ajaysundark, |
87864cf to
261f03d
Compare
Could you clarify your thoughts further on this? What are the downsides of using a json payload. This is also how kubectl saves last applied configurations in objects today - ref: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/#how-to-create-objects @AvineshTripathi / @Karthik-K-N I think fixing this short-term with a hash based approach for length immunity doesnt feel right. A more reliable long term solution would be to maintain the rule-status inside a JSON payload to track individual rule evaluation data. It would also address concerns such as #247 |
|
Hi @ajaysundark, thanks for the clarification, that makes sense. I can see how the structured JSON payload approach becomes more reliable long-term, especially with concerns like stale rule state and rule recreation handling from #247. My initial preference for the hybrid approach was mainly to keep the fix minimal and avoid larger behavioral changes in this PR. But I agree the stable key + structured payload model feels more extensible and better suited for tracking rule lifecycle/state going forward. |
@ajaysundark, the JSON payload approach is the right long-term design. It eliminates the key length issue at the root, preserves full observability (complete rule name in the value), and cleanly resolves #247, a deleted+recreated rule would no longer be blocked by a stale annotation. The main considerations are:
|
261f03d to
4f850ec
Compare
… state
Replace the per-rule hash-based annotation key approach with a single
structured JSON annotation on the node:
readiness.k8s.io/bootstrap-state -> {"rule-a": true, "rule-b": true}
This eliminates the 63-character Kubernetes annotation name-segment limit
at the root by moving rule names into the annotation value rather than
the key. The pattern mirrors kubectl's last-applied-configuration approach.
Benefits over the hybrid hash approach:
- Full rule name is always preserved and human-readable in the value
- No key length constraint for arbitrarily long rule names
- Resolves stale annotation issue on rule delete+recreate (kubernetes-sigs#247): a
deleted rule no longer silently blocks evaluation on recreation since
its entry can be absent from the map
- Single annotation provides a consolidated view of all bootstrap state
Read-modify-write races are handled via RetryOnConflict, consistent with
the existing addTaintBySpec/removeTaintBySpec pattern.
Existing per-rule readiness.k8s.io/bootstrap-completed-* annotations on
nodes are left as inert no-ops and do not affect the new logic.
66f3eeb to
86fbd4d
Compare
Description
This PR fixes a bug where NodeReadinessRule resources with long names (longer than 43 characters) caused the controller to fail when patching Node annotations. Kubernetes strictly limits the name part of an annotation key to 63 characters. Since our key pattern was
readiness.k8s.io/bootstrap-completed-<rule-name>, long rule names resulted in invalid annotation keys.Instead of a hash-based workaround, this PR adopts a structured JSON payload annotation on the node, the same pattern kubectl uses for
kubectl.kubernetes.io/last-applied-configuration. A single annotation key stores a JSON map of all bootstrap-completed rules:This eliminates the key length constraint at the root by moving rule names into the annotation value rather than the key, and also addresses the stale annotation issue from #247, a deleted and recreated rule is no longer silently skipped due to a persisting annotation key.
Related Issue
Fixes #223
Type of Change
/kind bug
Testing
Checklist
make testpassesmake lintpassesDoes this PR introduce a user-facing change?
Nodes that previously had readiness.k8s.io/bootstrap-completed-* annotations will retain them as harmless no-ops. Bootstrap state is now tracked under the single annotation readiness.k8s.io/bootstrap-state.